From eb02ecda206a007ba5aca672204c1ca3ddb4b31a Mon Sep 17 00:00:00 2001 From: RamiBerm Date: Mon, 19 Jul 2021 09:08:21 +0300 Subject: [PATCH 01/69] Update main.go --- api/main.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/api/main.go b/api/main.go index 40c930b73..c09af2ecc 100644 --- a/api/main.go +++ b/api/main.go @@ -10,6 +10,7 @@ import ( "github.com/romana/rlog" "github.com/up9inc/mizu/shared" "github.com/up9inc/mizu/tap" + "log" "mizuserver/pkg/api" "mizuserver/pkg/middleware" "mizuserver/pkg/models" @@ -18,6 +19,7 @@ import ( "mizuserver/pkg/utils" "os" "os/signal" + "runtime/pprof" "strings" ) @@ -65,6 +67,12 @@ func main() { go pipeChannelToSocket(socketConnection, harOutputChannel) go api.StartReadingOutbound(outboundLinkOutputChannel) } else if *aggregator { + f, err := os.Create("/app/profile.pprof") + if err != nil { + log.Fatal(err) + } + fmt.Println("Starting profiling4") + pprof.StartCPUProfile(f) socketHarOutChannel := make(chan *tap.OutputChannelItem, 1000) filteredHarChannel := make(chan *tap.OutputChannelItem) From 9d9f64098e1432e73818b38122c96cc54a8f1237 Mon Sep 17 00:00:00 2001 From: RamiBerm Date: Mon, 19 Jul 2021 17:39:59 +0300 Subject: [PATCH 02/69] Update go.mod and go.sum --- api/go.mod | 8 ++-- api/go.sum | 137 +++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 127 insertions(+), 18 deletions(-) diff --git a/api/go.mod b/api/go.mod index 27833d4e4..621967485 100644 --- a/api/go.mod +++ b/api/go.mod @@ -3,14 +3,15 @@ module mizuserver go 1.16 require ( - github.com/antoniodipinto/ikisocket v0.0.0-20210417133349-f1502512d69a + github.com/antoniodipinto/ikisocket v0.0.0-20210719130628-946ce6188452 github.com/beevik/etree v1.1.0 github.com/djherbis/atime v1.0.0 github.com/fasthttp/websocket v1.4.3-beta.1 // indirect + github.com/fsnotify/fsnotify v1.4.9 github.com/go-playground/locales v0.13.0 github.com/go-playground/universal-translator v0.17.0 github.com/go-playground/validator/v10 v10.5.0 - github.com/gofiber/fiber/v2 v2.8.0 + github.com/gofiber/fiber/v2 v2.10.0 github.com/google/martian v2.1.0+incompatible github.com/gorilla/websocket v1.4.2 github.com/leodido/go-urn v1.2.1 // indirect @@ -23,9 +24,10 @@ require ( k8s.io/api v0.21.0 k8s.io/apimachinery v0.21.0 k8s.io/client-go v0.21.0 - github.com/fsnotify/fsnotify v1.4.9 ) replace github.com/up9inc/mizu/shared v0.0.0 => ../shared replace github.com/up9inc/mizu/tap v0.0.0 => ../tap + +replace github.com/antoniodipinto/ikisocket v0.0.0-20210719130628-946ce6188452 => github.com/up9inc/ikisocket v0.0.0-20210719130628-946ce6188452 diff --git a/api/go.sum b/api/go.sum index 28981733e..eea23521c 100644 --- a/api/go.sum +++ b/api/go.sum @@ -12,15 +12,20 @@ cloud.google.com/go v0.54.0 h1:3ithwDMr7/3vpAMXiH+ZQnYbuIsh+OPhUPMFC9enmn0= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0 h1:xE3CPsOgttP4ACBePh79zTKALtXwn/Edhcr16R5hMWU= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0 h1:Lpy6hKgdcl7a3WGSfJIFmxmcdjSpP6OmBEfcOv1Y680= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0 h1:UDpwYIwla4jHGzZJaEJYx1tOejbgSoNqsAfHAUYe2r8= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= @@ -36,25 +41,36 @@ github.com/Azure/go-autorest/logger v0.2.0 h1:e4RVHVZKC5p6UANLJHkM4OfR1UKZPj8Wt8 github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 h1:lsxEuwrXEAokXB9qhlbKWPpo3KMLZQ5WB5WLQRW1uq0= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= -github.com/antoniodipinto/ikisocket v0.0.0-20210417133349-f1502512d69a h1:76llBleIE3fkdqaJFDzdirtiYhQPdIQem8H8r2iwA1Q= -github.com/antoniodipinto/ikisocket v0.0.0-20210417133349-f1502512d69a/go.mod h1:QvDfsDQDmGxUsvEeWabVZ5pp2FMXpOkwQV0L6SE6cp0= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/aws/aws-sdk-go v1.34.28 h1:sscPpn/Ns3i0F4HPEWAVcwdIRaZZCuL7llJ2/60yPIk= github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= +github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -63,12 +79,19 @@ github.com/djherbis/atime v1.0.0 h1:ySLvBAM0EvOGaX7TI4dAM5lWj+RdJUCKtGSEHN8SGBg= github.com/djherbis/atime v1.0.0/go.mod h1:5W+KBIuTwVGcqjIfaTwt+KSYX1o6uep8dtevevQP/f8= 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/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1/YsqVWoWNLQO+fusocsw354rqGTZtAgw= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473 h1:4cmBvAEBNJaGARUEs3/suWRyfyBfhf7I60WBZq+bv2w= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fasthttp/websocket v0.0.0-20200320073529-1554a54587ab/go.mod h1:smsv/h4PBEBaU0XDTY5UwJTpZv69fQ0FfcLJr21mA6Y= github.com/fasthttp/websocket v1.4.2/go.mod h1:smsv/h4PBEBaU0XDTY5UwJTpZv69fQ0FfcLJr21mA6Y= github.com/fasthttp/websocket v1.4.3-beta.1 h1:stc4P2aoxYKsdmbe1AJ5mAm73Fxc1NOgrZpPftvZIXQ= github.com/fasthttp/websocket v1.4.3-beta.1/go.mod h1:JGrgLaT02bL9NuJkZbHN8mVV2tkCJZQh7yJ5/XCXO2g= @@ -77,18 +100,24 @@ github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoD github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -98,48 +127,63 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.5.0 h1:X9rflw/KmpACwT8zdrm1upefpvdy6ur8d1kWyq6sg3E= github.com/go-playground/validator/v10 v10.5.0/go.mod h1:xm76BBt941f7yWdGnI2DVPFFg1UK3YY04qifoXU3lOk= +github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd h1:hSkbZ9XSyjyBirMeqSqUrK+9HboWrweVlzRNqoBi2d4= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0 h1:31atYa/UW9V5q8vMJ+W6wd64OaaTHUrCUXER358zLM4= github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0 h1:GlXgaiBkmrYMHco6t4j7SacKO4XUjvh5pwXh0f4uxXU= github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3 h1:3GQ53z7E3o00C/yy7Ko8VXqQXoJGLkrTQCLTF1EjoXU= github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1 h1:iQ0D6SpNXIxu52WESsD+KoQ7af2e3nCfnSBoSF/hKe0= github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211 h1:mSVZ4vj4khv+oThUfS+SQU3UuFIZ5Zo6UNcvK8E8Mz8= github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1 h1:dLg+zb+uOyd/mKeQUYIbwbNmfRsr9hd/WtYWepmayhI= github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2 h1:8thhT+kUJMTMy3HlX4+y9Da+BNJck+p109tqqKp7WDs= github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2 h1:fq9WcL1BYrm36SzK6+aAnZ8hcp+SrmnDyAxhNx8dvJk= github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0 h1:4sGKOD8yaYJ+dek1FDkwcxCHA40M4kfKgFHx8N2kwbU= github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0 h1:Ir9W9XIm9j7bhhkKE9cokvtTl1vBm62A/fene/ZCj6A= github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754 h1:tpom+2CJmpzAWj5/VEHync2rJGi+epHNIeRSWjzGA+4= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= -github.com/gofiber/fiber/v2 v2.1.3/go.mod h1:MMiSv1HrDkN8Pv7NeVDYK+T/lwXOEKAvPBbLvJPCEfA= -github.com/gofiber/fiber/v2 v2.7.1/go.mod h1:f8BRRIMjMdRyt2qmJ/0Sea3j3rwwfufPrh9WNBRiVZ0= -github.com/gofiber/fiber/v2 v2.8.0 h1:BdWvZmg/WY/Vjtjm38aXOp1Lks1BhuyS2b7lSWSPAzk= -github.com/gofiber/fiber/v2 v2.8.0/go.mod h1:Ah3IJikrKNRepl/HuVawppS25X7FWohwfCSRn7kJG28= -github.com/gofiber/websocket/v2 v2.0.3 h1:nqPGHB4LQhxKX5KJUjayOd2xiiENieS/dn6TPfCL8uk= -github.com/gofiber/websocket/v2 v2.0.3/go.mod h1:/OTEImCxORKE5unw0dWqJYovid6vZF+wB1W0aaMKs2M= +github.com/gofiber/fiber/v2 v2.10.0 h1:cYwonWaFVa7wBd/LKhgKu7mFNg2CHv5ztY6gzXtrvW8= +github.com/gofiber/fiber/v2 v2.10.0/go.mod h1:Ah3IJikrKNRepl/HuVawppS25X7FWohwfCSRn7kJG28= +github.com/gofiber/websocket/v2 v2.0.4 h1:HvnHekk2dOX8mpqXkuVy5xkON/CkRqLkN5xPHv5pOyM= +github.com/gofiber/websocket/v2 v2.0.4/go.mod h1:qkOGMb5BTRkximKNgPWSSdUBX46yS447xcbL12JGFZM= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1 h1:ocYkMQY5RrXTYgXl7ICpV0IXwlEQGwKIsery4gyXa1U= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 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= @@ -154,8 +198,10 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -175,40 +221,56 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3 h1:SRgJV+IoxM5MKyFdlSUeNy6/ycRUF2yBAKdAQswoHUk= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3 h1:lOpSw2vJP0y5eLBW906QwKsUK/fe/QDyoqM5rnnuPDY= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= @@ -216,12 +278,16 @@ github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.13 h1:eSvu8Tmq6j2psUJqJrLcWH6K3w5Dwc+qipbaA6eVEN4= github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5 h1:hyz3dwM5QLc1Rfoz4FuWJQG5BN7tc6K1MndAUnGpQr4= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -230,12 +296,17 @@ github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgx github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2 h1:JgVTCPf0uBVcUSWpyXmGpgOc62nK5HWUBKAGc3Qqa5k= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ= github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -243,29 +314,38 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d h1:7PxY7LVfSZm7PEeBTyK1rj1gABdCO2mbri6GKO1cMDs= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/orcaman/concurrent-map v0.0.0-20210106121528-16402b402231 h1:fa50YL1pzKW+1SsBnJDOHppJN9stOEwS+CRWyUtyYGU= github.com/orcaman/concurrent-map v0.0.0-20210106121528-16402b402231/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= -github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pelletier/go-toml v1.7.0 h1:7utD74fnzVc/cpcyy8sjrlFr5vYpypUixARcHIMIGuI= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/romana/rlog v0.0.0-20171115192701-f018bc92e7d7 h1:jkvpcEatpwuMF5O5LVxTnehj6YZ/aEZN4NWD/Xml4pI= github.com/romana/rlog v0.0.0-20171115192701-f018bc92e7d7/go.mod h1:KTrHyWpO1sevuXPZwyeZc72ddWRFqNSKDFl7uVWKpg0= @@ -274,8 +354,11 @@ github.com/savsgio/gotils v0.0.0-20200616100644-13ff1fd2c28c h1:KKqhycXW1WVNkX7r github.com/savsgio/gotils v0.0.0-20200616100644-13ff1fd2c28c/go.mod h1:TWNAOTaVzGOXq8RbEvHnhzA/A2sLZzgn0m6URjnukY8= github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -291,28 +374,36 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/up9inc/ikisocket v0.0.0-20210719130628-946ce6188452 h1:9ysEGkPYoEPqDxkqv3NdlECoulHr0ozvqN6Rs9C49Kw= +github.com/up9inc/ikisocket v0.0.0-20210719130628-946ce6188452/go.mod h1:IRtlQDKcJq80t7y6JzYOBKMpHliAHd0dmu7hOhAXU9c= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.9.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/fasthttp v1.15.1/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= -github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= -github.com/valyala/fasthttp v1.18.0/go.mod h1:jjraHZVbKOXftJfsOYoAjaeygpj5hr8ermTRJNroD7A= -github.com/valyala/fasthttp v1.23.0 h1:0ufwSD9BhWa6f8HWdmdq4FHQ23peRo3Ng/Qs8m5NcFs= github.com/valyala/fasthttp v1.23.0/go.mod h1:0mw2RjXGOzxf4NL2jni3gUQ7LfjjUSiG5sskOUUSEpU= +github.com/valyala/fasthttp v1.24.0 h1:AAiG4oLDUArTb7rYf9oO2bkGooOqCaUF6a2u8asBP3I= +github.com/valyala/fasthttp v1.24.0/go.mod h1:0mw2RjXGOzxf4NL2jni3gUQ7LfjjUSiG5sskOUUSEpU= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.mongodb.org/mongo-driver v1.5.1 h1:9nOVLGDfOaZ9R0tBumx/BcuqkbFpyTCU2r/Po7A2azI= go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -335,8 +426,10 @@ golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -347,14 +440,17 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 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= @@ -378,7 +474,6 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226101413-39120d07d75e/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -397,6 +492,7 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -428,9 +524,7 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201210223839-7e3030f88018/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe h1:WdX7u8s3yOigWAhHEaDl8r9G+4XwFQEQFtBMYyN+kXQ= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -488,6 +582,7 @@ golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -503,6 +598,7 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0 h1:jz2KixHX7EcCPiQrySzPdnYT7DbINAypCqKZ1Z7GM40= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -528,6 +624,7 @@ google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4 google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -535,6 +632,7 @@ google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -551,10 +649,13 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -573,6 +674,7 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.21.0 h1:gu5iGF4V6tfVCQ/R+8Hc0h7H1JuEhzyEi9S4R5LM8+Y= k8s.io/api v0.21.0/go.mod h1:+YbrhBBGgsxbF6o6Kj4KJPJnBmAKuXDeS3E18bgHNVU= @@ -580,15 +682,20 @@ k8s.io/apimachinery v0.21.0 h1:3Fx+41if+IRavNcKOz09FwEXDBG6ORh6iMsTSelhkMA= k8s.io/apimachinery v0.21.0/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= k8s.io/client-go v0.21.0 h1:n0zzzJsAQmJngpC0IhgFcApZyoGXPrDIAD601HD09ag= k8s.io/client-go v0.21.0/go.mod h1:nNBytTF9qPFDEhoqgEPaarobC8QPae13bElIVHzIglA= +k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac h1:sAvhNk5RRuc6FNYGqe7Ygz3PSo/2wGWbulskmzRX8Vs= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts= k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 h1:vEx13qjvaZ4yfObSSXW7BrMc/KQBBT/Jyee8XtLf4x0= k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8= From 1d24188a0219179c6ebe7d88014ce4269d2aa961 Mon Sep 17 00:00:00 2001 From: RamiBerm Date: Tue, 20 Jul 2021 09:58:08 +0300 Subject: [PATCH 03/69] Update tapRunner.go --- cli/cmd/tapRunner.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index de2691397..26bec8fc2 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -230,6 +230,7 @@ func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provi podExactRegex := regexp.MustCompile(fmt.Sprintf("^%s$", mizu.AggregatorPodName)) added, modified, removed, errorChan := kubernetes.FilteredWatch(ctx, kubernetesProvider.GetPodWatcher(ctx, mizu.ResourcesNamespace), podExactRegex) isPodReady := false + timeAfter := time.After(25 * time.Second) for { select { case <-added: @@ -269,7 +270,7 @@ func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provi } } - case <-time.After(25 * time.Second): + case <- timeAfter: if !isPodReady { fmt.Printf("error: %s pod was not ready in time", mizu.AggregatorPodName) cancel() From b57cb0e615a956ea229ab7bcd9499833d08d711c Mon Sep 17 00:00:00 2001 From: RamiBerm Date: Tue, 20 Jul 2021 09:58:18 +0300 Subject: [PATCH 04/69] Update main.go --- api/main.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/api/main.go b/api/main.go index c09af2ecc..b7d358a18 100644 --- a/api/main.go +++ b/api/main.go @@ -10,7 +10,6 @@ import ( "github.com/romana/rlog" "github.com/up9inc/mizu/shared" "github.com/up9inc/mizu/tap" - "log" "mizuserver/pkg/api" "mizuserver/pkg/middleware" "mizuserver/pkg/models" @@ -19,7 +18,6 @@ import ( "mizuserver/pkg/utils" "os" "os/signal" - "runtime/pprof" "strings" ) @@ -67,12 +65,6 @@ func main() { go pipeChannelToSocket(socketConnection, harOutputChannel) go api.StartReadingOutbound(outboundLinkOutputChannel) } else if *aggregator { - f, err := os.Create("/app/profile.pprof") - if err != nil { - log.Fatal(err) - } - fmt.Println("Starting profiling4") - pprof.StartCPUProfile(f) socketHarOutChannel := make(chan *tap.OutputChannelItem, 1000) filteredHarChannel := make(chan *tap.OutputChannelItem) @@ -85,7 +77,6 @@ func main() { signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, os.Interrupt) <-signalChan - rlog.Info("Exiting") } From ef8314b554d8c88630364bf3a64f52c4096c404f Mon Sep 17 00:00:00 2001 From: RamiBerm Date: Tue, 20 Jul 2021 09:58:21 +0300 Subject: [PATCH 05/69] Update debug.Dockerfile --- debug.Dockerfile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/debug.Dockerfile b/debug.Dockerfile index d0dc3102b..c894d2f27 100644 --- a/debug.Dockerfile +++ b/debug.Dockerfile @@ -19,12 +19,15 @@ WORKDIR /app/api-build COPY api/go.mod api/go.sum ./ COPY shared/go.mod shared/go.mod ../shared/ +COPY tap/go.mod tap/go.mod ../tap/ + RUN go mod download # cheap trick to make the build faster (As long as go.mod wasn't changes) RUN go list -f '{{.Path}}@{{.Version}}' -m all | sed 1d | grep -e 'go-cache' -e 'sqlite' | xargs go get # Copy and build api code COPY shared ../shared +COPY tap ../tap COPY api . RUN go build -gcflags="all=-N -l" -o mizuagent . @@ -41,4 +44,5 @@ COPY --from=site-build ["/app/ui-build/build", "site"] # install remote debugging tool RUN go get github.com/go-delve/delve/cmd/dlv -CMD ["sh", "-c", "dlv --headless=true --listen=:2345 --log --api-version=2 --accept-multiclient exec ./mizuagent -- --aggregator"] +ENTRYPOINT "/app/mizuagent" +#CMD ["sh", "-c", "dlv --headless=true --listen=:2345 --log --api-version=2 --accept-multiclient exec ./mizuagent -- --aggregator"] From 3be0c9ecd925870499a4469b1559055f480a520f Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Tue, 20 Jul 2021 16:47:20 +0300 Subject: [PATCH 06/69] Adding telemetry reports --- cli/cmd/fetch.go | 1 + cli/cmd/tap.go | 3 ++- cli/cmd/version.go | 6 +++--- cli/cmd/view.go | 4 ++-- cli/mizu/telemetry.go | 29 +++++++++++++++++++++++++++++ 5 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 cli/mizu/telemetry.go diff --git a/cli/cmd/fetch.go b/cli/cmd/fetch.go index 62caaf4e6..9700b73ec 100644 --- a/cli/cmd/fetch.go +++ b/cli/cmd/fetch.go @@ -18,6 +18,7 @@ var fetchCmd = &cobra.Command{ Use: "fetch", Short: "Download recorded traffic to files", RunE: func(cmd *cobra.Command, args []string) error { + go mizu.ReportRun("tap", mizuTapOptions) if isCompatible, err := mizu.CheckVersionCompatibility(mizuFetchOptions.MizuPort); err != nil { return err } else if !isCompatible { diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go index 245b3d7df..2262076af 100644 --- a/cli/cmd/tap.go +++ b/cli/cmd/tap.go @@ -31,8 +31,8 @@ var mizuTapOptions = &MizuTapOptions{} var direction string var humanMaxEntriesDBSize string var regex *regexp.Regexp -const maxEntriesDBSizeFlagName = "max-entries-db-size" +const maxEntriesDBSizeFlagName = "max-entries-db-size" const analysisMessageToConfirm = `NOTE: running mizu with --analysis flag will upload recorded traffic to UP9 cloud for further analysis and enriched presentation options. @@ -44,6 +44,7 @@ var tapCmd = &cobra.Command{ Long: `Record the ingoing traffic of a kubernetes pod. Supported protocols are HTTP and gRPC.`, RunE: func(cmd *cobra.Command, args []string) error { + go mizu.ReportRun("tap", mizuTapOptions) RunMizuTap(regex, mizuTapOptions) return nil }, diff --git a/cli/cmd/version.go b/cli/cmd/version.go index 366b05da2..4fd4b8bf1 100644 --- a/cli/cmd/version.go +++ b/cli/cmd/version.go @@ -10,20 +10,20 @@ import ( ) type MizuVersionOptions struct { - DebugInfo bool + DebugInfo bool } - var mizuVersionOptions = &MizuVersionOptions{} var versionCmd = &cobra.Command{ Use: "version", Short: "Print version info", RunE: func(cmd *cobra.Command, args []string) error { + go mizu.ReportRun("version", mizuVersionOptions) if mizuVersionOptions.DebugInfo { timeStampInt, _ := strconv.ParseInt(mizu.BuildTimestamp, 10, 0) fmt.Printf("Version: %s \nBranch: %s (%s) \n", mizu.SemVer, mizu.Branch, mizu.GitCommitHash) - fmt.Printf("Build Time: %s (%s)\n", mizu.BuildTimestamp, time.Unix(timeStampInt, 0)) + fmt.Printf("Build Time: %s (%s)\n", mizu.BuildTimestamp, time.Unix(timeStampInt, 0)) } else { fmt.Printf("Version: %s (%s)\n", mizu.SemVer, mizu.Branch) diff --git a/cli/cmd/view.go b/cli/cmd/view.go index a49ebde75..6733418c1 100644 --- a/cli/cmd/view.go +++ b/cli/cmd/view.go @@ -6,7 +6,7 @@ import ( ) type MizuViewOptions struct { - GuiPort uint16 + GuiPort uint16 } var mizuViewOptions = &MizuViewOptions{} @@ -15,6 +15,7 @@ var viewCmd = &cobra.Command{ Use: "view", Short: "Open GUI in browser", RunE: func(cmd *cobra.Command, args []string) error { + go mizu.ReportRun("view", mizuFetchOptions) if isCompatible, err := mizu.CheckVersionCompatibility(mizuFetchOptions.MizuPort); err != nil { return err } else if !isCompatible { @@ -23,7 +24,6 @@ var viewCmd = &cobra.Command{ runMizuView(mizuViewOptions) return nil }, - } func init() { diff --git a/cli/mizu/telemetry.go b/cli/mizu/telemetry.go new file mode 100644 index 000000000..b3dff01d8 --- /dev/null +++ b/cli/mizu/telemetry.go @@ -0,0 +1,29 @@ +package mizu + +import ( + "bytes" + "encoding/json" + "fmt" + "github.com/romana/rlog" + "net/http" +) + +func ReportRun(cmd string, args interface{}) { + if Branch != "main" { + rlog.Debugf("reporting only on main branch") + return + } + url := "https://us-east4-up9-prod.cloudfunctions.net/mizu-telemetry" + + argsBytes, _ := json.Marshal(args) + argsMap := map[string]string{"telemetry_type": "mizu_execution", "cmd": cmd, "args": string(argsBytes), "component": "mizu_cli"} + argsMap["message"] = fmt.Sprintf("mizu %v - %v", argsMap["cmd"], string(argsBytes)) + + jsonValue, _ := json.Marshal(argsMap) + + if resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonValue)); err != nil { + rlog.Debugf("error sending telemtry err: %v, response %v", err, resp) + } else { + rlog.Debugf("Successfully reported telemetry") + } +} From 1e66ebd8b3d1bd6aa217322cb4acdc39c16ab8c3 Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Tue, 20 Jul 2021 16:51:52 +0300 Subject: [PATCH 07/69] . --- cli/mizu.go | 6 +++++- cli/mizu/telemetry.go | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/cli/mizu.go b/cli/mizu.go index 7caa61604..4b63a1342 100644 --- a/cli/mizu.go +++ b/cli/mizu.go @@ -1,7 +1,11 @@ package main -import "github.com/up9inc/mizu/cli/cmd" +import ( + "fmt" + "github.com/up9inc/mizu/cli/cmd" +) func main() { + fmt.Println("Running mizu...") cmd.Execute() } diff --git a/cli/mizu/telemetry.go b/cli/mizu/telemetry.go index b3dff01d8..e37208e5d 100644 --- a/cli/mizu/telemetry.go +++ b/cli/mizu/telemetry.go @@ -8,12 +8,13 @@ import ( "net/http" ) +var TELEMETRY_URL = "https://us-east4-up9-prod.cloudfunctions.net/mizu-telemetry" + func ReportRun(cmd string, args interface{}) { if Branch != "main" { rlog.Debugf("reporting only on main branch") return } - url := "https://us-east4-up9-prod.cloudfunctions.net/mizu-telemetry" argsBytes, _ := json.Marshal(args) argsMap := map[string]string{"telemetry_type": "mizu_execution", "cmd": cmd, "args": string(argsBytes), "component": "mizu_cli"} @@ -21,7 +22,7 @@ func ReportRun(cmd string, args interface{}) { jsonValue, _ := json.Marshal(argsMap) - if resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonValue)); err != nil { + if resp, err := http.Post(TELEMETRY_URL, "application/json", bytes.NewBuffer(jsonValue)); err != nil { rlog.Debugf("error sending telemtry err: %v, response %v", err, resp) } else { rlog.Debugf("Successfully reported telemetry") From a11e8f730e435a2055ed2155d4f5c83888536086 Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Tue, 20 Jul 2021 16:54:51 +0300 Subject: [PATCH 08/69] . --- cli/mizu/telemetry.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/mizu/telemetry.go b/cli/mizu/telemetry.go index e37208e5d..c19790ab3 100644 --- a/cli/mizu/telemetry.go +++ b/cli/mizu/telemetry.go @@ -8,7 +8,7 @@ import ( "net/http" ) -var TELEMETRY_URL = "https://us-east4-up9-prod.cloudfunctions.net/mizu-telemetry" +const TELEMETRY_URL = "https://us-east4-up9-prod.cloudfunctions.net/mizu-telemetry" func ReportRun(cmd string, args interface{}) { if Branch != "main" { From ea5054866dd3d7e026778a46fff736fab4f65e9b Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Tue, 20 Jul 2021 16:55:32 +0300 Subject: [PATCH 09/69] . --- cli/mizu/telemetry.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/mizu/telemetry.go b/cli/mizu/telemetry.go index c19790ab3..91735364b 100644 --- a/cli/mizu/telemetry.go +++ b/cli/mizu/telemetry.go @@ -8,7 +8,7 @@ import ( "net/http" ) -const TELEMETRY_URL = "https://us-east4-up9-prod.cloudfunctions.net/mizu-telemetry" +const telemetryUrl = "https://us-east4-up9-prod.cloudfunctions.net/mizu-telemetry" func ReportRun(cmd string, args interface{}) { if Branch != "main" { @@ -22,7 +22,7 @@ func ReportRun(cmd string, args interface{}) { jsonValue, _ := json.Marshal(argsMap) - if resp, err := http.Post(TELEMETRY_URL, "application/json", bytes.NewBuffer(jsonValue)); err != nil { + if resp, err := http.Post(telemetryUrl, "application/json", bytes.NewBuffer(jsonValue)); err != nil { rlog.Debugf("error sending telemtry err: %v, response %v", err, resp) } else { rlog.Debugf("Successfully reported telemetry") From 4a030c02f74aa72999d589bbd65d03bd73970b3e Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Tue, 20 Jul 2021 16:57:38 +0300 Subject: [PATCH 10/69] revert --- cli/mizu.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cli/mizu.go b/cli/mizu.go index 4b63a1342..7caa61604 100644 --- a/cli/mizu.go +++ b/cli/mizu.go @@ -1,11 +1,7 @@ package main -import ( - "fmt" - "github.com/up9inc/mizu/cli/cmd" -) +import "github.com/up9inc/mizu/cli/cmd" func main() { - fmt.Println("Running mizu...") cmd.Execute() } From 80e97e7f7ef271d4bd8f47dbdf34efb4dac69c8a Mon Sep 17 00:00:00 2001 From: RamiBerm Date: Wed, 21 Jul 2021 10:49:27 +0300 Subject: [PATCH 11/69] Update main.go, tap.go, and 4 more files... --- api/main.go | 4 +++- cli/cmd/tap.go | 2 ++ cli/cmd/tapRunner.go | 2 +- cli/kubernetes/provider.go | 4 ++-- shared/consts.go | 2 +- shared/models.go | 1 + 6 files changed, 10 insertions(+), 5 deletions(-) diff --git a/api/main.go b/api/main.go index b7d358a18..fe91f44bc 100644 --- a/api/main.go +++ b/api/main.go @@ -142,7 +142,9 @@ func filterHarItems(inChannel <-chan *tap.OutputChannelItem, outChannel chan *ta continue } - sensitiveDataFiltering.FilterSensitiveInfoFromHarRequest(message, filterOptions) + if !filterOptions.DisableRedaction { + sensitiveDataFiltering.FilterSensitiveInfoFromHarRequest(message, filterOptions) + } outChannel <- message } diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go index 245b3d7df..b88edb5a7 100644 --- a/cli/cmd/tap.go +++ b/cli/cmd/tap.go @@ -25,6 +25,7 @@ type MizuTapOptions struct { HideHealthChecks bool MaxEntriesDBSizeBytes int64 SleepIntervalSec uint16 + DisableRedaction bool } var mizuTapOptions = &MizuTapOptions{} @@ -102,4 +103,5 @@ func init() { tapCmd.Flags().StringVarP(&direction, "direction", "", "in", "Record traffic that goes in this direction (relative to the tapped pod): in/any") tapCmd.Flags().BoolVar(&mizuTapOptions.HideHealthChecks, "hide-healthchecks", false, "hides requests with kube-probe or prometheus user-agent headers") tapCmd.Flags().StringVarP(&humanMaxEntriesDBSize, maxEntriesDBSizeFlagName, "", "200MB", "override the default max entries db size of 200mb") + tapCmd.Flags().BoolVar(&mizuTapOptions.DisableRedaction, "no-redact", false, "Disables redaction of potentially sensitive request/response headers and body values") } diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index 26bec8fc2..2015e81ef 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -126,7 +126,7 @@ func getMizuApiFilteringOptions(tappingOptions *MizuTapOptions) (*shared.Traffic } } - return &shared.TrafficFilteringOptions{PlainTextMaskingRegexes: compiledRegexSlice, HideHealthChecks: tappingOptions.HideHealthChecks}, nil + return &shared.TrafficFilteringOptions{PlainTextMaskingRegexes: compiledRegexSlice, HideHealthChecks: tappingOptions.HideHealthChecks, DisableRedaction: tappingOptions.DisableRedaction}, nil } func updateMizuTappers(ctx context.Context, kubernetesProvider *kubernetes.Provider, nodeToTappedPodIPMap map[string][]string, tappingOptions *MizuTapOptions) error { diff --git a/cli/kubernetes/provider.go b/cli/kubernetes/provider.go index 9a9409eaf..7141e1a27 100644 --- a/cli/kubernetes/provider.go +++ b/cli/kubernetes/provider.go @@ -14,8 +14,8 @@ import ( core "k8s.io/api/core/v1" rbac "k8s.io/api/rbac/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" resource "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/watch" applyconfapp "k8s.io/client-go/applyconfigurations/apps/v1" @@ -118,7 +118,7 @@ func (provider *Provider) CreateMizuAggregatorPod(ctx context.Context, namespace Value: string(marshaledFilteringOptions), }, { - Name: shared.MaxEntriesDBSizeByteSEnvVar, + Name: shared.MaxEntriesDBSizeBytesEnvVar, Value: strconv.FormatInt(maxEntriesDBSizeBytes, 10), }, }, diff --git a/shared/consts.go b/shared/consts.go index 0d452910d..7effd97fa 100644 --- a/shared/consts.go +++ b/shared/consts.go @@ -5,5 +5,5 @@ const ( HostModeEnvVar = "HOST_MODE" NodeNameEnvVar = "NODE_NAME" TappedAddressesPerNodeDictEnvVar = "TAPPED_ADDRESSES_PER_HOST" - MaxEntriesDBSizeByteSEnvVar = "MAX_ENTRIES_DB_BYTES" + MaxEntriesDBSizeBytesEnvVar = "MAX_ENTRIES_DB_BYTES" ) diff --git a/shared/models.go b/shared/models.go index 14c1b3ce9..d0f7a15c5 100644 --- a/shared/models.go +++ b/shared/models.go @@ -60,6 +60,7 @@ func CreateWebSocketMessageTypeAnalyzeStatus(analyzeStatus AnalyzeStatus) WebSoc type TrafficFilteringOptions struct { PlainTextMaskingRegexes []*SerializableRegexp HideHealthChecks bool + DisableRedaction bool } type VersionResponse struct { From 17e1ccf9ef0701a7ba43899b70ff895ee45db23a Mon Sep 17 00:00:00 2001 From: RamiBerm Date: Wed, 21 Jul 2021 10:49:33 +0300 Subject: [PATCH 12/69] Update size_enforcer.go --- api/pkg/database/size_enforcer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/pkg/database/size_enforcer.go b/api/pkg/database/size_enforcer.go index 686775d35..26b923b10 100644 --- a/api/pkg/database/size_enforcer.go +++ b/api/pkg/database/size_enforcer.go @@ -62,7 +62,7 @@ func getMaxEntriesDBByteSize() (int64, error) { maxEntriesDBByteSize := defaultMaxDatabaseSizeBytes var err error - maxEntriesDBSizeByteSEnvVarValue := os.Getenv(shared.MaxEntriesDBSizeByteSEnvVar) + maxEntriesDBSizeByteSEnvVarValue := os.Getenv(shared.MaxEntriesDBSizeBytesEnvVar) if maxEntriesDBSizeByteSEnvVarValue != "" { maxEntriesDBByteSize, err = strconv.ParseInt(maxEntriesDBSizeByteSEnvVarValue, 10, 64) } From 679bf35ce320d5b2dc548381a4e4102692c7e3e9 Mon Sep 17 00:00:00 2001 From: RamiBerm Date: Wed, 21 Jul 2021 10:51:32 +0300 Subject: [PATCH 13/69] Update go.mod --- api/go.mod | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/api/go.mod b/api/go.mod index 621967485..ac5d571a7 100644 --- a/api/go.mod +++ b/api/go.mod @@ -3,7 +3,7 @@ module mizuserver go 1.16 require ( - github.com/antoniodipinto/ikisocket v0.0.0-20210719130628-946ce6188452 + github.com/antoniodipinto/ikisocket v0.0.0-20210719144512-dce3f3fbbd04 github.com/beevik/etree v1.1.0 github.com/djherbis/atime v1.0.0 github.com/fasthttp/websocket v1.4.3-beta.1 // indirect @@ -11,7 +11,7 @@ require ( github.com/go-playground/locales v0.13.0 github.com/go-playground/universal-translator v0.17.0 github.com/go-playground/validator/v10 v10.5.0 - github.com/gofiber/fiber/v2 v2.10.0 + github.com/gofiber/fiber/v2 v2.8.0 github.com/google/martian v2.1.0+incompatible github.com/gorilla/websocket v1.4.2 github.com/leodido/go-urn v1.2.1 // indirect @@ -24,10 +24,9 @@ require ( k8s.io/api v0.21.0 k8s.io/apimachinery v0.21.0 k8s.io/client-go v0.21.0 + github.com/fsnotify/fsnotify v1.4.9 ) replace github.com/up9inc/mizu/shared v0.0.0 => ../shared replace github.com/up9inc/mizu/tap v0.0.0 => ../tap - -replace github.com/antoniodipinto/ikisocket v0.0.0-20210719130628-946ce6188452 => github.com/up9inc/ikisocket v0.0.0-20210719130628-946ce6188452 From edc3d04d5958314ffbb71ee5bf2cfe59f6236cd0 Mon Sep 17 00:00:00 2001 From: RamiBerm Date: Wed, 21 Jul 2021 10:52:14 +0300 Subject: [PATCH 14/69] Update go.mod and go.sum --- api/go.mod | 3 +-- api/go.sum | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/api/go.mod b/api/go.mod index ac5d571a7..2a17b4b69 100644 --- a/api/go.mod +++ b/api/go.mod @@ -11,7 +11,7 @@ require ( github.com/go-playground/locales v0.13.0 github.com/go-playground/universal-translator v0.17.0 github.com/go-playground/validator/v10 v10.5.0 - github.com/gofiber/fiber/v2 v2.8.0 + github.com/gofiber/fiber/v2 v2.10.0 github.com/google/martian v2.1.0+incompatible github.com/gorilla/websocket v1.4.2 github.com/leodido/go-urn v1.2.1 // indirect @@ -24,7 +24,6 @@ require ( k8s.io/api v0.21.0 k8s.io/apimachinery v0.21.0 k8s.io/client-go v0.21.0 - github.com/fsnotify/fsnotify v1.4.9 ) replace github.com/up9inc/mizu/shared v0.0.0 => ../shared diff --git a/api/go.sum b/api/go.sum index eea23521c..6a0f7fbbe 100644 --- a/api/go.sum +++ b/api/go.sum @@ -54,6 +54,8 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/antoniodipinto/ikisocket v0.0.0-20210719144512-dce3f3fbbd04 h1:ru0T8O1coJ21vbtzangy+W6IpCaCQlLxLFr7eHffY3I= +github.com/antoniodipinto/ikisocket v0.0.0-20210719144512-dce3f3fbbd04/go.mod h1:IRtlQDKcJq80t7y6JzYOBKMpHliAHd0dmu7hOhAXU9c= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.34.28 h1:sscPpn/Ns3i0F4HPEWAVcwdIRaZZCuL7llJ2/60yPIk= From 7fb85df3ac3841872acf21df081da8a558ce0ebf Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Wed, 21 Jul 2021 10:52:37 +0300 Subject: [PATCH 15/69] Add version artifact --- .github/workflows/publish.yml | 8 ++++++++ cli/mizu/telemetry.go | 16 ++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5beaeb446..b60987ee2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -66,6 +66,14 @@ jobs: COMMIT_HASH=${{ github.sha }} - name: Build and Push CLI run: make push-cli SEM_VER='${{ steps.versioning.outputs.version }}' BUILD_TIMESTAMP='${{ steps.version_parameters.outputs.build_timestamp }}' + - shell: bash + run: | + expr '${{ steps.versioning.outputs.version }}' > version.txt + - name: Upload version artifact + uses: actions/upload-artifact@v2 + with: + name: version + path: version.txt - name: publish uses: ncipollo/release-action@v1 with: diff --git a/cli/mizu/telemetry.go b/cli/mizu/telemetry.go index 91735364b..f0a703866 100644 --- a/cli/mizu/telemetry.go +++ b/cli/mizu/telemetry.go @@ -8,22 +8,26 @@ import ( "net/http" ) -const telemetryUrl = "https://us-east4-up9-prod.cloudfunctions.net/mizu-telemetry" - func ReportRun(cmd string, args interface{}) { if Branch != "main" { rlog.Debugf("reporting only on main branch") return } - argsBytes, _ := json.Marshal(args) - argsMap := map[string]string{"telemetry_type": "mizu_execution", "cmd": cmd, "args": string(argsBytes), "component": "mizu_cli"} + argsMap := map[string]string{ + "telemetry_type": "execution", + "cmd": cmd, + "args": string(argsBytes), + "component": "mizu_cli", + "BuildTimestamp": BuildTimestamp, + "version": SemVer} argsMap["message"] = fmt.Sprintf("mizu %v - %v", argsMap["cmd"], string(argsBytes)) jsonValue, _ := json.Marshal(argsMap) - if resp, err := http.Post(telemetryUrl, "application/json", bytes.NewBuffer(jsonValue)); err != nil { - rlog.Debugf("error sending telemtry err: %v, response %v", err, resp) + if resp, err := http.Post("https://us-east4-up9-prod.cloudfunctions.net/mizu-telemetry", + "application/json", bytes.NewBuffer(jsonValue)); err != nil { + rlog.Debugf("error sending telemetry err: %v, response %v", err, resp) } else { rlog.Debugf("Successfully reported telemetry") } From 8db12a4b1a0b475f1e48ea0a51bdbbec62613f54 Mon Sep 17 00:00:00 2001 From: RamiBerm Date: Wed, 21 Jul 2021 10:53:25 +0300 Subject: [PATCH 16/69] Update go.mod --- api/go.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/go.mod b/api/go.mod index 2a17b4b69..4794dad3b 100644 --- a/api/go.mod +++ b/api/go.mod @@ -7,11 +7,10 @@ require ( github.com/beevik/etree v1.1.0 github.com/djherbis/atime v1.0.0 github.com/fasthttp/websocket v1.4.3-beta.1 // indirect - github.com/fsnotify/fsnotify v1.4.9 github.com/go-playground/locales v0.13.0 github.com/go-playground/universal-translator v0.17.0 github.com/go-playground/validator/v10 v10.5.0 - github.com/gofiber/fiber/v2 v2.10.0 + github.com/gofiber/fiber/v2 v2.8.0 github.com/google/martian v2.1.0+incompatible github.com/gorilla/websocket v1.4.2 github.com/leodido/go-urn v1.2.1 // indirect @@ -24,6 +23,7 @@ require ( k8s.io/api v0.21.0 k8s.io/apimachinery v0.21.0 k8s.io/client-go v0.21.0 + github.com/fsnotify/fsnotify v1.4.9 ) replace github.com/up9inc/mizu/shared v0.0.0 => ../shared From 5b9c134ab218725713628d8d2b7e36232747fc70 Mon Sep 17 00:00:00 2001 From: RamiBerm Date: Wed, 21 Jul 2021 10:59:14 +0300 Subject: [PATCH 17/69] Update go.mod and go.sum --- api/go.mod | 4 ++-- api/go.sum | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/api/go.mod b/api/go.mod index 4794dad3b..2a17b4b69 100644 --- a/api/go.mod +++ b/api/go.mod @@ -7,10 +7,11 @@ require ( github.com/beevik/etree v1.1.0 github.com/djherbis/atime v1.0.0 github.com/fasthttp/websocket v1.4.3-beta.1 // indirect + github.com/fsnotify/fsnotify v1.4.9 github.com/go-playground/locales v0.13.0 github.com/go-playground/universal-translator v0.17.0 github.com/go-playground/validator/v10 v10.5.0 - github.com/gofiber/fiber/v2 v2.8.0 + github.com/gofiber/fiber/v2 v2.10.0 github.com/google/martian v2.1.0+incompatible github.com/gorilla/websocket v1.4.2 github.com/leodido/go-urn v1.2.1 // indirect @@ -23,7 +24,6 @@ require ( k8s.io/api v0.21.0 k8s.io/apimachinery v0.21.0 k8s.io/client-go v0.21.0 - github.com/fsnotify/fsnotify v1.4.9 ) replace github.com/up9inc/mizu/shared v0.0.0 => ../shared diff --git a/api/go.sum b/api/go.sum index 6a0f7fbbe..afc27da11 100644 --- a/api/go.sum +++ b/api/go.sum @@ -378,8 +378,6 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/up9inc/ikisocket v0.0.0-20210719130628-946ce6188452 h1:9ysEGkPYoEPqDxkqv3NdlECoulHr0ozvqN6Rs9C49Kw= -github.com/up9inc/ikisocket v0.0.0-20210719130628-946ce6188452/go.mod h1:IRtlQDKcJq80t7y6JzYOBKMpHliAHd0dmu7hOhAXU9c= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.9.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= From eb67f76e2b2511ce4301854aae026249d20b8ef3 Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Wed, 21 Jul 2021 11:03:30 +0300 Subject: [PATCH 18/69] . --- .github/workflows/publish.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b60987ee2..0e6f163d2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -66,14 +66,6 @@ jobs: COMMIT_HASH=${{ github.sha }} - name: Build and Push CLI run: make push-cli SEM_VER='${{ steps.versioning.outputs.version }}' BUILD_TIMESTAMP='${{ steps.version_parameters.outputs.build_timestamp }}' - - shell: bash - run: | - expr '${{ steps.versioning.outputs.version }}' > version.txt - - name: Upload version artifact - uses: actions/upload-artifact@v2 - with: - name: version - path: version.txt - name: publish uses: ncipollo/release-action@v1 with: @@ -83,3 +75,10 @@ jobs: tag: ${{ steps.versioning.outputs.version }} prerelease: ${{ github.ref != 'refs/heads/main' }} bodyFile: 'cli/bin/README.md' + - shell: bash + run: echo '${{ steps.versioning.outputs.version }}' >> version.txt + - name: Upload version artifact + uses: actions/upload-artifact@v2 + with: + name: version + path: version.txt From efb1a0b58bf083467316347c61a3b47f62f47db9 Mon Sep 17 00:00:00 2001 From: RamiBerm Date: Wed, 21 Jul 2021 11:04:12 +0300 Subject: [PATCH 19/69] Update main.go --- api/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/api/main.go b/api/main.go index fe91f44bc..d5016b7f1 100644 --- a/api/main.go +++ b/api/main.go @@ -77,6 +77,7 @@ func main() { signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, os.Interrupt) <-signalChan + rlog.Info("Exiting") } From e883358cd629d0029dbcb681e66d74d84aea7a5d Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Wed, 21 Jul 2021 11:05:20 +0300 Subject: [PATCH 20/69] . --- .github/workflows/publish.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0e6f163d2..8de4458db 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -76,9 +76,9 @@ jobs: prerelease: ${{ github.ref != 'refs/heads/main' }} bodyFile: 'cli/bin/README.md' - shell: bash - run: echo '${{ steps.versioning.outputs.version }}' >> version.txt + run: echo '${{ steps.versioning.outputs.version }}' >> version.txt - name: Upload version artifact - uses: actions/upload-artifact@v2 - with: - name: version - path: version.txt + uses: actions/upload-artifact@v2 + with: + name: version + path: version.txt From 360a4ea562058d290d34b06f0863762747e57a1d Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Wed, 21 Jul 2021 11:06:42 +0300 Subject: [PATCH 21/69] . --- cli/mizu/telemetry.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cli/mizu/telemetry.go b/cli/mizu/telemetry.go index f0a703866..c1ac8fd1c 100644 --- a/cli/mizu/telemetry.go +++ b/cli/mizu/telemetry.go @@ -8,6 +8,8 @@ import ( "net/http" ) +const telemetryUrl = "https://us-east4-up9-prod.cloudfunctions.net/mizu-telemetry" + func ReportRun(cmd string, args interface{}) { if Branch != "main" { rlog.Debugf("reporting only on main branch") @@ -25,7 +27,7 @@ func ReportRun(cmd string, args interface{}) { jsonValue, _ := json.Marshal(argsMap) - if resp, err := http.Post("https://us-east4-up9-prod.cloudfunctions.net/mizu-telemetry", + if resp, err := http.Post(telemetryUrl, "application/json", bytes.NewBuffer(jsonValue)); err != nil { rlog.Debugf("error sending telemetry err: %v, response %v", err, resp) } else { From b195ed99051f23ed84dc372a68226dc2112397be Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Wed, 21 Jul 2021 11:18:37 +0300 Subject: [PATCH 22/69] Adding version as part of cli/bin --- .github/workflows/publish.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8de4458db..693fd999e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -66,6 +66,8 @@ jobs: COMMIT_HASH=${{ github.sha }} - name: Build and Push CLI run: make push-cli SEM_VER='${{ steps.versioning.outputs.version }}' BUILD_TIMESTAMP='${{ steps.version_parameters.outputs.build_timestamp }}' + - shell: bash + run: echo '${{ steps.versioning.outputs.version }}' >> cli/bin/version.txt - name: publish uses: ncipollo/release-action@v1 with: @@ -75,10 +77,4 @@ jobs: tag: ${{ steps.versioning.outputs.version }} prerelease: ${{ github.ref != 'refs/heads/main' }} bodyFile: 'cli/bin/README.md' - - shell: bash - run: echo '${{ steps.versioning.outputs.version }}' >> version.txt - - name: Upload version artifact - uses: actions/upload-artifact@v2 - with: - name: version - path: version.txt + From 594f1b973a8e3fb525bc2a00aec6dfa0e8459f0d Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Wed, 21 Jul 2021 11:23:49 +0300 Subject: [PATCH 23/69] . --- .github/workflows/publish.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 693fd999e..531e75f34 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -67,7 +67,8 @@ jobs: - name: Build and Push CLI run: make push-cli SEM_VER='${{ steps.versioning.outputs.version }}' BUILD_TIMESTAMP='${{ steps.version_parameters.outputs.build_timestamp }}' - shell: bash - run: echo '${{ steps.versioning.outputs.version }}' >> cli/bin/version.txt + run: | + echo '${{ steps.versioning.outputs.version }}' >> cli/bin/version.txt - name: publish uses: ncipollo/release-action@v1 with: From 7d5ed601dfcdeb8b23883c96e8aefc94ad20b7f1 Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Wed, 21 Jul 2021 16:36:47 +0300 Subject: [PATCH 24/69] Check if newer version exists in Github (#128) * Check if newer version exists in Github --- cli/cmd/tapRunner.go | 3 ++- cli/go.mod | 1 + cli/go.sum | 7 +++++- cli/mizu/versionCheck.go | 48 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index 2015e81ef..dff90fbb8 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -72,6 +72,7 @@ func RunMizuTap(podRegexQuery *regexp.Regexp, tappingOptions *MizuTapOptions) { return } + mizu.CheckNewerVersion() go portForwardApiPod(ctx, kubernetesProvider, cancel, tappingOptions) // TODO convert this to job for built in pod ttl or have the running app handle this go watchPodsForTapping(ctx, kubernetesProvider, cancel, podRegexQuery, tappingOptions) go syncApiStatus(ctx, cancel, tappingOptions) @@ -270,7 +271,7 @@ func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provi } } - case <- timeAfter: + case <-timeAfter: if !isPodReady { fmt.Printf("error: %s pod was not ready in time", mizu.AggregatorPodName) cancel() diff --git a/cli/go.mod b/cli/go.mod index 02730fa71..1ad46fbf1 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -3,6 +3,7 @@ module github.com/up9inc/mizu/cli go 1.16 require ( + github.com/google/go-github/v37 v37.0.0 github.com/gorilla/websocket v1.4.2 github.com/romana/rlog v0.0.0-20171115192701-f018bc92e7d7 github.com/spf13/cobra v1.1.3 diff --git a/cli/go.sum b/cli/go.sum index 9a79ea6a5..eef67ad62 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -203,8 +203,13 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-github/v37 v37.0.0 h1:rCspN8/6kB1BAJWZfuafvHhyfIo5fkAulaP/3bOQ/tM= +github.com/google/go-github/v37 v37.0.0/go.mod h1:LM7in3NmXDrX58GbEHy7FtNLbI2JijX93RnMKvWG3m4= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= diff --git a/cli/mizu/versionCheck.go b/cli/mizu/versionCheck.go index 3211f687d..b9d4f0913 100644 --- a/cli/mizu/versionCheck.go +++ b/cli/mizu/versionCheck.go @@ -1,15 +1,19 @@ package mizu import ( + "context" "encoding/json" "fmt" + "github.com/google/go-github/v37/github" + "github.com/romana/rlog" "github.com/up9inc/mizu/shared" "github.com/up9inc/mizu/shared/semver" + "io/ioutil" "net/http" "net/url" + "time" ) - func getApiVersion(port uint16) (string, error) { versionUrl, _ := url.Parse(fmt.Sprintf("http://localhost:%d/mizu/metadata/version", port)) req := &http.Request{ @@ -44,3 +48,45 @@ func CheckVersionCompatibility(port uint16) (bool, error) { fmt.Printf(Red, fmt.Sprintf("cli version (%s) is not compatible with api version (%s)\n", SemVer, apiSemVer)) return false, nil } + +func CheckNewerVersion() { + rlog.Debugf("Checking for newer version...") + start := time.Now() + client := github.NewClient(nil) + latestRelease, _, err := client.Repositories.GetLatestRelease(context.Background(), "up9inc", "mizu") + if err != nil { + rlog.Debugf("Failed to get latest release") + return + } + + versionFileUrl := "" + for _, asset := range latestRelease.Assets { + if *asset.Name == "version.txt" { + versionFileUrl = *asset.BrowserDownloadURL + break + } + } + if versionFileUrl == "" { + rlog.Debugf("Version file not found in the latest release") + return + } + + res, err := http.Get(versionFileUrl) + if err != nil { + rlog.Debugf("http.Get version asset -> %v", err) + return + } + + data, err := ioutil.ReadAll(res.Body) + res.Body.Close() + if err != nil { + rlog.Debugf("ioutil.ReadAll -> %v", err) + return + } + gitHubVersion := string(data) + gitHubVersion = gitHubVersion[:len(gitHubVersion)-1] + rlog.Debugf("Finished version validation, took %v", time.Since(start)) + if SemVer < gitHubVersion { + fmt.Printf(Yellow, fmt.Sprintf("Update available! %v -> %v (%v)\n", SemVer, gitHubVersion, *latestRelease.HTMLURL)) + } +} From e42c4f8648afc39cc9876ea690236ec67381b47d Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Wed, 21 Jul 2021 17:07:32 +0300 Subject: [PATCH 25/69] Cleaning unused code (#129) * Cleaning unused code --- api/pkg/resolver/loader.go | 45 -------------------------------------- cli/kubernetes/provider.go | 27 ++++++++++++----------- 2 files changed, 14 insertions(+), 58 deletions(-) diff --git a/api/pkg/resolver/loader.go b/api/pkg/resolver/loader.go index b9cd6e1fc..26de1dcc8 100644 --- a/api/pkg/resolver/loader.go +++ b/api/pkg/resolver/loader.go @@ -7,10 +7,6 @@ import ( _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" _ "k8s.io/client-go/plugin/pkg/client/auth/openstack" restclient "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" - "k8s.io/client-go/util/homedir" - "path/filepath" - "os" ) func NewFromInCluster(errOut chan error) (*Resolver, error) { @@ -24,44 +20,3 @@ func NewFromInCluster(errOut chan error) (*Resolver, error) { } return &Resolver{clientConfig: config, clientSet: clientset, nameMap: make(map[string]string), serviceMap: make(map[string]string), errOut: errOut}, nil } - -func NewFromOutOfCluster(kubeConfigPath string, errOut chan error) (*Resolver, error) { - if kubeConfigPath == "" { - env := os.Getenv("KUBECONFIG") - if env != "" { - kubeConfigPath = env - } else { - home := homedir.HomeDir() - kubeConfigPath = filepath.Join(home, ".kube", "config") - } - } - - configPathList := filepath.SplitList(kubeConfigPath) - configLoadingRules := &clientcmd.ClientConfigLoadingRules{} - if len(configPathList) <= 1 { - configLoadingRules.ExplicitPath = kubeConfigPath - } else { - configLoadingRules.Precedence = configPathList - } - contextName := "" - clientConfigLoader := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( - configLoadingRules, - &clientcmd.ConfigOverrides{ - CurrentContext: contextName, - }, - ) - clientConfig, err := clientConfigLoader.ClientConfig() - if err != nil { - return nil, err - } - clientset, err := kubernetes.NewForConfig(clientConfig) - if err != nil { - return nil, err - } - - return &Resolver{clientConfig: clientConfig, clientSet: clientset, nameMap: make(map[string]string), serviceMap: make(map[string]string), errOut: errOut}, nil -} - -func NewFromExisting(clientConfig *restclient.Config, clientSet *kubernetes.Clientset, errOut chan error) *Resolver { - return &Resolver{clientConfig: clientConfig, clientSet: clientSet, nameMap: make(map[string]string), serviceMap: make(map[string]string), errOut: errOut} -} diff --git a/cli/kubernetes/provider.go b/cli/kubernetes/provider.go index 7141e1a27..42a157b64 100644 --- a/cli/kubernetes/provider.go +++ b/cli/kubernetes/provider.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "os" "path/filepath" "regexp" "strconv" @@ -45,6 +46,9 @@ const ( ) func NewProvider(kubeConfigPath string) *Provider { + if kubeConfigPath == "" { + kubeConfigPath = os.Getenv("KUBECONFIG") + } kubernetesConfig := loadKubernetesConfiguration(kubeConfigPath) restClientConfig, err := kubernetesConfig.ClientConfig() if err != nil { @@ -124,11 +128,11 @@ func (provider *Provider) CreateMizuAggregatorPod(ctx context.Context, namespace }, Resources: core.ResourceRequirements{ Limits: core.ResourceList{ - "cpu": cpuLimit, + "cpu": cpuLimit, "memory": memLimit, }, Requests: core.ResourceList{ - "cpu": cpuRequests, + "cpu": cpuRequests, "memory": memRequests, }, }, @@ -248,8 +252,7 @@ func (provider *Provider) CreateMizuRBAC(ctx context.Context, namespace string, } func (provider *Provider) RemovePod(ctx context.Context, namespace string, podName string) error { - if isFound, err := provider.CheckPodExists(ctx, namespace, podName); - err != nil { + if isFound, err := provider.CheckPodExists(ctx, namespace, podName); err != nil { return err } else if !isFound { return nil @@ -259,8 +262,7 @@ func (provider *Provider) RemovePod(ctx context.Context, namespace string, podNa } func (provider *Provider) RemoveService(ctx context.Context, namespace string, serviceName string) error { - if isFound, err := provider.CheckServiceExists(ctx, namespace, serviceName); - err != nil { + if isFound, err := provider.CheckServiceExists(ctx, namespace, serviceName); err != nil { return err } else if !isFound { return nil @@ -270,8 +272,7 @@ func (provider *Provider) RemoveService(ctx context.Context, namespace string, s } func (provider *Provider) RemoveDaemonSet(ctx context.Context, namespace string, daemonSetName string) error { - if isFound, err := provider.CheckDaemonSetExists(ctx, namespace, daemonSetName); - err != nil { + if isFound, err := provider.CheckDaemonSetExists(ctx, namespace, daemonSetName); err != nil { return err } else if !isFound { return nil @@ -283,7 +284,7 @@ func (provider *Provider) RemoveDaemonSet(ctx context.Context, namespace string, func (provider *Provider) CheckPodExists(ctx context.Context, namespace string, name string) (bool, error) { listOptions := metav1.ListOptions{ FieldSelector: fmt.Sprintf("metadata.name=%s", name), - Limit: 1, + Limit: 1, } resourceList, err := provider.clientSet.CoreV1().Pods(namespace).List(ctx, listOptions) if err != nil { @@ -300,7 +301,7 @@ func (provider *Provider) CheckPodExists(ctx context.Context, namespace string, func (provider *Provider) CheckServiceExists(ctx context.Context, namespace string, name string) (bool, error) { listOptions := metav1.ListOptions{ FieldSelector: fmt.Sprintf("metadata.name=%s", name), - Limit: 1, + Limit: 1, } resourceList, err := provider.clientSet.CoreV1().Services(namespace).List(ctx, listOptions) if err != nil { @@ -317,7 +318,7 @@ func (provider *Provider) CheckServiceExists(ctx context.Context, namespace stri func (provider *Provider) CheckDaemonSetExists(ctx context.Context, namespace string, name string) (bool, error) { listOptions := metav1.ListOptions{ FieldSelector: fmt.Sprintf("metadata.name=%s", name), - Limit: 1, + Limit: 1, } resourceList, err := provider.clientSet.AppsV1().DaemonSets(namespace).List(ctx, listOptions) if err != nil { @@ -387,11 +388,11 @@ func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespac return errors.New("invalid memory request for tapper container") } agentResourceLimits := core.ResourceList{ - "cpu": cpuLimit, + "cpu": cpuLimit, "memory": memLimit, } agentResourceRequests := core.ResourceList{ - "cpu": cpuRequests, + "cpu": cpuRequests, "memory": memRequests, } agentResources := applyconfcore.ResourceRequirements().WithRequests(agentResourceRequests).WithLimits(agentResourceLimits) From 2996c1a4bcd860529c711367439a91854161ff43 Mon Sep 17 00:00:00 2001 From: nimrod-up9 <59927337+nimrod-up9@users.noreply.github.com> Date: Thu, 22 Jul 2021 14:26:12 +0300 Subject: [PATCH 26/69] Install Mizu in a dedicated namespace (#123) * Use "mizu" namespace instead of "default". Create and delete as necessary. * Wait until namespace is deleted. * Distinguish between timeout and other errors. * Sorted consts. * k8s provider gets the names of Mizu serviceaccount, clusterrole and clusterrolebindings from caller. * Renames. * Remove non-namespaced mizu resources when finished: clusterrole and clusterrolebindings. * Don't wait for namespace deletion if it was already deleted. * When watching pods, check for cancellation before reading from channels. * Allow user to cancel resource deletion and to cancel the wait. * Increased cleanup timeout. * go mod tidy. * Ignore cli build products. * Print err. * Don't delete clusterrole and clusterrolebinding if we do not have permissions. * Added roles list in README. * Added clusterrole and clusterrolebindings examples. --- README.md | 93 ++++++++-- cli/.gitignore | 1 + cli/cmd/tapRunner.go | 77 ++++++-- cli/go.sum | 6 + cli/kubernetes/provider.go | 165 ++++++++++++++++-- cli/mizu/consts.go | 13 +- ...-all-namespaces-without-ip-resolution.yaml | 35 ++++ .../roles/permissions-all-namespaces.yaml | 52 ++++++ 8 files changed, 402 insertions(+), 40 deletions(-) create mode 100644 cli/.gitignore create mode 100644 examples/roles/permissions-all-namespaces-without-ip-resolution.yaml create mode 100644 examples/roles/permissions-all-namespaces.yaml diff --git a/README.md b/README.md index 1f4d07f87..50157ece2 100644 --- a/README.md +++ b/README.md @@ -29,46 +29,117 @@ Pick one from the [Releases](https://github.com/up9inc/mizu/releases) page. ## Prerequisites 1. Set `KUBECONFIG` environment variable to your kubernetes configuration. If this is not set, mizu assumes that configuration is at `${HOME}/.kube/config` 2. mizu needs following permissions on your kubernetes cluster to run -``` + +```yaml - apiGroups: - "" - - apps resources: - pods - - services verbs: - list - - get + - watch - create - - delete - apiGroups: - "" + resources: + - services + verbs: + - create +- apiGroups: - apps resources: - daemonsets verbs: - - list - - get - create - patch +- apiGroups: + - "" + resources: + - namespaces + verbs: + - list + - watch + - create - delete +- apiGroups: + - "" + resources: + - services/proxy + verbs: + - get ``` 3. Optionally, for resolving traffic ip to kubernetes service name, mizu needs below permissions -``` + +```yaml +- apiGroups: + - "" + resources: + - pods + verbs: + - get +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch +- apiGroups: + - apps + - extensions + resources: + - pods + verbs: + - get + - list + - watch +- apiGroups: + - apps + - extensions + resources: + - services + verbs: + - get + - list + - watch - apiGroups: - "" - apps - - "rbac.authorization.k8s.io" + - extensions + resources: + - endpoints + verbs: + - get + - list + - watch +- apiGroups: + - "" resources: - - clusterroles - - clusterrolebindings - serviceaccounts verbs: - get - create +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + verbs: + - list + - create + - delete +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + verbs: + - list + - create - delete ``` +See `examples/roles` for example `clusterroles`. + ## How to run 1. Find pod you'd like to tap to in your Kubernetes cluster diff --git a/cli/.gitignore b/cli/.gitignore new file mode 100644 index 000000000..ba077a403 --- /dev/null +++ b/cli/.gitignore @@ -0,0 +1 @@ +bin diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index dff90fbb8..709cee3db 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -9,6 +9,7 @@ import ( "github.com/up9inc/mizu/shared" "github.com/up9inc/mizu/shared/debounce" core "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/wait" "log" "net/http" "net/url" @@ -24,6 +25,7 @@ var aggregatorService *core.Service const ( updateTappersDelay = 5 * time.Second + cleanupTimeout = time.Minute ) var currentlyTappedPods []core.Pod @@ -42,6 +44,7 @@ func RunMizuTap(podRegexQuery *regexp.Regexp, tappingOptions *MizuTapOptions) { targetNamespace := getNamespace(tappingOptions, kubernetesProvider) if matchingPods, err := kubernetesProvider.GetAllPodsMatchingRegex(ctx, podRegexQuery, targetNamespace); err != nil { + fmt.Printf("Error listing pods: %v", err) return } else { currentlyTappedPods = matchingPods @@ -82,6 +85,10 @@ func RunMizuTap(podRegexQuery *regexp.Regexp, tappingOptions *MizuTapOptions) { } func createMizuResources(ctx context.Context, kubernetesProvider *kubernetes.Provider, nodeToTappedPodIPMap map[string][]string, tappingOptions *MizuTapOptions, mizuApiFilteringOptions *shared.TrafficFilteringOptions) error { + if err := createMizuNamespace(ctx, kubernetesProvider); err != nil { + return err + } + if err := createMizuAggregator(ctx, kubernetesProvider, tappingOptions, mizuApiFilteringOptions); err != nil { return err } @@ -93,11 +100,26 @@ func createMizuResources(ctx context.Context, kubernetesProvider *kubernetes.Pro return nil } +func createMizuNamespace(ctx context.Context, kubernetesProvider *kubernetes.Provider) error { + _, err := kubernetesProvider.CreateNamespace(ctx, mizu.ResourcesNamespace) + if err != nil { + fmt.Printf("Error creating Namespace %s: %v\n", mizu.ResourcesNamespace, err) + } + + return err +} + func createMizuAggregator(ctx context.Context, kubernetesProvider *kubernetes.Provider, tappingOptions *MizuTapOptions, mizuApiFilteringOptions *shared.TrafficFilteringOptions) error { var err error mizuServiceAccountExists = createRBACIfNecessary(ctx, kubernetesProvider) - _, err = kubernetesProvider.CreateMizuAggregatorPod(ctx, mizu.ResourcesNamespace, mizu.AggregatorPodName, tappingOptions.MizuImage, mizuServiceAccountExists, mizuApiFilteringOptions, tappingOptions.MaxEntriesDBSizeBytes) + var serviceAccountName string + if mizuServiceAccountExists { + serviceAccountName = mizu.ServiceAccountName + } else { + serviceAccountName = "" + } + _, err = kubernetesProvider.CreateMizuAggregatorPod(ctx, mizu.ResourcesNamespace, mizu.AggregatorPodName, tappingOptions.MizuImage, serviceAccountName, mizuApiFilteringOptions, tappingOptions.MaxEntriesDBSizeBytes) if err != nil { fmt.Printf("Error creating mizu collector pod: %v\n", err) return err @@ -132,6 +154,13 @@ func getMizuApiFilteringOptions(tappingOptions *MizuTapOptions) (*shared.Traffic func updateMizuTappers(ctx context.Context, kubernetesProvider *kubernetes.Provider, nodeToTappedPodIPMap map[string][]string, tappingOptions *MizuTapOptions) error { if len(nodeToTappedPodIPMap) > 0 { + var serviceAccountName string + if mizuServiceAccountExists { + serviceAccountName = mizu.ServiceAccountName + } else { + serviceAccountName = "" + } + if err := kubernetesProvider.ApplyMizuTapperDaemonSet( ctx, mizu.ResourcesNamespace, @@ -140,7 +169,7 @@ func updateMizuTappers(ctx context.Context, kubernetesProvider *kubernetes.Provi mizu.TapperPodName, fmt.Sprintf("%s.%s.svc.cluster.local", aggregatorService.Name, aggregatorService.Namespace), nodeToTappedPodIPMap, - mizuServiceAccountExists, + serviceAccountName, tappingOptions.TapOutgoing, ); err != nil { fmt.Printf("Error creating mizu tapper daemonset: %v\n", err) @@ -159,15 +188,35 @@ func updateMizuTappers(ctx context.Context, kubernetesProvider *kubernetes.Provi func cleanUpMizuResources(kubernetesProvider *kubernetes.Provider) { fmt.Printf("\nRemoving mizu resources\n") - removalCtx, _ := context.WithTimeout(context.Background(), 5*time.Second) - if err := kubernetesProvider.RemovePod(removalCtx, mizu.ResourcesNamespace, mizu.AggregatorPodName); err != nil { - fmt.Printf("Error removing Pod %s in namespace %s: %s (%v,%+v)\n", mizu.AggregatorPodName, mizu.ResourcesNamespace, err, err, err) + removalCtx, cancel := context.WithTimeout(context.Background(), cleanupTimeout) + defer cancel() + + if err := kubernetesProvider.RemoveNamespace(removalCtx, mizu.ResourcesNamespace); err != nil { + fmt.Printf("Error removing Namespace %s: %s (%v,%+v)\n", mizu.ResourcesNamespace, err, err, err) + return } - if err := kubernetesProvider.RemoveService(removalCtx, mizu.ResourcesNamespace, mizu.AggregatorPodName); err != nil { - fmt.Printf("Error removing Service %s in namespace %s: %s (%v,%+v)\n", mizu.AggregatorPodName, mizu.ResourcesNamespace, err, err, err) + + if mizuServiceAccountExists { + if err := kubernetesProvider.RemoveNonNamespacedResources(removalCtx, mizu.ClusterRoleName, mizu.ClusterRoleBindingName); err != nil { + fmt.Printf("Error removing non-namespaced resources: %s (%v,%+v)\n", err, err, err) + return + } } - if err := kubernetesProvider.RemoveDaemonSet(removalCtx, mizu.ResourcesNamespace, mizu.TapperDaemonSetName); err != nil { - fmt.Printf("Error removing DaemonSet %s in namespace %s: %s (%v,%+v)\n", mizu.TapperDaemonSetName, mizu.ResourcesNamespace, err, err, err) + + // Call cancel if a terminating signal was received. Allows user to skip the wait. + go func() { + waitForFinish(removalCtx, cancel) + }() + + if err := kubernetesProvider.WaitUtilNamespaceDeleted(removalCtx, mizu.ResourcesNamespace); err != nil { + switch { + case removalCtx.Err() == context.Canceled: + // Do nothing. User interrupted the wait. + case err == wait.ErrWaitTimeout: + fmt.Printf("Timeout while removing Namespace %s\n", mizu.ResourcesNamespace) + default: + fmt.Printf("Error while waiting for Namespace %s to be deleted: %s (%v,%+v)\n", mizu.ResourcesNamespace, err, err, err) + } } } @@ -234,6 +283,9 @@ func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provi timeAfter := time.After(25 * time.Second) for { select { + case <-ctx.Done(): + return + case <-added: continue case <-removed: @@ -279,21 +331,18 @@ func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provi case <-errorChan: cancel() - - case <-ctx.Done(): - return } } } func createRBACIfNecessary(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool { - mizuRBACExists, err := kubernetesProvider.DoesMizuRBACExist(ctx, mizu.ResourcesNamespace) + mizuRBACExists, err := kubernetesProvider.DoesServiceAccountExist(ctx, mizu.ResourcesNamespace, mizu.ServiceAccountName) if err != nil { fmt.Printf("warning: could not ensure mizu rbac resources exist %v\n", err) return false } if !mizuRBACExists { - err := kubernetesProvider.CreateMizuRBAC(ctx, mizu.ResourcesNamespace, mizu.RBACVersion) + err := kubernetesProvider.CreateMizuRBAC(ctx, mizu.ResourcesNamespace, mizu.ServiceAccountName, mizu.ClusterRoleName, mizu.ClusterRoleBindingName, mizu.RBACVersion) if err != nil { fmt.Printf("warning: could not create mizu rbac resources %v\n", err) return false diff --git a/cli/go.sum b/cli/go.sum index eef67ad62..de1e9bcd7 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -99,6 +99,7 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= @@ -174,6 +175,7 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -223,6 +225,7 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= @@ -250,6 +253,7 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= @@ -336,6 +340,7 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -710,6 +715,7 @@ k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts= k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 h1:vEx13qjvaZ4yfObSSXW7BrMc/KQBBT/Jyee8XtLf4x0= k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= k8s.io/kubectl v0.21.2 h1:9XPCetvOMDqrIZZXb1Ei+g8t6KrIp9ENJaysQjUuLiE= k8s.io/kubectl v0.21.2/go.mod h1:PgeUclpG8VVmmQIl8zpLar3IQEpFc9mrmvlwY3CK1xo= diff --git a/cli/kubernetes/provider.go b/cli/kubernetes/provider.go index 42a157b64..ddf79dffe 100644 --- a/cli/kubernetes/provider.go +++ b/cli/kubernetes/provider.go @@ -17,6 +17,7 @@ import ( k8serrors "k8s.io/apimachinery/pkg/api/errors" resource "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/watch" applyconfapp "k8s.io/client-go/applyconfigurations/apps/v1" @@ -28,8 +29,10 @@ import ( _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" _ "k8s.io/client-go/plugin/pkg/client/auth/openstack" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/clientcmd" _ "k8s.io/client-go/tools/portforward" + watchtools "k8s.io/client-go/tools/watch" "k8s.io/client-go/util/homedir" ) @@ -41,7 +44,6 @@ type Provider struct { } const ( - serviceAccountName = "mizu-service-account" fieldManagerName = "mizu-manager" ) @@ -68,6 +70,46 @@ func (provider *Provider) CurrentNamespace() string { return ns } +func (provider *Provider) WaitUtilNamespaceDeleted(ctx context.Context, name string) error { + fieldSelector := fmt.Sprintf("metadata.name=%s", name) + var limit int64 = 1 + lw := &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + options.FieldSelector = fieldSelector + options.Limit = limit + return provider.clientSet.CoreV1().Namespaces().List(ctx, options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + options.FieldSelector = fieldSelector + options.Limit = limit + return provider.clientSet.CoreV1().Namespaces().Watch(ctx, options) + }, + } + + var preconditionFunc watchtools.PreconditionFunc = func(store cache.Store) (bool, error) { + _, exists, err := store.Get(&core.Namespace{ObjectMeta: metav1.ObjectMeta{Name: name}}) + if err != nil { + return false, err + } + if exists { + return false, nil + } + return true, nil + } + + conditionFunc := func(e watch.Event) (bool, error) { + if e.Type == watch.Deleted { + return true, nil + } + return false, nil + } + + obj := &core.Namespace{} + _, err := watchtools.UntilWithSync(ctx, lw, obj, preconditionFunc, conditionFunc) + + return err +} + func (provider *Provider) GetPodWatcher(ctx context.Context, namespace string) watch.Interface { watcher, err := provider.clientSet.CoreV1().Pods(namespace).Watch(ctx, metav1.ListOptions{Watch: true}) if err != nil { @@ -76,7 +118,16 @@ func (provider *Provider) GetPodWatcher(ctx context.Context, namespace string) w return watcher } -func (provider *Provider) CreateMizuAggregatorPod(ctx context.Context, namespace string, podName string, podImage string, linkServiceAccount bool, mizuApiFilteringOptions *shared.TrafficFilteringOptions, maxEntriesDBSizeBytes int64) (*core.Pod, error) { +func (provider *Provider) CreateNamespace(ctx context.Context, name string) (*core.Namespace, error) { + namespaceSpec := &core.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + } + return provider.clientSet.CoreV1().Namespaces().Create(ctx, namespaceSpec, metav1.CreateOptions{}) +} + +func (provider *Provider) CreateMizuAggregatorPod(ctx context.Context, namespace string, podName string, podImage string, serviceAccountName string, mizuApiFilteringOptions *shared.TrafficFilteringOptions, maxEntriesDBSizeBytes int64) (*core.Pod, error) { marshaledFilteringOptions, err := json.Marshal(mizuApiFilteringOptions) if err != nil { return nil, err @@ -143,7 +194,7 @@ func (provider *Provider) CreateMizuAggregatorPod(ctx context.Context, namespace }, } //define the service account only when it exists to prevent pod crash - if linkServiceAccount { + if serviceAccountName != "" { pod.Spec.ServiceAccountName = serviceAccountName } return provider.clientSet.CoreV1().Pods(namespace).Create(ctx, pod, metav1.CreateOptions{}) @@ -164,7 +215,7 @@ func (provider *Provider) CreateService(ctx context.Context, namespace string, s return provider.clientSet.CoreV1().Services(namespace).Create(ctx, &service, metav1.CreateOptions{}) } -func (provider *Provider) DoesMizuRBACExist(ctx context.Context, namespace string) (bool, error) { +func (provider *Provider) DoesServiceAccountExist(ctx context.Context, namespace string, serviceAccountName string) (bool, error) { serviceAccount, err := provider.clientSet.CoreV1().ServiceAccounts(namespace).Get(ctx, serviceAccountName, metav1.GetOptions{}) var statusError *k8serrors.StatusError @@ -195,9 +246,7 @@ func (provider *Provider) DoesServicesExist(ctx context.Context, namespace strin return service != nil, nil } -func (provider *Provider) CreateMizuRBAC(ctx context.Context, namespace string, version string) error { - clusterRoleName := "mizu-cluster-role" - +func (provider *Provider) CreateMizuRBAC(ctx context.Context, namespace string, serviceAccountName string, clusterRoleName string, clusterRoleBindingName string, version string) error { serviceAccount := &core.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ Name: serviceAccountName, @@ -220,7 +269,7 @@ func (provider *Provider) CreateMizuRBAC(ctx context.Context, namespace string, } clusterRoleBinding := &rbac.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ - Name: "mizu-cluster-role-binding", + Name: clusterRoleBindingName, Labels: map[string]string{"mizu-cli-version": version}, }, RoleRef: rbac.RoleRef{ @@ -251,6 +300,51 @@ func (provider *Provider) CreateMizuRBAC(ctx context.Context, namespace string, return nil } +func (provider *Provider) RemoveNamespace(ctx context.Context, name string) error { + if isFound, err := provider.CheckNamespaceExists(ctx, name); + err != nil { + return err + } else if !isFound { + return nil + } + + return provider.clientSet.CoreV1().Namespaces().Delete(ctx, name, metav1.DeleteOptions{}) +} + +func (provider *Provider) RemoveNonNamespacedResources(ctx context.Context, clusterRoleName string, clusterRoleBindingName string) error { + if err := provider.RemoveClusterRole(ctx, clusterRoleName); err != nil { + return err + } + + if err := provider.RemoveClusterRoleBinding(ctx, clusterRoleBindingName); err != nil { + return err + } + + return nil +} + +func (provider *Provider) RemoveClusterRole(ctx context.Context, name string) error { + if isFound, err := provider.CheckClusterRoleExists(ctx, name); + err != nil { + return err + } else if !isFound { + return nil + } + + return provider.clientSet.RbacV1().ClusterRoles().Delete(ctx, name, metav1.DeleteOptions{}) +} + +func (provider *Provider) RemoveClusterRoleBinding(ctx context.Context, name string) error { + if isFound, err := provider.CheckClusterRoleBindingExists(ctx, name); + err != nil { + return err + } else if !isFound { + return nil + } + + return provider.clientSet.RbacV1().ClusterRoleBindings().Delete(ctx, name, metav1.DeleteOptions{}) +} + func (provider *Provider) RemovePod(ctx context.Context, namespace string, podName string) error { if isFound, err := provider.CheckPodExists(ctx, namespace, podName); err != nil { return err @@ -281,6 +375,57 @@ func (provider *Provider) RemoveDaemonSet(ctx context.Context, namespace string, return provider.clientSet.AppsV1().DaemonSets(namespace).Delete(ctx, daemonSetName, metav1.DeleteOptions{}) } +func (provider *Provider) CheckNamespaceExists(ctx context.Context, name string) (bool, error) { + listOptions := metav1.ListOptions{ + FieldSelector: fmt.Sprintf("metadata.name=%s", name), + Limit: 1, + } + resourceList, err := provider.clientSet.CoreV1().Namespaces().List(ctx, listOptions) + if err != nil { + return false, err + } + + if len(resourceList.Items) > 0 { + return true, nil + } + + return false, nil +} + +func (provider *Provider) CheckClusterRoleExists(ctx context.Context, name string) (bool, error) { + listOptions := metav1.ListOptions{ + FieldSelector: fmt.Sprintf("metadata.name=%s", name), + Limit: 1, + } + resourceList, err := provider.clientSet.RbacV1().ClusterRoles().List(ctx, listOptions) + if err != nil { + return false, err + } + + if len(resourceList.Items) > 0 { + return true, nil + } + + return false, nil +} + +func (provider *Provider) CheckClusterRoleBindingExists(ctx context.Context, name string) (bool, error) { + listOptions := metav1.ListOptions{ + FieldSelector: fmt.Sprintf("metadata.name=%s", name), + Limit: 1, + } + resourceList, err := provider.clientSet.RbacV1().ClusterRoleBindings().List(ctx, listOptions) + if err != nil { + return false, err + } + + if len(resourceList.Items) > 0 { + return true, nil + } + + return false, nil +} + func (provider *Provider) CheckPodExists(ctx context.Context, namespace string, name string) (bool, error) { listOptions := metav1.ListOptions{ FieldSelector: fmt.Sprintf("metadata.name=%s", name), @@ -332,7 +477,7 @@ func (provider *Provider) CheckDaemonSetExists(ctx context.Context, namespace st return false, nil } -func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespace string, daemonSetName string, podImage string, tapperPodName string, aggregatorPodIp string, nodeToTappedPodIPMap map[string][]string, linkServiceAccount bool, tapOutgoing bool) error { +func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespace string, daemonSetName string, podImage string, tapperPodName string, aggregatorPodIp string, nodeToTappedPodIPMap map[string][]string, serviceAccountName string, tapOutgoing bool) error { if len(nodeToTappedPodIPMap) == 0 { return fmt.Errorf("Daemon set %s must tap at least 1 pod", daemonSetName) } @@ -426,7 +571,7 @@ func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespac podSpec.WithHostNetwork(true) podSpec.WithDNSPolicy(core.DNSClusterFirstWithHostNet) podSpec.WithTerminationGracePeriodSeconds(0) - if linkServiceAccount { + if serviceAccountName != "" { podSpec.WithServiceAccountName(serviceAccountName) } podSpec.WithContainers(agentContainer) diff --git a/cli/mizu/consts.go b/cli/mizu/consts.go index 1f960ead2..45d2a2246 100644 --- a/cli/mizu/consts.go +++ b/cli/mizu/consts.go @@ -9,11 +9,14 @@ var ( ) const ( - ResourcesNamespace = "default" - TapperDaemonSetName = "mizu-tapper-daemon-set" - AggregatorPodName = "mizu-collector" - TapperPodName = "mizu-tapper" - K8sAllNamespaces = "" + AggregatorPodName = "mizu-collector" + ClusterRoleBindingName = "mizu-cluster-role-binding" + ClusterRoleName = "mizu-cluster-role" + K8sAllNamespaces = "" + ResourcesNamespace = "mizu" + ServiceAccountName = "mizu-service-account" + TapperDaemonSetName = "mizu-tapper-daemon-set" + TapperPodName = "mizu-tapper" ) const ( diff --git a/examples/roles/permissions-all-namespaces-without-ip-resolution.yaml b/examples/roles/permissions-all-namespaces-without-ip-resolution.yaml new file mode 100644 index 000000000..3252abb89 --- /dev/null +++ b/examples/roles/permissions-all-namespaces-without-ip-resolution.yaml @@ -0,0 +1,35 @@ +# This example shows the roles required for a user to be able to use Mizu in all namespaces with IP resolution disabled. +# (Traffic will be recorded, but Mizu will not translate IP addresses to names) +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: mizu-runner-clusterrole +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["list", "watch", "create"] +- apiGroups: [""] + resources: ["services"] + verbs: ["create"] +- apiGroups: ["apps"] + resources: ["daemonsets"] + verbs: ["create", "patch"] +- apiGroups: [""] + resources: ["namespaces"] + verbs: ["list", "watch", "create", "delete"] +- apiGroups: [""] + resources: ["services/proxy"] + verbs: ["get"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: mizu-runner-clusterrolebindings +subjects: +- kind: User + name: user1 + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: mizu-runner-clusterrole + apiGroup: rbac.authorization.k8s.io diff --git a/examples/roles/permissions-all-namespaces.yaml b/examples/roles/permissions-all-namespaces.yaml new file mode 100644 index 000000000..0f3ba3dff --- /dev/null +++ b/examples/roles/permissions-all-namespaces.yaml @@ -0,0 +1,52 @@ +# This example shows the roles required for a user to be able to use Mizu in all namespaces. +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: mizu-runner-clusterrole +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch", "create"] +- apiGroups: [""] + resources: ["services"] + verbs: ["get", "list", "watch", "create"] +- apiGroups: ["apps"] + resources: ["daemonsets"] + verbs: ["create", "patch"] +- apiGroups: [""] + resources: ["namespaces"] + verbs: ["list", "watch", "create", "delete"] +- apiGroups: [""] + resources: ["services/proxy"] + verbs: ["get"] +- apiGroups: [""] + resources: ["serviceaccounts"] + verbs: ["get", "create"] +- apiGroups: ["rbac.authorization.k8s.io"] + resources: ["clusterroles"] + verbs: ["list", "create", "delete"] +- apiGroups: ["rbac.authorization.k8s.io"] + resources: ["clusterrolebindings"] + verbs: ["list", "create", "delete"] +- apiGroups: ["apps", "extensions"] + resources: ["pods"] + verbs: ["get", "list", "watch"] +- apiGroups: ["apps", "extensions"] + resources: ["services"] + verbs: ["get", "list", "watch"] +- apiGroups: ["", "apps", "extensions"] + resources: ["endpoints"] + verbs: ["get", "list", "watch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: mizu-runner-clusterrolebindings +subjects: +- kind: User + name: user1 + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: mizu-runner-clusterrole + apiGroup: rbac.authorization.k8s.io From ac358be8777007403e3d445df1a1c31d5449da2e Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Thu, 22 Jul 2021 15:26:28 +0300 Subject: [PATCH 27/69] Making kube config errors more user friendly (#132) * Making kube config errors more user friendly --- cli/cmd/tapRunner.go | 13 ++++++++++++- cli/cmd/view.go | 9 +++++---- cli/cmd/viewRunner.go | 13 ++++++++++++- cli/kubernetes/provider.go | 34 ++++++++++++++++------------------ 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index 709cee3db..3301f9341 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -9,6 +9,7 @@ import ( "github.com/up9inc/mizu/shared" "github.com/up9inc/mizu/shared/debounce" core "k8s.io/api/core/v1" + "k8s.io/client-go/tools/clientcmd" "k8s.io/apimachinery/pkg/util/wait" "log" "net/http" @@ -36,7 +37,17 @@ func RunMizuTap(podRegexQuery *regexp.Regexp, tappingOptions *MizuTapOptions) { return } - kubernetesProvider := kubernetes.NewProvider(tappingOptions.KubeConfigPath) + kubernetesProvider, err := kubernetes.NewProvider(tappingOptions.KubeConfigPath) + if err != nil { + if clientcmd.IsEmptyConfig(err) { + fmt.Printf(mizu.Red, "Couldn't find the kube config file, or file is empty. Try adding '--kube-config='\n") + return + } + if clientcmd.IsConfigurationInvalid(err) { + fmt.Printf(mizu.Red, "Invalid kube config file. Try using a different config with '--kube-config='\n") + return + } + } defer cleanUpMizuResources(kubernetesProvider) ctx, cancel := context.WithCancel(context.Background()) diff --git a/cli/cmd/view.go b/cli/cmd/view.go index 6733418c1..8d6bfd0fe 100644 --- a/cli/cmd/view.go +++ b/cli/cmd/view.go @@ -6,7 +6,8 @@ import ( ) type MizuViewOptions struct { - GuiPort uint16 + GuiPort uint16 + KubeConfigPath string } var mizuViewOptions = &MizuViewOptions{} @@ -15,8 +16,8 @@ var viewCmd = &cobra.Command{ Use: "view", Short: "Open GUI in browser", RunE: func(cmd *cobra.Command, args []string) error { - go mizu.ReportRun("view", mizuFetchOptions) - if isCompatible, err := mizu.CheckVersionCompatibility(mizuFetchOptions.MizuPort); err != nil { + go mizu.ReportRun("view", mizuViewOptions) + if isCompatible, err := mizu.CheckVersionCompatibility(mizuViewOptions.GuiPort); err != nil { return err } else if !isCompatible { return nil @@ -30,5 +31,5 @@ func init() { rootCmd.AddCommand(viewCmd) viewCmd.Flags().Uint16VarP(&mizuViewOptions.GuiPort, "gui-port", "p", 8899, "Provide a custom port for the web interface webserver") - + viewCmd.Flags().StringVarP(&mizuViewOptions.KubeConfigPath, "kube-config", "k", "", "Path to kube-config file") } diff --git a/cli/cmd/viewRunner.go b/cli/cmd/viewRunner.go index 289ba5234..d37a85559 100644 --- a/cli/cmd/viewRunner.go +++ b/cli/cmd/viewRunner.go @@ -5,11 +5,22 @@ import ( "fmt" "github.com/up9inc/mizu/cli/kubernetes" "github.com/up9inc/mizu/cli/mizu" + "k8s.io/client-go/tools/clientcmd" "net/http" ) func runMizuView(mizuViewOptions *MizuViewOptions) { - kubernetesProvider := kubernetes.NewProvider("") + kubernetesProvider, err := kubernetes.NewProvider(mizuViewOptions.KubeConfigPath) + if err != nil { + if clientcmd.IsEmptyConfig(err) { + fmt.Printf(mizu.Red, "Couldn't find the kube config file, or file is empty. Try adding '--kube-config='\n") + return + } + if clientcmd.IsConfigurationInvalid(err) { + fmt.Printf(mizu.Red, "Invalid kube config file. Try using a different config with '--kube-config='\n") + return + } + } ctx, cancel := context.WithCancel(context.Background()) defer cancel() diff --git a/cli/kubernetes/provider.go b/cli/kubernetes/provider.go index ddf79dffe..df62afae7 100644 --- a/cli/kubernetes/provider.go +++ b/cli/kubernetes/provider.go @@ -6,6 +6,8 @@ import ( "encoding/json" "errors" "fmt" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" "os" "path/filepath" "regexp" @@ -17,7 +19,6 @@ import ( k8serrors "k8s.io/apimachinery/pkg/api/errors" resource "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/watch" applyconfapp "k8s.io/client-go/applyconfigurations/apps/v1" @@ -29,7 +30,6 @@ import ( _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" _ "k8s.io/client-go/plugin/pkg/client/auth/openstack" restclient "k8s.io/client-go/rest" - "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/clientcmd" _ "k8s.io/client-go/tools/portforward" watchtools "k8s.io/client-go/tools/watch" @@ -44,17 +44,14 @@ type Provider struct { } const ( - fieldManagerName = "mizu-manager" + fieldManagerName = "mizu-manager" ) -func NewProvider(kubeConfigPath string) *Provider { - if kubeConfigPath == "" { - kubeConfigPath = os.Getenv("KUBECONFIG") - } +func NewProvider(kubeConfigPath string) (*Provider, error) { kubernetesConfig := loadKubernetesConfiguration(kubeConfigPath) restClientConfig, err := kubernetesConfig.ClientConfig() if err != nil { - panic(err.Error()) + return nil, err } clientSet := getClientSet(restClientConfig) @@ -62,7 +59,7 @@ func NewProvider(kubeConfigPath string) *Provider { clientSet: clientSet, kubernetesConfig: kubernetesConfig, clientConfig: *restClientConfig, - } + }, nil } func (provider *Provider) CurrentNamespace() string { @@ -301,8 +298,7 @@ func (provider *Provider) CreateMizuRBAC(ctx context.Context, namespace string, } func (provider *Provider) RemoveNamespace(ctx context.Context, name string) error { - if isFound, err := provider.CheckNamespaceExists(ctx, name); - err != nil { + if isFound, err := provider.CheckNamespaceExists(ctx, name); err != nil { return err } else if !isFound { return nil @@ -324,8 +320,7 @@ func (provider *Provider) RemoveNonNamespacedResources(ctx context.Context, clus } func (provider *Provider) RemoveClusterRole(ctx context.Context, name string) error { - if isFound, err := provider.CheckClusterRoleExists(ctx, name); - err != nil { + if isFound, err := provider.CheckClusterRoleExists(ctx, name); err != nil { return err } else if !isFound { return nil @@ -335,8 +330,7 @@ func (provider *Provider) RemoveClusterRole(ctx context.Context, name string) er } func (provider *Provider) RemoveClusterRoleBinding(ctx context.Context, name string) error { - if isFound, err := provider.CheckClusterRoleBindingExists(ctx, name); - err != nil { + if isFound, err := provider.CheckClusterRoleBindingExists(ctx, name); err != nil { return err } else if !isFound { return nil @@ -378,7 +372,7 @@ func (provider *Provider) RemoveDaemonSet(ctx context.Context, namespace string, func (provider *Provider) CheckNamespaceExists(ctx context.Context, name string) (bool, error) { listOptions := metav1.ListOptions{ FieldSelector: fmt.Sprintf("metadata.name=%s", name), - Limit: 1, + Limit: 1, } resourceList, err := provider.clientSet.CoreV1().Namespaces().List(ctx, listOptions) if err != nil { @@ -395,7 +389,7 @@ func (provider *Provider) CheckNamespaceExists(ctx context.Context, name string) func (provider *Provider) CheckClusterRoleExists(ctx context.Context, name string) (bool, error) { listOptions := metav1.ListOptions{ FieldSelector: fmt.Sprintf("metadata.name=%s", name), - Limit: 1, + Limit: 1, } resourceList, err := provider.clientSet.RbacV1().ClusterRoles().List(ctx, listOptions) if err != nil { @@ -412,7 +406,7 @@ func (provider *Provider) CheckClusterRoleExists(ctx context.Context, name strin func (provider *Provider) CheckClusterRoleBindingExists(ctx context.Context, name string) (bool, error) { listOptions := metav1.ListOptions{ FieldSelector: fmt.Sprintf("metadata.name=%s", name), - Limit: 1, + Limit: 1, } resourceList, err := provider.clientSet.RbacV1().ClusterRoleBindings().List(ctx, listOptions) if err != nil { @@ -615,6 +609,10 @@ func getClientSet(config *restclient.Config) *kubernetes.Clientset { } func loadKubernetesConfiguration(kubeConfigPath string) clientcmd.ClientConfig { + if kubeConfigPath == "" { + kubeConfigPath = os.Getenv("KUBECONFIG") + } + if kubeConfigPath == "" { home := homedir.HomeDir() kubeConfigPath = filepath.Join(home, ".kube", "config") From a2150b4a7836e9e20fdf40150f20009b044b03a6 Mon Sep 17 00:00:00 2001 From: lirazyehezkel <61656597+lirazyehezkel@users.noreply.github.com> Date: Thu, 22 Jul 2021 15:41:09 +0300 Subject: [PATCH 28/69] UI api helper (#131) * Api helper * cr fixes --- ui/package-lock.json | 21229 +------------------------ ui/package.json | 1 + ui/src/components/HarEntriesList.tsx | 12 +- ui/src/components/HarPage.tsx | 51 +- ui/src/components/StatusBar.tsx | 12 +- ui/src/helpers/api.js | 45 + 6 files changed, 113 insertions(+), 21237 deletions(-) create mode 100644 ui/src/helpers/api.js diff --git a/ui/package-lock.json b/ui/package-lock.json index 759012d82..b5ae0c17a 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -1,21181 +1,8 @@ { "name": "mizu-ui", "version": "0.1.0", - "lockfileVersion": 2, + "lockfileVersion": 1, "requires": true, - "packages": { - "": { - "name": "mizu-ui", - "version": "0.1.0", - "dependencies": { - "@material-ui/core": "^4.11.3", - "@testing-library/jest-dom": "^5.11.10", - "@testing-library/react": "^11.2.6", - "@testing-library/user-event": "^12.8.3", - "@types/jest": "^26.0.22", - "@types/node": "^12.20.10", - "@types/react": "^17.0.3", - "@types/react-dom": "^17.0.3", - "node-sass": "^5.0.0", - "numeral": "^2.0.6", - "protobuf-decoder": "^0.1.0", - "react": "^17.0.2", - "react-copy-to-clipboard": "^5.0.3", - "react-dom": "^17.0.2", - "react-scripts": "4.0.3", - "react-scrollable-feed": "^1.3.0", - "react-syntax-highlighter": "^15.4.3", - "typescript": "^4.2.4", - "web-vitals": "^1.1.1" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "dependencies": { - "@babel/highlight": "^7.12.13" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.15.tgz", - "integrity": "sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==" - }, - "node_modules/@babel/core": { - "version": "7.12.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.3.tgz", - "integrity": "sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g==", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.1", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.1", - "@babel/parser": "^7.12.3", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@babel/generator": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.16.tgz", - "integrity": "sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg==", - "dependencies": { - "@babel/types": "^7.13.16", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", - "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", - "dependencies": { - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz", - "integrity": "sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA==", - "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", - "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", - "dependencies": { - "@babel/compat-data": "^7.13.15", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", - "semver": "^6.3.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.13.11", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz", - "integrity": "sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw==", - "dependencies": { - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-member-expression-to-functions": "^7.13.0", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/helper-replace-supers": "^7.13.0", - "@babel/helper-split-export-declaration": "^7.12.13" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz", - "integrity": "sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.12.13", - "regexpu-core": "^4.7.1" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.0.tgz", - "integrity": "sha512-JT8tHuFjKBo8NnaUbblz7mIu1nnvUDiHVjXXkulZULyidvo/7P6TY7+YqpV37IfF+KUFxmlK04elKtGKXaiVgw==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.13.0", - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/traverse": "^7.13.0", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" - } - }, - "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz", - "integrity": "sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA==", - "dependencies": { - "@babel/types": "^7.13.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", - "dependencies": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", - "dependencies": { - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.16.tgz", - "integrity": "sha512-1eMtTrXtrwscjcAeO4BVK+vvkxaLJSPFz1w1KLawz6HLNi9bPFGBNwwDyVfiu1Tv/vRRFYfoGaKhmAQPGPn5Wg==", - "dependencies": { - "@babel/traverse": "^7.13.15", - "@babel/types": "^7.13.16" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", - "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", - "dependencies": { - "@babel/types": "^7.13.12" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", - "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", - "dependencies": { - "@babel/types": "^7.13.12" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", - "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", - "dependencies": { - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-replace-supers": "^7.13.12", - "@babel/helper-simple-access": "^7.13.12", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.12.11", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", - "dependencies": { - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==" - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz", - "integrity": "sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.12.13", - "@babel/helper-wrap-function": "^7.13.0", - "@babel/types": "^7.13.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", - "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", - "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", - "dependencies": { - "@babel/types": "^7.13.12" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz", - "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==", - "dependencies": { - "@babel/types": "^7.12.1" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", - "dependencies": { - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==" - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz", - "integrity": "sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA==", - "dependencies": { - "@babel/helper-function-name": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.16.tgz", - "integrity": "sha512-x5otxUaLpdWHl02P4L94wBU+2BJXBkvO+6d6uzQ+xD9/h2hTSAwA5O8QV8GqKx/l8i+VYmKKQg9e2QGTa2Wu3Q==", - "dependencies": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.15", - "@babel/types": "^7.13.16" - } - }, - "node_modules/@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", - "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz", - "integrity": "sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", - "@babel/plugin-proposal-optional-chaining": "^7.13.12" - } - }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.15.tgz", - "integrity": "sha512-VapibkWzFeoa6ubXy/NgV5U2U4MVnUlvnx6wo1XhlsaTrLYWE0UFpDQsVrmn22q5CzeloqJ8gEMHSKxuee6ZdA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-remap-async-to-generator": "^7.13.0", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz", - "integrity": "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.12.1.tgz", - "integrity": "sha512-knNIuusychgYN8fGJHONL0RbFxLGawhXOJNLBk75TniTsZZeA+wdkDuv6wp4lGwzQEKjZi6/WYtnb3udNPmQmQ==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-decorators": "^7.12.1" - } - }, - "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz", - "integrity": "sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz", - "integrity": "sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz", - "integrity": "sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-json-strings": "^7.8.3" - } - }, - "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz", - "integrity": "sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - } - }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz", - "integrity": "sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - } - }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz", - "integrity": "sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz", - "integrity": "sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g==", - "dependencies": { - "@babel/compat-data": "^7.13.8", - "@babel/helper-compilation-targets": "^7.13.8", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.13.0" - } - }, - "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz", - "integrity": "sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - } - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz", - "integrity": "sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } - }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz", - "integrity": "sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz", - "integrity": "sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.12.13.tgz", - "integrity": "sha512-Rw6aIXGuqDLr6/LoBBYE57nKOzQpz/aDkKlMqEwH+Vp0MXbG6H/TfRjaY343LKxzAKAMXIHsQ8JzaZKuDZ9MwA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "node_modules/@babel/plugin-syntax-flow": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.12.13.tgz", - "integrity": "sha512-J/RYxnlSLXZLVR7wTRsozxKT8qbsx1mNKJzXEEjQ0Kjx1ZACcyHgbanNWNCFtc36IzuWhYWPpvJFFoexoOWFmA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.13.tgz", - "integrity": "sha512-d4HM23Q1K7oq/SLNmG6mRt85l2csmQ0cHRaxRXjKW0YFdEXqlZ5kzFQKH5Uc3rDJECgu+yCRgPkG04Mm98R/1g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz", - "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz", - "integrity": "sha512-cHP3u1JiUiG2LFDKbXnwVad81GvfyIOmCD6HIEId6ojrY0Drfy2q1jw7BwN7dE84+kTnBjLkXoL3IEy/3JPu2w==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz", - "integrity": "sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz", - "integrity": "sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg==", - "dependencies": { - "@babel/helper-module-imports": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-remap-async-to-generator": "^7.13.0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz", - "integrity": "sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.13.16.tgz", - "integrity": "sha512-ad3PHUxGnfWF4Efd3qFuznEtZKoBp0spS+DgqzVzRPV7urEBvPLue3y2j80w4Jf2YLzZHj8TOv/Lmvdmh3b2xg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz", - "integrity": "sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.12.13", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-replace-supers": "^7.13.0", - "@babel/helper-split-export-declaration": "^7.12.13", - "globals": "^11.1.0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz", - "integrity": "sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.0.tgz", - "integrity": "sha512-zym5em7tePoNT9s964c0/KU3JPPnuq7VhIxPRefJ4/s82cD+q1mgKfuGRDMCPL0HTyKz4dISuQlCusfgCJ86HA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz", - "integrity": "sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz", - "integrity": "sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz", - "integrity": "sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA==", - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.12.1.tgz", - "integrity": "sha512-8hAtkmsQb36yMmEtk2JZ9JnVyDSnDOdlB+0nEGzIDLuK4yR3JcEjfuFPYkdEPSh8Id+rAMeBEn+X0iVEyho6Hg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-flow": "^7.12.1" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz", - "integrity": "sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz", - "integrity": "sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ==", - "dependencies": { - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz", - "integrity": "sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz", - "integrity": "sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz", - "integrity": "sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ==", - "dependencies": { - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz", - "integrity": "sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw==", - "dependencies": { - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-simple-access": "^7.12.13", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.13.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz", - "integrity": "sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A==", - "dependencies": { - "@babel/helper-hoist-variables": "^7.13.0", - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-validator-identifier": "^7.12.11", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz", - "integrity": "sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw==", - "dependencies": { - "@babel/helper-module-transforms": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz", - "integrity": "sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz", - "integrity": "sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz", - "integrity": "sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13", - "@babel/helper-replace-supers": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz", - "integrity": "sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz", - "integrity": "sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.13.13.tgz", - "integrity": "sha512-SNJU53VM/SjQL0bZhyU+f4kJQz7bQQajnrZRSaU21hruG/NWY41AEM9AWXeXX90pYr/C2yAmTgI6yW3LlLrAUQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.13.tgz", - "integrity": "sha512-MprESJzI9O5VnJZrL7gg1MpdqmiFcUv41Jc7SahxYsNP2kDkFqClxxTZq+1Qv4AFCamm+GXMRDQINNn+qrxmiA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.13.12.tgz", - "integrity": "sha512-jcEI2UqIcpCqB5U5DRxIl0tQEProI2gcu+g8VTIqxLO5Iidojb4d77q+fwGseCvd8af/lJ9masp4QWzBXFE2xA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.12.13", - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-jsx": "^7.12.13", - "@babel/types": "^7.13.12" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.17.tgz", - "integrity": "sha512-BPjYV86SVuOaudFhsJR1zjgxxOhJDt6JHNoD48DxWEIxUCAMjV1ys6DYw4SDYZh0b1QsS2vfIA9t/ZsQGsDOUQ==", - "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.12.17" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.12.13.tgz", - "integrity": "sha512-FXYw98TTJ125GVCCkFLZXlZ1qGcsYqNQhVBQcZjyrwf8FEUtVfKIoidnO8S0q+KBQpDYNTmiGo1gn67Vti04lQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.12.13.tgz", - "integrity": "sha512-O5JJi6fyfih0WfDgIJXksSPhGP/G0fQpfxYy87sDc+1sFmsCS6wr3aAn+whbzkhbjtq4VMqLRaSzR6IsshIC0Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz", - "integrity": "sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz", - "integrity": "sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ==", - "dependencies": { - "regenerator-transform": "^0.14.2" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz", - "integrity": "sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.1.tgz", - "integrity": "sha512-Ac/H6G9FEIkS2tXsZjL4RAdS3L3WHxci0usAnz7laPWUmFiGtj7tIASChqKZMHTSQTQY6xDbOq+V1/vIq3QrWg==", - "dependencies": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "resolve": "^1.8.1", - "semver": "^5.5.1" - } - }, - "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz", - "integrity": "sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz", - "integrity": "sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz", - "integrity": "sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz", - "integrity": "sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz", - "integrity": "sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.13.0.tgz", - "integrity": "sha512-elQEwluzaU8R8dbVuW2Q2Y8Nznf7hnjM7+DSCd14Lo5fF63C9qNLbwZYbmZrtV9/ySpSUpkRpQXvJb6xyu4hCQ==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.13.0", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-typescript": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz", - "integrity": "sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz", - "integrity": "sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.12.13", - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.13.15.tgz", - "integrity": "sha512-D4JAPMXcxk69PKe81jRJ21/fP/uYdcTZ3hJDF5QX2HSI9bBxxYw/dumdR6dGumhjxlprHPE4XWoPaqzZUVy2MA==", - "dependencies": { - "@babel/compat-data": "^7.13.15", - "@babel/helper-compilation-targets": "^7.13.13", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-validator-option": "^7.12.17", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.13.12", - "@babel/plugin-proposal-async-generator-functions": "^7.13.15", - "@babel/plugin-proposal-class-properties": "^7.13.0", - "@babel/plugin-proposal-dynamic-import": "^7.13.8", - "@babel/plugin-proposal-export-namespace-from": "^7.12.13", - "@babel/plugin-proposal-json-strings": "^7.13.8", - "@babel/plugin-proposal-logical-assignment-operators": "^7.13.8", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", - "@babel/plugin-proposal-numeric-separator": "^7.12.13", - "@babel/plugin-proposal-object-rest-spread": "^7.13.8", - "@babel/plugin-proposal-optional-catch-binding": "^7.13.8", - "@babel/plugin-proposal-optional-chaining": "^7.13.12", - "@babel/plugin-proposal-private-methods": "^7.13.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.12.13", - "@babel/plugin-transform-arrow-functions": "^7.13.0", - "@babel/plugin-transform-async-to-generator": "^7.13.0", - "@babel/plugin-transform-block-scoped-functions": "^7.12.13", - "@babel/plugin-transform-block-scoping": "^7.12.13", - "@babel/plugin-transform-classes": "^7.13.0", - "@babel/plugin-transform-computed-properties": "^7.13.0", - "@babel/plugin-transform-destructuring": "^7.13.0", - "@babel/plugin-transform-dotall-regex": "^7.12.13", - "@babel/plugin-transform-duplicate-keys": "^7.12.13", - "@babel/plugin-transform-exponentiation-operator": "^7.12.13", - "@babel/plugin-transform-for-of": "^7.13.0", - "@babel/plugin-transform-function-name": "^7.12.13", - "@babel/plugin-transform-literals": "^7.12.13", - "@babel/plugin-transform-member-expression-literals": "^7.12.13", - "@babel/plugin-transform-modules-amd": "^7.13.0", - "@babel/plugin-transform-modules-commonjs": "^7.13.8", - "@babel/plugin-transform-modules-systemjs": "^7.13.8", - "@babel/plugin-transform-modules-umd": "^7.13.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13", - "@babel/plugin-transform-new-target": "^7.12.13", - "@babel/plugin-transform-object-super": "^7.12.13", - "@babel/plugin-transform-parameters": "^7.13.0", - "@babel/plugin-transform-property-literals": "^7.12.13", - "@babel/plugin-transform-regenerator": "^7.13.15", - "@babel/plugin-transform-reserved-words": "^7.12.13", - "@babel/plugin-transform-shorthand-properties": "^7.12.13", - "@babel/plugin-transform-spread": "^7.13.0", - "@babel/plugin-transform-sticky-regex": "^7.12.13", - "@babel/plugin-transform-template-literals": "^7.13.0", - "@babel/plugin-transform-typeof-symbol": "^7.12.13", - "@babel/plugin-transform-unicode-escapes": "^7.12.13", - "@babel/plugin-transform-unicode-regex": "^7.12.13", - "@babel/preset-modules": "^0.1.4", - "@babel/types": "^7.13.14", - "babel-plugin-polyfill-corejs2": "^0.2.0", - "babel-plugin-polyfill-corejs3": "^0.2.0", - "babel-plugin-polyfill-regenerator": "^0.2.0", - "core-js-compat": "^3.9.0", - "semver": "^6.3.0" - } - }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", - "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "node_modules/@babel/preset-react": { - "version": "7.13.13", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.13.13.tgz", - "integrity": "sha512-gx+tDLIE06sRjKJkVtpZ/t3mzCDOnPG+ggHZG9lffUbX8+wC739x20YQc9V35Do6ZAxaUc/HhVHIiOzz5MvDmA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/helper-validator-option": "^7.12.17", - "@babel/plugin-transform-react-display-name": "^7.12.13", - "@babel/plugin-transform-react-jsx": "^7.13.12", - "@babel/plugin-transform-react-jsx-development": "^7.12.17", - "@babel/plugin-transform-react-pure-annotations": "^7.12.1" - } - }, - "node_modules/@babel/preset-typescript": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.12.1.tgz", - "integrity": "sha512-hNK/DhmoJPsksdHuI/RVrcEws7GN5eamhi28JkO52MqIxU8Z0QpmiSOQxZHWOHV7I3P4UjHV97ay4TcamMA6Kw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-transform-typescript": "^7.12.1" - } - }, - "node_modules/@babel/runtime": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.16.tgz", - "integrity": "sha512-7VsWJsI5USRhBLE/3of+VU2DDNWtYHQlq2IHu2iL15+Yx4qVqP8KllR6JMHQlTKWRyDk9Tw6unkqSusaHXt//A==", - "dependencies": { - "regenerator-runtime": "^0.13.4" - } - }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.13.16.tgz", - "integrity": "sha512-HJq7yXmBSAGLl/4BSO25vjWnrhzKHYcB6doNbO+FjYQz6C5lgYsmJF1U8ziDP8/RBqIhNAyU7SjRip+flbjV3g==", - "dependencies": { - "core-js-pure": "^3.0.0", - "regenerator-runtime": "^0.13.4" - } - }, - "node_modules/@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" - } - }, - "node_modules/@babel/traverse": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.15.tgz", - "integrity": "sha512-/mpZMNvj6bce59Qzl09fHEs8Bt8NnpEDQYleHUPZQ3wXUMvXi+HJPLars68oAbmp839fGoOkv2pSL2z9ajCIaQ==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.15", - "@babel/types": "^7.13.14", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "node_modules/@babel/types": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.16.tgz", - "integrity": "sha512-7enM8Wxhrl1hB1+k6+xO6RmxpNkaveRWkdpyii8DkrLWRgr0l3x29/SEuhTIkP+ynHsU/Hpjn8Evd/axv/ll6Q==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "to-fast-properties": "^2.0.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" - }, - "node_modules/@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "dependencies": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - }, - "bin": { - "watch": "cli.js" - }, - "engines": { - "node": ">=0.1.95" - } - }, - "node_modules/@csstools/convert-colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz", - "integrity": "sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/@csstools/normalize.css": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz", - "integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==" - }, - "node_modules/@emotion/hash": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", - "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" - }, - "node_modules/@eslint/eslintrc": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", - "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dependencies": { - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@hapi/address": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", - "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==" - }, - "node_modules/@hapi/bourne": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", - "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==" - }, - "node_modules/@hapi/hoek": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", - "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==" - }, - "node_modules/@hapi/joi": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", - "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", - "dependencies": { - "@hapi/address": "2.x.x", - "@hapi/bourne": "1.x.x", - "@hapi/hoek": "8.x.x", - "@hapi/topo": "3.x.x" - } - }, - "node_modules/@hapi/topo": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", - "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", - "dependencies": { - "@hapi/hoek": "^8.3.0" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/console/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@jest/console/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/console/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@jest/console/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.6.2", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-resolve-dependencies": "^26.6.3", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "jest-watcher": "^26.6.2", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/core/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@jest/core/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/core/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@jest/core/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core/node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/core/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", - "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", - "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" - }, - "engines": { - "node": ">= 10.14.2" - }, - "optionalDependencies": { - "node-notifier": "^8.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@jest/reporters/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@jest/reporters/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/reporters/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/reporters/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/source-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/source-map/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", - "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", - "dependencies": { - "@jest/test-result": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.6.2", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/transform/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@jest/transform/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/transform/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@jest/transform/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/transform/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/transform/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/types/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@jest/types/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/types/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@jest/types/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@material-ui/core": { - "version": "4.11.3", - "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.3.tgz", - "integrity": "sha512-Adt40rGW6Uds+cAyk3pVgcErpzU/qxc7KBR94jFHBYretU4AtWZltYcNsbeMn9tXL86jjVL1kuGcIHsgLgFGRw==", - "dependencies": { - "@babel/runtime": "^7.4.4", - "@material-ui/styles": "^4.11.3", - "@material-ui/system": "^4.11.3", - "@material-ui/types": "^5.1.0", - "@material-ui/utils": "^4.11.2", - "@types/react-transition-group": "^4.2.0", - "clsx": "^1.0.4", - "hoist-non-react-statics": "^3.3.2", - "popper.js": "1.16.1-lts", - "prop-types": "^15.7.2", - "react-is": "^16.8.0 || ^17.0.0", - "react-transition-group": "^4.4.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@material-ui/styles": { - "version": "4.11.3", - "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.3.tgz", - "integrity": "sha512-HzVzCG+PpgUGMUYEJ2rTEmQYeonGh41BYfILNFb/1ueqma+p1meSdu4RX6NjxYBMhf7k+jgfHFTTz+L1SXL/Zg==", - "dependencies": { - "@babel/runtime": "^7.4.4", - "@emotion/hash": "^0.8.0", - "@material-ui/types": "^5.1.0", - "@material-ui/utils": "^4.11.2", - "clsx": "^1.0.4", - "csstype": "^2.5.2", - "hoist-non-react-statics": "^3.3.2", - "jss": "^10.5.1", - "jss-plugin-camel-case": "^10.5.1", - "jss-plugin-default-unit": "^10.5.1", - "jss-plugin-global": "^10.5.1", - "jss-plugin-nested": "^10.5.1", - "jss-plugin-props-sort": "^10.5.1", - "jss-plugin-rule-value-function": "^10.5.1", - "jss-plugin-vendor-prefixer": "^10.5.1", - "prop-types": "^15.7.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@material-ui/styles/node_modules/csstype": { - "version": "2.6.17", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz", - "integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A==" - }, - "node_modules/@material-ui/system": { - "version": "4.11.3", - "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.11.3.tgz", - "integrity": "sha512-SY7otguNGol41Mu2Sg6KbBP1ZRFIbFLHGK81y4KYbsV2yIcaEPOmsCK6zwWlp+2yTV3J/VwT6oSBARtGIVdXPw==", - "dependencies": { - "@babel/runtime": "^7.4.4", - "@material-ui/utils": "^4.11.2", - "csstype": "^2.5.2", - "prop-types": "^15.7.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@material-ui/system/node_modules/csstype": { - "version": "2.6.17", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz", - "integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A==" - }, - "node_modules/@material-ui/types": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz", - "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==" - }, - "node_modules/@material-ui/utils": { - "version": "4.11.2", - "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.2.tgz", - "integrity": "sha512-Uul8w38u+PICe2Fg2pDKCaIG7kOyhowZ9vjiC1FsVwPABTW8vPPKfF6OvxRq3IiBaI1faOJmgdvMG7rMJARBhA==", - "dependencies": { - "@babel/runtime": "^7.4.4", - "prop-types": "^15.7.2", - "react-is": "^16.8.0 || ^17.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", - "dependencies": { - "@nodelib/fs.stat": "2.0.4", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.4", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@npmcli/move-file/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.4.3.tgz", - "integrity": "sha512-br5Qwvh8D2OQqSXpd1g/xqXKnK0r+Jz6qVKBbWmpUcrbGOxUrf39V5oZ1876084CGn18uMdR5uvPqBv9UqtBjQ==", - "dependencies": { - "ansi-html": "^0.0.7", - "error-stack-parser": "^2.0.6", - "html-entities": "^1.2.1", - "native-url": "^0.2.6", - "schema-utils": "^2.6.5", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">= 10.x" - } - }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz", - "integrity": "sha512-RxtSL3XmdTAE2byxekYLnx+98kEUOrPHF/KRVjLH+DEIHy6kjIw7YINQzn+NXiH/NTrQLAwYs0GWB+csWygA9Q==", - "dependencies": { - "@rollup/pluginutils": "^3.0.8", - "@types/resolve": "0.0.8", - "builtin-modules": "^3.1.0", - "is-module": "^1.0.0", - "resolve": "^1.14.2" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/@rollup/plugin-replace": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", - "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "magic-string": "^0.25.7" - } - }, - "node_modules/@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "dependencies": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/@rollup/pluginutils/node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@surma/rollup-plugin-off-main-thread": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-1.4.2.tgz", - "integrity": "sha512-yBMPqmd1yEJo/280PAMkychuaALyQ9Lkb5q1ck3mjJrFuEobIfhnQ4J3mbvBoISmR3SWMWV+cGB/I0lCQee79A==", - "dependencies": { - "ejs": "^2.6.1", - "magic-string": "^0.25.0" - } - }, - "node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", - "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", - "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", - "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", - "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", - "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", - "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@svgr/babel-preset": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", - "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", - "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", - "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", - "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", - "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", - "@svgr/babel-plugin-transform-svg-component": "^5.5.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@svgr/core": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", - "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", - "dependencies": { - "@svgr/plugin-jsx": "^5.5.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^7.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@svgr/hast-util-to-babel-ast": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", - "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", - "dependencies": { - "@babel/types": "^7.12.6" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@svgr/plugin-jsx": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", - "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", - "dependencies": { - "@babel/core": "^7.12.3", - "@svgr/babel-preset": "^5.5.0", - "@svgr/hast-util-to-babel-ast": "^5.5.0", - "svg-parser": "^2.0.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@svgr/plugin-svgo": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", - "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", - "dependencies": { - "cosmiconfig": "^7.0.0", - "deepmerge": "^4.2.2", - "svgo": "^1.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@svgr/webpack": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", - "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/plugin-transform-react-constant-elements": "^7.12.1", - "@babel/preset-env": "^7.12.1", - "@babel/preset-react": "^7.12.5", - "@svgr/core": "^5.5.0", - "@svgr/plugin-jsx": "^5.5.0", - "@svgr/plugin-svgo": "^5.5.0", - "loader-utils": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@testing-library/dom": { - "version": "7.30.3", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-7.30.3.tgz", - "integrity": "sha512-7JhIg2MW6WPwyikH2iL3o7z+FTVgSOd2jqCwTAHqK7Qal2gRRYiUQyURAxtbK9VXm/UTyG9bRihv8C5Tznr2zw==", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^4.2.2", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.4", - "lz-string": "^1.4.4", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@testing-library/dom/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/dom/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@testing-library/dom/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/dom/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@testing-library/dom/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/dom/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/jest-dom": { - "version": "5.11.10", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.11.10.tgz", - "integrity": "sha512-FuKiq5xuk44Fqm0000Z9w0hjOdwZRNzgx7xGGxQYepWFZy+OYUMOT/wPI4nLYXCaVltNVpU1W/qmD88wLWDsqQ==", - "dependencies": { - "@babel/runtime": "^7.9.2", - "@types/testing-library__jest-dom": "^5.9.1", - "aria-query": "^4.2.2", - "chalk": "^3.0.0", - "css": "^3.0.0", - "css.escape": "^1.5.1", - "lodash": "^4.17.15", - "redent": "^3.0.0" - }, - "engines": { - "node": ">=8", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/@testing-library/jest-dom/node_modules/css": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", - "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", - "dependencies": { - "inherits": "^2.0.4", - "source-map": "^0.6.1", - "source-map-resolve": "^0.6.0" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/source-map-resolve": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", - "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/react": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-11.2.6.tgz", - "integrity": "sha512-TXMCg0jT8xmuU8BkKMtp8l7Z50Ykew5WNX8UoIKTaLFwKkP2+1YDhOLA2Ga3wY4x29jyntk7EWfum0kjlYiSjQ==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^7.28.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@testing-library/user-event": { - "version": "12.8.3", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-12.8.3.tgz", - "integrity": "sha512-IR0iWbFkgd56Bu5ZI/ej8yQwrkCv8Qydx6RzwbKz9faXazR/+5tvYKsZQgyXJiwgpcva127YO6JcWy7YlCfofQ==", - "dependencies": { - "@babel/runtime": "^7.12.5" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - } - }, - "node_modules/@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==" - }, - "node_modules/@types/aria-query": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.1.tgz", - "integrity": "sha512-S6oPal772qJZHoRZLFc/XoZW2gFvwXusYUmXPXkgxJLuEk2vOt7jc4Yo6z/vtI0EBkbPBVrJJ0B+prLIKiWqHg==" - }, - "node_modules/@types/babel__core": { - "version": "7.1.14", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz", - "integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", - "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", - "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.1.tgz", - "integrity": "sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==", - "dependencies": { - "@babel/types": "^7.3.0" - } - }, - "node_modules/@types/eslint": { - "version": "7.2.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz", - "integrity": "sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/estree": { - "version": "0.0.47", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz", - "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==" - }, - "node_modules/@types/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/hast": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.1.tgz", - "integrity": "sha512-viwwrB+6xGzw+G1eWpF9geV3fnsDgXqHG+cqgiHrvQfDUW5hzhCyV7Sy3UJxhfRFBsgky2SSW33qi/YrIkjX5Q==", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/html-minifier-terser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", - "integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==" - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "26.0.22", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.22.tgz", - "integrity": "sha512-eeWwWjlqxvBxc4oQdkueW5OF/gtfSceKk4OnOAGlUSwS/liBRtZppbJuz1YkgbrbfGOoeBHun9fOvXnjNwrSOw==", - "dependencies": { - "jest-diff": "^26.0.0", - "pretty-format": "^26.0.0" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" - }, - "node_modules/@types/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==" - }, - "node_modules/@types/node": { - "version": "12.20.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.10.tgz", - "integrity": "sha512-TxCmnSSppKBBOzYzPR2BR25YlX5Oay8z2XGwFBInuA/Co0V9xJhLlW4kjbxKtgeNo3NOMbQP1A5Rc03y+XecPw==" - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" - }, - "node_modules/@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" - }, - "node_modules/@types/prettier": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", - "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==" - }, - "node_modules/@types/prop-types": { - "version": "15.7.3", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", - "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" - }, - "node_modules/@types/q": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", - "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" - }, - "node_modules/@types/react": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.3.tgz", - "integrity": "sha512-wYOUxIgs2HZZ0ACNiIayItyluADNbONl7kt8lkLjVK8IitMH5QMyAh75Fwhmo37r1m7L2JaFj03sIfxBVDvRAg==", - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.3.tgz", - "integrity": "sha512-4NnJbCeWE+8YBzupn/YrJxZ8VnjcJq5iR1laqQ1vkpQgBiA7bwk0Rp24fxsdNinzJY2U+HHS4dJJDPdoMjdJ7w==", - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/react-transition-group": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.1.tgz", - "integrity": "sha512-vIo69qKKcYoJ8wKCJjwSgCTM+z3chw3g18dkrDfVX665tMH7tmbDxEAnPdey4gTlwZz5QuHGzd+hul0OVZDqqQ==", - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/scheduler": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz", - "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==" - }, - "node_modules/@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==" - }, - "node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==" - }, - "node_modules/@types/tapable": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.7.tgz", - "integrity": "sha512-0VBprVqfgFD7Ehb2vd8Lh9TG3jP98gvr8rgehQqzztZNI7o8zS8Ad4jyZneKELphpuE212D8J70LnSNQSyO6bQ==" - }, - "node_modules/@types/testing-library__jest-dom": { - "version": "5.9.5", - "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.9.5.tgz", - "integrity": "sha512-ggn3ws+yRbOHog9GxnXiEZ/35Mow6YtPZpd7Z5mKDeZS/o7zx3yAle0ov/wjhVB5QT4N2Dt+GNoGCdqkBGCajQ==", - "dependencies": { - "@types/jest": "*" - } - }, - "node_modules/@types/uglify-js": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.0.tgz", - "integrity": "sha512-EGkrJD5Uy+Pg0NUR8uA4bJ5WMfljyad0G+784vLCNUkD+QwOJXUbBYExXfVGf7YtyzdQp3L/XMYcliB987kL5Q==", - "dependencies": { - "source-map": "^0.6.1" - } - }, - "node_modules/@types/uglify-js/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@types/unist": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", - "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" - }, - "node_modules/@types/webpack": { - "version": "4.41.27", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.27.tgz", - "integrity": "sha512-wK/oi5gcHi72VMTbOaQ70VcDxSQ1uX8S2tukBK9ARuGXrYM/+u4ou73roc7trXDNmCxCoerE8zruQqX/wuHszA==", - "dependencies": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "^1", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - } - }, - "node_modules/@types/webpack-sources": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.0.tgz", - "integrity": "sha512-LXn/oYIpBeucgP1EIJbKQ2/4ZmpvRl+dlrFdX7+94SKRUV3Evy3FsfMZY318vGhkWUS5MPhtOM3w1/hCOAOXcg==", - "dependencies": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.7.3" - } - }, - "node_modules/@types/webpack-sources/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@types/webpack/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@types/yargs": { - "version": "15.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz", - "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.22.0.tgz", - "integrity": "sha512-U8SP9VOs275iDXaL08Ln1Fa/wLXfj5aTr/1c0t0j6CdbOnxh+TruXu1p4I0NAvdPBQgoPjHsgKn28mOi0FzfoA==", - "dependencies": { - "@typescript-eslint/experimental-utils": "4.22.0", - "@typescript-eslint/scope-manager": "4.22.0", - "debug": "^4.1.1", - "functional-red-black-tree": "^1.0.1", - "lodash": "^4.17.15", - "regexpp": "^3.0.0", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.22.0.tgz", - "integrity": "sha512-xJXHHl6TuAxB5AWiVrGhvbGL8/hbiCQ8FiWwObO3r0fnvBdrbWEDy1hlvGQOAWc6qsCWuWMKdVWlLAEMpxnddg==", - "dependencies": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.22.0", - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/typescript-estree": "4.22.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.22.0.tgz", - "integrity": "sha512-z/bGdBJJZJN76nvAY9DkJANYgK3nlRstRRi74WHm3jjgf2I8AglrSY+6l7ogxOmn55YJ6oKZCLLy+6PW70z15Q==", - "dependencies": { - "@typescript-eslint/scope-manager": "4.22.0", - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/typescript-estree": "4.22.0", - "debug": "^4.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.22.0.tgz", - "integrity": "sha512-OcCO7LTdk6ukawUM40wo61WdeoA7NM/zaoq1/2cs13M7GyiF+T4rxuA4xM+6LeHWjWbss7hkGXjFDRcKD4O04Q==", - "dependencies": { - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/visitor-keys": "4.22.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.22.0.tgz", - "integrity": "sha512-sW/BiXmmyMqDPO2kpOhSy2Py5w6KvRRsKZnV0c4+0nr4GIcedJwXAq+RHNK4lLVEZAJYFltnnk1tJSlbeS9lYA==", - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.22.0.tgz", - "integrity": "sha512-TkIFeu5JEeSs5ze/4NID+PIcVjgoU3cUQUIZnH3Sb1cEn1lBo7StSV5bwPuJQuoxKXlzAObjYTilOEKRuhR5yg==", - "dependencies": { - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/visitor-keys": "4.22.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-glob": "^4.0.1", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.22.0.tgz", - "integrity": "sha512-nnMu4F+s4o0sll6cBSsTeVsT4cwxB7zECK3dFxzEjPBii9xLpq4yqqsy/FU5zMfan6G60DKZSCXAa3sHJZrcYw==", - "dependencies": { - "@typescript-eslint/types": "4.22.0", - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - } - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", - "dependencies": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", - "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", - "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", - "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==" - }, - "node_modules/@webassemblyjs/helper-code-frame": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", - "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", - "dependencies": { - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "node_modules/@webassemblyjs/helper-fsm": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", - "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==" - }, - "node_modules/@webassemblyjs/helper-module-context": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", - "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", - "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", - "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", - "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", - "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", - "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", - "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/helper-wasm-section": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-opt": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", - "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", - "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", - "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "node_modules/@webassemblyjs/wast-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", - "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/floating-point-hex-parser": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-code-frame": "1.9.0", - "@webassemblyjs/helper-fsm": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", - "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "node_modules/abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==" - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/address": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", - "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", - "engines": { - "node": ">= 0.12.0" - } - }, - "node_modules/adjust-sourcemap-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-3.0.0.tgz", - "integrity": "sha512-YBrGyT2/uVQ/c6Rr+t6ZJXniY03YtHGMJQYal368burRGYKqhx9qGTWqcBU5s1CwYY9E/ri63RYyG1IacMZtqw==", - "dependencies": { - "loader-utils": "^2.0.0", - "regex-parser": "^2.2.11" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "node_modules/ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==" - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" - }, - "node_modules/alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" - }, - "node_modules/amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "engines": { - "node": ">=0.4.2" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "engines": { - "node": ">=10" - } - }, - "node_modules/ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "node_modules/are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "node_modules/are-we-there-yet/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/are-we-there-yet/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", - "dependencies": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/arity-n": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", - "integrity": "sha1-2edrEXM+CFacCEeuezmyhgswt0U=" - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" - }, - "node_modules/array-includes": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.5" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", - "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", - "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "engines": { - "node": ">=8" - } - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" - }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dependencies": { - "object-assign": "^4.1.1", - "util": "0.10.3" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/assert/node_modules/inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - }, - "node_modules/assert/node_modules/util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dependencies": { - "inherits": "2.0.1" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=" - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" - }, - "node_modules/async-foreach": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", - "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", - "engines": { - "node": "*" - } - }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/autoprefixer": { - "version": "9.8.6", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", - "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", - "dependencies": { - "browserslist": "^4.12.0", - "caniuse-lite": "^1.0.30001109", - "colorette": "^1.2.1", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.32", - "postcss-value-parser": "^4.1.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, - "node_modules/axe-core": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.1.4.tgz", - "integrity": "sha512-Pdgfv6iP0gNx9ejRGa3zE7Xgkj/iclXqLfe7BnatdZz0QnLZ3jrRHUVH8wNSdN68w05Sk3ShGTb3ydktMTooig==", - "engines": { - "node": ">=4" - } - }, - "node_modules/axobject-query": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", - "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" - }, - "node_modules/babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/babel-eslint/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/babel-extract-comments": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz", - "integrity": "sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==", - "dependencies": { - "babylon": "^6.18.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/babel-jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", - "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", - "dependencies": { - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/babel-jest/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-jest/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/babel-jest/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/babel-jest/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/babel-jest/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-jest/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", - "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", - "dependencies": { - "find-cache-dir": "^2.1.0", - "loader-utils": "^1.4.0", - "mkdirp": "^0.5.3", - "pify": "^4.0.1", - "schema-utils": "^2.6.5" - }, - "engines": { - "node": ">= 6.9" - } - }, - "node_modules/babel-loader/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/babel-loader/node_modules/loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dependencies": { - "object.assign": "^4.1.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", - "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^4.0.0", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/babel-plugin-macros": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", - "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", - "dependencies": { - "@babel/runtime": "^7.7.2", - "cosmiconfig": "^6.0.0", - "resolve": "^1.12.0" - } - }, - "node_modules/babel-plugin-macros/node_modules/cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-named-asset-import": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.7.tgz", - "integrity": "sha512-squySRkf+6JGnvjoUtDEjSREJEBirnXi9NqP6rjSYsylxQxqBTz+pkmf395i9E2zsvmYUaI40BHo6SqZUdydlw==" - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.0.tgz", - "integrity": "sha512-9bNwiR0dS881c5SHnzCmmGlMkJLl0OUZvxrxHo9w/iNoRuqaPjqlvBf4HrovXtQs/au5yKkpcdgfT1cC5PAZwg==", - "dependencies": { - "@babel/compat-data": "^7.13.11", - "@babel/helper-define-polyfill-provider": "^0.2.0", - "semver": "^6.1.1" - } - }, - "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.0.tgz", - "integrity": "sha512-zZyi7p3BCUyzNxLx8KV61zTINkkV65zVkDAFNZmrTCRVhjo1jAS+YLvDJ9Jgd/w2tsAviCwFHReYfxO3Iql8Yg==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.2.0", - "core-js-compat": "^3.9.1" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.0.tgz", - "integrity": "sha512-J7vKbCuD2Xi/eEHxquHN14bXAW9CXtecwuLrOIDJtcZzTaPzV1VdEfoUf9AzcRBMolKUQKM9/GVojeh0hFiqMg==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.2.0" - } - }, - "node_modules/babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=" - }, - "node_modules/babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", - "dependencies": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" - } - }, - "node_modules/babel-plugin-transform-react-remove-prop-types": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", - "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "node_modules/babel-preset-jest": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", - "dependencies": { - "babel-plugin-jest-hoist": "^26.6.2", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/babel-preset-react-app": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.0.0.tgz", - "integrity": "sha512-itL2z8v16khpuKutx5IH8UdCdSTuzrOhRFTEdIhveZ2i1iBKDrVE0ATa4sFVy+02GLucZNVBWtoarXBy0Msdpg==", - "dependencies": { - "@babel/core": "7.12.3", - "@babel/plugin-proposal-class-properties": "7.12.1", - "@babel/plugin-proposal-decorators": "7.12.1", - "@babel/plugin-proposal-nullish-coalescing-operator": "7.12.1", - "@babel/plugin-proposal-numeric-separator": "7.12.1", - "@babel/plugin-proposal-optional-chaining": "7.12.1", - "@babel/plugin-transform-flow-strip-types": "7.12.1", - "@babel/plugin-transform-react-display-name": "7.12.1", - "@babel/plugin-transform-runtime": "7.12.1", - "@babel/preset-env": "7.12.1", - "@babel/preset-react": "7.12.1", - "@babel/preset-typescript": "7.12.1", - "@babel/runtime": "7.12.1", - "babel-plugin-macros": "2.8.0", - "babel-plugin-transform-react-remove-prop-types": "0.4.24" - } - }, - "node_modules/babel-preset-react-app/node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz", - "integrity": "sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "node_modules/babel-preset-react-app/node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz", - "integrity": "sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" - } - }, - "node_modules/babel-preset-react-app/node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.1.tgz", - "integrity": "sha512-MR7Ok+Af3OhNTCxYVjJZHS0t97ydnJZt/DbR4WISO39iDnhiD8XHrY12xuSJ90FFEGjir0Fzyyn7g/zY6hxbxA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "node_modules/babel-preset-react-app/node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.1.tgz", - "integrity": "sha512-c2uRpY6WzaVDzynVY9liyykS+kVU+WRZPMPYpkelXH8KBt1oXoI89kPbZKKG/jDT5UK92FTW2fZkZaJhdiBabw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", - "@babel/plugin-syntax-optional-chaining": "^7.8.0" - } - }, - "node_modules/babel-preset-react-app/node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.1.tgz", - "integrity": "sha512-cAzB+UzBIrekfYxyLlFqf/OagTvHLcVBb5vpouzkYkBclRPraiygVnafvAoipErZLI8ANv8Ecn6E/m5qPXD26w==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "node_modules/babel-preset-react-app/node_modules/@babel/preset-env": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.1.tgz", - "integrity": "sha512-H8kxXmtPaAGT7TyBvSSkoSTUK6RHh61So05SyEbpmr0MCZrsNYn7mGMzzeYoOUCdHzww61k8XBft2TaES+xPLg==", - "dependencies": { - "@babel/compat-data": "^7.12.1", - "@babel/helper-compilation-targets": "^7.12.1", - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-validator-option": "^7.12.1", - "@babel/plugin-proposal-async-generator-functions": "^7.12.1", - "@babel/plugin-proposal-class-properties": "^7.12.1", - "@babel/plugin-proposal-dynamic-import": "^7.12.1", - "@babel/plugin-proposal-export-namespace-from": "^7.12.1", - "@babel/plugin-proposal-json-strings": "^7.12.1", - "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", - "@babel/plugin-proposal-numeric-separator": "^7.12.1", - "@babel/plugin-proposal-object-rest-spread": "^7.12.1", - "@babel/plugin-proposal-optional-catch-binding": "^7.12.1", - "@babel/plugin-proposal-optional-chaining": "^7.12.1", - "@babel/plugin-proposal-private-methods": "^7.12.1", - "@babel/plugin-proposal-unicode-property-regex": "^7.12.1", - "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-class-properties": "^7.12.1", - "@babel/plugin-syntax-dynamic-import": "^7.8.0", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.0", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.12.1", - "@babel/plugin-transform-arrow-functions": "^7.12.1", - "@babel/plugin-transform-async-to-generator": "^7.12.1", - "@babel/plugin-transform-block-scoped-functions": "^7.12.1", - "@babel/plugin-transform-block-scoping": "^7.12.1", - "@babel/plugin-transform-classes": "^7.12.1", - "@babel/plugin-transform-computed-properties": "^7.12.1", - "@babel/plugin-transform-destructuring": "^7.12.1", - "@babel/plugin-transform-dotall-regex": "^7.12.1", - "@babel/plugin-transform-duplicate-keys": "^7.12.1", - "@babel/plugin-transform-exponentiation-operator": "^7.12.1", - "@babel/plugin-transform-for-of": "^7.12.1", - "@babel/plugin-transform-function-name": "^7.12.1", - "@babel/plugin-transform-literals": "^7.12.1", - "@babel/plugin-transform-member-expression-literals": "^7.12.1", - "@babel/plugin-transform-modules-amd": "^7.12.1", - "@babel/plugin-transform-modules-commonjs": "^7.12.1", - "@babel/plugin-transform-modules-systemjs": "^7.12.1", - "@babel/plugin-transform-modules-umd": "^7.12.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.1", - "@babel/plugin-transform-new-target": "^7.12.1", - "@babel/plugin-transform-object-super": "^7.12.1", - "@babel/plugin-transform-parameters": "^7.12.1", - "@babel/plugin-transform-property-literals": "^7.12.1", - "@babel/plugin-transform-regenerator": "^7.12.1", - "@babel/plugin-transform-reserved-words": "^7.12.1", - "@babel/plugin-transform-shorthand-properties": "^7.12.1", - "@babel/plugin-transform-spread": "^7.12.1", - "@babel/plugin-transform-sticky-regex": "^7.12.1", - "@babel/plugin-transform-template-literals": "^7.12.1", - "@babel/plugin-transform-typeof-symbol": "^7.12.1", - "@babel/plugin-transform-unicode-escapes": "^7.12.1", - "@babel/plugin-transform-unicode-regex": "^7.12.1", - "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.12.1", - "core-js-compat": "^3.6.2", - "semver": "^5.5.0" - } - }, - "node_modules/babel-preset-react-app/node_modules/@babel/preset-react": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.12.1.tgz", - "integrity": "sha512-euCExymHCi0qB9u5fKw7rvlw7AZSjw/NaB9h7EkdTt5+yHRrXdiRTh7fkG3uBPpJg82CqLfp1LHLqWGSCrab+g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-transform-react-display-name": "^7.12.1", - "@babel/plugin-transform-react-jsx": "^7.12.1", - "@babel/plugin-transform-react-jsx-development": "^7.12.1", - "@babel/plugin-transform-react-jsx-self": "^7.12.1", - "@babel/plugin-transform-react-jsx-source": "^7.12.1", - "@babel/plugin-transform-react-pure-annotations": "^7.12.1" - } - }, - "node_modules/babel-preset-react-app/node_modules/@babel/runtime": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.1.tgz", - "integrity": "sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==", - "dependencies": { - "regenerator-runtime": "^0.13.4" - } - }, - "node_modules/babel-preset-react-app/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dependencies": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "node_modules/babel-runtime/node_modules/core-js": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", - "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" - }, - "node_modules/babel-runtime/node_modules/regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - }, - "node_modules/babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "bin": { - "babylon": "bin/babylon.js" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/bfj": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", - "integrity": "sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw==", - "dependencies": { - "bluebird": "^3.5.5", - "check-types": "^11.1.1", - "hoopy": "^0.1.4", - "tryer": "^1.0.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dependencies": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", - "dependencies": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dependencies": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "node_modules/browserify-sign/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dependencies": { - "pako": "~1.0.5" - } - }, - "node_modules/browserslist": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.4.tgz", - "integrity": "sha512-d7rCxYV8I9kj41RH8UKYnvDYCRENUlHRgyXy/Rhr/1BaeLGfiCptEdFE8MIrvGfWbBFNjVYx76SQWvNX1j+/cQ==", - "dependencies": { - "caniuse-lite": "^1.0.30001208", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.712", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "node_modules/buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==" - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "node_modules/builtin-modules": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", - "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" - }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacache": { - "version": "15.0.6", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.6.tgz", - "integrity": "sha512-g1WYDMct/jzW+JdWEyjaX2zoBkZ6ZT9VpOyp2I/VMtDsNLffNat3kqPFfi1eDRSK9/SuKGyORDHcQMcPF8sQ/w==", - "dependencies": { - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/cacache/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "node_modules/caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dependencies": { - "callsites": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-callsite/node_modules/callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "dependencies": { - "caller-callsite": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/camel-case/node_modules/tslib": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", - "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" - }, - "node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dependencies": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/camelcase-keys/node_modules/camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001214", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001214.tgz", - "integrity": "sha512-O2/SCpuaU3eASWVaesQirZv1MSjUNOvmugaD8zNSJqw6Vv5SGwoOpA9LJs3pNPfM745nxqPvfZY3MQKY4AKHYg==" - }, - "node_modules/capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "dependencies": { - "rsvp": "^4.8.4" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/case-sensitive-paths-webpack-plugin": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz", - "integrity": "sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" - }, - "node_modules/character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" - }, - "node_modules/character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" - }, - "node_modules/check-types": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.1.2.tgz", - "integrity": "sha512-tzWzvgePgLORb9/3a0YenggReLKAIb2owL03H2Xdoe5pKcUyWRSEQ8xfCar8t2SIAuEDwtmx2da1YB52YuHQMQ==" - }, - "node_modules/chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "optional": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.3.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - }, - "engines": { - "node": ">= 8.10.0" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/cjs-module-lexer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==" - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-css": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", - "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/clean-css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/clipboard": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz", - "integrity": "sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==", - "optional": true, - "dependencies": { - "good-listener": "^1.2.2", - "select": "^1.1.2", - "tiny-emitter": "^2.0.0" - } - }, - "node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/clsx": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", - "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "dependencies": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==" - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz", - "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==", - "dependencies": { - "color-convert": "^1.9.1", - "color-string": "^1.5.4" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/color-string": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz", - "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/comma-separated-tokens": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", - "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==" - }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/common-tags": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", - "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "node_modules/compose-function": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", - "integrity": "sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8=", - "dependencies": { - "arity-n": "^1.0.4" - } - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/concat-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/confusing-browser-globals": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", - "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==" - }, - "node_modules/connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" - }, - "node_modules/contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "dependencies": { - "safe-buffer": "5.1.2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "node_modules/copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dependencies": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "node_modules/copy-concurrently/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/copy-to-clipboard": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz", - "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==", - "dependencies": { - "toggle-selection": "^1.0.6" - } - }, - "node_modules/core-js": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.10.2.tgz", - "integrity": "sha512-W+2oVYeNghuBr3yTzZFQ5rfmjZtYB/Ubg87R5YOmlGrIb+Uw9f7qjUbhsj+/EkXhcV7eOD3jiM4+sgraX3FZUw==" - }, - "node_modules/core-js-compat": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.10.2.tgz", - "integrity": "sha512-IGHnpuaM1N++gLSPI1F1wu3WXICPxSyj/Q++clcwsIOnUVp5uKUIPl/+6h0TQ112KU3fMiSxqJuM+OrCyKj5+A==", - "dependencies": { - "browserslist": "^4.16.4", - "semver": "7.0.0" - } - }, - "node_modules/core-js-compat/node_modules/semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/core-js-pure": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.10.2.tgz", - "integrity": "sha512-uu18pVHQ21n4mzfuSlCXpucu5VKsck3j2m5fjrBOBqqdgWAxwdCgUuGWj6cDDPN1zLj/qtiqKvBMxWgDeeu49Q==" - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "node_modules/cosmiconfig": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", - "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, - "node_modules/crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", - "engines": { - "node": ">=4" - } - }, - "node_modules/css": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", - "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "dependencies": { - "inherits": "^2.0.3", - "source-map": "^0.6.1", - "source-map-resolve": "^0.5.2", - "urix": "^0.1.0" - } - }, - "node_modules/css-blank-pseudo": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz", - "integrity": "sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==", - "dependencies": { - "postcss": "^7.0.5" - }, - "bin": { - "css-blank-pseudo": "cli.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", - "engines": { - "node": "*" - } - }, - "node_modules/css-declaration-sorter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", - "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", - "dependencies": { - "postcss": "^7.0.1", - "timsort": "^0.3.0" - }, - "engines": { - "node": ">4" - } - }, - "node_modules/css-has-pseudo": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz", - "integrity": "sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==", - "dependencies": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^5.0.0-rc.4" - }, - "bin": { - "css-has-pseudo": "cli.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/css-has-pseudo/node_modules/cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/css-has-pseudo/node_modules/postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dependencies": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/css-loader": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.3.0.tgz", - "integrity": "sha512-rdezjCjScIrsL8BSYszgT4s476IcNKt6yX69t0pHjJVnPUTDpn4WfIpDQTN3wCJvUvfsz/mFjuGOekf3PY3NUg==", - "dependencies": { - "camelcase": "^6.0.0", - "cssesc": "^3.0.0", - "icss-utils": "^4.1.1", - "loader-utils": "^2.0.0", - "postcss": "^7.0.32", - "postcss-modules-extract-imports": "^2.0.0", - "postcss-modules-local-by-default": "^3.0.3", - "postcss-modules-scope": "^2.2.0", - "postcss-modules-values": "^3.0.0", - "postcss-value-parser": "^4.1.0", - "schema-utils": "^2.7.1", - "semver": "^7.3.2" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/css-prefers-color-scheme": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz", - "integrity": "sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==", - "dependencies": { - "postcss": "^7.0.5" - }, - "bin": { - "css-prefers-color-scheme": "cli.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "node_modules/css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" - }, - "node_modules/css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", - "dependencies": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-tree/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-vendor": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", - "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", - "dependencies": { - "@babel/runtime": "^7.8.3", - "is-in-browser": "^1.0.2" - } - }, - "node_modules/css-what": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", - "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/css.escape": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=" - }, - "node_modules/css/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cssdb": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-4.4.0.tgz", - "integrity": "sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==" - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", - "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", - "dependencies": { - "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.8", - "is-resolvable": "^1.0.0", - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-preset-default": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", - "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", - "dependencies": { - "css-declaration-sorter": "^4.0.1", - "cssnano-util-raw-cache": "^4.0.1", - "postcss": "^7.0.0", - "postcss-calc": "^7.0.1", - "postcss-colormin": "^4.0.3", - "postcss-convert-values": "^4.0.1", - "postcss-discard-comments": "^4.0.2", - "postcss-discard-duplicates": "^4.0.2", - "postcss-discard-empty": "^4.0.1", - "postcss-discard-overridden": "^4.0.1", - "postcss-merge-longhand": "^4.0.11", - "postcss-merge-rules": "^4.0.3", - "postcss-minify-font-values": "^4.0.2", - "postcss-minify-gradients": "^4.0.2", - "postcss-minify-params": "^4.0.2", - "postcss-minify-selectors": "^4.0.2", - "postcss-normalize-charset": "^4.0.1", - "postcss-normalize-display-values": "^4.0.2", - "postcss-normalize-positions": "^4.0.2", - "postcss-normalize-repeat-style": "^4.0.2", - "postcss-normalize-string": "^4.0.2", - "postcss-normalize-timing-functions": "^4.0.2", - "postcss-normalize-unicode": "^4.0.1", - "postcss-normalize-url": "^4.0.1", - "postcss-normalize-whitespace": "^4.0.2", - "postcss-ordered-values": "^4.1.2", - "postcss-reduce-initial": "^4.0.3", - "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.3", - "postcss-unique-selectors": "^4.0.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-get-arguments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", - "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-get-match": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", - "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-raw-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", - "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-same-parent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", - "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano/node_modules/cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dependencies": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano/node_modules/import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dependencies": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "engines": { - "node": ">=4" - } - }, - "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dependencies": { - "css-tree": "^1.1.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "node_modules/csso/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" - }, - "node_modules/csstype": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", - "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" - }, - "node_modules/currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dependencies": { - "array-find-index": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=" - }, - "node_modules/d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "node_modules/damerau-levenshtein": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", - "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==" - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decimal.js": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", - "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==" - }, - "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" - }, - "node_modules/deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "dependencies": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" - }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", - "dependencies": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dependencies": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/del/node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dependencies": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/globby/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del/node_modules/p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/del/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/delegate": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", - "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", - "optional": true - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-node": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.5.tgz", - "integrity": "sha512-qi86tE6hRcFHy8jI1m2VG+LaPUR1LhqDa5G8tVjuUXmOrpuAgqsA1pN0+ldgr3aKUH+QLI9hCY/OcRYisERejw==" - }, - "node_modules/detect-port-alt": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", - "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", - "dependencies": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "bin": { - "detect": "bin/detect-port", - "detect-port": "bin/detect-port" - }, - "engines": { - "node": ">= 4.2.1" - } - }, - "node_modules/detect-port-alt/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/detect-port-alt/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=" - }, - "node_modules/dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", - "dependencies": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", - "dependencies": { - "buffer-indexof": "^1.0.0" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-accessibility-api": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.4.tgz", - "integrity": "sha512-TvrjBckDy2c6v6RLxPv5QXOnU+SmF9nBII5621Ve5fu6Z/BDrENurBEvlC1f44lKEUVqOpK4w9E5Idc5/EgkLQ==" - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dependencies": { - "utila": "~0.4" - } - }, - "node_modules/dom-helpers": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.0.tgz", - "integrity": "sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==", - "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - } - }, - "node_modules/dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dependencies": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "node_modules/dom-serializer/node_modules/domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" - }, - "node_modules/domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "engines": { - "node": ">=0.4", - "npm": ">=1.2" - } - }, - "node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dependencies": { - "domelementtype": "1" - } - }, - "node_modules/domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/dot-case/node_modules/tslib": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", - "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" - }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dotenv": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" - }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/duplexify/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/duplexify/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "node_modules/ejs": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", - "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.3.717", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.717.tgz", - "integrity": "sha512-OfzVPIqD1MkJ7fX+yTl2nKyOE4FReeVfMCzzxQS+Kp43hZYwHwThlGP+EGIZRXJsxCM7dqo8Y65NOX/HP12iXQ==" - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", - "dependencies": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/enhanced-resolve/node_modules/memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" - } - }, - "node_modules/enhanced-resolve/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/enhanced-resolve/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/error-stack-parser": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz", - "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==", - "dependencies": { - "stackframe": "^1.1.1" - } - }, - "node_modules/es-abstract": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", - "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.2", - "is-string": "^1.0.5", - "object-inspect": "^1.9.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "dependencies": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.24.0.tgz", - "integrity": "sha512-k9gaHeHiFmGCDQ2rEfvULlSLruz6tgfA8DEn+rY9/oYPFFTlz55mM/Q/Rij1b2Y42jwZiK3lXvNTw6w6TXzcKQ==", - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash": "^4.17.21", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.4", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/eslint-config-react-app": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-6.0.0.tgz", - "integrity": "sha512-bpoAAC+YRfzq0dsTk+6v9aHm/uqnDwayNAXleMypGl6CpxI9oXXscVHo4fk3eJPIn+rsbtNetB4r/ZIidFIE8A==", - "dependencies": { - "confusing-browser-globals": "^1.0.10" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", - "dependencies": { - "debug": "^2.6.9", - "resolve": "^1.13.1" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/eslint-module-utils": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", - "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", - "dependencies": { - "debug": "^2.6.9", - "pkg-dir": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/eslint-module-utils/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/eslint-module-utils/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dependencies": { - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-flowtype": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.7.1.tgz", - "integrity": "sha512-RsurlNszyKLIHJvw6J4C98ubTTsLlgzL5xYqQ6ZTV5d2E2iHIR744SxoU3o7yQf0HjIe0GwnAIxpD+g0IV+emg==", - "dependencies": { - "lodash": "^4.17.15", - "string-natural-compare": "^3.0.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.22.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", - "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", - "dependencies": { - "array-includes": "^3.1.1", - "array.prototype.flat": "^1.2.3", - "contains-path": "^0.1.0", - "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.4", - "eslint-module-utils": "^2.6.0", - "has": "^1.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.1", - "read-pkg-up": "^2.0.0", - "resolve": "^1.17.0", - "tsconfig-paths": "^3.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dependencies": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/eslint-plugin-jest": { - "version": "24.3.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.3.5.tgz", - "integrity": "sha512-XG4rtxYDuJykuqhsOqokYIR84/C8pRihRtEpVskYLbIIKGwPNW2ySxdctuVzETZE+MbF/e7wmsnbNVpzM0rDug==", - "dependencies": { - "@typescript-eslint/experimental-utils": "^4.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz", - "integrity": "sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg==", - "dependencies": { - "@babel/runtime": "^7.11.2", - "aria-query": "^4.2.2", - "array-includes": "^3.1.1", - "ast-types-flow": "^0.0.7", - "axe-core": "^4.0.2", - "axobject-query": "^2.2.0", - "damerau-levenshtein": "^1.0.6", - "emoji-regex": "^9.0.0", - "has": "^1.0.3", - "jsx-ast-utils": "^3.1.0", - "language-tags": "^1.0.5" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "node_modules/eslint-plugin-react": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.23.2.tgz", - "integrity": "sha512-AfjgFQB+nYszudkxRkTFu0UR1zEQig0ArVMPloKhxwlwkzaw/fBiH0QWcBBhZONlXqQC51+nfqFrkn4EzHcGBw==", - "dependencies": { - "array-includes": "^3.1.3", - "array.prototype.flatmap": "^1.2.4", - "doctrine": "^2.1.0", - "has": "^1.0.3", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.0.4", - "object.entries": "^1.1.3", - "object.fromentries": "^2.0.4", - "object.values": "^1.1.3", - "prop-types": "^15.7.2", - "resolve": "^2.0.0-next.3", - "string.prototype.matchall": "^4.0.4" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz", - "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", - "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", - "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "node_modules/eslint-plugin-testing-library": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-3.10.2.tgz", - "integrity": "sha512-WAmOCt7EbF1XM8XfbCKAEzAPnShkNSwcIsAD2jHdsMUT9mZJPjLCG7pMzbcC8kK366NOuGip8HKLDC+Xk4yIdA==", - "dependencies": { - "@typescript-eslint/experimental-utils": "^3.10.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0", - "npm": ">=6" - } - }, - "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/experimental-utils": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz", - "integrity": "sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==", - "dependencies": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/types": "3.10.1", - "@typescript-eslint/typescript-estree": "3.10.1", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/types": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.10.1.tgz", - "integrity": "sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ==", - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - } - }, - "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/typescript-estree": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz", - "integrity": "sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w==", - "dependencies": { - "@typescript-eslint/types": "3.10.1", - "@typescript-eslint/visitor-keys": "3.10.1", - "debug": "^4.1.1", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/eslint-plugin-testing-library/node_modules/@typescript-eslint/visitor-keys": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz", - "integrity": "sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ==", - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - } - }, - "node_modules/eslint-plugin-testing-library/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-webpack-plugin": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-2.5.4.tgz", - "integrity": "sha512-7rYh0m76KyKSDE+B+2PUQrlNS4HJ51t3WKpkJg6vo2jFMbEPTG99cBV0Dm7LXSHucN4WGCG65wQcRiTFrj7iWw==", - "dependencies": { - "@types/eslint": "^7.2.6", - "arrify": "^2.0.1", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "normalize-path": "^3.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dependencies": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/eslint/node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/eslint/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.8.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz", - "integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/eslint/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/eventsource": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz", - "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==", - "dependencies": { - "original": "^1.0.0" - }, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/exec-sh": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", - "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==" - }, - "node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/expect/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/expect/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/expect/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "dependencies": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/express/node_modules/qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", - "dependencies": { - "type": "^2.0.0" - } - }, - "node_modules/ext/node_modules/type": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", - "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==" - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extend-shallow/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" - }, - "node_modules/fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fault": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", - "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", - "dependencies": { - "format": "^0.2.0" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/file-loader": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.1.1.tgz", - "integrity": "sha512-Klt8C4BjWSXYQAfhpYYkG4qHNTna4toMHEbWrI5IuVoxbU6uiDKeKAP99R8mmbJi3lvewn/jQBOgU4+NS3tDQw==", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/file-loader/node_modules/schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dependencies": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, - "node_modules/filesize": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz", - "integrity": "sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==" - }, - "node_modules/flatten": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", - "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==" - }, - "node_modules/flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "node_modules/flush-write-stream/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/flush-write-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/follow-redirects": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", - "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "engines": { - "node": "*" - } - }, - "node_modules/fork-ts-checker-webpack-plugin": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz", - "integrity": "sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw==", - "dependencies": { - "@babel/code-frame": "^7.5.5", - "chalk": "^2.4.1", - "micromatch": "^3.1.10", - "minimatch": "^3.0.4", - "semver": "^5.6.0", - "tapable": "^1.0.0", - "worker-rpc": "^0.1.0" - }, - "engines": { - "node": ">=6.11.5", - "yarn": ">=1.0.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "node_modules/from2/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/from2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dependencies": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "node_modules/fs-write-stream-atomic/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/fs-write-stream-atomic/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" - }, - "node_modules/gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dependencies": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "node_modules/gauge/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gaze": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", - "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", - "dependencies": { - "globule": "^1.0.0" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "node_modules/get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/globby": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", - "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/globule": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", - "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", - "dependencies": { - "glob": "~7.1.1", - "lodash": "~4.17.10", - "minimatch": "~3.0.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/good-listener": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", - "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", - "optional": true, - "dependencies": { - "delegate": "^3.1.2" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" - }, - "node_modules/growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "optional": true - }, - "node_modules/gzip-size": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", - "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", - "dependencies": { - "duplexer": "^0.1.1", - "pify": "^4.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/harmony-reflect": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", - "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash-base/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hast-util-parse-selector": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", - "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==" - }, - "node_modules/hastscript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", - "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", - "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^1.0.0", - "hast-util-parse-selector": "^2.0.0", - "property-information": "^5.0.0", - "space-separated-tokens": "^1.0.0" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "bin": { - "he": "bin/he" - } - }, - "node_modules/hex-color-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", - "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" - }, - "node_modules/highlight.js": { - "version": "10.7.2", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz", - "integrity": "sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==", - "engines": { - "node": "*" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hoopy": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", - "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/hsl-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", - "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=" - }, - "node_modules/hsla-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", - "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=" - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-entities": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", - "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==" - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "node_modules/html-minifier-terser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", - "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", - "dependencies": { - "camel-case": "^4.1.1", - "clean-css": "^4.2.3", - "commander": "^4.1.1", - "he": "^1.2.0", - "param-case": "^3.0.3", - "relateurl": "^0.2.7", - "terser": "^4.6.3" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/html-webpack-plugin": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz", - "integrity": "sha512-MouoXEYSjTzCrjIxWwg8gxL5fE2X2WZJLmBYXlaJhQUH5K/b5OrqmV7T4dB7iu0xkmJ6JlUuV6fFVtnqbPopZw==", - "dependencies": { - "@types/html-minifier-terser": "^5.0.0", - "@types/tapable": "^1.0.5", - "@types/webpack": "^4.41.8", - "html-minifier-terser": "^5.0.1", - "loader-utils": "^1.2.3", - "lodash": "^4.17.15", - "pretty-error": "^2.1.1", - "tapable": "^1.1.3", - "util.promisify": "1.0.0" - }, - "engines": { - "node": ">=6.9" - } - }, - "node_modules/html-webpack-plugin/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/html-webpack-plugin/node_modules/loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/html-webpack-plugin/node_modules/util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dependencies": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" - } - }, - "node_modules/htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dependencies": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "node_modules/htmlparser2/node_modules/entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=" - }, - "node_modules/http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/http-errors/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "node_modules/http-parser-js": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", - "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==" - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", - "dependencies": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/http-proxy-middleware/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-proxy-middleware/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-proxy-middleware/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-proxy-middleware/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-proxy-middleware/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-proxy-middleware/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-proxy-middleware/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-proxy-middleware/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" - }, - "node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "engines": { - "node": ">=8.12.0" - } - }, - "node_modules/hyphenate-style-name": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", - "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", - "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", - "dependencies": { - "postcss": "^7.0.14" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/identity-obj-proxy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", - "integrity": "sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ=", - "dependencies": { - "harmony-reflect": "^1.4.6" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "node_modules/iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" - }, - "node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/immer": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz", - "integrity": "sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA==" - }, - "node_modules/import-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", - "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", - "dependencies": { - "import-from": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/import-from": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", - "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", - "dependencies": { - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-from/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "engines": { - "node": ">=4" - } - }, - "node_modules/import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/import-local/node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indefinite-observable": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/indefinite-observable/-/indefinite-observable-2.0.1.tgz", - "integrity": "sha512-G8vgmork+6H9S8lUAg1gtXEj2JxIQTo0g2PbFiYOdjkziSI0F7UYBiVwhZRuixhBCNGczAls34+5HJPyZysvxQ==", - "dependencies": { - "symbol-observable": "1.2.0" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" - }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", - "dependencies": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" - }, - "node_modules/ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "engines": { - "node": ">=4" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-absolute-url": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" - }, - "node_modules/is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "dependencies": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - } - }, - "node_modules/is-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", - "dependencies": { - "call-bind": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "node_modules/is-bigint": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", - "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "optional": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", - "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", - "dependencies": { - "call-bind": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "node_modules/is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-color-stop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", - "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", - "dependencies": { - "css-color-names": "^0.0.4", - "hex-color-regex": "^1.1.0", - "hsl-regex": "^1.0.0", - "hsla-regex": "^1.0.0", - "rgb-regex": "^1.0.1", - "rgba-regex": "^1.0.0" - } - }, - "node_modules/is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", - "dependencies": { - "has": "^1.0.3" - } - }, - "node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" - }, - "node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-finite": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" - }, - "node_modules/is-in-browser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", - "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=" - }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=" - }, - "node_modules/is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", - "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dependencies": { - "is-path-inside": "^2.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dependencies": { - "path-is-inside": "^1.0.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" - }, - "node_modules/is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", - "dependencies": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" - }, - "node_modules/is-root": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", - "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dependencies": { - "has-symbols": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "node_modules/is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest": { - "version": "26.6.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.0.tgz", - "integrity": "sha512-jxTmrvuecVISvKFFhOkjsWRZV7sFqdSUAd1ajOKY+/QE/aLBVstsJ/dX8GczLzwiT6ZEwwmZqtCUHLHHQVzcfA==", - "dependencies": { - "@jest/core": "^26.6.0", - "import-local": "^3.0.2", - "jest-cli": "^26.6.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-changed-files": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", - "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", - "dependencies": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-changed-files/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/jest-changed-files/node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-changed-files/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-changed-files/node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-changed-files/node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-changed-files/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-changed-files/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-changed-files/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-changed-files/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/jest-circus": { - "version": "26.6.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-26.6.0.tgz", - "integrity": "sha512-L2/Y9szN6FJPWFK8kzWXwfp+FOR7xq0cUL4lIsdbIdwz3Vh6P1nrpcqOleSzr28zOtSHQNV9Z7Tl+KkuK7t5Ng==", - "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.0", - "@jest/test-result": "^26.6.0", - "@jest/types": "^26.6.0", - "@types/babel__traverse": "^7.0.4", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^26.6.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.0", - "jest-matcher-utils": "^26.6.0", - "jest-message-util": "^26.6.0", - "jest-runner": "^26.6.0", - "jest-runtime": "^26.6.0", - "jest-snapshot": "^26.6.0", - "jest-util": "^26.6.0", - "pretty-format": "^26.6.0", - "stack-utils": "^2.0.2", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-circus/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-circus/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-circus/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-circus/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-circus/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-circus/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-config/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-config/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-config/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-config/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config/node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-config/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-diff/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-diff/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-diff/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-diff/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-each/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-each/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-each/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-each/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-each/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-each/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-environment-jsdom": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-environment-node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", - "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", - "dependencies": { - "@jest/types": "^26.6.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" - }, - "engines": { - "node": ">= 10.14.2" - }, - "optionalDependencies": { - "fsevents": "^2.1.2" - } - }, - "node_modules/jest-jasmine2": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", - "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", - "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^26.6.2", - "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-jasmine2/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-jasmine2/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-jasmine2/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-jasmine2/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-jasmine2/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-leak-detector": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", - "dependencies": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-matcher-utils/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-matcher-utils/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-matcher-utils/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-matcher-utils/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-matcher-utils/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-message-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-message-util/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-message-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-message-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-message-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-message-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "engines": { - "node": ">=6" - } - }, - "node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-resolve": { - "version": "26.6.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.0.tgz", - "integrity": "sha512-tRAz2bwraHufNp+CCmAD8ciyCpXCs1NQxB5EJAmtCFy6BN81loFEGWKzYu26Y62lAJJe4X4jg36Kf+NsQyiStQ==", - "dependencies": { - "@jest/types": "^26.6.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.0", - "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", - "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", - "dependencies": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-resolve/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-resolve/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-resolve/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-resolve/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.7.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.6.2", - "jest-leak-detector": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runner/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-runner/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-runner/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-runner/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner/node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runner/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/globals": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" - }, - "bin": { - "jest-runtime": "bin/jest-runtime.js" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runtime/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-runtime/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-runtime/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-runtime/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runtime/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.4" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", - "dependencies": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-snapshot/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-snapshot/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-snapshot/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-snapshot/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-snapshot/node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-snapshot/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-snapshot/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-snapshot/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-snapshot/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-util/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-util/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-util/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-util/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-validate": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", - "dependencies": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "leven": "^3.1.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-validate/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-validate/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-validate/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-validate/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-validate/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-0.6.1.tgz", - "integrity": "sha512-ITVnHhj3Jd/QkqQcTqZfRgjfyRhDFM/auzgVo2RKvSwi18YMvh0WvXDJFoFED6c7jd/5jxtu4kSOb9PTu2cPVg==", - "dependencies": { - "ansi-escapes": "^4.3.1", - "chalk": "^4.0.0", - "jest-regex-util": "^26.0.0", - "jest-watcher": "^26.3.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-watch-typeahead/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-watch-typeahead/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-watch-typeahead/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watcher": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", - "dependencies": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^26.6.2", - "string-length": "^4.0.1" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-watcher/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watcher/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-watcher/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-watcher/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest-watcher/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watcher/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/jest/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest/node_modules/jest-cli": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", - "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", - "dependencies": { - "@jest/core": "^26.6.3", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.6.3", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "prompts": "^2.0.1", - "yargs": "^15.4.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/js-base64": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", - "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "node_modules/jsdom": { - "version": "16.5.3", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.5.3.tgz", - "integrity": "sha512-Qj1H+PEvUsOtdPJ056ewXM4UJPCi4hhLA8wpiz9F2YvsRBhuFsXxtrIFAgGBDynQA9isAMGE91PfUYbdMPXuTA==", - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.1.0", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "html-encoding-sniffer": "^2.0.1", - "is-potential-custom-element-name": "^1.0.0", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "request": "^2.88.2", - "request-promise-native": "^1.0.9", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.4", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jsdom/node_modules/acorn": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.1.1.tgz", - "integrity": "sha512-xYiIVjNuqtKXMxlRMDc6mZUhXehod4a3gbZ1qRlM7icK4EbxUFNLhWoPblCvFtB2Y9CIqHP3CF/rdxLItaQv8g==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "node_modules/json3": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", - "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==" - }, - "node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "node_modules/jss": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/jss/-/jss-10.6.0.tgz", - "integrity": "sha512-n7SHdCozmxnzYGXBHe0NsO0eUf9TvsHVq2MXvi4JmTn3x5raynodDVE/9VQmBdWFyyj9HpHZ2B4xNZ7MMy7lkw==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "csstype": "^3.0.2", - "indefinite-observable": "^2.0.1", - "is-in-browser": "^1.1.3", - "tiny-warning": "^1.0.2" - } - }, - "node_modules/jss-plugin-camel-case": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.6.0.tgz", - "integrity": "sha512-JdLpA3aI/npwj3nDMKk308pvnhoSzkW3PXlbgHAzfx0yHWnPPVUjPhXFtLJzgKZge8lsfkUxvYSQ3X2OYIFU6A==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "hyphenate-style-name": "^1.0.3", - "jss": "10.6.0" - } - }, - "node_modules/jss-plugin-default-unit": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.6.0.tgz", - "integrity": "sha512-7y4cAScMHAxvslBK2JRK37ES9UT0YfTIXWgzUWD5euvR+JR3q+o8sQKzBw7GmkQRfZijrRJKNTiSt1PBsLI9/w==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "jss": "10.6.0" - } - }, - "node_modules/jss-plugin-global": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.6.0.tgz", - "integrity": "sha512-I3w7ji/UXPi3VuWrTCbHG9rVCgB4yoBQLehGDTmsnDfXQb3r1l3WIdcO8JFp9m0YMmyy2CU7UOV6oPI7/Tmu+w==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "jss": "10.6.0" - } - }, - "node_modules/jss-plugin-nested": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.6.0.tgz", - "integrity": "sha512-fOFQWgd98H89E6aJSNkEh2fAXquC9aZcAVjSw4q4RoQ9gU++emg18encR4AT4OOIFl4lQwt5nEyBBRn9V1Rk8g==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "jss": "10.6.0", - "tiny-warning": "^1.0.2" - } - }, - "node_modules/jss-plugin-props-sort": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.6.0.tgz", - "integrity": "sha512-oMCe7hgho2FllNc60d9VAfdtMrZPo9n1Iu6RNa+3p9n0Bkvnv/XX5San8fTPujrTBScPqv9mOE0nWVvIaohNuw==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "jss": "10.6.0" - } - }, - "node_modules/jss-plugin-rule-value-function": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.6.0.tgz", - "integrity": "sha512-TKFqhRTDHN1QrPTMYRlIQUOC2FFQb271+AbnetURKlGvRl/eWLswcgHQajwuxI464uZk91sPiTtdGi7r7XaWfA==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "jss": "10.6.0", - "tiny-warning": "^1.0.2" - } - }, - "node_modules/jss-plugin-vendor-prefixer": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.6.0.tgz", - "integrity": "sha512-doJ7MouBXT1lypLLctCwb4nJ6lDYqrTfVS3LtXgox42Xz0gXusXIIDboeh6UwnSmox90QpVnub7au8ybrb0krQ==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "css-vendor": "^2.0.8", - "jss": "10.6.0" - } - }, - "node_modules/jsx-ast-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", - "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", - "dependencies": { - "array-includes": "^3.1.2", - "object.assign": "^4.1.2" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/killable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", - "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==" - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "engines": { - "node": ">=6" - } - }, - "node_modules/klona": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz", - "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/language-subtag-registry": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", - "integrity": "sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==" - }, - "node_modules/language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", - "dependencies": { - "language-subtag-registry": "~0.3.2" - } - }, - "node_modules/last-call-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", - "dependencies": { - "lodash": "^4.17.5", - "webpack-sources": "^1.1.0" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" - }, - "node_modules/load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-json-file/node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dependencies": { - "error-ex": "^1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/load-json-file/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "engines": { - "node": ">=4.3.0 <5.0.0 || >=5.10" - } - }, - "node_modules/loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" - }, - "node_modules/lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" - }, - "node_modules/lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dependencies": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "node_modules/lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dependencies": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=" - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" - }, - "node_modules/loglevel": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", - "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dependencies": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lower-case/node_modules/tslib": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", - "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" - }, - "node_modules/lowlight": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", - "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", - "dependencies": { - "fault": "^1.0.0", - "highlight.js": "~10.7.0" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/lz-string": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", - "bin": { - "lz-string": "bin/bin.js" - } - }, - "node_modules/magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", - "dependencies": { - "sourcemap-codec": "^1.4.4" - } - }, - "node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", - "dependencies": { - "tmpl": "1.0.x" - } - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dependencies": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "node_modules/memory-fs/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/memory-fs/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dependencies": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/meow/node_modules/find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dependencies": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/meow/node_modules/indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dependencies": { - "repeating": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/meow/node_modules/load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/meow/node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dependencies": { - "error-ex": "^1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/meow/node_modules/path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dependencies": { - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/meow/node_modules/path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dependencies": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/meow/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/meow/node_modules/read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dependencies": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/meow/node_modules/read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dependencies": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/meow/node_modules/redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dependencies": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/meow/node_modules/strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dependencies": { - "is-utf8": "^0.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/meow/node_modules/strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dependencies": { - "get-stdin": "^4.0.1" - }, - "bin": { - "strip-indent": "cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/microevent.ts": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz", - "integrity": "sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==" - }, - "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", - "dependencies": { - "mime-db": "1.47.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "engines": { - "node": ">=4" - } - }, - "node_modules/mini-css-extract-plugin": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.3.tgz", - "integrity": "sha512-n9BA8LonkOkW1/zn+IbLPQmovsL0wMb9yx75fMJQZf2X1Zoec9yTZtyMePcyu19wPkmFbzZZA6fLTotpFhQsOA==", - "dependencies": { - "loader-utils": "^1.1.0", - "normalize-url": "1.9.1", - "schema-utils": "^1.0.0", - "webpack-sources": "^1.1.0" - }, - "engines": { - "node": ">= 6.9.0" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "node_modules/minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dependencies": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dependencies": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "node_modules/move-concurrently/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", - "dependencies": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/multicast-dns-service-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" - }, - "node_modules/nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" - }, - "node_modules/nanoid": { - "version": "3.1.22", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.22.tgz", - "integrity": "sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ==", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/native-url": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/native-url/-/native-url-0.2.6.tgz", - "integrity": "sha512-k4bDC87WtgrdD362gZz6zoiXQrl40kYlBmpfmSjwRO1VU0V5ccwJTlxuE72F6m3V0vc1xOf6n3UCP9QyerRqmA==", - "dependencies": { - "querystring": "^0.2.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" - }, - "node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node_modules/next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/no-case/node_modules/tslib": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", - "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" - }, - "node_modules/node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/node-gyp": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", - "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", - "dependencies": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.3", - "nopt": "^5.0.0", - "npmlog": "^4.1.2", - "request": "^2.88.2", - "rimraf": "^3.0.2", - "semver": "^7.3.2", - "tar": "^6.0.2", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": ">= 10.12.0" - } - }, - "node_modules/node-gyp/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, - "node_modules/node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dependencies": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - } - }, - "node_modules/node-libs-browser/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, - "node_modules/node-libs-browser/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/node-libs-browser/node_modules/readable-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/node-notifier": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", - "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", - "optional": true, - "dependencies": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.2", - "shellwords": "^0.1.1", - "uuid": "^8.3.0", - "which": "^2.0.2" - } - }, - "node_modules/node-notifier/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "optional": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==" - }, - "node_modules/node-sass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-5.0.0.tgz", - "integrity": "sha512-opNgmlu83ZCF792U281Ry7tak9IbVC+AKnXGovcQ8LG8wFaJv6cLnRlc6DIHlmNxWEexB5bZxi9SZ9JyUuOYjw==", - "dependencies": { - "async-foreach": "^0.1.3", - "chalk": "^1.1.1", - "cross-spawn": "^7.0.3", - "gaze": "^1.0.0", - "get-stdin": "^4.0.1", - "glob": "^7.0.3", - "lodash": "^4.17.15", - "meow": "^3.7.0", - "mkdirp": "^0.5.1", - "nan": "^2.13.2", - "node-gyp": "^7.1.0", - "npmlog": "^4.0.0", - "request": "^2.88.0", - "sass-graph": "2.2.5", - "stdout-stream": "^1.4.0", - "true-case-path": "^1.0.2" - }, - "bin": { - "node-sass": "bin/node-sass" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-sass/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/node-sass/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/node-sass/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/node-sass/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/node-sass/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/node-sass/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-sass/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/node-sass/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/node-sass/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/node-sass/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "dependencies": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dependencies": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "node_modules/nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dependencies": { - "boolbase": "~1.0.0" - } - }, - "node_modules/num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/numeral": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/numeral/-/numeral-2.0.6.tgz", - "integrity": "sha1-StCAk21EPCVhrtnyGX7//iX05QY=", - "engines": { - "node": "*" - } - }, - "node_modules/nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz", - "integrity": "sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==" - }, - "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.entries": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.3.tgz", - "integrity": "sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", - "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", - "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.values": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", - "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" - }, - "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "dependencies": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", - "dependencies": { - "is-wsl": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/opn/node_modules/is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/optimize-css-assets-webpack-plugin": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz", - "integrity": "sha512-wqd6FdI2a5/FdoiCNNkEvLeA//lHHfG24Ln2Xm2qqdIk4aOlsR18jwpyOihqQ8849W3qu2DX8fOYxpvTMj+93A==", - "dependencies": { - "cssnano": "^4.1.10", - "last-call-webpack-plugin": "^3.0.0" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", - "dependencies": { - "url-parse": "^1.4.3" - } - }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" - }, - "node_modules/p-each-series": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", - "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/p-retry": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", - "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", - "dependencies": { - "retry": "^0.12.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "node_modules/parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "dependencies": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "node_modules/parallel-transform/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/parallel-transform/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/param-case/node_modules/tslib": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", - "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "dependencies": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/pascal-case/node_modules/tslib": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", - "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==" - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" - }, - "node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "engines": { - "node": ">=4" - } - }, - "node_modules/path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "node_modules/picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", - "engines": { - "node": ">=8.6" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "engines": { - "node": ">=6" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "dependencies": { - "node-modules-regexp": "^1.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "engines": { - "node": ">=4" - } - }, - "node_modules/pnp-webpack-plugin": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz", - "integrity": "sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==", - "dependencies": { - "ts-pnp": "^1.1.6" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/popper.js": { - "version": "1.16.1-lts", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz", - "integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA==" - }, - "node_modules/portfinder": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", - "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", - "dependencies": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" - }, - "engines": { - "node": ">= 0.12.0" - } - }, - "node_modules/portfinder/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", - "dependencies": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-attribute-case-insensitive": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz", - "integrity": "sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^6.0.2" - } - }, - "node_modules/postcss-browser-comments": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-3.0.0.tgz", - "integrity": "sha512-qfVjLfq7HFd2e0HW4s1dvU8X080OZdG46fFbIBFjW7US7YPDcWfRvdElvwMJr2LI6hMmD+7LnH2HcmXTs+uOig==", - "dependencies": { - "postcss": "^7" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/postcss-calc": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", - "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", - "dependencies": { - "postcss": "^7.0.27", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.2" - } - }, - "node_modules/postcss-color-functional-notation": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz", - "integrity": "sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-color-gray": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz", - "integrity": "sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==", - "dependencies": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.5", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-color-hex-alpha": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz", - "integrity": "sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==", - "dependencies": { - "postcss": "^7.0.14", - "postcss-values-parser": "^2.0.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-color-mod-function": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz", - "integrity": "sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==", - "dependencies": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-color-rebeccapurple": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz", - "integrity": "sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-colormin": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", - "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", - "dependencies": { - "browserslist": "^4.0.0", - "color": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-colormin/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-convert-values": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", - "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", - "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-convert-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-custom-media": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz", - "integrity": "sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==", - "dependencies": { - "postcss": "^7.0.14" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-custom-properties": { - "version": "8.0.11", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz", - "integrity": "sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==", - "dependencies": { - "postcss": "^7.0.17", - "postcss-values-parser": "^2.0.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-custom-selectors": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz", - "integrity": "sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-custom-selectors/node_modules/cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-custom-selectors/node_modules/postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dependencies": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-dir-pseudo-class": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz", - "integrity": "sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/postcss-dir-pseudo-class/node_modules/cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-dir-pseudo-class/node_modules/postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dependencies": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-discard-comments": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", - "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", - "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-discard-empty": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", - "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", - "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-double-position-gradients": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz", - "integrity": "sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==", - "dependencies": { - "postcss": "^7.0.5", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-env-function": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-2.0.2.tgz", - "integrity": "sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-flexbugs-fixes": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz", - "integrity": "sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ==", - "dependencies": { - "postcss": "^7.0.26" - } - }, - "node_modules/postcss-focus-visible": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz", - "integrity": "sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==", - "dependencies": { - "postcss": "^7.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-focus-within": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz", - "integrity": "sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==", - "dependencies": { - "postcss": "^7.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-font-variant": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz", - "integrity": "sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA==", - "dependencies": { - "postcss": "^7.0.2" - } - }, - "node_modules/postcss-gap-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz", - "integrity": "sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==", - "dependencies": { - "postcss": "^7.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-image-set-function": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz", - "integrity": "sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-initial": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.4.tgz", - "integrity": "sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg==", - "dependencies": { - "postcss": "^7.0.2" - } - }, - "node_modules/postcss-lab-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz", - "integrity": "sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==", - "dependencies": { - "@csstools/convert-colors": "^1.4.0", - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-load-config": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", - "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", - "dependencies": { - "cosmiconfig": "^5.0.0", - "import-cwd": "^2.0.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/postcss-load-config/node_modules/cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dependencies": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-load-config/node_modules/import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dependencies": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-load-config/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-load-config/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", - "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", - "dependencies": { - "loader-utils": "^1.1.0", - "postcss": "^7.0.0", - "postcss-load-config": "^2.0.0", - "schema-utils": "^1.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/postcss-loader/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/postcss-loader/node_modules/loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/postcss-loader/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/postcss-logical": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-3.0.0.tgz", - "integrity": "sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==", - "dependencies": { - "postcss": "^7.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-media-minmax": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz", - "integrity": "sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==", - "dependencies": { - "postcss": "^7.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-merge-longhand": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", - "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", - "dependencies": { - "css-color-names": "0.0.4", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "stylehacks": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-merge-longhand/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-merge-rules": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", - "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "cssnano-util-same-parent": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0", - "vendors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dependencies": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", - "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", - "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-minify-font-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-minify-gradients": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", - "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", - "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "is-color-stop": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-minify-gradients/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-minify-params": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", - "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", - "dependencies": { - "alphanum-sort": "^1.0.0", - "browserslist": "^4.0.0", - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "uniqs": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-minify-params/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-minify-selectors": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", - "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", - "dependencies": { - "alphanum-sort": "^1.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dependencies": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", - "dependencies": { - "postcss": "^7.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", - "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", - "dependencies": { - "icss-utils": "^4.1.1", - "postcss": "^7.0.32", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/postcss-modules-scope": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", - "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", - "dependencies": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/postcss-modules-values": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", - "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", - "dependencies": { - "icss-utils": "^4.0.0", - "postcss": "^7.0.6" - } - }, - "node_modules/postcss-nesting": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-7.0.1.tgz", - "integrity": "sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==", - "dependencies": { - "postcss": "^7.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-normalize": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-8.0.1.tgz", - "integrity": "sha512-rt9JMS/m9FHIRroDDBGSMsyW1c0fkvOJPy62ggxSHUldJO7B195TqFMqIf+lY5ezpDcYOV4j86aUp3/XbxzCCQ==", - "dependencies": { - "@csstools/normalize.css": "^10.1.0", - "browserslist": "^4.6.2", - "postcss": "^7.0.17", - "postcss-browser-comments": "^3.0.0", - "sanitize.css": "^10.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", - "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", - "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", - "dependencies": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-display-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-normalize-positions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", - "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", - "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-positions/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", - "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", - "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-repeat-style/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-normalize-string": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", - "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", - "dependencies": { - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-string/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", - "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", - "dependencies": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-timing-functions/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-normalize-unicode": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", - "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", - "dependencies": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-unicode/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-normalize-url": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", - "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", - "dependencies": { - "is-absolute-url": "^2.0.0", - "normalize-url": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-url/node_modules/normalize-url": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/postcss-normalize-url/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-normalize-whitespace": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", - "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", - "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-normalize-whitespace/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-ordered-values": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", - "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", - "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-ordered-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-overflow-shorthand": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz", - "integrity": "sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==", - "dependencies": { - "postcss": "^7.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-page-break": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-2.0.0.tgz", - "integrity": "sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==", - "dependencies": { - "postcss": "^7.0.2" - } - }, - "node_modules/postcss-place": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-4.0.1.tgz", - "integrity": "sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-values-parser": "^2.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-preset-env": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz", - "integrity": "sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg==", - "dependencies": { - "autoprefixer": "^9.6.1", - "browserslist": "^4.6.4", - "caniuse-lite": "^1.0.30000981", - "css-blank-pseudo": "^0.1.4", - "css-has-pseudo": "^0.10.0", - "css-prefers-color-scheme": "^3.1.1", - "cssdb": "^4.4.0", - "postcss": "^7.0.17", - "postcss-attribute-case-insensitive": "^4.0.1", - "postcss-color-functional-notation": "^2.0.1", - "postcss-color-gray": "^5.0.0", - "postcss-color-hex-alpha": "^5.0.3", - "postcss-color-mod-function": "^3.0.3", - "postcss-color-rebeccapurple": "^4.0.1", - "postcss-custom-media": "^7.0.8", - "postcss-custom-properties": "^8.0.11", - "postcss-custom-selectors": "^5.1.2", - "postcss-dir-pseudo-class": "^5.0.0", - "postcss-double-position-gradients": "^1.0.0", - "postcss-env-function": "^2.0.2", - "postcss-focus-visible": "^4.0.0", - "postcss-focus-within": "^3.0.0", - "postcss-font-variant": "^4.0.0", - "postcss-gap-properties": "^2.0.0", - "postcss-image-set-function": "^3.0.1", - "postcss-initial": "^3.0.0", - "postcss-lab-function": "^2.0.1", - "postcss-logical": "^3.0.0", - "postcss-media-minmax": "^4.0.0", - "postcss-nesting": "^7.0.0", - "postcss-overflow-shorthand": "^2.0.0", - "postcss-page-break": "^2.0.0", - "postcss-place": "^4.0.1", - "postcss-pseudo-class-any-link": "^6.0.0", - "postcss-replace-overflow-wrap": "^3.0.0", - "postcss-selector-matches": "^4.0.0", - "postcss-selector-not": "^4.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-pseudo-class-any-link": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz", - "integrity": "sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==", - "dependencies": { - "postcss": "^7.0.2", - "postcss-selector-parser": "^5.0.0-rc.3" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/postcss-pseudo-class-any-link/node_modules/cssesc": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", - "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-pseudo-class-any-link/node_modules/postcss-selector-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", - "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", - "dependencies": { - "cssesc": "^2.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-reduce-initial": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", - "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", - "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", - "dependencies": { - "cssnano-util-get-match": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-reduce-transforms/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-replace-overflow-wrap": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz", - "integrity": "sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==", - "dependencies": { - "postcss": "^7.0.2" - } - }, - "node_modules/postcss-safe-parser": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-5.0.2.tgz", - "integrity": "sha512-jDUfCPJbKOABhwpUKcqCVbbXiloe/QXMcbJ6Iipf3sDIihEzTqRCeMBfRaOHxhBuTYqtASrI1KJWxzztZU4qUQ==", - "dependencies": { - "postcss": "^8.1.0" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/postcss-safe-parser/node_modules/postcss": { - "version": "8.2.10", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.10.tgz", - "integrity": "sha512-b/h7CPV7QEdrqIxtAf2j31U5ef05uBDuvoXv6L51Q4rcS1jdlXAVKJv+atCFdUXYl9dyTHGyoMzIepwowRJjFw==", - "dependencies": { - "colorette": "^1.2.2", - "nanoid": "^3.1.22", - "source-map": "^0.6.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-safe-parser/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-selector-matches": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz", - "integrity": "sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==", - "dependencies": { - "balanced-match": "^1.0.0", - "postcss": "^7.0.2" - } - }, - "node_modules/postcss-selector-not": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz", - "integrity": "sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ==", - "dependencies": { - "balanced-match": "^1.0.0", - "postcss": "^7.0.2" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.5.tgz", - "integrity": "sha512-aFYPoYmXbZ1V6HZaSvat08M97A8HqO6Pjz+PiNpw/DhuRrC72XWAdp3hL6wusDCN31sSmcZyMGa2hZEuX+Xfhg==", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-svgo": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", - "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", - "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "svgo": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-svgo/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" - }, - "node_modules/postcss-unique-selectors": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", - "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", - "dependencies": { - "alphanum-sort": "^1.0.0", - "postcss": "^7.0.0", - "uniqs": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" - }, - "node_modules/postcss-values-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", - "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", - "dependencies": { - "flatten": "^1.0.2", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=6.14.4" - } - }, - "node_modules/postcss/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss/node_modules/supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/pretty-error": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", - "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^2.0.4" - } - }, - "node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-format/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/pretty-format/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/pretty-format/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - }, - "node_modules/prismjs": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz", - "integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==", - "optionalDependencies": { - "clipboard": "^2.0.0" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==", - "dependencies": { - "asap": "~2.0.6" - } - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" - }, - "node_modules/prompts": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", - "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "node_modules/property-information": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", - "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", - "dependencies": { - "xtend": "^4.0.0" - } - }, - "node_modules/protobuf-decoder": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/protobuf-decoder/-/protobuf-decoder-0.1.1.tgz", - "integrity": "sha512-yeyeCkdvOnzv+6/2YNx2FlT7565arz/mb0QnhmXFdHMwnek9Jp/0PpHJVdJkzdFBgi85XQWRcHdWHh2dOBrSng==" - }, - "node_modules/proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", - "dependencies": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/pumpify/node_modules/pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, - "node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "dependencies": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/querystring": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz", - "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "node_modules/raf": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", - "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", - "dependencies": { - "performance-now": "^2.1.0" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dependencies": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-app-polyfill": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-2.0.0.tgz", - "integrity": "sha512-0sF4ny9v/B7s6aoehwze9vJNWcmCemAUYBVasscVr92+UYiEqDXOxfKjXN685mDaMRNF3WdhHQs76oTODMocFA==", - "dependencies": { - "core-js": "^3.6.5", - "object-assign": "^4.1.1", - "promise": "^8.1.0", - "raf": "^3.4.1", - "regenerator-runtime": "^0.13.7", - "whatwg-fetch": "^3.4.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/react-copy-to-clipboard": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.3.tgz", - "integrity": "sha512-9S3j+m+UxDZOM0Qb8mhnT/rMR0NGSrj9A/073yz2DSxPMYhmYFBMYIdI2X4o8AjOjyFsSNxDRnCX6s/gRxpriw==", - "dependencies": { - "copy-to-clipboard": "^3", - "prop-types": "^15.5.8" - } - }, - "node_modules/react-dev-utils": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz", - "integrity": "sha512-dx0LvIGHcOPtKbeiSUM4jqpBl3TcY7CDjZdfOIcKeznE7BWr9dg0iPG90G5yfVQ+p/rGNMXdbfStvzQZEVEi4A==", - "dependencies": { - "@babel/code-frame": "7.10.4", - "address": "1.1.2", - "browserslist": "4.14.2", - "chalk": "2.4.2", - "cross-spawn": "7.0.3", - "detect-port-alt": "1.1.6", - "escape-string-regexp": "2.0.0", - "filesize": "6.1.0", - "find-up": "4.1.0", - "fork-ts-checker-webpack-plugin": "4.1.6", - "global-modules": "2.0.0", - "globby": "11.0.1", - "gzip-size": "5.1.1", - "immer": "8.0.1", - "is-root": "2.1.0", - "loader-utils": "2.0.0", - "open": "^7.0.2", - "pkg-up": "3.1.0", - "prompts": "2.4.0", - "react-error-overlay": "^6.0.9", - "recursive-readdir": "2.2.2", - "shell-quote": "1.7.2", - "strip-ansi": "6.0.0", - "text-table": "0.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/react-dev-utils/node_modules/@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/react-dev-utils/node_modules/browserslist": { - "version": "4.14.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.2.tgz", - "integrity": "sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw==", - "dependencies": { - "caniuse-lite": "^1.0.30001125", - "electron-to-chromium": "^1.3.564", - "escalade": "^3.0.2", - "node-releases": "^1.1.61" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/react-dev-utils/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/react-dev-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/react-dev-utils/node_modules/globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/react-dev-utils/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/react-dev-utils/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/react-dev-utils/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/react-dev-utils/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" - } - }, - "node_modules/react-error-overlay": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", - "integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==" - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/react-refresh": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", - "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-scripts": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-4.0.3.tgz", - "integrity": "sha512-S5eO4vjUzUisvkIPB7jVsKtuH2HhWcASREYWHAQ1FP5HyCv3xgn+wpILAEWkmy+A+tTNbSZClhxjT3qz6g4L1A==", - "dependencies": { - "@babel/core": "7.12.3", - "@pmmmwh/react-refresh-webpack-plugin": "0.4.3", - "@svgr/webpack": "5.5.0", - "@typescript-eslint/eslint-plugin": "^4.5.0", - "@typescript-eslint/parser": "^4.5.0", - "babel-eslint": "^10.1.0", - "babel-jest": "^26.6.0", - "babel-loader": "8.1.0", - "babel-plugin-named-asset-import": "^0.3.7", - "babel-preset-react-app": "^10.0.0", - "bfj": "^7.0.2", - "camelcase": "^6.1.0", - "case-sensitive-paths-webpack-plugin": "2.3.0", - "css-loader": "4.3.0", - "dotenv": "8.2.0", - "dotenv-expand": "5.1.0", - "eslint": "^7.11.0", - "eslint-config-react-app": "^6.0.0", - "eslint-plugin-flowtype": "^5.2.0", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-jest": "^24.1.0", - "eslint-plugin-jsx-a11y": "^6.3.1", - "eslint-plugin-react": "^7.21.5", - "eslint-plugin-react-hooks": "^4.2.0", - "eslint-plugin-testing-library": "^3.9.2", - "eslint-webpack-plugin": "^2.5.2", - "file-loader": "6.1.1", - "fs-extra": "^9.0.1", - "html-webpack-plugin": "4.5.0", - "identity-obj-proxy": "3.0.0", - "jest": "26.6.0", - "jest-circus": "26.6.0", - "jest-resolve": "26.6.0", - "jest-watch-typeahead": "0.6.1", - "mini-css-extract-plugin": "0.11.3", - "optimize-css-assets-webpack-plugin": "5.0.4", - "pnp-webpack-plugin": "1.6.4", - "postcss-flexbugs-fixes": "4.2.1", - "postcss-loader": "3.0.0", - "postcss-normalize": "8.0.1", - "postcss-preset-env": "6.7.0", - "postcss-safe-parser": "5.0.2", - "prompts": "2.4.0", - "react-app-polyfill": "^2.0.0", - "react-dev-utils": "^11.0.3", - "react-refresh": "^0.8.3", - "resolve": "1.18.1", - "resolve-url-loader": "^3.1.2", - "sass-loader": "^10.0.5", - "semver": "7.3.2", - "style-loader": "1.3.0", - "terser-webpack-plugin": "4.2.3", - "ts-pnp": "1.2.0", - "url-loader": "4.1.1", - "webpack": "4.44.2", - "webpack-dev-server": "3.11.1", - "webpack-manifest-plugin": "2.2.0", - "workbox-webpack-plugin": "5.1.4" - }, - "bin": { - "react-scripts": "bin/react-scripts.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.1.3" - } - }, - "node_modules/react-scrollable-feed": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/react-scrollable-feed/-/react-scrollable-feed-1.3.0.tgz", - "integrity": "sha512-ZoaWcrYlzNoGHNuYy//Wkz9jtFiy+pb8VvHzRVmthktU4cJAN4//aYzEIATyT+amAROL8qpZnoWUZJypDtmvfg==", - "engines": { - "node": ">=8", - "npm": ">=5" - } - }, - "node_modules/react-syntax-highlighter": { - "version": "15.4.3", - "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.4.3.tgz", - "integrity": "sha512-TnhGgZKXr5o8a63uYdRTzeb8ijJOgRGe0qjrE0eK/gajtdyqnSO6LqB3vW16hHB0cFierYSoy/AOJw8z1Dui8g==", - "dependencies": { - "@babel/runtime": "^7.3.1", - "highlight.js": "^10.4.1", - "lowlight": "^1.17.0", - "prismjs": "^1.22.0", - "refractor": "^3.2.0" - } - }, - "node_modules/react-transition-group": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", - "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==", - "dependencies": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - } - }, - "node_modules/read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dependencies": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dependencies": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dependencies": { - "pify": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "optional": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/recursive-readdir": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", - "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", - "dependencies": { - "minimatch": "3.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/refractor": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.3.1.tgz", - "integrity": "sha512-vaN6R56kLMuBszHSWlwTpcZ8KTMG6aUCok4GrxYDT20UIOXxOc5o6oDc8tNTzSlH3m2sI+Eu9Jo2kVdDcUTWYw==", - "dependencies": { - "hastscript": "^6.0.0", - "parse-entities": "^2.0.0", - "prismjs": "~1.23.0" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "node_modules/regenerate-unicode-properties": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", - "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", - "dependencies": { - "regenerate": "^1.4.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" - }, - "node_modules/regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-parser": { - "version": "2.2.11", - "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", - "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==" - }, - "node_modules/regexp.prototype.flags": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", - "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/regexpu-core": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", - "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", - "dependencies": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.2.0", - "regjsgen": "^0.5.1", - "regjsparser": "^0.6.4", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==" - }, - "node_modules/regjsparser": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", - "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" - }, - "node_modules/renderkid": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.5.tgz", - "integrity": "sha512-ccqoLg+HLOHq1vdfYNm4TBeaCDIi1FLt3wGojTDSvdewUv65oTmI3cnT2E4hRjl1gzKZIPK+KZrXzlUYKnR+vQ==", - "dependencies": { - "css-select": "^2.0.2", - "dom-converter": "^0.2", - "htmlparser2": "^3.10.1", - "lodash": "^4.17.20", - "strip-ansi": "^3.0.0" - } - }, - "node_modules/renderkid/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/renderkid/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dependencies": { - "is-finite": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "dependencies": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/request-promise-native/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/request/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" - }, - "node_modules/resolve": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.18.1.tgz", - "integrity": "sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA==", - "dependencies": { - "is-core-module": "^2.0.0", - "path-parse": "^1.0.6" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" - }, - "node_modules/resolve-url-loader": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.2.tgz", - "integrity": "sha512-QEb4A76c8Mi7I3xNKXlRKQSlLBwjUV/ULFMP+G7n3/7tJZ8MG5wsZ3ucxP1Jz8Vevn6fnJsxDx9cIls+utGzPQ==", - "dependencies": { - "adjust-sourcemap-loader": "3.0.0", - "camelcase": "5.3.1", - "compose-function": "3.0.3", - "convert-source-map": "1.7.0", - "es6-iterator": "2.0.3", - "loader-utils": "1.2.3", - "postcss": "7.0.21", - "rework": "1.0.1", - "rework-visit": "1.0.0", - "source-map": "0.6.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/resolve-url-loader/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/resolve-url-loader/node_modules/emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/resolve-url-loader/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/resolve-url-loader/node_modules/loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/resolve-url-loader/node_modules/postcss": { - "version": "7.0.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz", - "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==", - "dependencies": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/resolve-url-loader/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-url-loader/node_modules/supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "engines": { - "node": ">=0.12" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rework": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz", - "integrity": "sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc=", - "dependencies": { - "convert-source-map": "^0.3.3", - "css": "^2.0.0" - } - }, - "node_modules/rework-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz", - "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=" - }, - "node_modules/rework/node_modules/convert-source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", - "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=" - }, - "node_modules/rgb-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", - "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=" - }, - "node_modules/rgba-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", - "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=" - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/rollup": { - "version": "1.32.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz", - "integrity": "sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==", - "dependencies": { - "@types/estree": "*", - "@types/node": "*", - "acorn": "^7.1.0" - }, - "bin": { - "rollup": "dist/bin/rollup" - } - }, - "node_modules/rollup-plugin-babel": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.4.0.tgz", - "integrity": "sha512-Lek/TYp1+7g7I+uMfJnnSJ7YWoD58ajo6Oarhlex7lvUce+RCKRuGRSgztDO3/MF/PuGKmUL5iTHKf208UNszw==", - "dependencies": { - "@babel/helper-module-imports": "^7.0.0", - "rollup-pluginutils": "^2.8.1" - } - }, - "node_modules/rollup-plugin-terser": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.3.1.tgz", - "integrity": "sha512-1pkwkervMJQGFYvM9nscrUoncPwiKR/K+bHdjv6PFgRo3cgPHoRT83y2Aa3GvINj4539S15t/tpFPb775TDs6w==", - "dependencies": { - "@babel/code-frame": "^7.5.5", - "jest-worker": "^24.9.0", - "rollup-pluginutils": "^2.8.2", - "serialize-javascript": "^4.0.0", - "terser": "^4.6.2" - } - }, - "node_modules/rollup-plugin-terser/node_modules/jest-worker": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", - "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", - "dependencies": { - "merge-stream": "^2.0.0", - "supports-color": "^6.1.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/rollup-plugin-terser/node_modules/serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/rollup-plugin-terser/node_modules/supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/rollup-pluginutils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", - "dependencies": { - "estree-walker": "^0.6.1" - } - }, - "node_modules/rollup-pluginutils/node_modules/estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==" - }, - "node_modules/rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "engines": { - "node": "6.* || >= 7.*" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dependencies": { - "aproba": "^1.1.1" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "dependencies": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - }, - "bin": { - "sane": "src/cli.js" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/sane/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/sane/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sanitize.css": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-10.0.0.tgz", - "integrity": "sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg==" - }, - "node_modules/sass-graph": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", - "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", - "dependencies": { - "glob": "^7.0.0", - "lodash": "^4.0.0", - "scss-tokenizer": "^0.2.3", - "yargs": "^13.3.2" - } - }, - "node_modules/sass-graph/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/sass-graph/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/sass-graph/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/sass-graph/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "node_modules/sass-graph/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/sass-graph/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "engines": { - "node": ">=4" - } - }, - "node_modules/sass-graph/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/sass-graph/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/sass-graph/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "engines": { - "node": ">=4" - } - }, - "node_modules/sass-graph/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/sass-graph/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/sass-graph/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/sass-graph/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "node_modules/sass-graph/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "node_modules/sass-loader": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.1.1.tgz", - "integrity": "sha512-W6gVDXAd5hR/WHsPicvZdjAWHBcEJ44UahgxcIE196fW2ong0ZHMPO1kZuI5q0VlvMQZh32gpv69PLWQm70qrw==", - "dependencies": { - "klona": "^2.0.4", - "loader-utils": "^2.0.0", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", - "semver": "^7.3.2" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/sass-loader/node_modules/schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dependencies": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 8.9.0" - } - }, - "node_modules/scss-tokenizer": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", - "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", - "dependencies": { - "js-base64": "^2.1.8", - "source-map": "^0.4.2" - } - }, - "node_modules/scss-tokenizer/node_modules/source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dependencies": { - "amdefine": ">=0.0.4" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/select": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", - "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", - "optional": true - }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" - }, - "node_modules/selfsigned": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz", - "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==", - "dependencies": { - "node-forge": "^0.10.0" - } - }, - "node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "node_modules/serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, - "node_modules/serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "node_modules/setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shell-quote": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", - "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==" - }, - "node_modules/shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "optional": true - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "node_modules/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/sockjs": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz", - "integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==", - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^3.4.0", - "websocket-driver": "^0.7.4" - } - }, - "node_modules/sockjs-client": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.1.tgz", - "integrity": "sha512-VnVAb663fosipI/m6pqRXakEOw7nvd7TUgdr3PlR/8V2I95QIdwT8L4nMxhyU8SmDBHYXU1TOElaKOmKLfYzeQ==", - "dependencies": { - "debug": "^3.2.6", - "eventsource": "^1.0.7", - "faye-websocket": "^0.11.3", - "inherits": "^2.0.4", - "json3": "^3.3.3", - "url-parse": "^1.5.1" - } - }, - "node_modules/sockjs-client/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/sockjs/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dependencies": { - "is-plain-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" - }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" - }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" - }, - "node_modules/space-separated-tokens": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", - "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==" - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==" - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" - }, - "node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/stackframe": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", - "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==" - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/stdout-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", - "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", - "dependencies": { - "readable-stream": "^2.0.1" - } - }, - "node_modules/stdout-stream/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/stdout-stream/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dependencies": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "node_modules/stream-browserify/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/stream-browserify/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dependencies": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/stream-http/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/stream-http/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" - }, - "node_modules/strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-natural-compare": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", - "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" - }, - "node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.matchall": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.4.tgz", - "integrity": "sha512-pknFIWVachNcyqRfaQSeu/FUfpvJTe4uskUSZ9Wc1RijsPuzbZ8TyYT8WCNnntCjUEqQ3vUHMAfVj2+wLAisPQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has-symbols": "^1.0.1", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.3.1", - "side-channel": "^1.0.4" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "node_modules/stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dependencies": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stringify-object/node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-comments": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-1.0.2.tgz", - "integrity": "sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==", - "dependencies": { - "babel-extract-comments": "^1.0.0", - "babel-plugin-transform-object-rest-spread": "^6.26.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "engines": { - "node": ">=8" - } - }, - "node_modules/style-loader": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.3.0.tgz", - "integrity": "sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q==", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^2.7.0" - }, - "engines": { - "node": ">= 8.9.0" - } - }, - "node_modules/stylehacks": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", - "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", - "dependencies": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/stylehacks/node_modules/postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dependencies": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" - }, - "node_modules/svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "dependencies": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" - }, - "node_modules/table": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.3.0.tgz", - "integrity": "sha512-gM9kB7aNIuSagW89Fh+SdL49uhKnVSORxMcV72u/dfptFdqExInNn5M21wgq/Uf5UdJpsboFhNe/0SoNKjaxzg==", - "dependencies": { - "ajv": "^8.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "lodash.clonedeep": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.1.0.tgz", - "integrity": "sha512-B/Sk2Ix7A36fs/ZkuGLIR86EdjbgR6fsAcbx9lOP/QBSXujDNbVmIS/U4Itz5k8fPFDeVZl/zQ/gJW4Jrq6XjQ==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/tar": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", - "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/tar/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/temp-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", - "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/tempy": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.3.0.tgz", - "integrity": "sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ==", - "dependencies": { - "temp-dir": "^1.0.0", - "type-fest": "^0.3.1", - "unique-string": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tempy/node_modules/type-fest": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/terser": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", - "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", - "dependencies": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz", - "integrity": "sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ==", - "dependencies": { - "cacache": "^15.0.5", - "find-cache-dir": "^3.3.1", - "jest-worker": "^26.5.0", - "p-limit": "^3.0.2", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "source-map": "^0.6.1", - "terser": "^5.3.4", - "webpack-sources": "^1.4.3" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/terser-webpack-plugin/node_modules/find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/terser-webpack-plugin/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/terser-webpack-plugin/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin/node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dependencies": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/terser-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/terser": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.1.tgz", - "integrity": "sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==", - "dependencies": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.19" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin/node_modules/terser/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/terser/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "node_modules/throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/through2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" - }, - "node_modules/timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dependencies": { - "setimmediate": "^1.0.4" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" - }, - "node_modules/tiny-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", - "optional": true - }, - "node_modules/tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, - "node_modules/tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=" - }, - "node_modules/to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toggle-selection": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=" - }, - "node_modules/toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/tr46": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", - "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/true-case-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", - "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", - "dependencies": { - "glob": "^7.1.2" - } - }, - "node_modules/tryer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", - "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" - }, - "node_modules/ts-pnp": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", - "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", - "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", - "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", - "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", - "engines": { - "node": ">=4" - } - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" - }, - "node_modules/uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=" - }, - "node_modules/unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dependencies": { - "unique-slug": "^2.0.0" - } - }, - "node_modules/unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dependencies": { - "imurmurhash": "^0.1.4" - } - }, - "node_modules/unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", - "dependencies": { - "crypto-random-string": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=" - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" - }, - "node_modules/url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/url-loader": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "dependencies": { - "loader-utils": "^2.0.0", - "mime-types": "^2.1.27", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/url-loader/node_modules/schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dependencies": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/url-parse": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", - "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/url/node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" - }, - "node_modules/url/node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dependencies": { - "inherits": "2.0.3" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - } - }, - "node_modules/util/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "optional": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" - }, - "node_modules/v8-to-istanbul": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.1.tgz", - "integrity": "sha512-p0BB09E5FRjx0ELN6RgusIPsSPhtgexSRcKETybEs6IGOTXJSZqfwxp7r//55nnu0f1AxltY5VvdVqy2vZf9AA==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/v8-to-istanbul/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/vendors": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", - "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==" - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==" - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "dependencies": { - "makeerror": "1.0.x" - } - }, - "node_modules/watchpack": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", - "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", - "dependencies": { - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - }, - "optionalDependencies": { - "chokidar": "^3.4.1", - "watchpack-chokidar2": "^2.0.1" - } - }, - "node_modules/watchpack-chokidar2": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", - "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", - "optional": true, - "dependencies": { - "chokidar": "^2.1.8" - } - }, - "node_modules/watchpack-chokidar2/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "optional": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/watchpack-chokidar2/node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "optional": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "optional": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "optional": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "optional": true, - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "optional": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "optional": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "optional": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "optional": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "optional": true, - "dependencies": { - "binary-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "optional": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "optional": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "optional": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "optional": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/watchpack-chokidar2/node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/watchpack-chokidar2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/watchpack-chokidar2/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "optional": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/web-vitals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-1.1.1.tgz", - "integrity": "sha512-jYOaqu01Ny1NvMwJ3dBJDUOJ2PGWknZWH4AUnvFOscvbdHMERIKT2TlgiAey5rVyfOePG7so2JcXXZdSnBvioQ==" - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "engines": { - "node": ">=10.4" - } - }, - "node_modules/webpack": { - "version": "4.44.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.2.tgz", - "integrity": "sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q==", - "dependencies": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/wasm-edit": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^6.4.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.3.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.3", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.7.4", - "webpack-sources": "^1.4.1" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/webpack-dev-middleware": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", - "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", - "dependencies": { - "memory-fs": "^0.4.1", - "mime": "^2.4.4", - "mkdirp": "^0.5.1", - "range-parser": "^1.2.1", - "webpack-log": "^2.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/webpack-dev-middleware/node_modules/mime": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", - "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/webpack-dev-server": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz", - "integrity": "sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ==", - "dependencies": { - "ansi-html": "0.0.7", - "bonjour": "^3.5.0", - "chokidar": "^2.1.8", - "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "debug": "^4.1.1", - "del": "^4.1.1", - "express": "^4.17.1", - "html-entities": "^1.3.1", - "http-proxy-middleware": "0.19.1", - "import-local": "^2.0.0", - "internal-ip": "^4.3.0", - "ip": "^1.1.5", - "is-absolute-url": "^3.0.3", - "killable": "^1.0.1", - "loglevel": "^1.6.8", - "opn": "^5.5.0", - "p-retry": "^3.0.1", - "portfinder": "^1.0.26", - "schema-utils": "^1.0.0", - "selfsigned": "^1.10.8", - "semver": "^6.3.0", - "serve-index": "^1.9.1", - "sockjs": "^0.3.21", - "sockjs-client": "^1.5.0", - "spdy": "^4.0.2", - "strip-ansi": "^3.0.1", - "supports-color": "^6.1.0", - "url": "^0.11.0", - "webpack-dev-middleware": "^3.7.2", - "webpack-log": "^2.0.0", - "ws": "^6.2.1", - "yargs": "^13.3.2" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 6.11.5" - } - }, - "node_modules/webpack-dev-server/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/webpack-dev-server/node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-dev-server/node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "optionalDependencies": { - "fsevents": "^1.2.7" - } - }, - "node_modules/webpack-dev-server/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/webpack-dev-server/node_modules/cliui/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-dev-server/node_modules/cliui/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-dev-server/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "node_modules/webpack-dev-server/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-dev-server/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/webpack-dev-server/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/webpack-dev-server/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", - "dependencies": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-dev-server/node_modules/is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/webpack-dev-server/node_modules/is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dependencies": { - "binary-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "engines": { - "node": ">=4" - } - }, - "node_modules/webpack-dev-server/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-dev-server/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-dev-server/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "engines": { - "node": ">=4" - } - }, - "node_modules/webpack-dev-server/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/webpack-dev-server/node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/webpack-dev-server/node_modules/resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dependencies": { - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/webpack-dev-server/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "engines": { - "node": ">=4" - } - }, - "node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/webpack-dev-server/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/webpack-dev-server/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/webpack-dev-server/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-dev-server/node_modules/string-width/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-dev-server/node_modules/string-width/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-dev-server/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-dev-server/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-dev-server/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-dev-server/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-dev-server/node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "dependencies": { - "async-limiter": "~1.0.0" - } - }, - "node_modules/webpack-dev-server/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "node_modules/webpack-dev-server/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "node_modules/webpack-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", - "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", - "dependencies": { - "ansi-colors": "^3.0.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/webpack-log/node_modules/ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/webpack-log/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/webpack-manifest-plugin": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-2.2.0.tgz", - "integrity": "sha512-9S6YyKKKh/Oz/eryM1RyLVDVmy3NSPV0JXMRhZ18fJsq+AwGxUY34X54VNwkzYcEmEkDwNxuEOboCZEebJXBAQ==", - "dependencies": { - "fs-extra": "^7.0.0", - "lodash": ">=3.5 <5", - "object.entries": "^1.1.0", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/webpack-manifest-plugin/node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/webpack-manifest-plugin/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/webpack-manifest-plugin/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "node_modules/webpack-sources/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/webpack/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dependencies": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "node_modules/webpack/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "node_modules/webpack/node_modules/eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dependencies": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/webpack/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/webpack/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/webpack/node_modules/loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/webpack/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/webpack/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dependencies": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/webpack/node_modules/serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/webpack/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", - "dependencies": { - "figgy-pudding": "^3.5.1" - } - }, - "node_modules/webpack/node_modules/terser-webpack-plugin": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", - "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", - "dependencies": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - }, - "engines": { - "node": ">= 6.9.0" - } - }, - "node_modules/webpack/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" - }, - "node_modules/whatwg-url": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.5.0.tgz", - "integrity": "sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg==", - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.0.2", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workbox-background-sync": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-5.1.4.tgz", - "integrity": "sha512-AH6x5pYq4vwQvfRDWH+vfOePfPIYQ00nCEB7dJRU1e0n9+9HMRyvI63FlDvtFT2AvXVRsXvUt7DNMEToyJLpSA==", - "dependencies": { - "workbox-core": "^5.1.4" - } - }, - "node_modules/workbox-broadcast-update": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-5.1.4.tgz", - "integrity": "sha512-HTyTWkqXvHRuqY73XrwvXPud/FN6x3ROzkfFPsRjtw/kGZuZkPzfeH531qdUGfhtwjmtO/ZzXcWErqVzJNdXaA==", - "dependencies": { - "workbox-core": "^5.1.4" - } - }, - "node_modules/workbox-build": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-5.1.4.tgz", - "integrity": "sha512-xUcZn6SYU8usjOlfLb9Y2/f86Gdo+fy1fXgH8tJHjxgpo53VVsqRX0lUDw8/JuyzNmXuo8vXX14pXX2oIm9Bow==", - "dependencies": { - "@babel/core": "^7.8.4", - "@babel/preset-env": "^7.8.4", - "@babel/runtime": "^7.8.4", - "@hapi/joi": "^15.1.0", - "@rollup/plugin-node-resolve": "^7.1.1", - "@rollup/plugin-replace": "^2.3.1", - "@surma/rollup-plugin-off-main-thread": "^1.1.1", - "common-tags": "^1.8.0", - "fast-json-stable-stringify": "^2.1.0", - "fs-extra": "^8.1.0", - "glob": "^7.1.6", - "lodash.template": "^4.5.0", - "pretty-bytes": "^5.3.0", - "rollup": "^1.31.1", - "rollup-plugin-babel": "^4.3.3", - "rollup-plugin-terser": "^5.3.1", - "source-map": "^0.7.3", - "source-map-url": "^0.4.0", - "stringify-object": "^3.3.0", - "strip-comments": "^1.0.2", - "tempy": "^0.3.0", - "upath": "^1.2.0", - "workbox-background-sync": "^5.1.4", - "workbox-broadcast-update": "^5.1.4", - "workbox-cacheable-response": "^5.1.4", - "workbox-core": "^5.1.4", - "workbox-expiration": "^5.1.4", - "workbox-google-analytics": "^5.1.4", - "workbox-navigation-preload": "^5.1.4", - "workbox-precaching": "^5.1.4", - "workbox-range-requests": "^5.1.4", - "workbox-routing": "^5.1.4", - "workbox-strategies": "^5.1.4", - "workbox-streams": "^5.1.4", - "workbox-sw": "^5.1.4", - "workbox-window": "^5.1.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/workbox-build/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/workbox-build/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/workbox-build/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/workbox-build/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/workbox-cacheable-response": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-5.1.4.tgz", - "integrity": "sha512-0bfvMZs0Of1S5cdswfQK0BXt6ulU5kVD4lwer2CeI+03czHprXR3V4Y8lPTooamn7eHP8Iywi5QjyAMjw0qauA==", - "dependencies": { - "workbox-core": "^5.1.4" - } - }, - "node_modules/workbox-core": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-5.1.4.tgz", - "integrity": "sha512-+4iRQan/1D8I81nR2L5vcbaaFskZC2CL17TLbvWVzQ4qiF/ytOGF6XeV54pVxAvKUtkLANhk8TyIUMtiMw2oDg==" - }, - "node_modules/workbox-expiration": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-5.1.4.tgz", - "integrity": "sha512-oDO/5iC65h2Eq7jctAv858W2+CeRW5e0jZBMNRXpzp0ZPvuT6GblUiHnAsC5W5lANs1QS9atVOm4ifrBiYY7AQ==", - "dependencies": { - "workbox-core": "^5.1.4" - } - }, - "node_modules/workbox-google-analytics": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-5.1.4.tgz", - "integrity": "sha512-0IFhKoEVrreHpKgcOoddV+oIaVXBFKXUzJVBI+nb0bxmcwYuZMdteBTp8AEDJacENtc9xbR0wa9RDCnYsCDLjA==", - "dependencies": { - "workbox-background-sync": "^5.1.4", - "workbox-core": "^5.1.4", - "workbox-routing": "^5.1.4", - "workbox-strategies": "^5.1.4" - } - }, - "node_modules/workbox-navigation-preload": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-5.1.4.tgz", - "integrity": "sha512-Wf03osvK0wTflAfKXba//QmWC5BIaIZARU03JIhAEO2wSB2BDROWI8Q/zmianf54kdV7e1eLaIEZhth4K4MyfQ==", - "dependencies": { - "workbox-core": "^5.1.4" - } - }, - "node_modules/workbox-precaching": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-5.1.4.tgz", - "integrity": "sha512-gCIFrBXmVQLFwvAzuGLCmkUYGVhBb7D1k/IL7pUJUO5xacjLcFUaLnnsoVepBGAiKw34HU1y/YuqvTKim9qAZA==", - "dependencies": { - "workbox-core": "^5.1.4" - } - }, - "node_modules/workbox-range-requests": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-5.1.4.tgz", - "integrity": "sha512-1HSujLjgTeoxHrMR2muDW2dKdxqCGMc1KbeyGcmjZZAizJTFwu7CWLDmLv6O1ceWYrhfuLFJO+umYMddk2XMhw==", - "dependencies": { - "workbox-core": "^5.1.4" - } - }, - "node_modules/workbox-routing": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-5.1.4.tgz", - "integrity": "sha512-8ljknRfqE1vEQtnMtzfksL+UXO822jJlHTIR7+BtJuxQ17+WPZfsHqvk1ynR/v0EHik4x2+826Hkwpgh4GKDCw==", - "dependencies": { - "workbox-core": "^5.1.4" - } - }, - "node_modules/workbox-strategies": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-5.1.4.tgz", - "integrity": "sha512-VVS57LpaJTdjW3RgZvPwX0NlhNmscR7OQ9bP+N/34cYMDzXLyA6kqWffP6QKXSkca1OFo/v6v7hW7zrrguo6EA==", - "dependencies": { - "workbox-core": "^5.1.4", - "workbox-routing": "^5.1.4" - } - }, - "node_modules/workbox-streams": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-5.1.4.tgz", - "integrity": "sha512-xU8yuF1hI/XcVhJUAfbQLa1guQUhdLMPQJkdT0kn6HP5CwiPOGiXnSFq80rAG4b1kJUChQQIGPrq439FQUNVrw==", - "dependencies": { - "workbox-core": "^5.1.4", - "workbox-routing": "^5.1.4" - } - }, - "node_modules/workbox-sw": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-5.1.4.tgz", - "integrity": "sha512-9xKnKw95aXwSNc8kk8gki4HU0g0W6KXu+xks7wFuC7h0sembFnTrKtckqZxbSod41TDaGh+gWUA5IRXrL0ECRA==" - }, - "node_modules/workbox-webpack-plugin": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-5.1.4.tgz", - "integrity": "sha512-PZafF4HpugZndqISi3rZ4ZK4A4DxO8rAqt2FwRptgsDx7NF8TVKP86/huHquUsRjMGQllsNdn4FNl8CD/UvKmQ==", - "dependencies": { - "@babel/runtime": "^7.5.5", - "fast-json-stable-stringify": "^2.0.0", - "source-map-url": "^0.4.0", - "upath": "^1.1.2", - "webpack-sources": "^1.3.0", - "workbox-build": "^5.1.4" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/workbox-window": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-5.1.4.tgz", - "integrity": "sha512-vXQtgTeMCUq/4pBWMfQX8Ee7N2wVC4Q7XYFqLnfbXJ2hqew/cU1uMTD2KqGEgEpE4/30luxIxgE+LkIa8glBYw==", - "dependencies": { - "workbox-core": "^5.1.4" - } - }, - "node_modules/worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dependencies": { - "errno": "~0.1.7" - } - }, - "node_modules/worker-rpc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/worker-rpc/-/worker-rpc-0.1.1.tgz", - "integrity": "sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==", - "dependencies": { - "microevent.ts": "~0.1.1" - } - }, - "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", - "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", - "engines": { - "node": ">=8.3.0" - } - }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs-parser/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "engines": { - "node": ">=10" - } - } - }, "dependencies": { "@babel/code-frame": { "version": "7.12.13", @@ -24381,6 +3208,14 @@ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.1.4.tgz", "integrity": "sha512-Pdgfv6iP0gNx9ejRGa3zE7Xgkj/iclXqLfe7BnatdZz0QnLZ3jrRHUVH8wNSdN68w05Sk3ShGTb3ydktMTooig==" }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -36353,21 +15188,6 @@ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } - } - }, "string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -36424,6 +15244,21 @@ "define-properties": "^1.1.3" } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, "stringify-object": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", @@ -38307,14 +17142,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -38340,6 +17167,14 @@ } } }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", diff --git a/ui/package.json b/ui/package.json index 1b393ee13..52349b91e 100644 --- a/ui/package.json +++ b/ui/package.json @@ -11,6 +11,7 @@ "@types/node": "^12.20.10", "@types/react": "^17.0.3", "@types/react-dom": "^17.0.3", + "axios": "^0.21.1", "node-sass": "^5.0.0", "numeral": "^2.0.6", "protobuf-decoder": "^0.1.0", diff --git a/ui/src/components/HarEntriesList.tsx b/ui/src/components/HarEntriesList.tsx index f446d135d..cea3c2cef 100644 --- a/ui/src/components/HarEntriesList.tsx +++ b/ui/src/components/HarEntriesList.tsx @@ -4,6 +4,7 @@ import styles from './style/HarEntriesList.module.sass'; import spinner from './assets/spinner.svg'; import ScrollableFeed from "react-scrollable-feed"; import {StatusType} from "./HarFilters"; +import Api from "../helpers/api"; interface HarEntriesListProps { entries: any[]; @@ -25,6 +26,8 @@ enum FetchOperator { GT = "gt" } +const api = new Api(); + export const HarEntriesList: React.FC = ({entries, setEntries, focusedEntryId, setFocusedEntryId, connectionOpen, noMoreDataTop, setNoMoreDataTop, noMoreDataBottom, setNoMoreDataBottom, methodsFilter, statusFilter, pathFilter}) => { const [loadMoreTop, setLoadMoreTop] = useState(false); @@ -54,14 +57,9 @@ export const HarEntriesList: React.FC = ({entries, setEntri return entries.filter(filterEntries); },[entries, filterEntries]) - const fetchData = async (operator, timestamp) => { - const response = await fetch(`http://localhost:8899/api/entries?limit=50&operator=${operator}×tamp=${timestamp}`); - return await response.json(); - } - const getOldEntries = useCallback(async () => { setIsLoadingTop(true); - const data = await fetchData(FetchOperator.LT, entries[0].timestamp); + const data = await api.fetchEntries(FetchOperator.LT, entries[0].timestamp); setLoadMoreTop(false); let scrollTo; @@ -89,7 +87,7 @@ export const HarEntriesList: React.FC = ({entries, setEntri }, [loadMoreTop, connectionOpen, noMoreDataTop, getOldEntries]); const getNewEntries = async () => { - const data = await fetchData(FetchOperator.GT, entries[entries.length - 1].timestamp); + const data = await api.fetchEntries(FetchOperator.GT, entries[entries.length - 1].timestamp); let scrollTo; if(data.length === 0) { setNoMoreDataBottom(true); diff --git a/ui/src/components/HarPage.tsx b/ui/src/components/HarPage.tsx index f9d32fdc5..03875b794 100644 --- a/ui/src/components/HarPage.tsx +++ b/ui/src/components/HarPage.tsx @@ -9,6 +9,7 @@ import playIcon from './assets/run.svg'; import pauseIcon from './assets/pause.svg'; import variables from './style/variables.module.scss'; import {StatusBar} from "./StatusBar"; +import Api, {MizuWebsocketURL} from "../helpers/api"; const useLayoutStyles = makeStyles(() => ({ details: { @@ -39,21 +40,7 @@ interface HarPageProps { setAnalyzeStatus: (status: any) => void; } -const mizuAPIPathPrefix = "/mizu"; - - -// When working locally (with npm run start) we need to change the PORT -const getMizuApiUrl = () => { - return `${window.location.origin}${mizuAPIPathPrefix}`; -}; - -const getMizuWebsocketUrl = () => { - return `ws://${window.location.host}${mizuAPIPathPrefix}/ws`; -} - - -const mizuApiUrl = getMizuApiUrl(); -const mizuWebsocketUrl = getMizuWebsocketUrl(); +const api = new Api(); export const HarPage: React.FC = ({setAnalyzeStatus}) => { @@ -75,7 +62,7 @@ export const HarPage: React.FC = ({setAnalyzeStatus}) => { const ws = useRef(null); const openWebSocket = () => { - ws.current = new WebSocket(mizuWebsocketUrl); + ws.current = new WebSocket(MizuWebsocketURL); ws.current.onopen = () => setConnection(ConnectionStatus.Connected); ws.current.onclose = () => setConnection(ConnectionStatus.Closed); } @@ -113,24 +100,32 @@ export const HarPage: React.FC = ({setAnalyzeStatus}) => { } useEffect(() => { - openWebSocket(); - fetch(`${mizuApiUrl}/api/tapStatus`) - .then(response => response.json()) - .then(data => setTappingStatus(data)); - - fetch(`${mizuApiUrl}/api/analyzeStatus`) - .then(response => response.json()) - .then(data => setAnalyzeStatus(data)); + (async () => { + openWebSocket(); + try{ + const tapStatusResponse = await api.tapStatus(); + setTappingStatus(tapStatusResponse); + const analyzeStatusResponse = await api.analyzeStatus(); + setAnalyzeStatus(analyzeStatusResponse); + } catch (error) { + console.error(error); + } + })() // eslint-disable-next-line }, []); useEffect(() => { if (!focusedEntryId) return; - setSelectedHarEntry(null) - fetch(`${mizuApiUrl}/api/entries/${focusedEntryId}`) - .then(response => response.json()) - .then(data => setSelectedHarEntry(data)); + setSelectedHarEntry(null); + (async () => { + try { + const entryData = await api.getEntry(focusedEntryId); + setSelectedHarEntry(entryData); + } catch (error) { + console.error(error); + } + })() }, [focusedEntryId]) const toggleConnection = () => { diff --git a/ui/src/components/StatusBar.tsx b/ui/src/components/StatusBar.tsx index 0fb25b1e4..5fe6d2738 100644 --- a/ui/src/components/StatusBar.tsx +++ b/ui/src/components/StatusBar.tsx @@ -29,12 +29,14 @@ export const StatusBar: React.FC = ({tappingStatus}) => {
{`Tapping ${amountOfPods} ${pluralize('pod', amountOfPods)} in ${pluralize('namespace', uniqueNamespaces.length)} ${uniqueNamespaces.join(", ")}`}
{expandedBar &&
- - - - + + + + + + - {tappingStatus.pods.map(pod => + {tappingStatus.pods.map(pod => )} diff --git a/ui/src/helpers/api.js b/ui/src/helpers/api.js new file mode 100644 index 000000000..61a25ff20 --- /dev/null +++ b/ui/src/helpers/api.js @@ -0,0 +1,45 @@ +import * as axios from "axios"; + +const mizuAPIPathPrefix = "/mizu"; + +// When working locally (with npm run start) change to: +// export const MizuWebsocketURL = `ws://localhost:8899${mizuAPIPathPrefix}/ws`; +export const MizuWebsocketURL = `ws://${window.location.host}${mizuAPIPathPrefix}/ws`; + +export default class Api { + + constructor() { + + // When working locally (with npm run start) change to: + // const apiURL = `http://localhost:8899/${mizuAPIPathPrefix}/api/`; + const apiURL = `${window.location.origin}${mizuAPIPathPrefix}/api/`; + + this.client = axios.create({ + baseURL: apiURL, + timeout: 31000, + headers: { + Accept: "application/json", + } + }); + } + + tapStatus = async () => { + const response = await this.client.get("/tapStatus"); + return response.data; + } + + analyzeStatus = async () => { + const response = await this.client.get("/analyzeStatus"); + return response.data; + } + + getEntry = async (entryId) => { + const response = await this.client.get(`/entries/${entryId}`); + return response.data; + } + + fetchEntries = async (operator, timestamp) => { + const response = await this.client.get(`/entries?limit=50&operator=${operator}×tamp=${timestamp}`); + return response.data; + } +} \ No newline at end of file From 803681a239ddd86f58ff283a74f2d4e06ab56f54 Mon Sep 17 00:00:00 2001 From: nimrod-up9 <59927337+nimrod-up9@users.noreply.github.com> Date: Thu, 22 Jul 2021 17:17:17 +0300 Subject: [PATCH 29/69] Renamed collector, aggregator to api server, api folder to agent (#133) * Renamed aggregator -> apiServer. * Format errors with container names. * Renamed collector -> apiServer. * Rephrased help messages. * Moved api -> agent. * Continue renameing api -> agent in Makefile and Dockerfiles. --- Dockerfile | 14 +++++----- Makefile | 16 +++++------ {api => agent}/README.md | 6 ++-- {api => agent}/go.mod | 0 {api => agent}/go.sum | 0 {api => agent}/main.go | 16 +++++------ {api => agent}/pkg/api/main.go | 0 .../pkg/api/socket_server_handlers.go | 0 .../pkg/controllers/entries_controller.go | 0 .../pkg/controllers/metadata_controller.go | 0 .../pkg/controllers/resolving_controller.go | 0 .../pkg/controllers/status_controller.go | 0 {api => agent}/pkg/database/main.go | 0 {api => agent}/pkg/database/size_enforcer.go | 0 {api => agent}/pkg/holder/main.go | 0 .../pkg/middleware/fiber_middleware.go | 0 {api => agent}/pkg/models/models.go | 0 {api => agent}/pkg/resolver/README.md | 0 {api => agent}/pkg/resolver/go.sum | 0 {api => agent}/pkg/resolver/loader.go | 0 {api => agent}/pkg/resolver/resolver.go | 0 {api => agent}/pkg/routes/entries_routes.go | 0 {api => agent}/pkg/routes/metadata_routes.go | 0 {api => agent}/pkg/routes/not_found_route.go | 0 {api => agent}/pkg/routes/socket_routes.go | 0 .../pkg/sensitiveDataFiltering/consts.go | 0 .../messageSensitiveDataCleaner.go | 0 {api => agent}/pkg/up9/main.go | 0 {api => agent}/pkg/utils/pathUtils.go | 0 {api => agent}/pkg/utils/randomString.go | 0 {api => agent}/pkg/utils/truncating_logger.go | 0 {api => agent}/pkg/utils/utils.go | 0 {api => agent}/pkg/utils/zip.go | 0 {api => agent}/pkg/validation/validation.go | 0 {api => agent}/pkg/version/consts.go | 0 {api => agent}/start.sh | 0 cli/cmd/fetchRunner.go | 2 +- cli/cmd/tap.go | 2 +- cli/cmd/tapRunner.go | 28 +++++++++---------- cli/cmd/viewRunner.go | 14 +++++----- cli/kubernetes/provider.go | 24 ++++++++-------- cli/kubernetes/proxy.go | 8 +++--- cli/mizu/consts.go | 2 +- debug.Dockerfile | 16 +++++------ tap/passive_tapper.go | 3 +- 45 files changed, 75 insertions(+), 76 deletions(-) rename {api => agent}/README.md (91%) rename {api => agent}/go.mod (100%) rename {api => agent}/go.sum (100%) rename {api => agent}/main.go (91%) rename {api => agent}/pkg/api/main.go (100%) rename {api => agent}/pkg/api/socket_server_handlers.go (100%) rename {api => agent}/pkg/controllers/entries_controller.go (100%) rename {api => agent}/pkg/controllers/metadata_controller.go (100%) rename {api => agent}/pkg/controllers/resolving_controller.go (100%) rename {api => agent}/pkg/controllers/status_controller.go (100%) rename {api => agent}/pkg/database/main.go (100%) rename {api => agent}/pkg/database/size_enforcer.go (100%) rename {api => agent}/pkg/holder/main.go (100%) rename {api => agent}/pkg/middleware/fiber_middleware.go (100%) rename {api => agent}/pkg/models/models.go (100%) rename {api => agent}/pkg/resolver/README.md (100%) rename {api => agent}/pkg/resolver/go.sum (100%) rename {api => agent}/pkg/resolver/loader.go (100%) rename {api => agent}/pkg/resolver/resolver.go (100%) rename {api => agent}/pkg/routes/entries_routes.go (100%) rename {api => agent}/pkg/routes/metadata_routes.go (100%) rename {api => agent}/pkg/routes/not_found_route.go (100%) rename {api => agent}/pkg/routes/socket_routes.go (100%) rename {api => agent}/pkg/sensitiveDataFiltering/consts.go (100%) rename {api => agent}/pkg/sensitiveDataFiltering/messageSensitiveDataCleaner.go (100%) rename {api => agent}/pkg/up9/main.go (100%) rename {api => agent}/pkg/utils/pathUtils.go (100%) rename {api => agent}/pkg/utils/randomString.go (100%) rename {api => agent}/pkg/utils/truncating_logger.go (100%) rename {api => agent}/pkg/utils/utils.go (100%) rename {api => agent}/pkg/utils/zip.go (100%) rename {api => agent}/pkg/validation/validation.go (100%) rename {api => agent}/pkg/version/consts.go (100%) rename {api => agent}/start.sh (100%) diff --git a/Dockerfile b/Dockerfile index 0fa90f951..7a15bd2b8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,10 +13,10 @@ ENV CGO_ENABLED=1 GOOS=linux GOARCH=amd64 RUN apk add libpcap-dev gcc g++ make -# Move to api working directory (/api-build). -WORKDIR /app/api-build +# Move to agent working directory (/agent-build). +WORKDIR /app/agent-build -COPY api/go.mod api/go.sum ./ +COPY agent/go.mod agent/go.sum ./ COPY shared/go.mod shared/go.mod ../shared/ COPY tap/go.mod tap/go.mod ../tap/ RUN go mod download @@ -28,10 +28,10 @@ ARG GIT_BRANCH ARG BUILD_TIMESTAMP ARG SEM_VER -# Copy and build api code +# Copy and build agent code COPY shared ../shared COPY tap ../tap -COPY api . +COPY agent . RUN go build -ldflags="-s -w \ -X 'mizuserver/pkg/version.GitCommitHash=${COMMIT_HASH}' \ -X 'mizuserver/pkg/version.Branch=${GIT_BRANCH}' \ @@ -45,10 +45,10 @@ RUN apk add bash libpcap-dev tcpdump WORKDIR /app # Copy binary and config files from /build to root folder of scratch container. -COPY --from=builder ["/app/api-build/mizuagent", "."] +COPY --from=builder ["/app/agent-build/mizuagent", "."] COPY --from=site-build ["/app/ui-build/build", "site"] -COPY api/start.sh . +COPY agent/start.sh . # this script runs both apiserver and passivetapper and exits either if one of them exits, preventing a scenario where the container runs without one process ENTRYPOINT "/app/mizuagent" diff --git a/Makefile b/Makefile index b304676bc..2de4db43c 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ SHELL=/bin/bash # HELP # This will output the help for each task # thanks to https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html -.PHONY: help ui api cli tap docker +.PHONY: help ui agent cli tap docker help: ## This help. @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) @@ -27,10 +27,10 @@ ui: ## build UI cli: # build CLI @echo "building cli"; cd cli && $(MAKE) build -api: ## build API server - @(echo "building API server .." ) - @(cd api; go build -o build/apiserver main.go) - @ls -l api/build +agent: ## build mizuagent server + @(echo "building mizu agent .." ) + @(cd agent; go build -o build/mizuagent main.go) + @ls -l agent/build #tap: ## build tap binary # @(cd tap; go build -o build/tap ./src) @@ -55,13 +55,13 @@ push-cli: gsutil setmeta -r -h "Cache-Control:public, max-age=30" gs://${BUCKET_PATH}/\* -clean: clean-ui clean-api clean-cli clean-docker ## Clean all build artifacts +clean: clean-ui clean-agent clean-cli clean-docker ## Clean all build artifacts clean-ui: @(rm -rf ui/build ; echo "UI cleanup done" ) -clean-api: - @(rm -rf api/build ; echo "api cleanup done" ) +clean-agent: + @(rm -rf agent/build ; echo "agent cleanup done" ) clean-cli: @(cd cli; make clean ; echo "CLI cleanup done" ) diff --git a/api/README.md b/agent/README.md similarity index 91% rename from api/README.md rename to agent/README.md index cfa4b4627..f275a0988 100644 --- a/api/README.md +++ b/agent/README.md @@ -1,5 +1,5 @@ -# mizu API server -API server for MIZU +# mizu agent +Agent for MIZU (API server and tapper) Basic APIs: * /fetch - retrieve traffic data * /stats - retrieve statistics of collected data @@ -14,7 +14,7 @@ Basic APIs: ### Connecting 1. Start mizu using the cli with the debug image `mizu tap --mizu-image gcr.io/up9-docker-hub/mizu/debug:latest {tapped_pod_name}` -2. Forward the debug port using `kubectl port-forward -n default mizu-collector 2345:2345` +2. Forward the debug port using `kubectl port-forward -n default mizu-api-server 2345:2345` 3. Run the run/debug configuration you've created earlier in Intellij. Do note that dlv won't start the api until a debugger connects to it. diff --git a/api/go.mod b/agent/go.mod similarity index 100% rename from api/go.mod rename to agent/go.mod diff --git a/api/go.sum b/agent/go.sum similarity index 100% rename from api/go.sum rename to agent/go.sum diff --git a/api/main.go b/agent/main.go similarity index 91% rename from api/main.go rename to agent/main.go index d5016b7f1..5ea036aa5 100644 --- a/api/main.go +++ b/agent/main.go @@ -22,16 +22,16 @@ import ( ) var shouldTap = flag.Bool("tap", false, "Run in tapper mode without API") -var aggregator = flag.Bool("aggregator", false, "Run in aggregator mode with API") +var apiServer = flag.Bool("api-server", false, "Run in API server mode with API") var standalone = flag.Bool("standalone", false, "Run in standalone tapper and API mode") -var aggregatorAddress = flag.String("aggregator-address", "", "Address of mizu collector for tapping") +var apiServerAddress = flag.String("api-server-address", "", "Address of mizu API server") func main() { flag.Parse() hostMode := os.Getenv(shared.HostModeEnvVar) == "1" tapOpts := &tap.TapOpts{HostMode: hostMode} - if !*shouldTap && !*aggregator && !*standalone { + if !*shouldTap && !*apiServer && !*standalone { panic("One of the flags --tap, --api or --standalone must be provided") } @@ -45,8 +45,8 @@ func main() { hostApi(nil) } else if *shouldTap { - if *aggregatorAddress == "" { - panic("Aggregator address must be provided with --aggregator-address when using --tap") + if *apiServerAddress == "" { + panic("API server address must be provided with --api-server-address when using --tap") } tapTargets := getTapTargets() @@ -57,14 +57,14 @@ func main() { harOutputChannel, outboundLinkOutputChannel := tap.StartPassiveTapper(tapOpts) - socketConnection, err := shared.ConnectToSocketServer(*aggregatorAddress, shared.DEFAULT_SOCKET_RETRIES, shared.DEFAULT_SOCKET_RETRY_SLEEP_TIME, false) + socketConnection, err := shared.ConnectToSocketServer(*apiServerAddress, shared.DEFAULT_SOCKET_RETRIES, shared.DEFAULT_SOCKET_RETRY_SLEEP_TIME, false) if err != nil { - panic(fmt.Sprintf("Error connecting to socket server at %s %v", *aggregatorAddress, err)) + panic(fmt.Sprintf("Error connecting to socket server at %s %v", *apiServerAddress, err)) } go pipeChannelToSocket(socketConnection, harOutputChannel) go api.StartReadingOutbound(outboundLinkOutputChannel) - } else if *aggregator { + } else if *apiServer { socketHarOutChannel := make(chan *tap.OutputChannelItem, 1000) filteredHarChannel := make(chan *tap.OutputChannelItem) diff --git a/api/pkg/api/main.go b/agent/pkg/api/main.go similarity index 100% rename from api/pkg/api/main.go rename to agent/pkg/api/main.go diff --git a/api/pkg/api/socket_server_handlers.go b/agent/pkg/api/socket_server_handlers.go similarity index 100% rename from api/pkg/api/socket_server_handlers.go rename to agent/pkg/api/socket_server_handlers.go diff --git a/api/pkg/controllers/entries_controller.go b/agent/pkg/controllers/entries_controller.go similarity index 100% rename from api/pkg/controllers/entries_controller.go rename to agent/pkg/controllers/entries_controller.go diff --git a/api/pkg/controllers/metadata_controller.go b/agent/pkg/controllers/metadata_controller.go similarity index 100% rename from api/pkg/controllers/metadata_controller.go rename to agent/pkg/controllers/metadata_controller.go diff --git a/api/pkg/controllers/resolving_controller.go b/agent/pkg/controllers/resolving_controller.go similarity index 100% rename from api/pkg/controllers/resolving_controller.go rename to agent/pkg/controllers/resolving_controller.go diff --git a/api/pkg/controllers/status_controller.go b/agent/pkg/controllers/status_controller.go similarity index 100% rename from api/pkg/controllers/status_controller.go rename to agent/pkg/controllers/status_controller.go diff --git a/api/pkg/database/main.go b/agent/pkg/database/main.go similarity index 100% rename from api/pkg/database/main.go rename to agent/pkg/database/main.go diff --git a/api/pkg/database/size_enforcer.go b/agent/pkg/database/size_enforcer.go similarity index 100% rename from api/pkg/database/size_enforcer.go rename to agent/pkg/database/size_enforcer.go diff --git a/api/pkg/holder/main.go b/agent/pkg/holder/main.go similarity index 100% rename from api/pkg/holder/main.go rename to agent/pkg/holder/main.go diff --git a/api/pkg/middleware/fiber_middleware.go b/agent/pkg/middleware/fiber_middleware.go similarity index 100% rename from api/pkg/middleware/fiber_middleware.go rename to agent/pkg/middleware/fiber_middleware.go diff --git a/api/pkg/models/models.go b/agent/pkg/models/models.go similarity index 100% rename from api/pkg/models/models.go rename to agent/pkg/models/models.go diff --git a/api/pkg/resolver/README.md b/agent/pkg/resolver/README.md similarity index 100% rename from api/pkg/resolver/README.md rename to agent/pkg/resolver/README.md diff --git a/api/pkg/resolver/go.sum b/agent/pkg/resolver/go.sum similarity index 100% rename from api/pkg/resolver/go.sum rename to agent/pkg/resolver/go.sum diff --git a/api/pkg/resolver/loader.go b/agent/pkg/resolver/loader.go similarity index 100% rename from api/pkg/resolver/loader.go rename to agent/pkg/resolver/loader.go diff --git a/api/pkg/resolver/resolver.go b/agent/pkg/resolver/resolver.go similarity index 100% rename from api/pkg/resolver/resolver.go rename to agent/pkg/resolver/resolver.go diff --git a/api/pkg/routes/entries_routes.go b/agent/pkg/routes/entries_routes.go similarity index 100% rename from api/pkg/routes/entries_routes.go rename to agent/pkg/routes/entries_routes.go diff --git a/api/pkg/routes/metadata_routes.go b/agent/pkg/routes/metadata_routes.go similarity index 100% rename from api/pkg/routes/metadata_routes.go rename to agent/pkg/routes/metadata_routes.go diff --git a/api/pkg/routes/not_found_route.go b/agent/pkg/routes/not_found_route.go similarity index 100% rename from api/pkg/routes/not_found_route.go rename to agent/pkg/routes/not_found_route.go diff --git a/api/pkg/routes/socket_routes.go b/agent/pkg/routes/socket_routes.go similarity index 100% rename from api/pkg/routes/socket_routes.go rename to agent/pkg/routes/socket_routes.go diff --git a/api/pkg/sensitiveDataFiltering/consts.go b/agent/pkg/sensitiveDataFiltering/consts.go similarity index 100% rename from api/pkg/sensitiveDataFiltering/consts.go rename to agent/pkg/sensitiveDataFiltering/consts.go diff --git a/api/pkg/sensitiveDataFiltering/messageSensitiveDataCleaner.go b/agent/pkg/sensitiveDataFiltering/messageSensitiveDataCleaner.go similarity index 100% rename from api/pkg/sensitiveDataFiltering/messageSensitiveDataCleaner.go rename to agent/pkg/sensitiveDataFiltering/messageSensitiveDataCleaner.go diff --git a/api/pkg/up9/main.go b/agent/pkg/up9/main.go similarity index 100% rename from api/pkg/up9/main.go rename to agent/pkg/up9/main.go diff --git a/api/pkg/utils/pathUtils.go b/agent/pkg/utils/pathUtils.go similarity index 100% rename from api/pkg/utils/pathUtils.go rename to agent/pkg/utils/pathUtils.go diff --git a/api/pkg/utils/randomString.go b/agent/pkg/utils/randomString.go similarity index 100% rename from api/pkg/utils/randomString.go rename to agent/pkg/utils/randomString.go diff --git a/api/pkg/utils/truncating_logger.go b/agent/pkg/utils/truncating_logger.go similarity index 100% rename from api/pkg/utils/truncating_logger.go rename to agent/pkg/utils/truncating_logger.go diff --git a/api/pkg/utils/utils.go b/agent/pkg/utils/utils.go similarity index 100% rename from api/pkg/utils/utils.go rename to agent/pkg/utils/utils.go diff --git a/api/pkg/utils/zip.go b/agent/pkg/utils/zip.go similarity index 100% rename from api/pkg/utils/zip.go rename to agent/pkg/utils/zip.go diff --git a/api/pkg/validation/validation.go b/agent/pkg/validation/validation.go similarity index 100% rename from api/pkg/validation/validation.go rename to agent/pkg/validation/validation.go diff --git a/api/pkg/version/consts.go b/agent/pkg/version/consts.go similarity index 100% rename from api/pkg/version/consts.go rename to agent/pkg/version/consts.go diff --git a/api/start.sh b/agent/start.sh similarity index 100% rename from api/start.sh rename to agent/start.sh diff --git a/cli/cmd/fetchRunner.go b/cli/cmd/fetchRunner.go index 36e6182f9..0baa437c4 100644 --- a/cli/cmd/fetchRunner.go +++ b/cli/cmd/fetchRunner.go @@ -15,7 +15,7 @@ import ( ) func RunMizuFetch(fetch *MizuFetchOptions) { - mizuProxiedUrl := kubernetes.GetMizuCollectorProxiedHostAndPath(fetch.MizuPort) + mizuProxiedUrl := kubernetes.GetMizuApiServerProxiedHostAndPath(fetch.MizuPort) resp, err := http.Get(fmt.Sprintf("http://%s/api/har?from=%v&to=%v", mizuProxiedUrl, fetch.FromTimestamp, fetch.ToTimestamp)) if err != nil { log.Fatal(err) diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go index bdf7b732c..6d62e0084 100644 --- a/cli/cmd/tap.go +++ b/cli/cmd/tap.go @@ -99,7 +99,7 @@ func init() { tapCmd.Flags().Uint16VarP(&mizuTapOptions.SleepIntervalSec, "upload-interval", "", 10, "Interval in seconds for uploading data to UP9") tapCmd.Flags().BoolVarP(&mizuTapOptions.AllNamespaces, "all-namespaces", "A", false, "Tap all namespaces") tapCmd.Flags().StringVarP(&mizuTapOptions.KubeConfigPath, "kube-config", "k", "", "Path to kube-config file") - tapCmd.Flags().StringVarP(&mizuTapOptions.MizuImage, "mizu-image", "", fmt.Sprintf("gcr.io/up9-docker-hub/mizu/%s:%s", mizu.Branch, mizu.SemVer), "Custom image for mizu collector") + tapCmd.Flags().StringVarP(&mizuTapOptions.MizuImage, "mizu-image", "", fmt.Sprintf("gcr.io/up9-docker-hub/mizu/%s:%s", mizu.Branch, mizu.SemVer), "Custom image for mizu API server") tapCmd.Flags().StringArrayVarP(&mizuTapOptions.PlainTextFilterRegexes, "regex-masking", "r", nil, "List of regex expressions that are used to filter matching values from text/plain http bodies") tapCmd.Flags().StringVarP(&direction, "direction", "", "in", "Record traffic that goes in this direction (relative to the tapped pod): in/any") tapCmd.Flags().BoolVar(&mizuTapOptions.HideHealthChecks, "hide-healthchecks", false, "hides requests with kube-probe or prometheus user-agent headers") diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index 3301f9341..e086f6c82 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -22,7 +22,7 @@ import ( ) var mizuServiceAccountExists bool -var aggregatorService *core.Service +var apiServerService *core.Service const ( updateTappersDelay = 5 * time.Second @@ -100,7 +100,7 @@ func createMizuResources(ctx context.Context, kubernetesProvider *kubernetes.Pro return err } - if err := createMizuAggregator(ctx, kubernetesProvider, tappingOptions, mizuApiFilteringOptions); err != nil { + if err := createMizuApiServer(ctx, kubernetesProvider, tappingOptions, mizuApiFilteringOptions); err != nil { return err } @@ -120,7 +120,7 @@ func createMizuNamespace(ctx context.Context, kubernetesProvider *kubernetes.Pro return err } -func createMizuAggregator(ctx context.Context, kubernetesProvider *kubernetes.Provider, tappingOptions *MizuTapOptions, mizuApiFilteringOptions *shared.TrafficFilteringOptions) error { +func createMizuApiServer(ctx context.Context, kubernetesProvider *kubernetes.Provider, tappingOptions *MizuTapOptions, mizuApiFilteringOptions *shared.TrafficFilteringOptions) error { var err error mizuServiceAccountExists = createRBACIfNecessary(ctx, kubernetesProvider) @@ -130,15 +130,15 @@ func createMizuAggregator(ctx context.Context, kubernetesProvider *kubernetes.Pr } else { serviceAccountName = "" } - _, err = kubernetesProvider.CreateMizuAggregatorPod(ctx, mizu.ResourcesNamespace, mizu.AggregatorPodName, tappingOptions.MizuImage, serviceAccountName, mizuApiFilteringOptions, tappingOptions.MaxEntriesDBSizeBytes) + _, err = kubernetesProvider.CreateMizuApiServerPod(ctx, mizu.ResourcesNamespace, mizu.ApiServerPodName, tappingOptions.MizuImage, serviceAccountName, mizuApiFilteringOptions, tappingOptions.MaxEntriesDBSizeBytes) if err != nil { - fmt.Printf("Error creating mizu collector pod: %v\n", err) + fmt.Printf("Error creating mizu %s pod: %v\n", mizu.ApiServerPodName, err) return err } - aggregatorService, err = kubernetesProvider.CreateService(ctx, mizu.ResourcesNamespace, mizu.AggregatorPodName, mizu.AggregatorPodName) + apiServerService, err = kubernetesProvider.CreateService(ctx, mizu.ResourcesNamespace, mizu.ApiServerPodName, mizu.ApiServerPodName) if err != nil { - fmt.Printf("Error creating mizu collector service: %v\n", err) + fmt.Printf("Error creating mizu %s service: %v\n", mizu.ApiServerPodName, err) return err } @@ -178,7 +178,7 @@ func updateMizuTappers(ctx context.Context, kubernetesProvider *kubernetes.Provi mizu.TapperDaemonSetName, tappingOptions.MizuImage, mizu.TapperPodName, - fmt.Sprintf("%s.%s.svc.cluster.local", aggregatorService.Name, aggregatorService.Namespace), + fmt.Sprintf("%s.%s.svc.cluster.local", apiServerService.Name, apiServerService.Namespace), nodeToTappedPodIPMap, serviceAccountName, tappingOptions.TapOutgoing, @@ -288,7 +288,7 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro } func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provider, cancel context.CancelFunc, tappingOptions *MizuTapOptions) { - podExactRegex := regexp.MustCompile(fmt.Sprintf("^%s$", mizu.AggregatorPodName)) + podExactRegex := regexp.MustCompile(fmt.Sprintf("^%s$", mizu.ApiServerPodName)) added, modified, removed, errorChan := kubernetes.FilteredWatch(ctx, kubernetesProvider.GetPodWatcher(ctx, mizu.ResourcesNamespace), podExactRegex) isPodReady := false timeAfter := time.After(25 * time.Second) @@ -300,20 +300,20 @@ func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provi case <-added: continue case <-removed: - fmt.Printf("%s removed\n", mizu.AggregatorPodName) + fmt.Printf("%s removed\n", mizu.ApiServerPodName) cancel() return case modifiedPod := <-modified: if modifiedPod.Status.Phase == "Running" && !isPodReady { isPodReady = true go func() { - err := kubernetes.StartProxy(kubernetesProvider, tappingOptions.GuiPort, mizu.ResourcesNamespace, mizu.AggregatorPodName) + err := kubernetes.StartProxy(kubernetesProvider, tappingOptions.GuiPort, mizu.ResourcesNamespace, mizu.ApiServerPodName) if err != nil { fmt.Printf("Error occured while running k8s proxy %v\n", err) cancel() } }() - mizuProxiedUrl := kubernetes.GetMizuCollectorProxiedHostAndPath(tappingOptions.GuiPort) + mizuProxiedUrl := kubernetes.GetMizuApiServerProxiedHostAndPath(tappingOptions.GuiPort) fmt.Printf("Mizu is available at http://%s\n", mizuProxiedUrl) time.Sleep(time.Second * 5) // Waiting to be sure the proxy is ready @@ -336,7 +336,7 @@ func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provi case <-timeAfter: if !isPodReady { - fmt.Printf("error: %s pod was not ready in time", mizu.AggregatorPodName) + fmt.Printf("error: %s pod was not ready in time", mizu.ApiServerPodName) cancel() } @@ -389,7 +389,7 @@ func waitForFinish(ctx context.Context, cancel context.CancelFunc) { } func syncApiStatus(ctx context.Context, cancel context.CancelFunc, tappingOptions *MizuTapOptions) { - controlSocketStr := fmt.Sprintf("ws://%s/ws", kubernetes.GetMizuCollectorProxiedHostAndPath(tappingOptions.GuiPort)) + controlSocketStr := fmt.Sprintf("ws://%s/ws", kubernetes.GetMizuApiServerProxiedHostAndPath(tappingOptions.GuiPort)) controlSocket, err := mizu.CreateControlSocket(controlSocketStr) if err != nil { fmt.Printf("error establishing control socket connection %s\n", err) diff --git a/cli/cmd/viewRunner.go b/cli/cmd/viewRunner.go index d37a85559..d339010a7 100644 --- a/cli/cmd/viewRunner.go +++ b/cli/cmd/viewRunner.go @@ -25,25 +25,25 @@ func runMizuView(mizuViewOptions *MizuViewOptions) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - exists, err := kubernetesProvider.DoesServicesExist(ctx, mizu.ResourcesNamespace, mizu.AggregatorPodName) + exists, err := kubernetesProvider.DoesServicesExist(ctx, mizu.ResourcesNamespace, mizu.ApiServerPodName) if err != nil { panic(err) } if !exists { - fmt.Printf("The %s service not found\n", mizu.AggregatorPodName) + fmt.Printf("The %s service not found\n", mizu.ApiServerPodName) return } - mizuProxiedUrl := kubernetes.GetMizuCollectorProxiedHostAndPath(mizuViewOptions.GuiPort) + mizuProxiedUrl := kubernetes.GetMizuApiServerProxiedHostAndPath(mizuViewOptions.GuiPort) _, err = http.Get(fmt.Sprintf("http://%s/", mizuProxiedUrl)) if err == nil { - fmt.Printf("Found a running service %s and open port %d\n", mizu.AggregatorPodName, mizuViewOptions.GuiPort) + fmt.Printf("Found a running service %s and open port %d\n", mizu.ApiServerPodName, mizuViewOptions.GuiPort) return } - fmt.Printf("Found service %s, creating k8s proxy\n", mizu.AggregatorPodName) + fmt.Printf("Found service %s, creating k8s proxy\n", mizu.ApiServerPodName) - fmt.Printf("Mizu is available at http://%s\n", kubernetes.GetMizuCollectorProxiedHostAndPath(mizuViewOptions.GuiPort)) - err = kubernetes.StartProxy(kubernetesProvider, mizuViewOptions.GuiPort, mizu.ResourcesNamespace, mizu.AggregatorPodName) + fmt.Printf("Mizu is available at http://%s\n", kubernetes.GetMizuApiServerProxiedHostAndPath(mizuViewOptions.GuiPort)) + err = kubernetes.StartProxy(kubernetesProvider, mizuViewOptions.GuiPort, mizu.ResourcesNamespace, mizu.ApiServerPodName) if err != nil { fmt.Printf("Error occured while running k8s proxy %v\n", err) } diff --git a/cli/kubernetes/provider.go b/cli/kubernetes/provider.go index df62afae7..bf40986c3 100644 --- a/cli/kubernetes/provider.go +++ b/cli/kubernetes/provider.go @@ -124,7 +124,7 @@ func (provider *Provider) CreateNamespace(ctx context.Context, name string) (*co return provider.clientSet.CoreV1().Namespaces().Create(ctx, namespaceSpec, metav1.CreateOptions{}) } -func (provider *Provider) CreateMizuAggregatorPod(ctx context.Context, namespace string, podName string, podImage string, serviceAccountName string, mizuApiFilteringOptions *shared.TrafficFilteringOptions, maxEntriesDBSizeBytes int64) (*core.Pod, error) { +func (provider *Provider) CreateMizuApiServerPod(ctx context.Context, namespace string, podName string, podImage string, serviceAccountName string, mizuApiFilteringOptions *shared.TrafficFilteringOptions, maxEntriesDBSizeBytes int64) (*core.Pod, error) { marshaledFilteringOptions, err := json.Marshal(mizuApiFilteringOptions) if err != nil { return nil, err @@ -132,19 +132,19 @@ func (provider *Provider) CreateMizuAggregatorPod(ctx context.Context, namespace cpuLimit, err := resource.ParseQuantity("750m") if err != nil { - return nil, errors.New("invalid cpu limit for aggregator container") + return nil, errors.New(fmt.Sprintf("invalid cpu limit for %s container", podName)) } memLimit, err := resource.ParseQuantity("512Mi") if err != nil { - return nil, errors.New("invalid memory limit for aggregator container") + return nil, errors.New(fmt.Sprintf("invalid memory limit for %s container", podName)) } cpuRequests, err := resource.ParseQuantity("50m") if err != nil { - return nil, errors.New("invalid cpu request for aggregator container") + return nil, errors.New(fmt.Sprintf("invalid cpu request for %s container", podName)) } memRequests, err := resource.ParseQuantity("50Mi") if err != nil { - return nil, errors.New("invalid memory request for aggregator container") + return nil, errors.New(fmt.Sprintf("invalid memory request for %s container", podName)) } pod := &core.Pod{ @@ -159,7 +159,7 @@ func (provider *Provider) CreateMizuAggregatorPod(ctx context.Context, namespace Name: podName, Image: podImage, ImagePullPolicy: core.PullAlways, - Command: []string{"./mizuagent", "--aggregator"}, + Command: []string{"./mizuagent", "--api-server"}, Env: []core.EnvVar{ { Name: shared.HostModeEnvVar, @@ -471,7 +471,7 @@ func (provider *Provider) CheckDaemonSetExists(ctx context.Context, namespace st return false, nil } -func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespace string, daemonSetName string, podImage string, tapperPodName string, aggregatorPodIp string, nodeToTappedPodIPMap map[string][]string, serviceAccountName string, tapOutgoing bool) error { +func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespace string, daemonSetName string, podImage string, tapperPodName string, apiServerPodIp string, nodeToTappedPodIPMap map[string][]string, serviceAccountName string, tapOutgoing bool) error { if len(nodeToTappedPodIPMap) == 0 { return fmt.Errorf("Daemon set %s must tap at least 1 pod", daemonSetName) } @@ -486,7 +486,7 @@ func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespac "-i", "any", "--tap", "--hardump", - "--aggregator-address", fmt.Sprintf("ws://%s/wsTapper", aggregatorPodIp), + "--api-server-address", fmt.Sprintf("ws://%s/wsTapper", apiServerPodIp), } if tapOutgoing { mizuCmd = append(mizuCmd, "--anydirection") @@ -512,19 +512,19 @@ func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespac ) cpuLimit, err := resource.ParseQuantity("500m") if err != nil { - return errors.New("invalid cpu limit for tapper container") + return errors.New(fmt.Sprintf("invalid cpu limit for %s container", tapperPodName)) } memLimit, err := resource.ParseQuantity("1Gi") if err != nil { - return errors.New("invalid memory limit for tapper container") + return errors.New(fmt.Sprintf("invalid memory limit for %s container", tapperPodName)) } cpuRequests, err := resource.ParseQuantity("50m") if err != nil { - return errors.New("invalid cpu request for tapper container") + return errors.New(fmt.Sprintf("invalid cpu request for %s container", tapperPodName)) } memRequests, err := resource.ParseQuantity("50Mi") if err != nil { - return errors.New("invalid memory request for tapper container") + return errors.New(fmt.Sprintf("invalid memory request for %s container", tapperPodName)) } agentResourceLimits := core.ResourceList{ "cpu": cpuLimit, diff --git a/cli/kubernetes/proxy.go b/cli/kubernetes/proxy.go index 77904ddaa..2d2967bd4 100644 --- a/cli/kubernetes/proxy.go +++ b/cli/kubernetes/proxy.go @@ -40,24 +40,24 @@ func StartProxy(kubernetesProvider *Provider, mizuPort uint16, mizuNamespace str return server.Serve(l) } -func getMizuCollectorProxiedHostAndPath(mizuNamespace string, mizuServiceName string) string { +func getMizuApiServerProxiedHostAndPath(mizuNamespace string, mizuServiceName string) string { return fmt.Sprintf("/api/v1/namespaces/%s/services/%s:%d/proxy/", mizuNamespace, mizuServiceName, mizuServicePort) } -func GetMizuCollectorProxiedHostAndPath(mizuPort uint16) string { +func GetMizuApiServerProxiedHostAndPath(mizuPort uint16) string { return fmt.Sprintf("localhost:%d/mizu", mizuPort) } func getRerouteHttpHandlerMizuAPI(proxyHandler http.Handler, mizuNamespace string, mizuServiceName string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - r.URL.Path = strings.Replace(r.URL.Path, "/mizu/", getMizuCollectorProxiedHostAndPath(mizuNamespace, mizuServiceName), 1) + r.URL.Path = strings.Replace(r.URL.Path, "/mizu/", getMizuApiServerProxiedHostAndPath(mizuNamespace, mizuServiceName), 1) proxyHandler.ServeHTTP(w, r) }) } func getRerouteHttpHandlerMizuStatic(proxyHandler http.Handler, mizuNamespace string, mizuServiceName string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - r.URL.Path = strings.Replace(r.URL.Path, "/static/", fmt.Sprintf("%s/static/", getMizuCollectorProxiedHostAndPath(mizuNamespace, mizuServiceName)), 1) + r.URL.Path = strings.Replace(r.URL.Path, "/static/", fmt.Sprintf("%s/static/", getMizuApiServerProxiedHostAndPath(mizuNamespace, mizuServiceName)), 1) proxyHandler.ServeHTTP(w, r) }) } diff --git a/cli/mizu/consts.go b/cli/mizu/consts.go index 45d2a2246..6874069d5 100644 --- a/cli/mizu/consts.go +++ b/cli/mizu/consts.go @@ -9,7 +9,7 @@ var ( ) const ( - AggregatorPodName = "mizu-collector" + ApiServerPodName = "mizu-api-server" ClusterRoleBindingName = "mizu-cluster-role-binding" ClusterRoleName = "mizu-cluster-role" K8sAllNamespaces = "" diff --git a/debug.Dockerfile b/debug.Dockerfile index c894d2f27..f3145d218 100644 --- a/debug.Dockerfile +++ b/debug.Dockerfile @@ -1,4 +1,4 @@ -# creates image in which mizu api is remotely debuggable using delve +# creates image in which mizu agent is remotely debuggable using delve FROM node:14-slim AS site-build WORKDIR /app/ui-build @@ -14,10 +14,10 @@ ENV CGO_ENABLED=1 GOOS=linux GOARCH=amd64 RUN apk add libpcap-dev gcc g++ make -# Move to api working directory (/api-build). -WORKDIR /app/api-build +# Move to agent working directory (/agent-build). +WORKDIR /app/agent-build -COPY api/go.mod api/go.sum ./ +COPY agent/go.mod agent/go.sum ./ COPY shared/go.mod shared/go.mod ../shared/ COPY tap/go.mod tap/go.mod ../tap/ @@ -25,10 +25,10 @@ RUN go mod download # cheap trick to make the build faster (As long as go.mod wasn't changes) RUN go list -f '{{.Path}}@{{.Version}}' -m all | sed 1d | grep -e 'go-cache' -e 'sqlite' | xargs go get -# Copy and build api code +# Copy and build agent code COPY shared ../shared COPY tap ../tap -COPY api . +COPY agent . RUN go build -gcflags="all=-N -l" -o mizuagent . @@ -38,11 +38,11 @@ RUN apk add bash libpcap-dev tcpdump WORKDIR /app # Copy binary and config files from /build to root folder of scratch container. -COPY --from=builder ["/app/api-build/mizuagent", "."] +COPY --from=builder ["/app/agent-build/mizuagent", "."] COPY --from=site-build ["/app/ui-build/build", "site"] # install remote debugging tool RUN go get github.com/go-delve/delve/cmd/dlv ENTRYPOINT "/app/mizuagent" -#CMD ["sh", "-c", "dlv --headless=true --listen=:2345 --log --api-version=2 --accept-multiclient exec ./mizuagent -- --aggregator"] +#CMD ["sh", "-c", "dlv --headless=true --listen=:2345 --log --api-version=2 --accept-multiclient exec ./mizuagent -- --api-server"] diff --git a/tap/passive_tapper.go b/tap/passive_tapper.go index 0625c666d..c1eef2c75 100644 --- a/tap/passive_tapper.go +++ b/tap/passive_tapper.go @@ -33,8 +33,7 @@ import ( const AppPortsEnvVar = "APP_PORTS" const maxHTTP2DataLenEnvVar = "HTTP2_DATA_SIZE_LIMIT" -// default is 1MB, more than the max size accepted by collector and traffic-dumper -const maxHTTP2DataLenDefault = 1 * 1024 * 1024 +const maxHTTP2DataLenDefault = 1 * 1024 * 1024 // 1MB const cleanPeriod = time.Second * 10 var remoteOnlyOutboundPorts = []int { 80, 443 } From f64ee23c7441213a12f83644bd0ed26b3ea9b677 Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Sun, 25 Jul 2021 10:08:37 +0300 Subject: [PATCH 30/69] Introducing new logger, logging debug to file and info to stderr (#134) * Introducing new logger to file debug and info to stderr --- cli/cmd/fetchRunner.go | 5 +-- cli/cmd/tap.go | 6 ++-- cli/cmd/tapRunner.go | 68 ++++++++++++++++++------------------- cli/cmd/version.go | 10 +++--- cli/cmd/viewRunner.go | 14 ++++---- cli/go.mod | 2 +- cli/go.sum | 2 ++ cli/kubernetes/provider.go | 4 ++- cli/mizu.go | 6 +++- cli/mizu/logger.go | 39 +++++++++++++++++++++ cli/mizu/telemetry.go | 7 ++-- cli/mizu/versionCheck.go | 17 +++++----- cli/uiUtils/confirmation.go | 3 +- 13 files changed, 112 insertions(+), 71 deletions(-) create mode 100644 cli/mizu/logger.go diff --git a/cli/cmd/fetchRunner.go b/cli/cmd/fetchRunner.go index 0baa437c4..fd7c6c72b 100644 --- a/cli/cmd/fetchRunner.go +++ b/cli/cmd/fetchRunner.go @@ -5,6 +5,7 @@ import ( "bytes" "fmt" "github.com/up9inc/mizu/cli/kubernetes" + "github.com/up9inc/mizu/cli/mizu" "io" "io/ioutil" "log" @@ -63,7 +64,7 @@ func Unzip(reader *zip.Reader, dest string) error { _ = os.MkdirAll(path, f.Mode()) } else { _ = os.MkdirAll(filepath.Dir(path), f.Mode()) - fmt.Print("writing HAR file [ ", path, " ] .. ") + mizu.Log.Infof("writing HAR file [ %v ]", path) f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) if err != nil { return err @@ -72,7 +73,7 @@ func Unzip(reader *zip.Reader, dest string) error { if err := f.Close(); err != nil { panic(err) } - fmt.Println(" done") + mizu.Log.Info(" done") }() _, err = io.Copy(f, rc) diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go index 6d62e0084..dded96af1 100644 --- a/cli/cmd/tap.go +++ b/cli/cmd/tap.go @@ -67,7 +67,7 @@ Supported protocols are HTTP and gRPC.`, if parseHumanDataSizeErr != nil { return errors.New(fmt.Sprintf("Could not parse --max-entries-db-size value %s", humanMaxEntriesDBSize)) } - fmt.Printf("Mizu will store up to %s of traffic, old traffic will be cleared once the limit is reached.\n", units.BytesToHumanReadable(mizuTapOptions.MaxEntriesDBSizeBytes)) + mizu.Log.Infof("Mizu will store up to %s of traffic, old traffic will be cleared once the limit is reached.\n", units.BytesToHumanReadable(mizuTapOptions.MaxEntriesDBSizeBytes)) directionLowerCase := strings.ToLower(direction) if directionLowerCase == "any" { @@ -79,9 +79,9 @@ Supported protocols are HTTP and gRPC.`, } if mizuTapOptions.Analysis { - fmt.Printf(analysisMessageToConfirm) + mizu.Log.Infof(analysisMessageToConfirm) if !uiUtils.AskForConfirmation("Would you like to proceed [y/n]: ") { - fmt.Println("You can always run mizu without analysis, aborting") + mizu.Log.Infof("You can always run mizu without analysis, aborting") os.Exit(0) } } diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index e086f6c82..e8bd521af 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -3,14 +3,13 @@ package cmd import ( "context" "fmt" - "github.com/romana/rlog" "github.com/up9inc/mizu/cli/kubernetes" "github.com/up9inc/mizu/cli/mizu" "github.com/up9inc/mizu/shared" "github.com/up9inc/mizu/shared/debounce" core "k8s.io/api/core/v1" - "k8s.io/client-go/tools/clientcmd" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/tools/clientcmd" "log" "net/http" "net/url" @@ -40,11 +39,11 @@ func RunMizuTap(podRegexQuery *regexp.Regexp, tappingOptions *MizuTapOptions) { kubernetesProvider, err := kubernetes.NewProvider(tappingOptions.KubeConfigPath) if err != nil { if clientcmd.IsEmptyConfig(err) { - fmt.Printf(mizu.Red, "Couldn't find the kube config file, or file is empty. Try adding '--kube-config='\n") + mizu.Log.Infof(mizu.Red, "Couldn't find the kube config file, or file is empty. Try adding '--kube-config='\n") return } if clientcmd.IsConfigurationInvalid(err) { - fmt.Printf(mizu.Red, "Invalid kube config file. Try using a different config with '--kube-config='\n") + mizu.Log.Infof(mizu.Red, "Invalid kube config file. Try using a different config with '--kube-config='\n") return } } @@ -55,7 +54,7 @@ func RunMizuTap(podRegexQuery *regexp.Regexp, tappingOptions *MizuTapOptions) { targetNamespace := getNamespace(tappingOptions, kubernetesProvider) if matchingPods, err := kubernetesProvider.GetAllPodsMatchingRegex(ctx, podRegexQuery, targetNamespace); err != nil { - fmt.Printf("Error listing pods: %v", err) + mizu.Log.Infof("Error listing pods: %v", err) return } else { currentlyTappedPods = matchingPods @@ -67,14 +66,14 @@ func RunMizuTap(podRegexQuery *regexp.Regexp, tappingOptions *MizuTapOptions) { } else { namespacesStr = "all namespaces" } - fmt.Printf("Tapping pods in %s\n", namespacesStr) + mizu.Log.Infof("Tapping pods in %s\n", namespacesStr) if len(currentlyTappedPods) == 0 { var suggestionStr string if targetNamespace != mizu.K8sAllNamespaces { suggestionStr = "\nSelect a different namespace with -n or tap all namespaces with -A" } - fmt.Printf("Did not find any pods matching the regex argument%s\n", suggestionStr) + mizu.Log.Infof("Did not find any pods matching the regex argument%s\n", suggestionStr) } nodeToTappedPodIPMap, err := getNodeHostToTappedPodIpsMap(currentlyTappedPods) @@ -114,7 +113,7 @@ func createMizuResources(ctx context.Context, kubernetesProvider *kubernetes.Pro func createMizuNamespace(ctx context.Context, kubernetesProvider *kubernetes.Provider) error { _, err := kubernetesProvider.CreateNamespace(ctx, mizu.ResourcesNamespace) if err != nil { - fmt.Printf("Error creating Namespace %s: %v\n", mizu.ResourcesNamespace, err) + mizu.Log.Infof("Error creating Namespace %s: %v\n", mizu.ResourcesNamespace, err) } return err @@ -132,13 +131,13 @@ func createMizuApiServer(ctx context.Context, kubernetesProvider *kubernetes.Pro } _, err = kubernetesProvider.CreateMizuApiServerPod(ctx, mizu.ResourcesNamespace, mizu.ApiServerPodName, tappingOptions.MizuImage, serviceAccountName, mizuApiFilteringOptions, tappingOptions.MaxEntriesDBSizeBytes) if err != nil { - fmt.Printf("Error creating mizu %s pod: %v\n", mizu.ApiServerPodName, err) + mizu.Log.Infof("Error creating mizu %s pod: %v\n", mizu.ApiServerPodName, err) return err } apiServerService, err = kubernetesProvider.CreateService(ctx, mizu.ResourcesNamespace, mizu.ApiServerPodName, mizu.ApiServerPodName) if err != nil { - fmt.Printf("Error creating mizu %s service: %v\n", mizu.ApiServerPodName, err) + mizu.Log.Infof("Error creating mizu %s service: %v\n", mizu.ApiServerPodName, err) return err } @@ -153,7 +152,7 @@ func getMizuApiFilteringOptions(tappingOptions *MizuTapOptions) (*shared.Traffic for _, regexStr := range tappingOptions.PlainTextFilterRegexes { compiledRegex, err := shared.CompileRegexToSerializableRegexp(regexStr) if err != nil { - fmt.Printf("Regex %s is invalid: %v", regexStr, err) + mizu.Log.Infof("Regex %s is invalid: %v", regexStr, err) return nil, err } compiledRegexSlice = append(compiledRegexSlice, compiledRegex) @@ -183,12 +182,12 @@ func updateMizuTappers(ctx context.Context, kubernetesProvider *kubernetes.Provi serviceAccountName, tappingOptions.TapOutgoing, ); err != nil { - fmt.Printf("Error creating mizu tapper daemonset: %v\n", err) + mizu.Log.Infof("Error creating mizu tapper daemonset: %v\n", err) return err } } else { if err := kubernetesProvider.RemoveDaemonSet(ctx, mizu.ResourcesNamespace, mizu.TapperDaemonSetName); err != nil { - fmt.Printf("Error deleting mizu tapper daemonset: %v\n", err) + mizu.Log.Infof("Error deleting mizu tapper daemonset: %v\n", err) return err } } @@ -197,19 +196,19 @@ func updateMizuTappers(ctx context.Context, kubernetesProvider *kubernetes.Provi } func cleanUpMizuResources(kubernetesProvider *kubernetes.Provider) { - fmt.Printf("\nRemoving mizu resources\n") + mizu.Log.Infof("\nRemoving mizu resources\n") removalCtx, cancel := context.WithTimeout(context.Background(), cleanupTimeout) defer cancel() if err := kubernetesProvider.RemoveNamespace(removalCtx, mizu.ResourcesNamespace); err != nil { - fmt.Printf("Error removing Namespace %s: %s (%v,%+v)\n", mizu.ResourcesNamespace, err, err, err) + mizu.Log.Infof("Error removing Namespace %s: %s (%v,%+v)\n", mizu.ResourcesNamespace, err, err, err) return } if mizuServiceAccountExists { if err := kubernetesProvider.RemoveNonNamespacedResources(removalCtx, mizu.ClusterRoleName, mizu.ClusterRoleBindingName); err != nil { - fmt.Printf("Error removing non-namespaced resources: %s (%v,%+v)\n", err, err, err) + mizu.Log.Infof("Error removing non-namespaced resources: %s (%v,%+v)\n", err, err, err) return } } @@ -224,9 +223,9 @@ func cleanUpMizuResources(kubernetesProvider *kubernetes.Provider) { case removalCtx.Err() == context.Canceled: // Do nothing. User interrupted the wait. case err == wait.ErrWaitTimeout: - fmt.Printf("Timeout while removing Namespace %s\n", mizu.ResourcesNamespace) + mizu.Log.Infof("Timeout while removing Namespace %s\n", mizu.ResourcesNamespace) default: - fmt.Printf("Error while waiting for Namespace %s to be deleted: %s (%v,%+v)\n", mizu.ResourcesNamespace, err, err, err) + mizu.Log.Infof("Error while waiting for Namespace %s to be deleted: %s (%v,%+v)\n", mizu.ResourcesNamespace, err, err, err) } } } @@ -238,7 +237,7 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro restartTappers := func() { if matchingPods, err := kubernetesProvider.GetAllPodsMatchingRegex(ctx, podRegex, targetNamespace); err != nil { - fmt.Printf("Error getting pods by regex: %s (%v,%+v)\n", err, err, err) + mizu.Log.Infof("Error getting pods by regex: %s (%v,%+v)\n", err, err, err) cancel() } else { currentlyTappedPods = matchingPods @@ -246,12 +245,12 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro nodeToTappedPodIPMap, err := getNodeHostToTappedPodIpsMap(currentlyTappedPods) if err != nil { - fmt.Printf("Error building node to ips map: %s (%v,%+v)\n", err, err, err) + mizu.Log.Infof("Error building node to ips map: %s (%v,%+v)\n", err, err, err) cancel() } if err := updateMizuTappers(ctx, kubernetesProvider, nodeToTappedPodIPMap, tappingOptions); err != nil { - fmt.Printf("Error updating daemonset: %s (%v,%+v)\n", err, err, err) + mizu.Log.Infof("Error updating daemonset: %s (%v,%+v)\n", err, err, err) cancel() } } @@ -260,10 +259,10 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro for { select { case newTarget := <-added: - fmt.Printf(mizu.Green, fmt.Sprintf("+%s\n", newTarget.Name)) + mizu.Log.Infof(mizu.Green, fmt.Sprintf("+%s\n", newTarget.Name)) case removedTarget := <-removed: - fmt.Printf(mizu.Red, fmt.Sprintf("-%s\n", removedTarget.Name)) + mizu.Log.Infof(mizu.Red, fmt.Sprintf("-%s\n", removedTarget.Name)) restartTappersDebouncer.SetOn() case modifiedTarget := <-modified: @@ -300,7 +299,7 @@ func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provi case <-added: continue case <-removed: - fmt.Printf("%s removed\n", mizu.ApiServerPodName) + mizu.Log.Infof("%s removed\n", mizu.ApiServerPodName) cancel() return case modifiedPod := <-modified: @@ -309,12 +308,12 @@ func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provi go func() { err := kubernetes.StartProxy(kubernetesProvider, tappingOptions.GuiPort, mizu.ResourcesNamespace, mizu.ApiServerPodName) if err != nil { - fmt.Printf("Error occured while running k8s proxy %v\n", err) + mizu.Log.Infof("Error occured while running k8s proxy %v\n", err) cancel() } }() mizuProxiedUrl := kubernetes.GetMizuApiServerProxiedHostAndPath(tappingOptions.GuiPort) - fmt.Printf("Mizu is available at http://%s\n", mizuProxiedUrl) + mizu.Log.Infof("Mizu is available at http://%s\n", mizuProxiedUrl) time.Sleep(time.Second * 5) // Waiting to be sure the proxy is ready if tappingOptions.Analysis { @@ -324,19 +323,18 @@ func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provi if err != nil { log.Fatal(fmt.Sprintf("Failed parsing the URL %v\n", err)) } - rlog.Debugf("Sending get request to %v\n", u.String()) + mizu.Log.Debugf("Sending get request to %v\n", u.String()) if response, err := http.Get(u.String()); err != nil || response.StatusCode != 200 { - fmt.Printf("error sending upload entries req, status code: %v, err: %v\n", response.StatusCode, err) + mizu.Log.Infof("error sending upload entries req, status code: %v, err: %v\n", response.StatusCode, err) } else { - fmt.Printf(mizu.Purple, "Traffic is uploading to UP9 for further analsys") - fmt.Println() + mizu.Log.Infof(mizu.Purple, "Traffic is uploading to UP9 for further analysis\n") } } } case <-timeAfter: if !isPodReady { - fmt.Printf("error: %s pod was not ready in time", mizu.ApiServerPodName) + mizu.Log.Infof("error: %s pod was not ready in time", mizu.ApiServerPodName) cancel() } @@ -349,13 +347,13 @@ func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provi func createRBACIfNecessary(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool { mizuRBACExists, err := kubernetesProvider.DoesServiceAccountExist(ctx, mizu.ResourcesNamespace, mizu.ServiceAccountName) if err != nil { - fmt.Printf("warning: could not ensure mizu rbac resources exist %v\n", err) + mizu.Log.Infof("warning: could not ensure mizu rbac resources exist %v\n", err) return false } if !mizuRBACExists { err := kubernetesProvider.CreateMizuRBAC(ctx, mizu.ResourcesNamespace, mizu.ServiceAccountName, mizu.ClusterRoleName, mizu.ClusterRoleBindingName, mizu.RBACVersion) if err != nil { - fmt.Printf("warning: could not create mizu rbac resources %v\n", err) + mizu.Log.Infof("warning: could not create mizu rbac resources %v\n", err) return false } } @@ -392,7 +390,7 @@ func syncApiStatus(ctx context.Context, cancel context.CancelFunc, tappingOption controlSocketStr := fmt.Sprintf("ws://%s/ws", kubernetes.GetMizuApiServerProxiedHostAndPath(tappingOptions.GuiPort)) controlSocket, err := mizu.CreateControlSocket(controlSocketStr) if err != nil { - fmt.Printf("error establishing control socket connection %s\n", err) + mizu.Log.Infof("error establishing control socket connection %s\n", err) cancel() } @@ -403,7 +401,7 @@ func syncApiStatus(ctx context.Context, cancel context.CancelFunc, tappingOption default: err = controlSocket.SendNewTappedPodsListMessage(currentlyTappedPods) if err != nil { - rlog.Debugf("error Sending message via control socket %v, error: %s\n", controlSocketStr, err) + mizu.Log.Debugf("error Sending message via control socket %v, error: %s\n", controlSocketStr, err) } time.Sleep(10 * time.Second) } diff --git a/cli/cmd/version.go b/cli/cmd/version.go index 4fd4b8bf1..dfe071c52 100644 --- a/cli/cmd/version.go +++ b/cli/cmd/version.go @@ -1,12 +1,10 @@ package cmd import ( - "fmt" + "github.com/spf13/cobra" "github.com/up9inc/mizu/cli/mizu" "strconv" "time" - - "github.com/spf13/cobra" ) type MizuVersionOptions struct { @@ -22,11 +20,11 @@ var versionCmd = &cobra.Command{ go mizu.ReportRun("version", mizuVersionOptions) if mizuVersionOptions.DebugInfo { timeStampInt, _ := strconv.ParseInt(mizu.BuildTimestamp, 10, 0) - fmt.Printf("Version: %s \nBranch: %s (%s) \n", mizu.SemVer, mizu.Branch, mizu.GitCommitHash) - fmt.Printf("Build Time: %s (%s)\n", mizu.BuildTimestamp, time.Unix(timeStampInt, 0)) + mizu.Log.Infof("Version: %s \nBranch: %s (%s) \n", mizu.SemVer, mizu.Branch, mizu.GitCommitHash) + mizu.Log.Infof("Build Time: %s (%s)\n", mizu.BuildTimestamp, time.Unix(timeStampInt, 0)) } else { - fmt.Printf("Version: %s (%s)\n", mizu.SemVer, mizu.Branch) + mizu.Log.Infof("Version: %s (%s)\n", mizu.SemVer, mizu.Branch) } return nil }, diff --git a/cli/cmd/viewRunner.go b/cli/cmd/viewRunner.go index d339010a7..cfa1fd657 100644 --- a/cli/cmd/viewRunner.go +++ b/cli/cmd/viewRunner.go @@ -13,11 +13,11 @@ func runMizuView(mizuViewOptions *MizuViewOptions) { kubernetesProvider, err := kubernetes.NewProvider(mizuViewOptions.KubeConfigPath) if err != nil { if clientcmd.IsEmptyConfig(err) { - fmt.Printf(mizu.Red, "Couldn't find the kube config file, or file is empty. Try adding '--kube-config='\n") + mizu.Log.Infof("Couldn't find the kube config file, or file is empty. Try adding '--kube-config='\n") return } if clientcmd.IsConfigurationInvalid(err) { - fmt.Printf(mizu.Red, "Invalid kube config file. Try using a different config with '--kube-config='\n") + mizu.Log.Infof(mizu.Red, "Invalid kube config file. Try using a different config with '--kube-config='\n") return } } @@ -30,21 +30,21 @@ func runMizuView(mizuViewOptions *MizuViewOptions) { panic(err) } if !exists { - fmt.Printf("The %s service not found\n", mizu.ApiServerPodName) + mizu.Log.Infof("The %s service not found\n", mizu.ApiServerPodName) return } mizuProxiedUrl := kubernetes.GetMizuApiServerProxiedHostAndPath(mizuViewOptions.GuiPort) _, err = http.Get(fmt.Sprintf("http://%s/", mizuProxiedUrl)) if err == nil { - fmt.Printf("Found a running service %s and open port %d\n", mizu.ApiServerPodName, mizuViewOptions.GuiPort) + mizu.Log.Infof("Found a running service %s and open port %d\n", mizu.ApiServerPodName, mizuViewOptions.GuiPort) return } - fmt.Printf("Found service %s, creating k8s proxy\n", mizu.ApiServerPodName) + mizu.Log.Infof("Found service %s, creating k8s proxy\n", mizu.ApiServerPodName) - fmt.Printf("Mizu is available at http://%s\n", kubernetes.GetMizuApiServerProxiedHostAndPath(mizuViewOptions.GuiPort)) + mizu.Log.Infof("Mizu is available at http://%s\n", kubernetes.GetMizuApiServerProxiedHostAndPath(mizuViewOptions.GuiPort)) err = kubernetes.StartProxy(kubernetesProvider, mizuViewOptions.GuiPort, mizu.ResourcesNamespace, mizu.ApiServerPodName) if err != nil { - fmt.Printf("Error occured while running k8s proxy %v\n", err) + mizu.Log.Infof("Error occured while running k8s proxy %v\n", err) } } diff --git a/cli/go.mod b/cli/go.mod index 1ad46fbf1..f7566a05f 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -5,7 +5,7 @@ go 1.16 require ( github.com/google/go-github/v37 v37.0.0 github.com/gorilla/websocket v1.4.2 - github.com/romana/rlog v0.0.0-20171115192701-f018bc92e7d7 + github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 github.com/spf13/cobra v1.1.3 github.com/up9inc/mizu/shared v0.0.0 k8s.io/api v0.21.2 diff --git a/cli/go.sum b/cli/go.sum index de1e9bcd7..d9a2b280c 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -333,6 +333,8 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= diff --git a/cli/kubernetes/provider.go b/cli/kubernetes/provider.go index bf40986c3..1fa057162 100644 --- a/cli/kubernetes/provider.go +++ b/cli/kubernetes/provider.go @@ -6,8 +6,10 @@ import ( "encoding/json" "errors" "fmt" + "github.com/up9inc/mizu/cli/mizu" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/homedir" "os" "path/filepath" "regexp" @@ -33,7 +35,6 @@ import ( "k8s.io/client-go/tools/clientcmd" _ "k8s.io/client-go/tools/portforward" watchtools "k8s.io/client-go/tools/watch" - "k8s.io/client-go/util/homedir" ) type Provider struct { @@ -618,6 +619,7 @@ func loadKubernetesConfiguration(kubeConfigPath string) clientcmd.ClientConfig { kubeConfigPath = filepath.Join(home, ".kube", "config") } + mizu.Log.Debugf("Using kube config %s", kubeConfigPath) configPathList := filepath.SplitList(kubeConfigPath) configLoadingRules := &clientcmd.ClientConfigLoadingRules{} if len(configPathList) <= 1 { diff --git a/cli/mizu.go b/cli/mizu.go index 7caa61604..d3ff3c55b 100644 --- a/cli/mizu.go +++ b/cli/mizu.go @@ -1,7 +1,11 @@ package main -import "github.com/up9inc/mizu/cli/cmd" +import ( + "github.com/up9inc/mizu/cli/cmd" + "github.com/up9inc/mizu/cli/mizu" +) func main() { + mizu.InitLogger() cmd.Execute() } diff --git a/cli/mizu/logger.go b/cli/mizu/logger.go new file mode 100644 index 000000000..9283f6e15 --- /dev/null +++ b/cli/mizu/logger.go @@ -0,0 +1,39 @@ +package mizu + +import ( + "fmt" + "github.com/op/go-logging" + "os" + "path" +) + +var Log = logging.MustGetLogger("mizu_cli") + +var format = logging.MustStringFormatter( + `%{time} %{level:.5s} â–¶ %{pid} %{shortfile} %{shortfunc} â–¶ %{message}`, +) + +func InitLogger() { + homeDirPath, err := os.UserHomeDir() + mizuDirPath := path.Join(homeDirPath, ".mizu") + if err := os.MkdirAll(mizuDirPath, os.ModePerm); err != nil { + panic(fmt.Sprintf("Failed creating .mizu dir: %v, err %v", mizuDirPath, err)) + } + logPath := path.Join(mizuDirPath, "log.log") + f, err := os.OpenFile(logPath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + panic(fmt.Sprintf("Failed mizu log file: %v, err %v", logPath, err)) + } + + fileLog := logging.NewLogBackend(f, "", 0) + consoleLog := logging.NewLogBackend(os.Stderr, "", 0) + + backend2Formatter := logging.NewBackendFormatter(fileLog, format) + + backend1Leveled := logging.AddModuleLevel(consoleLog) + backend1Leveled.SetLevel(logging.INFO, "") + + logging.SetBackend(backend1Leveled, backend2Formatter) + + Log.Debugf("Running mizu version %v", SemVer) +} diff --git a/cli/mizu/telemetry.go b/cli/mizu/telemetry.go index c1ac8fd1c..73aae4a28 100644 --- a/cli/mizu/telemetry.go +++ b/cli/mizu/telemetry.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/json" "fmt" - "github.com/romana/rlog" "net/http" ) @@ -12,7 +11,7 @@ const telemetryUrl = "https://us-east4-up9-prod.cloudfunctions.net/mizu-telemetr func ReportRun(cmd string, args interface{}) { if Branch != "main" { - rlog.Debugf("reporting only on main branch") + Log.Debugf("reporting only on main branch") return } argsBytes, _ := json.Marshal(args) @@ -29,8 +28,8 @@ func ReportRun(cmd string, args interface{}) { if resp, err := http.Post(telemetryUrl, "application/json", bytes.NewBuffer(jsonValue)); err != nil { - rlog.Debugf("error sending telemetry err: %v, response %v", err, resp) + Log.Debugf("error sending telemetry err: %v, response %v", err, resp) } else { - rlog.Debugf("Successfully reported telemetry") + Log.Debugf("Successfully reported telemetry") } } diff --git a/cli/mizu/versionCheck.go b/cli/mizu/versionCheck.go index b9d4f0913..cef0e790a 100644 --- a/cli/mizu/versionCheck.go +++ b/cli/mizu/versionCheck.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "github.com/google/go-github/v37/github" - "github.com/romana/rlog" "github.com/up9inc/mizu/shared" "github.com/up9inc/mizu/shared/semver" "io/ioutil" @@ -45,17 +44,17 @@ func CheckVersionCompatibility(port uint16) (bool, error) { return true, nil } - fmt.Printf(Red, fmt.Sprintf("cli version (%s) is not compatible with api version (%s)\n", SemVer, apiSemVer)) + Log.Infof(Red, fmt.Sprintf("cli version (%s) is not compatible with api version (%s)\n", SemVer, apiSemVer)) return false, nil } func CheckNewerVersion() { - rlog.Debugf("Checking for newer version...") + Log.Debugf("Checking for newer version...") start := time.Now() client := github.NewClient(nil) latestRelease, _, err := client.Repositories.GetLatestRelease(context.Background(), "up9inc", "mizu") if err != nil { - rlog.Debugf("Failed to get latest release") + Log.Debugf("Failed to get latest release") return } @@ -67,26 +66,26 @@ func CheckNewerVersion() { } } if versionFileUrl == "" { - rlog.Debugf("Version file not found in the latest release") + Log.Debugf("Version file not found in the latest release") return } res, err := http.Get(versionFileUrl) if err != nil { - rlog.Debugf("http.Get version asset -> %v", err) + Log.Debugf("http.Get version asset -> %v", err) return } data, err := ioutil.ReadAll(res.Body) res.Body.Close() if err != nil { - rlog.Debugf("ioutil.ReadAll -> %v", err) + Log.Debugf("ioutil.ReadAll -> %v", err) return } gitHubVersion := string(data) gitHubVersion = gitHubVersion[:len(gitHubVersion)-1] - rlog.Debugf("Finished version validation, took %v", time.Since(start)) + Log.Debugf("Finished version validation, took %v", time.Since(start)) if SemVer < gitHubVersion { - fmt.Printf(Yellow, fmt.Sprintf("Update available! %v -> %v (%v)\n", SemVer, gitHubVersion, *latestRelease.HTMLURL)) + Log.Infof(Yellow, fmt.Sprintf("Update available! %v -> %v (%v)\n", SemVer, gitHubVersion, *latestRelease.HTMLURL)) } } diff --git a/cli/uiUtils/confirmation.go b/cli/uiUtils/confirmation.go index 06b912431..7a0da1aac 100644 --- a/cli/uiUtils/confirmation.go +++ b/cli/uiUtils/confirmation.go @@ -2,7 +2,6 @@ package uiUtils import ( "bufio" - "fmt" "github.com/up9inc/mizu/cli/mizu" "log" "os" @@ -12,7 +11,7 @@ import ( func AskForConfirmation(s string) bool { reader := bufio.NewReader(os.Stdin) - fmt.Printf(mizu.Magenta, s) + mizu.Log.Infof(mizu.Magenta, s) response, err := reader.ReadString('\n') if err != nil { From 6dd2bf705b0fce79cfe6e0790122470a7510326d Mon Sep 17 00:00:00 2001 From: RamiBerm <54766858+RamiBerm@users.noreply.github.com> Date: Sun, 25 Jul 2021 13:08:29 +0300 Subject: [PATCH 31/69] TRA-3437 switch fiber and ikisocket with gin-gonic and gorilla websocket (#136) * WIP * WIP * WIP * Update socket_server_handlers.go and socket_routes.go * Fix stuck sockets * Update go.mod, go.sum, and 5 more files... * Update socket_routes.go * Update Dockerfile, go.sum, and fiber_middleware.go * fix analyze Co-authored-by: RamiBerm --- Dockerfile | 3 + agent/go.mod | 6 +- agent/go.sum | 172 ++---------------- agent/main.go | 42 +++-- agent/pkg/api/socket_server_handlers.go | 63 +++---- agent/pkg/controllers/entries_controller.go | 69 +++---- agent/pkg/controllers/metadata_controller.go | 7 +- agent/pkg/controllers/resolving_controller.go | 7 +- agent/pkg/controllers/status_controller.go | 11 +- agent/pkg/middleware/fiber_middleware.go | 18 -- agent/pkg/models/models.go | 4 +- agent/pkg/routes/entries_routes.go | 26 +-- agent/pkg/routes/metadata_routes.go | 8 +- agent/pkg/routes/not_found_route.go | 13 +- agent/pkg/routes/socket_routes.go | 131 ++++++++++--- agent/pkg/utils/utils.go | 18 +- 16 files changed, 284 insertions(+), 314 deletions(-) delete mode 100644 agent/pkg/middleware/fiber_middleware.go diff --git a/Dockerfile b/Dockerfile index 7a15bd2b8..c19b1805f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -50,5 +50,8 @@ COPY --from=site-build ["/app/ui-build/build", "site"] COPY agent/start.sh . +# gin-gonic runs in debug mode without this +ENV GIN_MODE=release + # this script runs both apiserver and passivetapper and exits either if one of them exits, preventing a scenario where the container runs without one process ENTRYPOINT "/app/mizuagent" diff --git a/agent/go.mod b/agent/go.mod index 2a17b4b69..9c44390ee 100644 --- a/agent/go.mod +++ b/agent/go.mod @@ -3,18 +3,16 @@ module mizuserver go 1.16 require ( - github.com/antoniodipinto/ikisocket v0.0.0-20210719144512-dce3f3fbbd04 github.com/beevik/etree v1.1.0 github.com/djherbis/atime v1.0.0 - github.com/fasthttp/websocket v1.4.3-beta.1 // indirect github.com/fsnotify/fsnotify v1.4.9 + github.com/gin-contrib/static v0.0.1 + github.com/gin-gonic/gin v1.7.2 github.com/go-playground/locales v0.13.0 github.com/go-playground/universal-translator v0.17.0 github.com/go-playground/validator/v10 v10.5.0 - github.com/gofiber/fiber/v2 v2.10.0 github.com/google/martian v2.1.0+incompatible github.com/gorilla/websocket v1.4.2 - github.com/leodido/go-urn v1.2.1 // indirect github.com/romana/rlog v0.0.0-20171115192701-f018bc92e7d7 github.com/up9inc/mizu/shared v0.0.0 github.com/up9inc/mizu/tap v0.0.0 diff --git a/agent/go.sum b/agent/go.sum index afc27da11..e452527af 100644 --- a/agent/go.sum +++ b/agent/go.sum @@ -12,20 +12,15 @@ cloud.google.com/go v0.54.0 h1:3ithwDMr7/3vpAMXiH+ZQnYbuIsh+OPhUPMFC9enmn0= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0 h1:xE3CPsOgttP4ACBePh79zTKALtXwn/Edhcr16R5hMWU= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0 h1:Lpy6hKgdcl7a3WGSfJIFmxmcdjSpP6OmBEfcOv1Y680= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0 h1:UDpwYIwla4jHGzZJaEJYx1tOejbgSoNqsAfHAUYe2r8= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= @@ -41,38 +36,20 @@ github.com/Azure/go-autorest/logger v0.2.0 h1:e4RVHVZKC5p6UANLJHkM4OfR1UKZPj8Wt8 github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 h1:lsxEuwrXEAokXB9qhlbKWPpo3KMLZQ5WB5WLQRW1uq0= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= -github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= -github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= -github.com/antoniodipinto/ikisocket v0.0.0-20210719144512-dce3f3fbbd04 h1:ru0T8O1coJ21vbtzangy+W6IpCaCQlLxLFr7eHffY3I= -github.com/antoniodipinto/ikisocket v0.0.0-20210719144512-dce3f3fbbd04/go.mod h1:IRtlQDKcJq80t7y6JzYOBKMpHliAHd0dmu7hOhAXU9c= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/aws/aws-sdk-go v1.34.28 h1:sscPpn/Ns3i0F4HPEWAVcwdIRaZZCuL7llJ2/60yPIk= github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= -github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -81,45 +58,36 @@ github.com/djherbis/atime v1.0.0 h1:ySLvBAM0EvOGaX7TI4dAM5lWj+RdJUCKtGSEHN8SGBg= github.com/djherbis/atime v1.0.0/go.mod h1:5W+KBIuTwVGcqjIfaTwt+KSYX1o6uep8dtevevQP/f8= 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/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1/YsqVWoWNLQO+fusocsw354rqGTZtAgw= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473 h1:4cmBvAEBNJaGARUEs3/suWRyfyBfhf7I60WBZq+bv2w= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/fasthttp/websocket v0.0.0-20200320073529-1554a54587ab/go.mod h1:smsv/h4PBEBaU0XDTY5UwJTpZv69fQ0FfcLJr21mA6Y= -github.com/fasthttp/websocket v1.4.2/go.mod h1:smsv/h4PBEBaU0XDTY5UwJTpZv69fQ0FfcLJr21mA6Y= -github.com/fasthttp/websocket v1.4.3-beta.1 h1:stc4P2aoxYKsdmbe1AJ5mAm73Fxc1NOgrZpPftvZIXQ= -github.com/fasthttp/websocket v1.4.3-beta.1/go.mod h1:JGrgLaT02bL9NuJkZbHN8mVV2tkCJZQh7yJ5/XCXO2g= github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-contrib/static v0.0.1 h1:JVxuvHPuUfkoul12N7dtQw7KRn/pSMq7Ue1Va9Swm1U= +github.com/gin-contrib/static v0.0.1/go.mod h1:CSxeF+wep05e0kCOsqWdAWbSszmc31zTIbD8TvWl7Hs= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.7.2 h1:Tg03T9yM2xa8j6I3Z3oqLaQRSmKvxPd6g/2HJ6zICFA= +github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc= github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= -github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -127,65 +95,46 @@ github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8c github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-playground/validator/v10 v10.5.0 h1:X9rflw/KmpACwT8zdrm1upefpvdy6ur8d1kWyq6sg3E= github.com/go-playground/validator/v10 v10.5.0/go.mod h1:xm76BBt941f7yWdGnI2DVPFFg1UK3YY04qifoXU3lOk= -github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd h1:hSkbZ9XSyjyBirMeqSqUrK+9HboWrweVlzRNqoBi2d4= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= -github.com/gobuffalo/depgen v0.1.0 h1:31atYa/UW9V5q8vMJ+W6wd64OaaTHUrCUXER358zLM4= github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.0 h1:GlXgaiBkmrYMHco6t4j7SacKO4XUjvh5pwXh0f4uxXU= github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/flect v0.1.3 h1:3GQ53z7E3o00C/yy7Ko8VXqQXoJGLkrTQCLTF1EjoXU= github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= -github.com/gobuffalo/genny v0.1.1 h1:iQ0D6SpNXIxu52WESsD+KoQ7af2e3nCfnSBoSF/hKe0= github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= -github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211 h1:mSVZ4vj4khv+oThUfS+SQU3UuFIZ5Zo6UNcvK8E8Mz8= github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= -github.com/gobuffalo/gogen v0.1.1 h1:dLg+zb+uOyd/mKeQUYIbwbNmfRsr9hd/WtYWepmayhI= github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= -github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2 h1:8thhT+kUJMTMy3HlX4+y9Da+BNJck+p109tqqKp7WDs= github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/mapi v1.0.2 h1:fq9WcL1BYrm36SzK6+aAnZ8hcp+SrmnDyAxhNx8dvJk= github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packd v0.1.0 h1:4sGKOD8yaYJ+dek1FDkwcxCHA40M4kfKgFHx8N2kwbU= github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= -github.com/gobuffalo/packr/v2 v2.2.0 h1:Ir9W9XIm9j7bhhkKE9cokvtTl1vBm62A/fene/ZCj6A= github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= -github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754 h1:tpom+2CJmpzAWj5/VEHync2rJGi+epHNIeRSWjzGA+4= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= -github.com/gofiber/fiber/v2 v2.10.0 h1:cYwonWaFVa7wBd/LKhgKu7mFNg2CHv5ztY6gzXtrvW8= -github.com/gofiber/fiber/v2 v2.10.0/go.mod h1:Ah3IJikrKNRepl/HuVawppS25X7FWohwfCSRn7kJG28= -github.com/gofiber/websocket/v2 v2.0.4 h1:HvnHekk2dOX8mpqXkuVy5xkON/CkRqLkN5xPHv5pOyM= -github.com/gofiber/websocket/v2 v2.0.4/go.mod h1:qkOGMb5BTRkximKNgPWSSdUBX46yS447xcbL12JGFZM= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1 h1:ocYkMQY5RrXTYgXl7ICpV0IXwlEQGwKIsery4gyXa1U= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 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= @@ -200,10 +149,8 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -223,92 +170,62 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3 h1:SRgJV+IoxM5MKyFdlSUeNy6/ycRUF2yBAKdAQswoHUk= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= -github.com/karrick/godirwalk v1.10.3 h1:lOpSw2vJP0y5eLBW906QwKsUK/fe/QDyoqM5rnnuPDY= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= -github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.13 h1:eSvu8Tmq6j2psUJqJrLcWH6K3w5Dwc+qipbaA6eVEN4= -github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5 h1:hyz3dwM5QLc1Rfoz4FuWJQG5BN7tc6K1MndAUnGpQr4= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= -github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2 h1:JgVTCPf0uBVcUSWpyXmGpgOc62nK5HWUBKAGc3Qqa5k= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= -github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ= github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -316,51 +233,35 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d h1:7PxY7LVfSZm7PEeBTyK1rj1gABdCO2mbri6GKO1cMDs= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/orcaman/concurrent-map v0.0.0-20210106121528-16402b402231 h1:fa50YL1pzKW+1SsBnJDOHppJN9stOEwS+CRWyUtyYGU= github.com/orcaman/concurrent-map v0.0.0-20210106121528-16402b402231/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= -github.com/pelletier/go-toml v1.7.0 h1:7utD74fnzVc/cpcyy8sjrlFr5vYpypUixARcHIMIGuI= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/romana/rlog v0.0.0-20171115192701-f018bc92e7d7 h1:jkvpcEatpwuMF5O5LVxTnehj6YZ/aEZN4NWD/Xml4pI= github.com/romana/rlog v0.0.0-20171115192701-f018bc92e7d7/go.mod h1:KTrHyWpO1sevuXPZwyeZc72ddWRFqNSKDFl7uVWKpg0= -github.com/savsgio/gotils v0.0.0-20200117113501-90175b0fbe3f/go.mod h1:lHhJedqxCoHN+zMtwGNTXWmF0u9Jt363FYRhV6g0CdY= -github.com/savsgio/gotils v0.0.0-20200616100644-13ff1fd2c28c h1:KKqhycXW1WVNkX7r4ekTV2gFkbhdyihlWD8c0/FiWmk= -github.com/savsgio/gotils v0.0.0-20200616100644-13ff1fd2c28c/go.mod h1:TWNAOTaVzGOXq8RbEvHnhzA/A2sLZzgn0m6URjnukY8= github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -368,42 +269,28 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.9.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= -github.com/valyala/fasthttp v1.15.1/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= -github.com/valyala/fasthttp v1.23.0/go.mod h1:0mw2RjXGOzxf4NL2jni3gUQ7LfjjUSiG5sskOUUSEpU= -github.com/valyala/fasthttp v1.24.0 h1:AAiG4oLDUArTb7rYf9oO2bkGooOqCaUF6a2u8asBP3I= -github.com/valyala/fasthttp v1.24.0/go.mod h1:0mw2RjXGOzxf4NL2jni3gUQ7LfjjUSiG5sskOUUSEpU= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= -github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.mongodb.org/mongo-driver v1.5.1 h1:9nOVLGDfOaZ9R0tBumx/BcuqkbFpyTCU2r/Po7A2azI= go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -426,10 +313,8 @@ golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -440,17 +325,14 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 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= @@ -473,10 +355,8 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226101413-39120d07d75e/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210421230115-4e50805a0758 h1:aEpZnXcAmXkd6AvLb2OPt+EN1Zu/8Ne3pCqPjja5PXY= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -492,7 +372,6 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -516,13 +395,13 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -582,7 +461,6 @@ golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -598,7 +476,6 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0 h1:jz2KixHX7EcCPiQrySzPdnYT7DbINAypCqKZ1Z7GM40= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -624,7 +501,6 @@ google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4 google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -632,7 +508,6 @@ google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -649,13 +524,10 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -674,7 +546,6 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.21.0 h1:gu5iGF4V6tfVCQ/R+8Hc0h7H1JuEhzyEi9S4R5LM8+Y= k8s.io/api v0.21.0/go.mod h1:+YbrhBBGgsxbF6o6Kj4KJPJnBmAKuXDeS3E18bgHNVU= @@ -682,20 +553,15 @@ k8s.io/apimachinery v0.21.0 h1:3Fx+41if+IRavNcKOz09FwEXDBG6ORh6iMsTSelhkMA= k8s.io/apimachinery v0.21.0/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= k8s.io/client-go v0.21.0 h1:n0zzzJsAQmJngpC0IhgFcApZyoGXPrDIAD601HD09ag= k8s.io/client-go v0.21.0/go.mod h1:nNBytTF9qPFDEhoqgEPaarobC8QPae13bElIVHzIglA= -k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac h1:sAvhNk5RRuc6FNYGqe7Ygz3PSo/2wGWbulskmzRX8Vs= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts= k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 h1:vEx13qjvaZ4yfObSSXW7BrMc/KQBBT/Jyee8XtLf4x0= k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8= diff --git a/agent/main.go b/agent/main.go index 5ea036aa5..84baf3b0f 100644 --- a/agent/main.go +++ b/agent/main.go @@ -4,18 +4,18 @@ import ( "encoding/json" "flag" "fmt" - "github.com/gofiber/fiber/v2" - "github.com/gofiber/fiber/v2/middleware/cors" + "github.com/gin-contrib/static" + "github.com/gin-gonic/gin" "github.com/gorilla/websocket" "github.com/romana/rlog" "github.com/up9inc/mizu/shared" "github.com/up9inc/mizu/tap" "mizuserver/pkg/api" - "mizuserver/pkg/middleware" "mizuserver/pkg/models" "mizuserver/pkg/routes" "mizuserver/pkg/sensitiveDataFiltering" "mizuserver/pkg/utils" + "net/http" "os" "os/signal" "strings" @@ -82,23 +82,19 @@ func main() { } func hostApi(socketHarOutputChannel chan<- *tap.OutputChannelItem) { - app := fiber.New() + app := gin.Default() - app.Use(cors.New(cors.Config{ - AllowOrigins: "*", - AllowMethods: "*", - AllowHeaders: "*", - })) - middleware.FiberMiddleware(app) // Register Fiber's middleware for app. - app.Static("/", "./site") - - //Simple route to know server is running - app.Get("/echo", func(c *fiber.Ctx) error { - return c.SendString("Hello, World 👋!") + app.GET("/echo", func(c *gin.Context) { + c.String(http.StatusOK, "Hello, World 👋!") }) + eventHandlers := api.RoutesEventHandlers{ SocketHarOutChannel: socketHarOutputChannel, } + + app.Use(static.ServeRoot("/", "./site")) + app.Use(CORSMiddleware()) // This has to be called after the static middleware, does not work if its called before + routes.WebSocketRoutes(app, &eventHandlers) routes.EntriesRoutes(app) routes.MetadataRoutes(app) @@ -107,6 +103,22 @@ func hostApi(socketHarOutputChannel chan<- *tap.OutputChannelItem) { utils.StartServer(app) } +func CORSMiddleware() gin.HandlerFunc { + return func(c *gin.Context) { + c.Writer.Header().Set("Access-Control-Allow-Origin", "*") + c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") + c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") + c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT") + + if c.Request.Method == "OPTIONS" { + c.AbortWithStatus(204) + return + } + + c.Next() + } +} + func getTapTargets() []string { nodeName := os.Getenv(shared.NodeNameEnvVar) var tappedAddressesPerNodeDict map[string][]string diff --git a/agent/pkg/api/socket_server_handlers.go b/agent/pkg/api/socket_server_handlers.go index c705bb9e3..c2fa7c628 100644 --- a/agent/pkg/api/socket_server_handlers.go +++ b/agent/pkg/api/socket_server_handlers.go @@ -2,7 +2,7 @@ package api import ( "encoding/json" - "github.com/antoniodipinto/ikisocket" + "fmt" "github.com/romana/rlog" "github.com/up9inc/mizu/shared" "github.com/up9inc/mizu/tap" @@ -10,9 +10,11 @@ import ( "mizuserver/pkg/models" "mizuserver/pkg/routes" "mizuserver/pkg/up9" + "sync" ) -var browserClientSocketUUIDs = make([]string, 0) +var browserClientSocketUUIDs = make([]int, 0) +var socketListLock = sync.Mutex{} type RoutesEventHandlers struct { routes.EventHandlers @@ -23,51 +25,50 @@ func init() { go up9.UpdateAnalyzeStatus(broadcastToBrowserClients) } -func (h *RoutesEventHandlers) WebSocketConnect(ep *ikisocket.EventPayload) { - if ep.Kws.GetAttribute("is_tapper") == true { - rlog.Infof("Websocket Connection event - Tapper connected: %s", ep.SocketUUID) +func (h *RoutesEventHandlers) WebSocketConnect(socketId int, isTapper bool) { + if isTapper { + rlog.Infof("Websocket Connection event - Tapper connected: %s", socketId) } else { - rlog.Infof("Websocket Connection event - Browser socket connected: %s", ep.SocketUUID) - browserClientSocketUUIDs = append(browserClientSocketUUIDs, ep.SocketUUID) + rlog.Infof("Websocket Connection event - Browser socket connected: %s", socketId) + socketListLock.Lock() + browserClientSocketUUIDs = append(browserClientSocketUUIDs, socketId) + socketListLock.Unlock() } } -func (h *RoutesEventHandlers) WebSocketDisconnect(ep *ikisocket.EventPayload) { - if ep.Kws.GetAttribute("is_tapper") == true { - rlog.Infof("Disconnection event - Tapper connected: %s", ep.SocketUUID) +func (h *RoutesEventHandlers) WebSocketDisconnect(socketId int, isTapper bool) { + if isTapper { + rlog.Infof("Disconnection event - Tapper connected: %s", socketId) } else { - rlog.Infof("Disconnection event - Browser socket connected: %s", ep.SocketUUID) - removeSocketUUIDFromBrowserSlice(ep.SocketUUID) + rlog.Infof("Disconnection event - Browser socket connected: %s", socketId) + socketListLock.Lock() + removeSocketUUIDFromBrowserSlice(socketId) + socketListLock.Unlock() } } func broadcastToBrowserClients(message []byte) { - ikisocket.EmitToList(browserClientSocketUUIDs, message) -} + for _, socketId := range browserClientSocketUUIDs { + go func(socketId int) { + err := routes.SendToSocket(socketId, message) + if err != nil { + fmt.Printf("error sending message to socket id %d: %v", socketId, err) + } + }(socketId) -func (h *RoutesEventHandlers) WebSocketClose(ep *ikisocket.EventPayload) { - if ep.Kws.GetAttribute("is_tapper") == true { - rlog.Infof("Websocket Close event - Tapper connected: %s", ep.SocketUUID) - } else { - rlog.Infof("Websocket Close event - Browser socket connected: %s", ep.SocketUUID) - removeSocketUUIDFromBrowserSlice(ep.SocketUUID) } } -func (h *RoutesEventHandlers) WebSocketError(ep *ikisocket.EventPayload) { - rlog.Infof("Socket error - Socket uuid : %s %v", ep.SocketUUID, ep.Error) -} - -func (h *RoutesEventHandlers) WebSocketMessage(ep *ikisocket.EventPayload) { +func (h *RoutesEventHandlers) WebSocketMessage(_ int, message []byte) { var socketMessageBase shared.WebSocketMessageMetadata - err := json.Unmarshal(ep.Data, &socketMessageBase) + err := json.Unmarshal(message, &socketMessageBase) if err != nil { rlog.Infof("Could not unmarshal websocket message %v\n", err) } else { switch socketMessageBase.MessageType { case shared.WebSocketMessageTypeTappedEntry: var tappedEntryMessage models.WebSocketTappedEntryMessage - err := json.Unmarshal(ep.Data, &tappedEntryMessage) + err := json.Unmarshal(message, &tappedEntryMessage) if err != nil { rlog.Infof("Could not unmarshal message of message type %s %v\n", socketMessageBase.MessageType, err) } else { @@ -75,12 +76,12 @@ func (h *RoutesEventHandlers) WebSocketMessage(ep *ikisocket.EventPayload) { } case shared.WebSocketMessageTypeUpdateStatus: var statusMessage shared.WebSocketStatusMessage - err := json.Unmarshal(ep.Data, &statusMessage) + err := json.Unmarshal(message, &statusMessage) if err != nil { rlog.Infof("Could not unmarshal message of message type %s %v\n", socketMessageBase.MessageType, err) } else { controllers.TapStatus = statusMessage.TappingStatus - broadcastToBrowserClients(ep.Data) + broadcastToBrowserClients(message) } default: rlog.Infof("Received socket message of type %s for which no handlers are defined", socketMessageBase.MessageType) @@ -88,8 +89,8 @@ func (h *RoutesEventHandlers) WebSocketMessage(ep *ikisocket.EventPayload) { } } -func removeSocketUUIDFromBrowserSlice(uuidToRemove string) { - newUUIDSlice := make([]string, 0, len(browserClientSocketUUIDs)) +func removeSocketUUIDFromBrowserSlice(uuidToRemove int) { + newUUIDSlice := make([]int, 0, len(browserClientSocketUUIDs)) for _, uuid := range browserClientSocketUUIDs { if uuid != uuidToRemove { newUUIDSlice = append(newUUIDSlice, uuid) diff --git a/agent/pkg/controllers/entries_controller.go b/agent/pkg/controllers/entries_controller.go index af96feb18..57dc611e9 100644 --- a/agent/pkg/controllers/entries_controller.go +++ b/agent/pkg/controllers/entries_controller.go @@ -3,7 +3,7 @@ package controllers import ( "encoding/json" "fmt" - "github.com/gofiber/fiber/v2" + "github.com/gin-gonic/gin" "github.com/google/martian/har" "github.com/romana/rlog" "mizuserver/pkg/database" @@ -11,19 +11,20 @@ import ( "mizuserver/pkg/up9" "mizuserver/pkg/utils" "mizuserver/pkg/validation" + "net/http" "strings" "time" ) -func GetEntries(c *fiber.Ctx) error { +func GetEntries(c *gin.Context) { entriesFilter := &models.EntriesFilter{} - if err := c.QueryParser(entriesFilter); err != nil { - return c.Status(fiber.StatusBadRequest).JSON(err) + if err := c.BindQuery(entriesFilter); err != nil { + c.JSON(http.StatusBadRequest, err) } err := validation.Validate(entriesFilter) if err != nil { - return c.Status(fiber.StatusBadRequest).JSON(err) + c.JSON(http.StatusBadRequest, err) } order := database.OperatorToOrderMapping[entriesFilter.Operator] @@ -50,18 +51,18 @@ func GetEntries(c *fiber.Ctx) error { baseEntries = append(baseEntries, harEntry) } - return c.Status(fiber.StatusOK).JSON(baseEntries) + c.JSON(http.StatusOK, baseEntries) } -func GetHARs(c *fiber.Ctx) error { +func GetHARs(c *gin.Context) { entriesFilter := &models.HarFetchRequestBody{} order := database.OrderDesc - if err := c.QueryParser(entriesFilter); err != nil { - return c.Status(fiber.StatusBadRequest).JSON(err) + if err := c.BindQuery(entriesFilter); err != nil { + c.JSON(http.StatusBadRequest, err) } err := validation.Validate(entriesFilter) if err != nil { - return c.Status(fiber.StatusBadRequest).JSON(err) + c.JSON(http.StatusBadRequest, err) } var timestampFrom, timestampTo int64 @@ -137,40 +138,45 @@ func GetHARs(c *fiber.Ctx) error { retObj[k] = bytesData } buffer := utils.ZipData(retObj) - return c.Status(fiber.StatusOK).SendStream(buffer) + c.Data(http.StatusOK, "application/octet-stream", buffer.Bytes()) } -func UploadEntries(c *fiber.Ctx) error { +func UploadEntries(c *gin.Context) { rlog.Infof("Upload entries - started\n") uploadRequestBody := &models.UploadEntriesRequestBody{} - if err := c.QueryParser(uploadRequestBody); err != nil { - return c.Status(fiber.StatusBadRequest).JSON(err) + if err := c.BindQuery(uploadRequestBody); err != nil { + c.JSON(http.StatusBadRequest, err) + return } if err := validation.Validate(uploadRequestBody); err != nil { - return c.Status(fiber.StatusBadRequest).JSON(err) + c.JSON(http.StatusBadRequest, err) + return } if up9.GetAnalyzeInfo().IsAnalyzing { - return c.Status(fiber.StatusBadRequest).SendString("Cannot analyze, mizu is already analyzing") + c.String(http.StatusBadRequest, "Cannot analyze, mizu is already analyzing") + return } + rlog.Infof("Upload entries - creating token. dest %s\n", uploadRequestBody.Dest) token, err := up9.CreateAnonymousToken(uploadRequestBody.Dest) if err != nil { - return c.Status(fiber.StatusServiceUnavailable).SendString("Can't get token") + c.String(http.StatusServiceUnavailable, "Cannot analyze, mizu is already analyzing") + return } rlog.Infof("Upload entries - uploading. token: %s model: %s\n", token.Token, token.Model) go up9.UploadEntriesImpl(token.Token, token.Model, uploadRequestBody.Dest, uploadRequestBody.SleepIntervalSec) - return c.Status(fiber.StatusOK).SendString("OK") + c.String(http.StatusOK, "OK") } -func GetFullEntries(c *fiber.Ctx) error { +func GetFullEntries(c *gin.Context) { entriesFilter := &models.HarFetchRequestBody{} - if err := c.QueryParser(entriesFilter); err != nil { - return c.Status(fiber.StatusBadRequest).JSON(err) + if err := c.BindQuery(entriesFilter); err != nil { + c.JSON(http.StatusBadRequest, err) } err := validation.Validate(entriesFilter) if err != nil { - return c.Status(fiber.StatusBadRequest).JSON(err) + c.JSON(http.StatusBadRequest, err) } var timestampFrom, timestampTo int64 @@ -195,38 +201,37 @@ func GetFullEntries(c *fiber.Ctx) error { } result = append(result, harEntry) } - - return c.Status(fiber.StatusOK).JSON(result) + c.JSON(http.StatusOK, result) } -func GetEntry(c *fiber.Ctx) error { +func GetEntry(c *gin.Context) { var entryData models.MizuEntry database.GetEntriesTable(). - Where(map[string]string{"entryId": c.Params("entryId")}). + Where(map[string]string{"entryId": c.Param("entryId")}). First(&entryData) fullEntry := models.FullEntryDetails{} if err := models.GetEntry(&entryData, &fullEntry); err != nil { - return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + c.JSON(http.StatusInternalServerError, map[string]interface{}{ "error": true, "msg": "Can't get entry details", }) } - return c.Status(fiber.StatusOK).JSON(fullEntry) + c.JSON(http.StatusOK, fullEntry) } -func DeleteAllEntries(c *fiber.Ctx) error { +func DeleteAllEntries(c *gin.Context) { database.GetEntriesTable(). Where("1 = 1"). Delete(&models.MizuEntry{}) - return c.Status(fiber.StatusOK).JSON(fiber.Map{ + c.JSON(http.StatusOK, map[string]string{ "msg": "Success", }) } -func GetGeneralStats(c *fiber.Ctx) error { +func GetGeneralStats(c *gin.Context) { sqlQuery := "SELECT count(*) as count, min(timestamp) as min, max(timestamp) as max from mizu_entries" var result struct { Count int @@ -234,5 +239,5 @@ func GetGeneralStats(c *fiber.Ctx) error { Max int } database.GetEntriesTable().Raw(sqlQuery).Scan(&result) - return c.Status(fiber.StatusOK).JSON(&result) + c.JSON(http.StatusOK, result) } diff --git a/agent/pkg/controllers/metadata_controller.go b/agent/pkg/controllers/metadata_controller.go index 702e682b4..37de565c8 100644 --- a/agent/pkg/controllers/metadata_controller.go +++ b/agent/pkg/controllers/metadata_controller.go @@ -1,12 +1,13 @@ package controllers import ( - "github.com/gofiber/fiber/v2" + "github.com/gin-gonic/gin" "github.com/up9inc/mizu/shared" "mizuserver/pkg/version" + "net/http" ) -func GetVersion(c *fiber.Ctx) error { +func GetVersion(c *gin.Context) { resp := shared.VersionResponse{SemVer: version.SemVer} - return c.Status(fiber.StatusOK).JSON(resp) + c.JSON(http.StatusOK, resp) } diff --git a/agent/pkg/controllers/resolving_controller.go b/agent/pkg/controllers/resolving_controller.go index cdd3df4f5..dd9cc08bf 100644 --- a/agent/pkg/controllers/resolving_controller.go +++ b/agent/pkg/controllers/resolving_controller.go @@ -1,11 +1,12 @@ package controllers import ( - "github.com/gofiber/fiber/v2" + "github.com/gin-gonic/gin" "mizuserver/pkg/holder" + "net/http" ) -func GetCurrentResolvingInformation(c *fiber.Ctx) error { - return c.Status(fiber.StatusOK).JSON(holder.GetResolver().GetMap()) +func GetCurrentResolvingInformation(c *gin.Context) { + c.JSON(http.StatusOK, holder.GetResolver().GetMap()) } diff --git a/agent/pkg/controllers/status_controller.go b/agent/pkg/controllers/status_controller.go index e4fed4c55..88c29e82f 100644 --- a/agent/pkg/controllers/status_controller.go +++ b/agent/pkg/controllers/status_controller.go @@ -1,17 +1,18 @@ package controllers import ( - "github.com/gofiber/fiber/v2" + "github.com/gin-gonic/gin" "github.com/up9inc/mizu/shared" "mizuserver/pkg/up9" + "net/http" ) var TapStatus shared.TapStatus -func GetTappingStatus(c *fiber.Ctx) error { - return c.Status(fiber.StatusOK).JSON(TapStatus) +func GetTappingStatus(c *gin.Context) { + c.JSON(http.StatusOK, TapStatus) } -func AnalyzeInformation(c *fiber.Ctx) error { - return c.Status(fiber.StatusOK).JSON(up9.GetAnalyzeInfo()) +func AnalyzeInformation(c *gin.Context) { + c.JSON(http.StatusOK, up9.GetAnalyzeInfo()) } diff --git a/agent/pkg/middleware/fiber_middleware.go b/agent/pkg/middleware/fiber_middleware.go deleted file mode 100644 index 24bc453a7..000000000 --- a/agent/pkg/middleware/fiber_middleware.go +++ /dev/null @@ -1,18 +0,0 @@ -package middleware - -import ( - "github.com/gofiber/fiber/v2" - "github.com/gofiber/fiber/v2/middleware/cors" - "github.com/gofiber/fiber/v2/middleware/logger" -) - -// FiberMiddleware provide Fiber's built-in middlewares. -// See: https://docs.gofiber.io/api/middleware -func FiberMiddleware(a *fiber.App) { - a.Use( - // Add CORS to each route. - cors.New(), - // Add simple logger. - logger.New(), - ) -} diff --git a/agent/pkg/models/models.go b/agent/pkg/models/models.go index c12119db9..40be49bc1 100644 --- a/agent/pkg/models/models.go +++ b/agent/pkg/models/models.go @@ -113,8 +113,8 @@ type EntriesFilter struct { } type UploadEntriesRequestBody struct { - Dest string `query:"dest"` - SleepIntervalSec int `query:"interval"` + Dest string `form:"dest"` + SleepIntervalSec int `form:"interval"` } type HarFetchRequestBody struct { diff --git a/agent/pkg/routes/entries_routes.go b/agent/pkg/routes/entries_routes.go index 9f5f751be..cf4e29b9f 100644 --- a/agent/pkg/routes/entries_routes.go +++ b/agent/pkg/routes/entries_routes.go @@ -1,25 +1,25 @@ package routes import ( - "github.com/gofiber/fiber/v2" + "github.com/gin-gonic/gin" "mizuserver/pkg/controllers" ) // EntriesRoutes defines the group of har entries routes. -func EntriesRoutes(fiberApp *fiber.App) { - routeGroup := fiberApp.Group("/api") +func EntriesRoutes(ginApp *gin.Engine) { + routeGroup := ginApp.Group("/api") - routeGroup.Get("/entries", controllers.GetEntries) // get entries (base/thin entries) - routeGroup.Get("/entries/:entryId", controllers.GetEntry) // get single (full) entry - routeGroup.Get("/exportEntries", controllers.GetFullEntries) - routeGroup.Get("/uploadEntries", controllers.UploadEntries) - routeGroup.Get("/resolving", controllers.GetCurrentResolvingInformation) + routeGroup.GET("/entries", controllers.GetEntries) // get entries (base/thin entries) + routeGroup.GET("/entries/:entryId", controllers.GetEntry) // get single (full) entry + routeGroup.GET("/exportEntries", controllers.GetFullEntries) + routeGroup.GET("/uploadEntries", controllers.UploadEntries) + routeGroup.GET("/resolving", controllers.GetCurrentResolvingInformation) - routeGroup.Get("/har", controllers.GetHARs) + routeGroup.GET("/har", controllers.GetHARs) - routeGroup.Get("/resetDB", controllers.DeleteAllEntries) // get single (full) entry - routeGroup.Get("/generalStats", controllers.GetGeneralStats) // get general stats about entries in DB + routeGroup.GET("/resetDB", controllers.DeleteAllEntries) // get single (full) entry + routeGroup.GET("/generalStats", controllers.GetGeneralStats) // get general stats about entries in DB - routeGroup.Get("/tapStatus", controllers.GetTappingStatus) // get tapping status - routeGroup.Get("/analyzeStatus", controllers.AnalyzeInformation) + routeGroup.GET("/tapStatus", controllers.GetTappingStatus) // get tapping status + routeGroup.GET("/analyzeStatus", controllers.AnalyzeInformation) } diff --git a/agent/pkg/routes/metadata_routes.go b/agent/pkg/routes/metadata_routes.go index 3a3d3da11..4f32ff771 100644 --- a/agent/pkg/routes/metadata_routes.go +++ b/agent/pkg/routes/metadata_routes.go @@ -1,13 +1,13 @@ package routes import ( - "github.com/gofiber/fiber/v2" + "github.com/gin-gonic/gin" "mizuserver/pkg/controllers" ) // MetadataRoutes defines the group of metadata routes. -func MetadataRoutes(fiberApp *fiber.App) { - routeGroup := fiberApp.Group("/metadata") +func MetadataRoutes(app *gin.Engine) { + routeGroup := app.Group("/metadata") - routeGroup.Get("/version", controllers.GetVersion) + routeGroup.GET("/version", controllers.GetVersion) } diff --git a/agent/pkg/routes/not_found_route.go b/agent/pkg/routes/not_found_route.go index 452caa8e0..bde062ff0 100644 --- a/agent/pkg/routes/not_found_route.go +++ b/agent/pkg/routes/not_found_route.go @@ -1,12 +1,15 @@ package routes -import "github.com/gofiber/fiber/v2" +import ( + "github.com/gin-gonic/gin" + "net/http" +) // NotFoundRoute defines the 404 Error route. -func NotFoundRoute(fiberApp *fiber.App) { - fiberApp.Use( - func(c *fiber.Ctx) error { - return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ +func NotFoundRoute(app *gin.Engine) { + app.Use( + func(c *gin.Context) { + c.JSON(http.StatusNotFound, map[string]interface{}{ "error": true, "msg": "sorry, endpoint is not found", }) diff --git a/agent/pkg/routes/socket_routes.go b/agent/pkg/routes/socket_routes.go index a66cc401b..31831c4ee 100644 --- a/agent/pkg/routes/socket_routes.go +++ b/agent/pkg/routes/socket_routes.go @@ -1,31 +1,118 @@ package routes import ( - "github.com/antoniodipinto/ikisocket" - "github.com/gofiber/fiber/v2" + "errors" + "fmt" + "github.com/gin-gonic/gin" + "github.com/gorilla/websocket" + "github.com/up9inc/mizu/shared/debounce" + "net/http" + "sync" + "time" ) type EventHandlers interface { - WebSocketConnect(ep *ikisocket.EventPayload) - WebSocketDisconnect(ep *ikisocket.EventPayload) - WebSocketClose(ep *ikisocket.EventPayload) - WebSocketError(ep *ikisocket.EventPayload) - WebSocketMessage(ep *ikisocket.EventPayload) + WebSocketConnect(socketId int, isTapper bool) + WebSocketDisconnect(socketId int, isTapper bool) + WebSocketMessage(socketId int, message []byte) } -func WebSocketRoutes(app *fiber.App, eventHandlers EventHandlers) { - app.Get("/ws", ikisocket.New(func(kws *ikisocket.Websocket) { - kws.SetAttribute("is_tapper", false) - })) - - app.Get("/wsTapper", ikisocket.New(func(kws *ikisocket.Websocket) { - // Tapper clients are handled differently, they don't need to receive new message broadcasts. - kws.SetAttribute("is_tapper", true) - })) - - ikisocket.On(ikisocket.EventMessage, eventHandlers.WebSocketMessage) - ikisocket.On(ikisocket.EventConnect, eventHandlers.WebSocketConnect) - ikisocket.On(ikisocket.EventDisconnect, eventHandlers.WebSocketDisconnect) - ikisocket.On(ikisocket.EventClose, eventHandlers.WebSocketClose) // This event is called when the server disconnects the user actively with .Close() method - ikisocket.On(ikisocket.EventError, eventHandlers.WebSocketError) // On error event +type SocketConnection struct { + connection *websocket.Conn + lock *sync.Mutex + eventHandlers EventHandlers + isTapper bool +} + +var websocketUpgrader = websocket.Upgrader{ + ReadBufferSize: 1024, + WriteBufferSize: 1024, +} + +var websocketIdsLock = sync.Mutex{} +var connectedWebsockets map[int]*SocketConnection +var connectedWebsocketIdCounter = 0 + +func init() { + websocketUpgrader.CheckOrigin = func(r *http.Request) bool { return true } // like cors for web socket + connectedWebsockets = make(map[int]*SocketConnection, 0) +} + +func WebSocketRoutes(app *gin.Engine, eventHandlers EventHandlers) { + app.GET("/ws", func(c *gin.Context) { + websocketHandler(c.Writer, c.Request, eventHandlers, false) + }) + app.GET("/wsTapper", func(c *gin.Context) { + websocketHandler(c.Writer, c.Request, eventHandlers, true) + }) +} + +func websocketHandler(w http.ResponseWriter, r *http.Request, eventHandlers EventHandlers, isTapper bool) { + conn, err := websocketUpgrader.Upgrade(w, r, nil) + if err != nil { + fmt.Println("Failed to set websocket upgrade: %+v", err) + return + } + + websocketIdsLock.Lock() + + connectedWebsocketIdCounter++ + socketId := connectedWebsocketIdCounter + connectedWebsockets[socketId] = &SocketConnection{connection: conn, lock: &sync.Mutex{}, eventHandlers: eventHandlers, isTapper: isTapper} + + websocketIdsLock.Unlock() + + defer func() { + socketCleanup(socketId, connectedWebsockets[socketId]) + }() + + eventHandlers.WebSocketConnect(socketId, isTapper) + + for { + _, msg, err := conn.ReadMessage() + if err != nil { + fmt.Printf("Conn err: %v\n", err) + break + } + eventHandlers.WebSocketMessage(socketId, msg) + } +} + +func socketCleanup(socketId int, socketConnection *SocketConnection) { + err := socketConnection.connection.Close() + if err != nil { + fmt.Printf("Error closing socket connection for socket id %d: %v\n", socketId, err) + } + + websocketIdsLock.Lock() + connectedWebsockets[socketId] = nil + websocketIdsLock.Unlock() + + socketConnection.eventHandlers.WebSocketDisconnect(socketId, socketConnection.isTapper) +} + +var db = debounce.NewDebouncer(time.Second * 5, func() { + fmt.Println("Successfully sent to socket") +}) + +func SendToSocket(socketId int, message []byte) error { + socketObj := connectedWebsockets[socketId] + if socketObj == nil { + return errors.New("Socket is disconnected") + } + + var sent = false + time.AfterFunc(time.Second * 5, func() { + if !sent { + fmt.Println("Socket timed out") + socketCleanup(socketId, socketObj) + } + }) + + socketObj.lock.Lock() // gorilla socket panics from concurrent writes to a single socket + err := socketObj.connection.WriteMessage(1, message) + socketObj.lock.Unlock() + + sent = true + return err } diff --git a/agent/pkg/utils/utils.go b/agent/pkg/utils/utils.go index 6d66b9674..cdb5a35cb 100644 --- a/agent/pkg/utils/utils.go +++ b/agent/pkg/utils/utils.go @@ -1,32 +1,42 @@ package utils import ( - "github.com/gofiber/fiber/v2" + "context" + "github.com/gin-gonic/gin" "github.com/romana/rlog" "log" + "net/http" "net/url" "os" "os/signal" "reflect" "syscall" + "time" ) // StartServer starts the server with a graceful shutdown -func StartServer(app *fiber.App) { +func StartServer(app *gin.Engine) { signals := make(chan os.Signal, 2) signal.Notify(signals, os.Interrupt, // this catch ctrl + c syscall.SIGTSTP, // this catch ctrl + z ) + srv := &http.Server{ + Addr: ":8080", + Handler: app, + } + go func() { _ = <-signals rlog.Infof("Shutting down...") - _ = app.Shutdown() + ctx, _ := context.WithTimeout(context.Background(), 5*time.Second) + _ = srv.Shutdown(ctx) + os.Exit(0) }() // Run server. - if err := app.Listen(":8899"); err != nil { + if err := app.Run(":8899"); err != nil { log.Printf("Oops... Server is not running! Reason: %v", err) } } From f175480f6589b2d7fa83895f9759a279ffc45b5a Mon Sep 17 00:00:00 2001 From: gadotroee <55343099+gadotroee@users.noreply.github.com> Date: Mon, 26 Jul 2021 11:23:35 +0300 Subject: [PATCH 32/69] Adding (basic) configuration (#135) --- cli/cmd/config.go | 34 ++++++ cli/cmd/root.go | 18 +++ cli/cmd/tap.go | 15 ++- cli/cmd/tapRunner.go | 11 +- cli/cmd/viewRunner.go | 3 +- cli/go.mod | 1 + cli/go.sum | 5 +- cli/mizu/config.go | 211 ++++++++++++++++++++++++++++++++++++ cli/mizu/consts.go | 11 -- cli/mizu/logger.go | 2 +- cli/mizu/telemetry.go | 3 +- cli/mizu/versionCheck.go | 5 +- cli/uiUtils/colors.go | 13 +++ cli/uiUtils/confirmation.go | 4 +- cli/uiUtils/prettyString.go | 36 ++++++ 15 files changed, 340 insertions(+), 32 deletions(-) create mode 100644 cli/cmd/config.go create mode 100644 cli/mizu/config.go create mode 100644 cli/uiUtils/colors.go create mode 100644 cli/uiUtils/prettyString.go diff --git a/cli/cmd/config.go b/cli/cmd/config.go new file mode 100644 index 000000000..64d3d9818 --- /dev/null +++ b/cli/cmd/config.go @@ -0,0 +1,34 @@ +package cmd + +import ( + "fmt" + "github.com/spf13/cobra" + "github.com/up9inc/mizu/cli/mizu" + "github.com/up9inc/mizu/cli/uiUtils" + "os" +) + +var outputFileName string + +var configCmd = &cobra.Command{ + Use: "config", + Short: "Generate example config file to stdout", + RunE: func(cmd *cobra.Command, args []string) error { + template := mizu.GetTemplateConfig() + if outputFileName != "" { + data := []byte(template) + _ = os.WriteFile(outputFileName, data, 0644) + mizu.Log.Infof(fmt.Sprintf("Template File written to %s", fmt.Sprintf(uiUtils.Purple, outputFileName))) + } else { + mizu.Log.Debugf("Writing template config.\n%v", template) + fmt.Printf("%v", template) + } + return nil + }, +} + +func init() { + rootCmd.AddCommand(configCmd) + + configCmd.Flags().StringVarP(&outputFileName, "file", "f", "", "Save content to local file") +} diff --git a/cli/cmd/root.go b/cli/cmd/root.go index 239d76a62..0e311a312 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -1,14 +1,32 @@ package cmd import ( + "errors" + "fmt" "github.com/spf13/cobra" + "github.com/up9inc/mizu/cli/mizu" ) +var commandLineFlags []string + var rootCmd = &cobra.Command{ Use: "mizu", Short: "A web traffic viewer for kubernetes", Long: `A web traffic viewer for kubernetes Further info is available at https://github.com/up9inc/mizu`, + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + if err := mizu.InitConfig(commandLineFlags); err != nil { + mizu.Log.Errorf("Invalid config, Exit %s", err) + return errors.New(fmt.Sprintf("%v", err)) + } + prettifiedConfig := mizu.GetConfigStr() + mizu.Log.Debugf("Final Config: %s", prettifiedConfig) + return nil + }, +} + +func init() { + rootCmd.PersistentFlags().StringSliceVar(&commandLineFlags, "set", []string{}, "Override values using --set") } // Execute adds all child commands to the root command and sets flags appropriately. diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go index dded96af1..4476bb5a7 100644 --- a/cli/cmd/tap.go +++ b/cli/cmd/tap.go @@ -35,8 +35,8 @@ var regex *regexp.Regexp const maxEntriesDBSizeFlagName = "max-entries-db-size" -const analysisMessageToConfirm = `NOTE: running mizu with --analysis flag will upload recorded traffic -to UP9 cloud for further analysis and enriched presentation options. +const analysisMessageToConfirm = `NOTE: running mizu with --analysis flag will upload recorded traffic +for further analysis and enriched presentation options. ` var tapCmd = &cobra.Command{ @@ -48,8 +48,16 @@ Supported protocols are HTTP and gRPC.`, go mizu.ReportRun("tap", mizuTapOptions) RunMizuTap(regex, mizuTapOptions) return nil + }, PreRunE: func(cmd *cobra.Command, args []string) error { + mizu.Log.Info("Getting params") + mizuTapOptions.AnalysisDestination = mizu.GetString(mizu.ConfigurationKeyAnalyzingDestination) + mizuTapOptions.SleepIntervalSec = uint16(mizu.GetInt(mizu.ConfigurationKeyUploadInterval)) + mizuTapOptions.MizuImage = mizu.GetString(mizu.ConfigurationKeyMizuImage) + mizu.Log.Infof(uiUtils.PrettyJson(mizuTapOptions)) + + if len(args) == 0 { return errors.New("POD REGEX argument is required") } else if len(args) > 1 { @@ -95,11 +103,8 @@ func init() { tapCmd.Flags().Uint16VarP(&mizuTapOptions.GuiPort, "gui-port", "p", 8899, "Provide a custom port for the web interface webserver") tapCmd.Flags().StringVarP(&mizuTapOptions.Namespace, "namespace", "n", "", "Namespace selector") tapCmd.Flags().BoolVar(&mizuTapOptions.Analysis, "analysis", false, "Uploads traffic to UP9 for further analysis (Beta)") - tapCmd.Flags().StringVar(&mizuTapOptions.AnalysisDestination, "dest", "up9.app", "Destination environment") - tapCmd.Flags().Uint16VarP(&mizuTapOptions.SleepIntervalSec, "upload-interval", "", 10, "Interval in seconds for uploading data to UP9") tapCmd.Flags().BoolVarP(&mizuTapOptions.AllNamespaces, "all-namespaces", "A", false, "Tap all namespaces") tapCmd.Flags().StringVarP(&mizuTapOptions.KubeConfigPath, "kube-config", "k", "", "Path to kube-config file") - tapCmd.Flags().StringVarP(&mizuTapOptions.MizuImage, "mizu-image", "", fmt.Sprintf("gcr.io/up9-docker-hub/mizu/%s:%s", mizu.Branch, mizu.SemVer), "Custom image for mizu API server") tapCmd.Flags().StringArrayVarP(&mizuTapOptions.PlainTextFilterRegexes, "regex-masking", "r", nil, "List of regex expressions that are used to filter matching values from text/plain http bodies") tapCmd.Flags().StringVarP(&direction, "direction", "", "in", "Record traffic that goes in this direction (relative to the tapped pod): in/any") tapCmd.Flags().BoolVar(&mizuTapOptions.HideHealthChecks, "hide-healthchecks", false, "hides requests with kube-probe or prometheus user-agent headers") diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index e8bd521af..be0199b48 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/up9inc/mizu/cli/kubernetes" "github.com/up9inc/mizu/cli/mizu" + "github.com/up9inc/mizu/cli/uiUtils" "github.com/up9inc/mizu/shared" "github.com/up9inc/mizu/shared/debounce" core "k8s.io/api/core/v1" @@ -39,11 +40,11 @@ func RunMizuTap(podRegexQuery *regexp.Regexp, tappingOptions *MizuTapOptions) { kubernetesProvider, err := kubernetes.NewProvider(tappingOptions.KubeConfigPath) if err != nil { if clientcmd.IsEmptyConfig(err) { - mizu.Log.Infof(mizu.Red, "Couldn't find the kube config file, or file is empty. Try adding '--kube-config='\n") + mizu.Log.Infof(uiUtils.Red, "Couldn't find the kube config file, or file is empty. Try adding '--kube-config='\n") return } if clientcmd.IsConfigurationInvalid(err) { - mizu.Log.Infof(mizu.Red, "Invalid kube config file. Try using a different config with '--kube-config='\n") + mizu.Log.Infof(uiUtils.Red, "Invalid kube config file. Try using a different config with '--kube-config='\n") return } } @@ -259,10 +260,10 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro for { select { case newTarget := <-added: - mizu.Log.Infof(mizu.Green, fmt.Sprintf("+%s\n", newTarget.Name)) + mizu.Log.Infof(uiUtils.Green, fmt.Sprintf("+%s\n", newTarget.Name)) case removedTarget := <-removed: - mizu.Log.Infof(mizu.Red, fmt.Sprintf("-%s\n", removedTarget.Name)) + mizu.Log.Infof(uiUtils.Red, fmt.Sprintf("-%s\n", removedTarget.Name)) restartTappersDebouncer.SetOn() case modifiedTarget := <-modified: @@ -327,7 +328,7 @@ func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provi if response, err := http.Get(u.String()); err != nil || response.StatusCode != 200 { mizu.Log.Infof("error sending upload entries req, status code: %v, err: %v\n", response.StatusCode, err) } else { - mizu.Log.Infof(mizu.Purple, "Traffic is uploading to UP9 for further analysis\n") + mizu.Log.Infof(uiUtils.Purple, "Traffic is uploading to UP9 for further analysis\n") } } } diff --git a/cli/cmd/viewRunner.go b/cli/cmd/viewRunner.go index cfa1fd657..caf6bd2d0 100644 --- a/cli/cmd/viewRunner.go +++ b/cli/cmd/viewRunner.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/up9inc/mizu/cli/kubernetes" "github.com/up9inc/mizu/cli/mizu" + "github.com/up9inc/mizu/cli/uiUtils" "k8s.io/client-go/tools/clientcmd" "net/http" ) @@ -17,7 +18,7 @@ func runMizuView(mizuViewOptions *MizuViewOptions) { return } if clientcmd.IsConfigurationInvalid(err) { - mizu.Log.Infof(mizu.Red, "Invalid kube config file. Try using a different config with '--kube-config='\n") + mizu.Log.Infof(uiUtils.Red, "Invalid kube config file. Try using a different config with '--kube-config='\n") return } } diff --git a/cli/go.mod b/cli/go.mod index f7566a05f..436fce829 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -8,6 +8,7 @@ require ( github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 github.com/spf13/cobra v1.1.3 github.com/up9inc/mizu/shared v0.0.0 + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b k8s.io/api v0.21.2 k8s.io/apimachinery v0.21.2 k8s.io/client-go v0.21.2 diff --git a/cli/go.sum b/cli/go.sum index d9a2b280c..cef04c856 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -367,8 +367,6 @@ github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/romana/rlog v0.0.0-20171115192701-f018bc92e7d7 h1:jkvpcEatpwuMF5O5LVxTnehj6YZ/aEZN4NWD/Xml4pI= -github.com/romana/rlog v0.0.0-20171115192701-f018bc92e7d7/go.mod h1:KTrHyWpO1sevuXPZwyeZc72ddWRFqNSKDFl7uVWKpg0= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -691,8 +689,9 @@ gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/cli/mizu/config.go b/cli/mizu/config.go new file mode 100644 index 000000000..3042c6a8a --- /dev/null +++ b/cli/mizu/config.go @@ -0,0 +1,211 @@ +package mizu + +import ( + "errors" + "fmt" + "github.com/up9inc/mizu/cli/uiUtils" + "gopkg.in/yaml.v3" + "io/ioutil" + "os" + "path" + "reflect" + "strconv" + "strings" +) + +const separator = "=" + +var configObj = map[string]interface{}{} + +type CommandLineFlag struct { + CommandLineName string + YamlHierarchyName string + DefaultValue interface{} + Type reflect.Kind +} + +const ( + ConfigurationKeyAnalyzingDestination = "tap.dest" + ConfigurationKeyUploadInterval = "tap.uploadInterval" + ConfigurationKeyMizuImage = "mizuImage" +) + +var allowedSetFlags = []CommandLineFlag{ + { + CommandLineName: "dest", + YamlHierarchyName: ConfigurationKeyAnalyzingDestination, + DefaultValue: "up9.app", + Type: reflect.String, + // TODO: maybe add short description that we can show + }, + { + CommandLineName: "uploadInterval", + YamlHierarchyName: ConfigurationKeyUploadInterval, + DefaultValue: 10, + Type: reflect.Int, + }, + { + CommandLineName: "mizuImage", + YamlHierarchyName: ConfigurationKeyMizuImage, + DefaultValue: fmt.Sprintf("gcr.io/up9-docker-hub/mizu/%s:%s", Branch, SemVer), + Type: reflect.String, + }, +} + +func GetString(key string) string { + return fmt.Sprintf("%v", getValueFromMergedConfig(key)) +} + +func GetInt(key string) int { + stringVal := GetString(key) + Log.Debugf("Found string value %v", stringVal) + + val, err := strconv.Atoi(stringVal) + if err != nil { + Log.Warningf("Invalid value %v for key %s", val, key) + os.Exit(1) + } + return val +} + +func InitConfig(commandLineValues []string) error { + Log.Debugf("Merging default values") + mergeDefaultValues() + Log.Debugf("Merging config file values") + if err1 := mergeConfigFile(); err1 != nil { + Log.Infof(fmt.Sprintf(uiUtils.Red, "Invalid config file\n")) + return err1 + } + Log.Debugf("Merging command line values") + if err2 := mergeCommandLineFlags(commandLineValues); err2 != nil { + Log.Infof(fmt.Sprintf(uiUtils.Red, "Invalid commanad argument\n")) + return err2 + } + finalConfigPrettified, _ := uiUtils.PrettyJson(configObj) + Log.Debugf("Merged all config successfully\n Final config: %v", finalConfigPrettified) + return nil +} + +func GetTemplateConfig() string { + templateConfig := map[string]interface{}{} + for _, allowedFlag := range allowedSetFlags { + addToConfigObj(allowedFlag.YamlHierarchyName, allowedFlag.DefaultValue, templateConfig) + } + prettifiedConfig, _ := uiUtils.PrettyYaml(templateConfig) + return prettifiedConfig +} + +func GetConfigStr() string { + val, _ := uiUtils.PrettyYaml(configObj) + return val +} + +func getValueFromMergedConfig(key string) interface{} { + if a, ok := configObj[key]; ok { + return a + } + return nil +} + +func mergeDefaultValues() { + for _, allowedFlag := range allowedSetFlags { + Log.Debugf("Setting %v to %v", allowedFlag.YamlHierarchyName, allowedFlag.DefaultValue) + configObj[allowedFlag.YamlHierarchyName] = allowedFlag.DefaultValue + } +} + +func mergeConfigFile() error { + Log.Debugf("Merging mizu config file values") + home, homeDirErr := os.UserHomeDir() + if homeDirErr != nil { + return nil + } + reader, openErr := os.Open(path.Join(home, ".mizu", "config.yaml")) + if openErr != nil { + return nil + } + buf, readErr := ioutil.ReadAll(reader) + if readErr != nil { + return readErr + } + m := make(map[string]interface{}) + if err := yaml.Unmarshal(buf, &m); err != nil { + return err + } + for k, v := range m { + addToConfig(k, v) + } + return nil +} + +func addToConfig(prefix string, value interface{}) { + typ := reflect.TypeOf(value).Kind() + if typ == reflect.Int || typ == reflect.String || typ == reflect.Slice { + validateConfigFileKey(prefix) + configObj[prefix] = value + } else if typ == reflect.Map { + for k1, v1 := range value.(map[string]interface{}) { + addToConfig(fmt.Sprintf("%s.%s", prefix, k1), v1) + } + } +} + +func mergeCommandLineFlags(commandLineValues []string) error { + Log.Debugf("Merging Command line flags") + for _, e := range commandLineValues { + if !strings.Contains(e, separator) { + return errors.New(fmt.Sprintf("invalid set argument %s", e)) + } + split := strings.SplitN(e, separator, 2) + if len(split) != 2 { + return errors.New(fmt.Sprintf("invalid set argument %s", e)) + } + setFlagKey, argumentValue := split[0], split[1] + argumentNameInConfig, expectedType, err := flagFromAllowed(setFlagKey) + if err != nil { + return err + } + argumentType := reflect.ValueOf(argumentValue).Kind() + if argumentType != expectedType { + return errors.New(fmt.Sprintf("Invalid value for argument %s (should be type %s but got %s", setFlagKey, expectedType, argumentType)) + } + configObj[argumentNameInConfig] = argumentValue + } + return nil +} + +func flagFromAllowed(setFlagKey string) (string, reflect.Kind, error) { + for _, allowedFlag := range allowedSetFlags { + if strings.ToLower(allowedFlag.CommandLineName) == strings.ToLower(setFlagKey) { + return allowedFlag.YamlHierarchyName, allowedFlag.Type, nil + } + } + return "", reflect.Invalid, errors.New(fmt.Sprintf("invalid set argument %s", setFlagKey)) +} + +func validateConfigFileKey(configFileKey string) { + for _, allowedFlag := range allowedSetFlags { + if allowedFlag.YamlHierarchyName == configFileKey { + return + } + } + Log.Info(fmt.Sprintf("Unknown argument: %s. Exit", configFileKey)) + os.Exit(1) +} + +func addToConfigObj(key string, value interface{}, configObj map[string]interface{}) { + typ := reflect.TypeOf(value).Kind() + if typ == reflect.Int || typ == reflect.String || typ == reflect.Slice { + if strings.Contains(key, ".") { + split := strings.SplitN(key, ".", 2) + firstLevelKey := split[0] + if _, ok := configObj[firstLevelKey]; !ok { + configObj[firstLevelKey] = map[string]interface{}{} + } + addToConfigObj(split[1], value, configObj[firstLevelKey].(map[string]interface{})) + } else { + configObj[key] = value + } + } +} + diff --git a/cli/mizu/consts.go b/cli/mizu/consts.go index 6874069d5..0f966ea9b 100644 --- a/cli/mizu/consts.go +++ b/cli/mizu/consts.go @@ -18,14 +18,3 @@ const ( TapperDaemonSetName = "mizu-tapper-daemon-set" TapperPodName = "mizu-tapper" ) - -const ( - Black = "\033[1;30m%s\033[0m" - Red = "\033[1;31m%s\033[0m" - Green = "\033[1;32m%s\033[0m" - Yellow = "\033[1;33m%s\033[0m" - Purple = "\033[1;34m%s\033[0m" - Magenta = "\033[1;35m%s\033[0m" - Teal = "\033[1;36m%s\033[0m" - White = "\033[1;37m%s\033[0m" -) diff --git a/cli/mizu/logger.go b/cli/mizu/logger.go index 9283f6e15..a708b4879 100644 --- a/cli/mizu/logger.go +++ b/cli/mizu/logger.go @@ -14,7 +14,7 @@ var format = logging.MustStringFormatter( ) func InitLogger() { - homeDirPath, err := os.UserHomeDir() + homeDirPath, _ := os.UserHomeDir() mizuDirPath := path.Join(homeDirPath, ".mizu") if err := os.MkdirAll(mizuDirPath, os.ModePerm); err != nil { panic(fmt.Sprintf("Failed creating .mizu dir: %v, err %v", mizuDirPath, err)) diff --git a/cli/mizu/telemetry.go b/cli/mizu/telemetry.go index 73aae4a28..beea7a93a 100644 --- a/cli/mizu/telemetry.go +++ b/cli/mizu/telemetry.go @@ -26,8 +26,7 @@ func ReportRun(cmd string, args interface{}) { jsonValue, _ := json.Marshal(argsMap) - if resp, err := http.Post(telemetryUrl, - "application/json", bytes.NewBuffer(jsonValue)); err != nil { + if resp, err := http.Post(telemetryUrl, "application/json", bytes.NewBuffer(jsonValue)); err != nil { Log.Debugf("error sending telemetry err: %v, response %v", err, resp) } else { Log.Debugf("Successfully reported telemetry") diff --git a/cli/mizu/versionCheck.go b/cli/mizu/versionCheck.go index cef0e790a..8677fdba2 100644 --- a/cli/mizu/versionCheck.go +++ b/cli/mizu/versionCheck.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "github.com/google/go-github/v37/github" + "github.com/up9inc/mizu/cli/uiUtils" "github.com/up9inc/mizu/shared" "github.com/up9inc/mizu/shared/semver" "io/ioutil" @@ -44,7 +45,7 @@ func CheckVersionCompatibility(port uint16) (bool, error) { return true, nil } - Log.Infof(Red, fmt.Sprintf("cli version (%s) is not compatible with api version (%s)\n", SemVer, apiSemVer)) + Log.Infof(uiUtils.Red, fmt.Sprintf("cli version (%s) is not compatible with api version (%s)\n", SemVer, apiSemVer)) return false, nil } @@ -86,6 +87,6 @@ func CheckNewerVersion() { gitHubVersion = gitHubVersion[:len(gitHubVersion)-1] Log.Debugf("Finished version validation, took %v", time.Since(start)) if SemVer < gitHubVersion { - Log.Infof(Yellow, fmt.Sprintf("Update available! %v -> %v (%v)\n", SemVer, gitHubVersion, *latestRelease.HTMLURL)) + Log.Infof(uiUtils.Yellow, fmt.Sprintf("Update available! %v -> %v (%v)\n", SemVer, gitHubVersion, *latestRelease.HTMLURL)) } } diff --git a/cli/uiUtils/colors.go b/cli/uiUtils/colors.go new file mode 100644 index 000000000..e4c684dda --- /dev/null +++ b/cli/uiUtils/colors.go @@ -0,0 +1,13 @@ +package uiUtils + + +const ( + Black = "\033[1;30m%s\033[0m" + Red = "\033[1;31m%s\033[0m" + Green = "\033[1;32m%s\033[0m" + Yellow = "\033[1;33m%s\033[0m" + Purple = "\033[1;34m%s\033[0m" + Magenta = "\033[1;35m%s\033[0m" + Teal = "\033[1;36m%s\033[0m" + White = "\033[1;37m%s\033[0m" +) \ No newline at end of file diff --git a/cli/uiUtils/confirmation.go b/cli/uiUtils/confirmation.go index 7a0da1aac..afa57a1bd 100644 --- a/cli/uiUtils/confirmation.go +++ b/cli/uiUtils/confirmation.go @@ -2,7 +2,7 @@ package uiUtils import ( "bufio" - "github.com/up9inc/mizu/cli/mizu" + "fmt" "log" "os" "strings" @@ -11,7 +11,7 @@ import ( func AskForConfirmation(s string) bool { reader := bufio.NewReader(os.Stdin) - mizu.Log.Infof(mizu.Magenta, s) + fmt.Printf(Magenta, s) response, err := reader.ReadString('\n') if err != nil { diff --git a/cli/uiUtils/prettyString.go b/cli/uiUtils/prettyString.go new file mode 100644 index 000000000..561ca52ee --- /dev/null +++ b/cli/uiUtils/prettyString.go @@ -0,0 +1,36 @@ +package uiUtils + +import ( + "bytes" + "encoding/json" + "gopkg.in/yaml.v3" +) + +const ( + empty = "" + tab = "\t" +) + +func PrettyJson(data interface{}) (string, error) { + buffer := new(bytes.Buffer) + encoder := json.NewEncoder(buffer) + encoder.SetIndent(empty, tab) + + err := encoder.Encode(data) + if err != nil { + return empty, err + } + return buffer.String(), nil +} + +func PrettyYaml(data interface{}) (string, error) { + buffer := new(bytes.Buffer) + encoder := yaml.NewEncoder(buffer) + encoder.SetIndent(0) + + err := encoder.Encode(data) + if err != nil { + return empty, err + } + return buffer.String(), nil +} From 58f0de4d4eeb6577b5ac555eaaad7a017a10e3d2 Mon Sep 17 00:00:00 2001 From: gadotroee <55343099+gadotroee@users.noreply.github.com> Date: Mon, 26 Jul 2021 12:00:36 +0300 Subject: [PATCH 33/69] WriteFile fix(#138) --- cli/cmd/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/cmd/config.go b/cli/cmd/config.go index 64d3d9818..3949924e6 100644 --- a/cli/cmd/config.go +++ b/cli/cmd/config.go @@ -5,7 +5,7 @@ import ( "github.com/spf13/cobra" "github.com/up9inc/mizu/cli/mizu" "github.com/up9inc/mizu/cli/uiUtils" - "os" + "io/ioutil" ) var outputFileName string @@ -17,7 +17,7 @@ var configCmd = &cobra.Command{ template := mizu.GetTemplateConfig() if outputFileName != "" { data := []byte(template) - _ = os.WriteFile(outputFileName, data, 0644) + _ = ioutil.WriteFile(outputFileName, data, 0644) mizu.Log.Infof(fmt.Sprintf("Template File written to %s", fmt.Sprintf(uiUtils.Purple, outputFileName))) } else { mizu.Log.Debugf("Writing template config.\n%v", template) From 6d49339e296a78e5e8c59e98da69835ab061392c Mon Sep 17 00:00:00 2001 From: gadotroee <55343099+gadotroee@users.noreply.github.com> Date: Mon, 26 Jul 2021 14:04:48 +0300 Subject: [PATCH 34/69] Fix log to debug (#139) --- cli/cmd/tap.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go index 4476bb5a7..978059be1 100644 --- a/cli/cmd/tap.go +++ b/cli/cmd/tap.go @@ -35,9 +35,7 @@ var regex *regexp.Regexp const maxEntriesDBSizeFlagName = "max-entries-db-size" -const analysisMessageToConfirm = `NOTE: running mizu with --analysis flag will upload recorded traffic -for further analysis and enriched presentation options. -` +const analysisMessageToConfirm = `NOTE: running mizu with --analysis flag will upload recorded traffic for further analysis and enriched presentation options.` var tapCmd = &cobra.Command{ Use: "tap [POD REGEX]", @@ -51,11 +49,11 @@ Supported protocols are HTTP and gRPC.`, }, PreRunE: func(cmd *cobra.Command, args []string) error { - mizu.Log.Info("Getting params") + mizu.Log.Debugf("Getting params") mizuTapOptions.AnalysisDestination = mizu.GetString(mizu.ConfigurationKeyAnalyzingDestination) mizuTapOptions.SleepIntervalSec = uint16(mizu.GetInt(mizu.ConfigurationKeyUploadInterval)) mizuTapOptions.MizuImage = mizu.GetString(mizu.ConfigurationKeyMizuImage) - mizu.Log.Infof(uiUtils.PrettyJson(mizuTapOptions)) + mizu.Log.Debugf(uiUtils.PrettyJson(mizuTapOptions)) if len(args) == 0 { From 0566f63d721197537ef2558b6295c6d229e7fff8 Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Tue, 27 Jul 2021 13:10:40 +0300 Subject: [PATCH 35/69] Remove redundant '\n' at the end of each log (#142) --- cli/cmd/tap.go | 3 +-- cli/cmd/tapRunner.go | 52 ++++++++++++++++++++-------------------- cli/cmd/version.go | 6 ++--- cli/cmd/viewRunner.go | 12 +++++----- cli/mizu/versionCheck.go | 4 ++-- 5 files changed, 38 insertions(+), 39 deletions(-) diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go index 978059be1..3e67195cd 100644 --- a/cli/cmd/tap.go +++ b/cli/cmd/tap.go @@ -55,7 +55,6 @@ Supported protocols are HTTP and gRPC.`, mizuTapOptions.MizuImage = mizu.GetString(mizu.ConfigurationKeyMizuImage) mizu.Log.Debugf(uiUtils.PrettyJson(mizuTapOptions)) - if len(args) == 0 { return errors.New("POD REGEX argument is required") } else if len(args) > 1 { @@ -73,7 +72,7 @@ Supported protocols are HTTP and gRPC.`, if parseHumanDataSizeErr != nil { return errors.New(fmt.Sprintf("Could not parse --max-entries-db-size value %s", humanMaxEntriesDBSize)) } - mizu.Log.Infof("Mizu will store up to %s of traffic, old traffic will be cleared once the limit is reached.\n", units.BytesToHumanReadable(mizuTapOptions.MaxEntriesDBSizeBytes)) + mizu.Log.Infof("Mizu will store up to %s of traffic, old traffic will be cleared once the limit is reached.", units.BytesToHumanReadable(mizuTapOptions.MaxEntriesDBSizeBytes)) directionLowerCase := strings.ToLower(direction) if directionLowerCase == "any" { diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index be0199b48..742b4e4a0 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -67,14 +67,14 @@ func RunMizuTap(podRegexQuery *regexp.Regexp, tappingOptions *MizuTapOptions) { } else { namespacesStr = "all namespaces" } - mizu.Log.Infof("Tapping pods in %s\n", namespacesStr) + mizu.Log.Infof("Tapping pods in %s", namespacesStr) if len(currentlyTappedPods) == 0 { var suggestionStr string if targetNamespace != mizu.K8sAllNamespaces { suggestionStr = "\nSelect a different namespace with -n or tap all namespaces with -A" } - mizu.Log.Infof("Did not find any pods matching the regex argument%s\n", suggestionStr) + mizu.Log.Infof("Did not find any pods matching the regex argument%s", suggestionStr) } nodeToTappedPodIPMap, err := getNodeHostToTappedPodIpsMap(currentlyTappedPods) @@ -114,7 +114,7 @@ func createMizuResources(ctx context.Context, kubernetesProvider *kubernetes.Pro func createMizuNamespace(ctx context.Context, kubernetesProvider *kubernetes.Provider) error { _, err := kubernetesProvider.CreateNamespace(ctx, mizu.ResourcesNamespace) if err != nil { - mizu.Log.Infof("Error creating Namespace %s: %v\n", mizu.ResourcesNamespace, err) + mizu.Log.Infof("Error creating Namespace %s: %v", mizu.ResourcesNamespace, err) } return err @@ -132,13 +132,13 @@ func createMizuApiServer(ctx context.Context, kubernetesProvider *kubernetes.Pro } _, err = kubernetesProvider.CreateMizuApiServerPod(ctx, mizu.ResourcesNamespace, mizu.ApiServerPodName, tappingOptions.MizuImage, serviceAccountName, mizuApiFilteringOptions, tappingOptions.MaxEntriesDBSizeBytes) if err != nil { - mizu.Log.Infof("Error creating mizu %s pod: %v\n", mizu.ApiServerPodName, err) + mizu.Log.Infof("Error creating mizu %s pod: %v", mizu.ApiServerPodName, err) return err } apiServerService, err = kubernetesProvider.CreateService(ctx, mizu.ResourcesNamespace, mizu.ApiServerPodName, mizu.ApiServerPodName) if err != nil { - mizu.Log.Infof("Error creating mizu %s service: %v\n", mizu.ApiServerPodName, err) + mizu.Log.Infof("Error creating mizu %s service: %v", mizu.ApiServerPodName, err) return err } @@ -183,12 +183,12 @@ func updateMizuTappers(ctx context.Context, kubernetesProvider *kubernetes.Provi serviceAccountName, tappingOptions.TapOutgoing, ); err != nil { - mizu.Log.Infof("Error creating mizu tapper daemonset: %v\n", err) + mizu.Log.Infof("Error creating mizu tapper daemonset: %v", err) return err } } else { if err := kubernetesProvider.RemoveDaemonSet(ctx, mizu.ResourcesNamespace, mizu.TapperDaemonSetName); err != nil { - mizu.Log.Infof("Error deleting mizu tapper daemonset: %v\n", err) + mizu.Log.Infof("Error deleting mizu tapper daemonset: %v", err) return err } } @@ -203,13 +203,13 @@ func cleanUpMizuResources(kubernetesProvider *kubernetes.Provider) { defer cancel() if err := kubernetesProvider.RemoveNamespace(removalCtx, mizu.ResourcesNamespace); err != nil { - mizu.Log.Infof("Error removing Namespace %s: %s (%v,%+v)\n", mizu.ResourcesNamespace, err, err, err) + mizu.Log.Infof("Error removing Namespace %s: %s (%v,%+v)", mizu.ResourcesNamespace, err, err, err) return } if mizuServiceAccountExists { if err := kubernetesProvider.RemoveNonNamespacedResources(removalCtx, mizu.ClusterRoleName, mizu.ClusterRoleBindingName); err != nil { - mizu.Log.Infof("Error removing non-namespaced resources: %s (%v,%+v)\n", err, err, err) + mizu.Log.Infof("Error removing non-namespaced resources: %s (%v,%+v)", err, err, err) return } } @@ -224,9 +224,9 @@ func cleanUpMizuResources(kubernetesProvider *kubernetes.Provider) { case removalCtx.Err() == context.Canceled: // Do nothing. User interrupted the wait. case err == wait.ErrWaitTimeout: - mizu.Log.Infof("Timeout while removing Namespace %s\n", mizu.ResourcesNamespace) + mizu.Log.Infof("Timeout while removing Namespace %s", mizu.ResourcesNamespace) default: - mizu.Log.Infof("Error while waiting for Namespace %s to be deleted: %s (%v,%+v)\n", mizu.ResourcesNamespace, err, err, err) + mizu.Log.Infof("Error while waiting for Namespace %s to be deleted: %s (%v,%+v)", mizu.ResourcesNamespace, err, err, err) } } } @@ -238,7 +238,7 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro restartTappers := func() { if matchingPods, err := kubernetesProvider.GetAllPodsMatchingRegex(ctx, podRegex, targetNamespace); err != nil { - mizu.Log.Infof("Error getting pods by regex: %s (%v,%+v)\n", err, err, err) + mizu.Log.Infof("Error getting pods by regex: %s (%v,%+v)", err, err, err) cancel() } else { currentlyTappedPods = matchingPods @@ -246,12 +246,12 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro nodeToTappedPodIPMap, err := getNodeHostToTappedPodIpsMap(currentlyTappedPods) if err != nil { - mizu.Log.Infof("Error building node to ips map: %s (%v,%+v)\n", err, err, err) + mizu.Log.Infof("Error building node to ips map: %s (%v,%+v)", err, err, err) cancel() } if err := updateMizuTappers(ctx, kubernetesProvider, nodeToTappedPodIPMap, tappingOptions); err != nil { - mizu.Log.Infof("Error updating daemonset: %s (%v,%+v)\n", err, err, err) + mizu.Log.Infof("Error updating daemonset: %s (%v,%+v)", err, err, err) cancel() } } @@ -260,10 +260,10 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro for { select { case newTarget := <-added: - mizu.Log.Infof(uiUtils.Green, fmt.Sprintf("+%s\n", newTarget.Name)) + mizu.Log.Infof(uiUtils.Green, fmt.Sprintf("+%s", newTarget.Name)) case removedTarget := <-removed: - mizu.Log.Infof(uiUtils.Red, fmt.Sprintf("-%s\n", removedTarget.Name)) + mizu.Log.Infof(uiUtils.Red, fmt.Sprintf("-%s", removedTarget.Name)) restartTappersDebouncer.SetOn() case modifiedTarget := <-modified: @@ -300,7 +300,7 @@ func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provi case <-added: continue case <-removed: - mizu.Log.Infof("%s removed\n", mizu.ApiServerPodName) + mizu.Log.Infof("%s removed", mizu.ApiServerPodName) cancel() return case modifiedPod := <-modified: @@ -309,12 +309,12 @@ func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provi go func() { err := kubernetes.StartProxy(kubernetesProvider, tappingOptions.GuiPort, mizu.ResourcesNamespace, mizu.ApiServerPodName) if err != nil { - mizu.Log.Infof("Error occured while running k8s proxy %v\n", err) + mizu.Log.Infof("Error occured while running k8s proxy %v", err) cancel() } }() mizuProxiedUrl := kubernetes.GetMizuApiServerProxiedHostAndPath(tappingOptions.GuiPort) - mizu.Log.Infof("Mizu is available at http://%s\n", mizuProxiedUrl) + mizu.Log.Infof("Mizu is available at http://%s", mizuProxiedUrl) time.Sleep(time.Second * 5) // Waiting to be sure the proxy is ready if tappingOptions.Analysis { @@ -324,11 +324,11 @@ func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provi if err != nil { log.Fatal(fmt.Sprintf("Failed parsing the URL %v\n", err)) } - mizu.Log.Debugf("Sending get request to %v\n", u.String()) + mizu.Log.Debugf("Sending get request to %v", u.String()) if response, err := http.Get(u.String()); err != nil || response.StatusCode != 200 { - mizu.Log.Infof("error sending upload entries req, status code: %v, err: %v\n", response.StatusCode, err) + mizu.Log.Infof("error sending upload entries req, status code: %v, err: %v", response.StatusCode, err) } else { - mizu.Log.Infof(uiUtils.Purple, "Traffic is uploading to UP9 for further analysis\n") + mizu.Log.Infof(uiUtils.Purple, "Traffic is uploading to UP9 for further analysis") } } } @@ -348,13 +348,13 @@ func portForwardApiPod(ctx context.Context, kubernetesProvider *kubernetes.Provi func createRBACIfNecessary(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool { mizuRBACExists, err := kubernetesProvider.DoesServiceAccountExist(ctx, mizu.ResourcesNamespace, mizu.ServiceAccountName) if err != nil { - mizu.Log.Infof("warning: could not ensure mizu rbac resources exist %v\n", err) + mizu.Log.Infof("warning: could not ensure mizu rbac resources exist %v", err) return false } if !mizuRBACExists { err := kubernetesProvider.CreateMizuRBAC(ctx, mizu.ResourcesNamespace, mizu.ServiceAccountName, mizu.ClusterRoleName, mizu.ClusterRoleBindingName, mizu.RBACVersion) if err != nil { - mizu.Log.Infof("warning: could not create mizu rbac resources %v\n", err) + mizu.Log.Infof("warning: could not create mizu rbac resources %v", err) return false } } @@ -391,7 +391,7 @@ func syncApiStatus(ctx context.Context, cancel context.CancelFunc, tappingOption controlSocketStr := fmt.Sprintf("ws://%s/ws", kubernetes.GetMizuApiServerProxiedHostAndPath(tappingOptions.GuiPort)) controlSocket, err := mizu.CreateControlSocket(controlSocketStr) if err != nil { - mizu.Log.Infof("error establishing control socket connection %s\n", err) + mizu.Log.Infof("error establishing control socket connection %s", err) cancel() } @@ -402,7 +402,7 @@ func syncApiStatus(ctx context.Context, cancel context.CancelFunc, tappingOption default: err = controlSocket.SendNewTappedPodsListMessage(currentlyTappedPods) if err != nil { - mizu.Log.Debugf("error Sending message via control socket %v, error: %s\n", controlSocketStr, err) + mizu.Log.Debugf("error Sending message via control socket %v, error: %s", controlSocketStr, err) } time.Sleep(10 * time.Second) } diff --git a/cli/cmd/version.go b/cli/cmd/version.go index dfe071c52..3a7a68667 100644 --- a/cli/cmd/version.go +++ b/cli/cmd/version.go @@ -20,11 +20,11 @@ var versionCmd = &cobra.Command{ go mizu.ReportRun("version", mizuVersionOptions) if mizuVersionOptions.DebugInfo { timeStampInt, _ := strconv.ParseInt(mizu.BuildTimestamp, 10, 0) - mizu.Log.Infof("Version: %s \nBranch: %s (%s) \n", mizu.SemVer, mizu.Branch, mizu.GitCommitHash) - mizu.Log.Infof("Build Time: %s (%s)\n", mizu.BuildTimestamp, time.Unix(timeStampInt, 0)) + mizu.Log.Infof("Version: %s \nBranch: %s (%s)", mizu.SemVer, mizu.Branch, mizu.GitCommitHash) + mizu.Log.Infof("Build Time: %s (%s)", mizu.BuildTimestamp, time.Unix(timeStampInt, 0)) } else { - mizu.Log.Infof("Version: %s (%s)\n", mizu.SemVer, mizu.Branch) + mizu.Log.Infof("Version: %s (%s)", mizu.SemVer, mizu.Branch) } return nil }, diff --git a/cli/cmd/viewRunner.go b/cli/cmd/viewRunner.go index caf6bd2d0..cbb9bc7fd 100644 --- a/cli/cmd/viewRunner.go +++ b/cli/cmd/viewRunner.go @@ -14,11 +14,11 @@ func runMizuView(mizuViewOptions *MizuViewOptions) { kubernetesProvider, err := kubernetes.NewProvider(mizuViewOptions.KubeConfigPath) if err != nil { if clientcmd.IsEmptyConfig(err) { - mizu.Log.Infof("Couldn't find the kube config file, or file is empty. Try adding '--kube-config='\n") + mizu.Log.Infof("Couldn't find the kube config file, or file is empty. Try adding '--kube-config='") return } if clientcmd.IsConfigurationInvalid(err) { - mizu.Log.Infof(uiUtils.Red, "Invalid kube config file. Try using a different config with '--kube-config='\n") + mizu.Log.Infof(uiUtils.Red, "Invalid kube config file. Try using a different config with '--kube-config='") return } } @@ -31,21 +31,21 @@ func runMizuView(mizuViewOptions *MizuViewOptions) { panic(err) } if !exists { - mizu.Log.Infof("The %s service not found\n", mizu.ApiServerPodName) + mizu.Log.Infof("The %s service not found", mizu.ApiServerPodName) return } mizuProxiedUrl := kubernetes.GetMizuApiServerProxiedHostAndPath(mizuViewOptions.GuiPort) _, err = http.Get(fmt.Sprintf("http://%s/", mizuProxiedUrl)) if err == nil { - mizu.Log.Infof("Found a running service %s and open port %d\n", mizu.ApiServerPodName, mizuViewOptions.GuiPort) + mizu.Log.Infof("Found a running service %s and open port %d", mizu.ApiServerPodName, mizuViewOptions.GuiPort) return } - mizu.Log.Infof("Found service %s, creating k8s proxy\n", mizu.ApiServerPodName) + mizu.Log.Infof("Found service %s, creating k8s proxy", mizu.ApiServerPodName) mizu.Log.Infof("Mizu is available at http://%s\n", kubernetes.GetMizuApiServerProxiedHostAndPath(mizuViewOptions.GuiPort)) err = kubernetes.StartProxy(kubernetesProvider, mizuViewOptions.GuiPort, mizu.ResourcesNamespace, mizu.ApiServerPodName) if err != nil { - mizu.Log.Infof("Error occured while running k8s proxy %v\n", err) + mizu.Log.Infof("Error occured while running k8s proxy %v", err) } } diff --git a/cli/mizu/versionCheck.go b/cli/mizu/versionCheck.go index 8677fdba2..365432f8d 100644 --- a/cli/mizu/versionCheck.go +++ b/cli/mizu/versionCheck.go @@ -45,7 +45,7 @@ func CheckVersionCompatibility(port uint16) (bool, error) { return true, nil } - Log.Infof(uiUtils.Red, fmt.Sprintf("cli version (%s) is not compatible with api version (%s)\n", SemVer, apiSemVer)) + Log.Infof(uiUtils.Red, fmt.Sprintf("cli version (%s) is not compatible with api version (%s)", SemVer, apiSemVer)) return false, nil } @@ -87,6 +87,6 @@ func CheckNewerVersion() { gitHubVersion = gitHubVersion[:len(gitHubVersion)-1] Log.Debugf("Finished version validation, took %v", time.Since(start)) if SemVer < gitHubVersion { - Log.Infof(uiUtils.Yellow, fmt.Sprintf("Update available! %v -> %v (%v)\n", SemVer, gitHubVersion, *latestRelease.HTMLURL)) + Log.Infof(uiUtils.Yellow, fmt.Sprintf("Update available! %v -> %v (%v)", SemVer, gitHubVersion, *latestRelease.HTMLURL)) } } From 1ef17542dd83c1df00892f4b8630704284d44f25 Mon Sep 17 00:00:00 2001 From: nimrod-up9 <59927337+nimrod-up9@users.noreply.github.com> Date: Tue, 27 Jul 2021 14:49:08 +0300 Subject: [PATCH 36/69] Format socket ID as int in logs. (#143) --- agent/pkg/api/socket_server_handlers.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/agent/pkg/api/socket_server_handlers.go b/agent/pkg/api/socket_server_handlers.go index c2fa7c628..3de88e389 100644 --- a/agent/pkg/api/socket_server_handlers.go +++ b/agent/pkg/api/socket_server_handlers.go @@ -27,9 +27,9 @@ func init() { func (h *RoutesEventHandlers) WebSocketConnect(socketId int, isTapper bool) { if isTapper { - rlog.Infof("Websocket Connection event - Tapper connected: %s", socketId) + rlog.Infof("Websocket event - Tapper connected, socket ID: %d", socketId) } else { - rlog.Infof("Websocket Connection event - Browser socket connected: %s", socketId) + rlog.Infof("Websocket event - Browser socket connected, socket ID: %d", socketId) socketListLock.Lock() browserClientSocketUUIDs = append(browserClientSocketUUIDs, socketId) socketListLock.Unlock() @@ -38,9 +38,9 @@ func (h *RoutesEventHandlers) WebSocketConnect(socketId int, isTapper bool) { func (h *RoutesEventHandlers) WebSocketDisconnect(socketId int, isTapper bool) { if isTapper { - rlog.Infof("Disconnection event - Tapper connected: %s", socketId) + rlog.Infof("Websocket event - Tapper disconnected, socket ID: %d", socketId) } else { - rlog.Infof("Disconnection event - Browser socket connected: %s", socketId) + rlog.Infof("Websocket event - Browser socket disconnected, socket ID: %d", socketId) socketListLock.Lock() removeSocketUUIDFromBrowserSlice(socketId) socketListLock.Unlock() @@ -52,7 +52,7 @@ func broadcastToBrowserClients(message []byte) { go func(socketId int) { err := routes.SendToSocket(socketId, message) if err != nil { - fmt.Printf("error sending message to socket id %d: %v", socketId, err) + fmt.Printf("error sending message to socket ID %d: %v", socketId, err) } }(socketId) From d888706e1e111fd285a06eee23289244451062e8 Mon Sep 17 00:00:00 2001 From: nimrod-up9 <59927337+nimrod-up9@users.noreply.github.com> Date: Tue, 27 Jul 2021 14:52:43 +0300 Subject: [PATCH 37/69] Show that the default answer to analysis prompt is yes. (#144) --- cli/cmd/tap.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go index 3e67195cd..16072facb 100644 --- a/cli/cmd/tap.go +++ b/cli/cmd/tap.go @@ -85,7 +85,7 @@ Supported protocols are HTTP and gRPC.`, if mizuTapOptions.Analysis { mizu.Log.Infof(analysisMessageToConfirm) - if !uiUtils.AskForConfirmation("Would you like to proceed [y/n]: ") { + if !uiUtils.AskForConfirmation("Would you like to proceed [Y/n]: ") { mizu.Log.Infof("You can always run mizu without analysis, aborting") os.Exit(0) } From ffa34039b14d903681490634724f58e0eb3a4938 Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Tue, 27 Jul 2021 15:10:22 +0300 Subject: [PATCH 38/69] Fix fetch telemetry report (#145) --- cli/cmd/fetch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/cmd/fetch.go b/cli/cmd/fetch.go index 9700b73ec..89faa545e 100644 --- a/cli/cmd/fetch.go +++ b/cli/cmd/fetch.go @@ -18,7 +18,7 @@ var fetchCmd = &cobra.Command{ Use: "fetch", Short: "Download recorded traffic to files", RunE: func(cmd *cobra.Command, args []string) error { - go mizu.ReportRun("tap", mizuTapOptions) + go mizu.ReportRun("fetch", mizuTapOptions) if isCompatible, err := mizu.CheckVersionCompatibility(mizuFetchOptions.MizuPort); err != nil { return err } else if !isCompatible { From 50e404f51e8f43e785fababed3be20f8de6c6712 Mon Sep 17 00:00:00 2001 From: Alon Girmonsky <1990761+alongir@users.noreply.github.com> Date: Tue, 27 Jul 2021 09:59:24 -0700 Subject: [PATCH 39/69] Create mizu-ui.png (#140) * Create mizu-ui.png --- README.md | 19 +++++++++++++++---- assets/mizu-example.png | Bin 0 -> 830144 bytes assets/mizu-logo.svg | 24 ++++++++++++++++++++++++ assets/mizu-ui.png | Bin 0 -> 502777 bytes 4 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 assets/mizu-example.png create mode 100644 assets/mizu-logo.svg create mode 100644 assets/mizu-ui.png diff --git a/README.md b/README.md index 50157ece2..34d720366 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,17 @@ -# æ°´ mizu +![Mizu: The API Traffic Viewer for Kubernetes](assets/mizu-logo.svg) +# The API Traffic Viewer for Kubernetes + A simple-yet-powerful API traffic viewer for Kubernetes to help you troubleshoot and debug your microservices. Think TCPDump and Chrome Dev Tools combined. +![Simple UI](assets/mizu-ui.png) + +## Features + +- Simple and powerful CLI +- Real time view of all HTTP requests, REST and gRPC API calls +- No installation or code instrumentation +- Works completely on premises (on-prem) + ## Download Download `mizu` for your platform and operating system @@ -142,10 +153,10 @@ See `examples/roles` for example `clusterroles`. ## How to run -1. Find pod you'd like to tap to in your Kubernetes cluster +1. Find pods you'd like to tap to in your Kubernetes cluster 2. Run `mizu tap PODNAME` or `mizu tap REGEX` -3. Open browser on `http://localhost:8899` as instructed .. -4. Watch the WebAPI traffic flowing .. +3. Open browser on `http://localhost:8899/mizu` **or** as instructed in the CLI .. +4. Watch the API traffic flowing .. 5. Type ^C to stop ## Examples diff --git a/assets/mizu-example.png b/assets/mizu-example.png new file mode 100644 index 0000000000000000000000000000000000000000..329da58ae10b38d7d7dadc6dda9eb41e7142d8d8 GIT binary patch literal 830144 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 + + + + + +} + +interface HAREntryPolicySectionContainerProps { + label: string; + matched: string; + children?: any; +} + +export const HAREntryPolicySectionContainer: React.FC = ({label, matched, children}) => { + const [expanded, setExpanded] = useState(false); + return setExpanded(!expanded)} + title={} + > + {children} + +} + +export const HAREntryTablePolicySection: React.FC = ({service, title, response, latency, arrayToIterate}) => { + const base64ToJson = response.content.mimeType === "application/json; charset=utf-8" ? JSON.parse(Buffer.from(response.content.text, "base64").toString()) : {}; + return + { + arrayToIterate && arrayToIterate.length > 0 ? + <> + +
Pod nameNamespace
Pod nameNamespace
{pod.name} {pod.namespace}
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 #|OF_Pu&S*2V9#4ZgSJT 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

ermY?&^8E!Kh2T1uhSVEq}Rvq-5XBe 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

{label}{matched}
+ + {arrayToIterate.map(({rule, matched}, index) => { + + + return ( + = latency : true)? "Success" : "Failure"}> + { + + <> + { + rule.Key != "" ? + + : null + } + { + rule.Latency != "" ? + + : null + } + { + rule.Method != "" ? + + : null + } + { + rule.Path != "" ? + + : null + } + { + rule.Service != "" ? + + : null + } + { + rule.Type != "" ? + + : null + } + { + rule.Value != "" ? + + : null + } + + } + + + + ) + } + ) + } + +
Key:{rule.Key}
Latency: {rule.Latency}
Method: {rule.Method}
Path: {rule.Path}
Service: {service}
Type: {rule.Type}
Value: {rule.Value}
+ + + : + } + +} \ No newline at end of file diff --git a/ui/src/components/HarEntryViewer/HAREntryViewer.tsx b/ui/src/components/HarEntryViewer/HAREntryViewer.tsx index 801d5cb2d..e0450e1e7 100644 --- a/ui/src/components/HarEntryViewer/HAREntryViewer.tsx +++ b/ui/src/components/HarEntryViewer/HAREntryViewer.tsx @@ -1,19 +1,22 @@ import React, {useState} from 'react'; import styles from './HAREntryViewer.module.sass'; import Tabs from "../Tabs"; -import {HAREntryTableSection, HAREntryBodySection} from "./HAREntrySections"; +import {HAREntryTableSection, HAREntryBodySection, HAREntryTablePolicySection} from "./HAREntrySections"; const MIME_TYPE_KEY = 'mimeType'; -const HAREntryDisplay: React.FC = ({entry, isCollapsed: initialIsCollapsed, isResponseMocked}) => { - const {request, response} = entry; - +const HAREntryDisplay: React.FC = ({har, entry, isCollapsed: initialIsCollapsed, isResponseMocked}) => { + const {request, response, timings: {receive}} = entry; + const rulesMatched = har.log.entries[0].rulesMatched const TABS = [ {tab: 'request'}, { tab: 'response', badge: <>{isResponseMocked && MOCK} }, + { + tab: 'Rules', + }, ]; const [currentTab, setCurrentTab] = useState(TABS[0].tab); @@ -43,6 +46,9 @@ const HAREntryDisplay: React.FC = ({entry, isCollapsed: initialIsCollapsed, } + {currentTab === TABS[2].tab && + + }
} ; } @@ -58,7 +64,7 @@ const HAREntryViewer: React.FC = ({harObject, className, isResponseMocked const {log: {entries}} = harObject; const isCollapsed = entries.length > 1; return
- {Object.keys(entries).map((entry: any, index) => )} + {Object.keys(entries).map((entry: any, index) => )}
}; diff --git a/ui/src/components/HarPage.tsx b/ui/src/components/HarPage.tsx index b96404cba..bfa7dbfb3 100644 --- a/ui/src/components/HarPage.tsx +++ b/ui/src/components/HarPage.tsx @@ -72,7 +72,6 @@ export const HarPage: React.FC = ({setAnalyzeStatus, onTLSDetected ws.current.onmessage = e => { if (!e?.data) return; const message = JSON.parse(e.data); - switch (message.messageType) { case "entry": const entry = message.data diff --git a/ui/src/components/style/HarEntry.module.sass b/ui/src/components/style/HarEntry.module.sass index fc5442f48..5425b1786 100644 --- a/ui/src/components/style/HarEntry.module.sass +++ b/ui/src/components/style/HarEntry.module.sass @@ -23,6 +23,14 @@ margin-left: 10px margin-right: 3px +.ruleSuccessRow + border: 1px $success-color solid + border-left: 5px $success-color solid + +.ruleFailureRow + border: 1px $failure-color solid + border-left: 5px $failure-color solid + .service text-overflow: ellipsis overflow: hidden From 04579eb03cc732f60e16b348d618948767e58961 Mon Sep 17 00:00:00 2001 From: Nimrod Gilboa Markevich <59927337+nimrod-up9@users.noreply.github.com> Date: Thu, 5 Aug 2021 10:28:31 +0300 Subject: [PATCH 55/69] Namespace restricted mode (#147) --- Makefile | 9 +- README.md | 205 +++++++++- agent/main.go | 19 +- agent/pkg/api/main.go | 4 +- agent/pkg/resolver/resolver.go | 23 +- cli/cmd/tap.go | 3 +- cli/cmd/tapRunner.go | 222 +++++++---- cli/cmd/viewRunner.go | 4 +- cli/errormessage/errormessage.go | 29 ++ cli/kubernetes/provider.go | 369 +++++++++--------- cli/mizu/configStruct.go | 29 +- cli/mizu/consts.go | 20 +- cli/uiUtils/colors.go | 20 +- ...-all-namespaces-without-ip-resolution.yaml | 8 +- .../roles/permissions-all-namespaces.yaml | 20 +- .../roles/permissions-ns-with-validation.yaml | 54 +++ .../permissions-ns-without-ip-resolution.yaml | 33 ++ examples/roles/permissions-ns.yaml | 51 +++ 18 files changed, 791 insertions(+), 331 deletions(-) create mode 100644 cli/errormessage/errormessage.go create mode 100644 examples/roles/permissions-ns-with-validation.yaml create mode 100644 examples/roles/permissions-ns-without-ip-resolution.yaml create mode 100644 examples/roles/permissions-ns.yaml diff --git a/Makefile b/Makefile index 6aa9b0847..bb85ff8ea 100644 --- a/Makefile +++ b/Makefile @@ -33,13 +33,8 @@ agent: ## Build agent. @(cd agent; go build -o build/mizuagent main.go) @ls -l agent/build -#tap: ## build tap binary -# @(cd tap; go build -o build/tap ./src) -# @ls -l tap/build - -docker: ## Build Docker image. - @(echo "building docker image" ) - ./build-push-featurebranch.sh +docker: ## Build and publish agent docker image. + $(MAKE) push-docker push: push-docker push-cli ## Build and publish agent docker image & CLI. diff --git a/README.md b/README.md index 34d720366..e09ab9988 100644 --- a/README.md +++ b/README.md @@ -50,12 +50,14 @@ Pick one from the [Releases](https://github.com/up9inc/mizu/releases) page. - list - watch - create + - delete - apiGroups: - "" resources: - services verbs: - create + - delete - apiGroups: - apps resources: @@ -63,11 +65,13 @@ Pick one from the [Releases](https://github.com/up9inc/mizu/releases) page. verbs: - create - patch + - delete - apiGroups: - "" resources: - namespaces verbs: + - get - list - watch - create @@ -79,7 +83,8 @@ Pick one from the [Releases](https://github.com/up9inc/mizu/releases) page. verbs: - get ``` -3. Optionally, for resolving traffic ip to kubernetes service name, mizu needs below permissions + +3. Optionally, for resolving traffic IP to kubernetes service name, mizu needs below permissions ```yaml - apiGroups: @@ -88,6 +93,10 @@ Pick one from the [Releases](https://github.com/up9inc/mizu/releases) page. - pods verbs: - get + - list + - watch + - create + - delete - apiGroups: - "" resources: @@ -96,6 +105,72 @@ Pick one from the [Releases](https://github.com/up9inc/mizu/releases) page. - get - list - watch + - create + - delete +- apiGroups: + - apps + resources: + - daemonsets + verbs: + - create + - patch + - delete +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch + - create + - delete +- apiGroups: + - "" + resources: + - services/proxy + verbs: + - get +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - get + - create + - delete +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + verbs: + - get + - create + - delete +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + verbs: + - get + - create + - delete +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - get + - create + - delete +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - get + - create + - delete - apiGroups: - apps - extensions @@ -124,6 +199,97 @@ Pick one from the [Releases](https://github.com/up9inc/mizu/releases) page. - get - list - watch +``` + +4. Optionally, in order to use the policy rules validation feature, mizu requires the following additional permissions: + +```yaml +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - create + - delete +``` + +5. Alternatively, in order to restrict mizu to one namespace only (by setting `agent.namespace` in the config file), mizu needs the following permissions in that namespace: + +```yaml +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + - create + - delete +- apiGroups: + - "" + resources: + - services + verbs: + - get + - create + - delete +- apiGroups: + - apps + resources: + - daemonsets + verbs: + - get + - create + - patch + - delete +- apiGroups: + - "" + resources: + - services/proxy + verbs: + - get +``` + +6. To restrict mizu to one namespace while also resolving IPs, mizu needs the following permissions in that namespace: + +```yaml +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + - create + - delete +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch + - create + - delete +- apiGroups: + - apps + resources: + - daemonsets + verbs: + - get + - create + - patch + - delete +- apiGroups: + - "" + resources: + - services/proxy + verbs: + - get - apiGroups: - "" resources: @@ -131,22 +297,51 @@ Pick one from the [Releases](https://github.com/up9inc/mizu/releases) page. verbs: - get - create + - delete - apiGroups: - rbac.authorization.k8s.io resources: - - clusterroles + - roles verbs: - - list + - get - create - delete - apiGroups: - rbac.authorization.k8s.io resources: - - clusterrolebindings + - rolebindings verbs: - - list + - get - create - delete +- apiGroups: + - apps + - extensions + resources: + - pods + verbs: + - get + - list + - watch +- apiGroups: + - apps + - extensions + resources: + - services + verbs: + - get + - list + - watch +- apiGroups: + - "" + - apps + - extensions + resources: + - endpoints + verbs: + - get + - list + - watch ``` See `examples/roles` for example `clusterroles`. diff --git a/agent/main.go b/agent/main.go index 2d7c8096e..381433832 100644 --- a/agent/main.go +++ b/agent/main.go @@ -21,21 +21,24 @@ import ( "strings" ) -var shouldTap = flag.Bool("tap", false, "Run in tapper mode without API") -var apiServer = flag.Bool("api-server", false, "Run in API server mode with API") -var standalone = flag.Bool("standalone", false, "Run in standalone tapper and API mode") +var tapperMode = flag.Bool("tap", false, "Run in tapper mode without API") +var apiServerMode = flag.Bool("api-server", false, "Run in API server mode with API") +var standaloneMode = flag.Bool("standalone", false, "Run in standalone tapper and API mode") var apiServerAddress = flag.String("api-server-address", "", "Address of mizu API server") +var namespace = flag.String("namespace", "", "Resolve IPs if they belong to resources in this namespace (default is all)") func main() { flag.Parse() hostMode := os.Getenv(shared.HostModeEnvVar) == "1" tapOpts := &tap.TapOpts{HostMode: hostMode} - if !*shouldTap && !*apiServer && !*standalone { + if !*tapperMode && !*apiServerMode && !*standaloneMode { panic("One of the flags --tap, --api or --standalone must be provided") } - if *standalone { + if *standaloneMode { + api.StartResolving(*namespace) + harOutputChannel, outboundLinkOutputChannel := tap.StartPassiveTapper(tapOpts) filteredHarChannel := make(chan *tap.OutputChannelItem) @@ -44,7 +47,7 @@ func main() { go api.StartReadingOutbound(outboundLinkOutputChannel) hostApi(nil) - } else if *shouldTap { + } else if *tapperMode { if *apiServerAddress == "" { panic("API server address must be provided with --api-server-address when using --tap") } @@ -64,7 +67,9 @@ func main() { go pipeTapChannelToSocket(socketConnection, harOutputChannel) go pipeOutboundLinksChannelToSocket(socketConnection, outboundLinkOutputChannel) - } else if *apiServer { + } else if *apiServerMode { + api.StartResolving(*namespace) + socketHarOutChannel := make(chan *tap.OutputChannelItem, 1000) filteredHarChannel := make(chan *tap.OutputChannelItem) diff --git a/agent/pkg/api/main.go b/agent/pkg/api/main.go index 70439fc47..5c41251fa 100644 --- a/agent/pkg/api/main.go +++ b/agent/pkg/api/main.go @@ -26,7 +26,7 @@ import ( var k8sResolver *resolver.Resolver -func init() { +func StartResolving(namespace string) { errOut := make(chan error, 100) res, err := resolver.NewFromInCluster(errOut) if err != nil { @@ -34,7 +34,7 @@ func init() { return } ctx := context.Background() - res.Start(ctx) + res.Start(ctx, namespace) go func() { for { select { diff --git a/agent/pkg/resolver/resolver.go b/agent/pkg/resolver/resolver.go index e2b09e4c3..6b8bd6e9f 100644 --- a/agent/pkg/resolver/resolver.go +++ b/agent/pkg/resolver/resolver.go @@ -18,17 +18,20 @@ const ( ) type Resolver struct { - clientConfig *restclient.Config - clientSet *kubernetes.Clientset - nameMap map[string]string - serviceMap map[string]string - isStarted bool - errOut chan error + clientConfig *restclient.Config + clientSet *kubernetes.Clientset + nameMap map[string]string + serviceMap map[string]string + isStarted bool + errOut chan error + namespace string } -func (resolver *Resolver) Start(ctx context.Context) { +func (resolver *Resolver) Start(ctx context.Context, namespace string) { if !resolver.isStarted { resolver.isStarted = true + resolver.namespace = namespace + go resolver.infiniteErrorHandleRetryFunc(ctx, resolver.watchServices) go resolver.infiniteErrorHandleRetryFunc(ctx, resolver.watchEndpoints) go resolver.infiniteErrorHandleRetryFunc(ctx, resolver.watchPods) @@ -54,7 +57,7 @@ func (resolver *Resolver) CheckIsServiceIP(address string) bool { func (resolver *Resolver) watchPods(ctx context.Context) error { // empty namespace makes the client watch all namespaces - watcher, err := resolver.clientSet.CoreV1().Pods("").Watch(ctx, metav1.ListOptions{Watch: true}) + watcher, err := resolver.clientSet.CoreV1().Pods(resolver.namespace).Watch(ctx, metav1.ListOptions{Watch: true}) if err != nil { return err } @@ -77,7 +80,7 @@ func (resolver *Resolver) watchPods(ctx context.Context) error { func (resolver *Resolver) watchEndpoints(ctx context.Context) error { // empty namespace makes the client watch all namespaces - watcher, err := resolver.clientSet.CoreV1().Endpoints("").Watch(ctx, metav1.ListOptions{Watch: true}) + watcher, err := resolver.clientSet.CoreV1().Endpoints(resolver.namespace).Watch(ctx, metav1.ListOptions{Watch: true}) if err != nil { return err } @@ -120,7 +123,7 @@ func (resolver *Resolver) watchEndpoints(ctx context.Context) error { func (resolver *Resolver) watchServices(ctx context.Context) error { // empty namespace makes the client watch all namespaces - watcher, err := resolver.clientSet.CoreV1().Services("").Watch(ctx, metav1.ListOptions{Watch: true}) + watcher, err := resolver.clientSet.CoreV1().Services(resolver.namespace).Watch(ctx, metav1.ListOptions{Watch: true}) if err != nil { return err } diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go index 098a54824..bfb62dcc6 100644 --- a/cli/cmd/tap.go +++ b/cli/cmd/tap.go @@ -6,6 +6,7 @@ import ( "github.com/creasty/defaults" "github.com/spf13/cobra" + "github.com/up9inc/mizu/cli/errormessage" "github.com/up9inc/mizu/cli/mizu" "github.com/up9inc/mizu/cli/mizu/configStructs" "github.com/up9inc/mizu/cli/uiUtils" @@ -31,7 +32,7 @@ Supported protocols are HTTP and gRPC.`, } if err := mizu.Config.Tap.Validate(); err != nil { - return err + return errormessage.FormatError(err) } mizu.Log.Infof("Mizu will store up to %s of traffic, old traffic will be cleared once the limit is reached.", mizu.Config.Tap.HumanMaxEntriesDBSize) diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index f3d8b0228..2a3868c1c 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -13,6 +13,7 @@ import ( "syscall" "time" + "github.com/up9inc/mizu/cli/errormessage" "github.com/up9inc/mizu/cli/kubernetes" "github.com/up9inc/mizu/cli/mizu" "github.com/up9inc/mizu/cli/uiUtils" @@ -20,31 +21,35 @@ import ( "github.com/up9inc/mizu/shared/debounce" yaml "gopkg.in/yaml.v3" core "k8s.io/api/core/v1" - errors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/tools/clientcmd" ) -var mizuServiceAccountExists bool -var apiServerService *core.Service - const ( - updateTappersDelay = 5 * time.Second cleanupTimeout = time.Minute + updateTappersDelay = 5 * time.Second ) -var currentlyTappedPods []core.Pod +type tapState struct { + apiServerService *core.Service + currentlyTappedPods []core.Pod + mizuServiceAccountExists bool + doNotRemoveConfigMap bool +} + +var state tapState func RunMizuTap() { mizuApiFilteringOptions, err := getMizuApiFilteringOptions() if err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error parsing regex-masking: %v", errormessage.FormatError(err))) return } var mizuValidationRules string if mizu.Config.Tap.EnforcePolicyFile != "" { mizuValidationRules, err = readValidationRules(mizu.Config.Tap.EnforcePolicyFile) if err != nil { - mizu.Log.Infof("error: %v", err) + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error reading policy file: %v", errormessage.FormatError(err))) return } } @@ -52,11 +57,11 @@ func RunMizuTap() { kubernetesProvider, err := kubernetes.NewProvider(mizu.Config.Tap.KubeConfigPath) if err != nil { if clientcmd.IsEmptyConfig(err) { - mizu.Log.Infof(uiUtils.Red, "Couldn't find the kube config file, or file is empty. Try adding '--kube-config='\n") + mizu.Log.Errorf(uiUtils.Error, "Couldn't find the kube config file, or file is empty. Try adding '--kube-config='\n") return } if clientcmd.IsConfigurationInvalid(err) { - mizu.Log.Infof(uiUtils.Red, "Invalid kube config file. Try using a different config with '--kube-config='\n") + mizu.Log.Errorf(uiUtils.Error, "Invalid kube config file. Try using a different config with '--kube-config='\n") return } } @@ -76,28 +81,26 @@ func RunMizuTap() { mizu.Log.Infof("Tapping pods in %s", namespacesStr) if err, _ := updateCurrentlyTappedPods(kubernetesProvider, ctx, targetNamespace); err != nil { - mizu.Log.Infof("Error listing pods: %v", err) + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error getting pods by regex: %v", errormessage.FormatError(err))) return } - if len(currentlyTappedPods) == 0 { + if len(state.currentlyTappedPods) == 0 { var suggestionStr string if targetNamespace != mizu.K8sAllNamespaces { - suggestionStr = "\nSelect a different namespace with -n or tap all namespaces with -A" + suggestionStr = ". Select a different namespace with -n or tap all namespaces with -A" } - mizu.Log.Infof("Did not find any pods matching the regex argument%s", suggestionStr) + mizu.Log.Warningf(uiUtils.Warning, fmt.Sprintf("Did not find any pods matching the regex argument%s", suggestionStr)) } if mizu.Config.Tap.DryRun { return } - nodeToTappedPodIPMap, err := getNodeHostToTappedPodIpsMap(currentlyTappedPods) - if err != nil { - return - } + nodeToTappedPodIPMap := getNodeHostToTappedPodIpsMap(state.currentlyTappedPods) if err := createMizuResources(ctx, kubernetesProvider, nodeToTappedPodIPMap, mizuApiFilteringOptions, mizuValidationRules); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error creating resources: %v", errormessage.FormatError(err))) return } @@ -118,8 +121,10 @@ func readValidationRules(file string) (string, error) { } func createMizuResources(ctx context.Context, kubernetesProvider *kubernetes.Provider, nodeToTappedPodIPMap map[string][]string, mizuApiFilteringOptions *shared.TrafficFilteringOptions, mizuValidationRules string) error { - if err := createMizuNamespace(ctx, kubernetesProvider); err != nil { - return err + if mizu.Config.IsOwnNamespace() { + if err := createMizuNamespace(ctx, kubernetesProvider); err != nil { + return err + } } if err := createMizuApiServer(ctx, kubernetesProvider, mizuApiFilteringOptions); err != nil { @@ -131,50 +136,57 @@ func createMizuResources(ctx context.Context, kubernetesProvider *kubernetes.Pro } if err := createMizuConfigmap(ctx, kubernetesProvider, mizuValidationRules); err != nil { - return err + mizu.Log.Warningf(uiUtils.Warning, fmt.Sprintf("Failed to create resources required for policy validation. Mizu will not validate policy rules. error: %v\n", errormessage.FormatError(err))) + state.doNotRemoveConfigMap = true + } else if mizuValidationRules == "" { + state.doNotRemoveConfigMap = true } return nil } func createMizuConfigmap(ctx context.Context, kubernetesProvider *kubernetes.Provider, data string) error { - err := kubernetesProvider.ApplyConfigMap(ctx, mizu.ResourcesNamespace, mizu.ConfigMapName, data) - if err != nil { - fmt.Printf("Error creating mizu configmap: %v\n", err) - } - return nil + err := kubernetesProvider.CreateConfigMap(ctx, mizu.Config.ResourcesNamespace(), mizu.ConfigMapName, data) + return err } func createMizuNamespace(ctx context.Context, kubernetesProvider *kubernetes.Provider) error { - _, err := kubernetesProvider.CreateNamespace(ctx, mizu.ResourcesNamespace) - if err != nil { - mizu.Log.Infof("Error creating Namespace %s: %v", mizu.ResourcesNamespace, err) - return err - } - mizu.Log.Debugf("Successfully creating Namespace %s", mizu.ResourcesNamespace) - return nil + _, err := kubernetesProvider.CreateNamespace(ctx, mizu.Config.ResourcesNamespace()) + return err } func createMizuApiServer(ctx context.Context, kubernetesProvider *kubernetes.Provider, mizuApiFilteringOptions *shared.TrafficFilteringOptions) error { var err error - mizuServiceAccountExists = createRBACIfNecessary(ctx, kubernetesProvider) + state.mizuServiceAccountExists, err = createRBACIfNecessary(ctx, kubernetesProvider) + if err != nil { + mizu.Log.Warningf(uiUtils.Warning, fmt.Sprintf("Failed to ensure the resources required for IP resolving. Mizu will not resolve target IPs to names. error: %v", errormessage.FormatError(err))) + } + var serviceAccountName string - if mizuServiceAccountExists { + if state.mizuServiceAccountExists { serviceAccountName = mizu.ServiceAccountName } else { serviceAccountName = "" } - _, err = kubernetesProvider.CreateMizuApiServerPod(ctx, mizu.ResourcesNamespace, mizu.ApiServerPodName, mizu.Config.MizuImage, serviceAccountName, mizuApiFilteringOptions, mizu.Config.Tap.MaxEntriesDBSizeBytes()) + + opts := &kubernetes.ApiServerOptions{ + Namespace: mizu.Config.ResourcesNamespace(), + PodName: mizu.ApiServerPodName, + PodImage: mizu.Config.MizuImage, + ServiceAccountName: serviceAccountName, + IsNamespaceRestricted: !mizu.Config.IsOwnNamespace(), + MizuApiFilteringOptions: mizuApiFilteringOptions, + MaxEntriesDBSizeBytes: mizu.Config.Tap.MaxEntriesDBSizeBytes(), + } + _, err = kubernetesProvider.CreateMizuApiServerPod(ctx, opts) if err != nil { - mizu.Log.Infof("Error creating mizu %s pod: %v", mizu.ApiServerPodName, err) return err } mizu.Log.Debugf("Successfully created API server pod: %s", mizu.ApiServerPodName) - apiServerService, err = kubernetesProvider.CreateService(ctx, mizu.ResourcesNamespace, mizu.ApiServerPodName, mizu.ApiServerPodName) + state.apiServerService, err = kubernetesProvider.CreateService(ctx, mizu.Config.ResourcesNamespace(), mizu.ApiServerPodName, mizu.ApiServerPodName) if err != nil { - mizu.Log.Infof("Error creating mizu %s service: %v", mizu.ApiServerPodName, err) return err } mizu.Log.Debugf("Successfully created service: %s", mizu.ApiServerPodName) @@ -183,7 +195,6 @@ func createMizuApiServer(ctx context.Context, kubernetesProvider *kubernetes.Pro } func getMizuApiFilteringOptions() (*shared.TrafficFilteringOptions, error) { - var compiledRegexSlice []*shared.SerializableRegexp if mizu.Config.Tap.PlainTextFilterRegexes != nil && len(mizu.Config.Tap.PlainTextFilterRegexes) > 0 { @@ -191,7 +202,6 @@ func getMizuApiFilteringOptions() (*shared.TrafficFilteringOptions, error) { for _, regexStr := range mizu.Config.Tap.PlainTextFilterRegexes { compiledRegex, err := shared.CompileRegexToSerializableRegexp(regexStr) if err != nil { - mizu.Log.Infof("Regex %s is invalid: %v", regexStr, err) return nil, err } compiledRegexSlice = append(compiledRegexSlice, compiledRegex) @@ -204,7 +214,7 @@ func getMizuApiFilteringOptions() (*shared.TrafficFilteringOptions, error) { func updateMizuTappers(ctx context.Context, kubernetesProvider *kubernetes.Provider, nodeToTappedPodIPMap map[string][]string) error { if len(nodeToTappedPodIPMap) > 0 { var serviceAccountName string - if mizuServiceAccountExists { + if state.mizuServiceAccountExists { serviceAccountName = mizu.ServiceAccountName } else { serviceAccountName = "" @@ -212,22 +222,20 @@ func updateMizuTappers(ctx context.Context, kubernetesProvider *kubernetes.Provi if err := kubernetesProvider.ApplyMizuTapperDaemonSet( ctx, - mizu.ResourcesNamespace, + mizu.Config.ResourcesNamespace(), mizu.TapperDaemonSetName, mizu.Config.MizuImage, mizu.TapperPodName, - fmt.Sprintf("%s.%s.svc.cluster.local", apiServerService.Name, apiServerService.Namespace), + fmt.Sprintf("%s.%s.svc.cluster.local", state.apiServerService.Name, state.apiServerService.Namespace), nodeToTappedPodIPMap, serviceAccountName, mizu.Config.Tap.TapOutgoing(), ); err != nil { - mizu.Log.Infof("Error creating mizu tapper daemonset: %v", err) return err } mizu.Log.Debugf("Successfully created %v tappers", len(nodeToTappedPodIPMap)) } else { - if err := kubernetesProvider.RemoveDaemonSet(ctx, mizu.ResourcesNamespace, mizu.TapperDaemonSetName); err != nil { - mizu.Log.Errorf("Error deleting mizu tapper daemonset: %v", err) + if err := kubernetesProvider.RemoveDaemonSet(ctx, mizu.Config.ResourcesNamespace(), mizu.TapperDaemonSetName); err != nil { return err } } @@ -241,31 +249,73 @@ func cleanUpMizuResources(kubernetesProvider *kubernetes.Provider) { removalCtx, cancel := context.WithTimeout(context.Background(), cleanupTimeout) defer cancel() - if err := kubernetesProvider.RemoveNamespace(removalCtx, mizu.ResourcesNamespace); err != nil { - mizu.Log.Infof("Error removing Namespace %s: %s (%v,%+v)", mizu.ResourcesNamespace, err, err, err) - return + if mizu.Config.IsOwnNamespace() { + if err := kubernetesProvider.RemoveNamespace(removalCtx, mizu.Config.ResourcesNamespace()); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing Namespace %s: %v", mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + return + } + } else { + if err := kubernetesProvider.RemovePod(removalCtx, mizu.Config.ResourcesNamespace(), mizu.ApiServerPodName); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing Pod %s in namespace %s: %v", mizu.ApiServerPodName, mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + } + + if err := kubernetesProvider.RemoveService(removalCtx, mizu.Config.ResourcesNamespace(), mizu.ApiServerPodName); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing Service %s in namespace %s: %v", mizu.ApiServerPodName, mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + } + + if err := kubernetesProvider.RemoveDaemonSet(removalCtx, mizu.Config.ResourcesNamespace(), mizu.TapperDaemonSetName); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing DaemonSet %s in namespace %s: %v", mizu.TapperDaemonSetName, mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + } + + if !state.doNotRemoveConfigMap { + if err := kubernetesProvider.RemoveConfigMap(removalCtx, mizu.Config.ResourcesNamespace(), mizu.ConfigMapName); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing ConfigMap %s in namespace %s: %v", mizu.ConfigMapName, mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + } + } + } - if mizuServiceAccountExists { - if err := kubernetesProvider.RemoveNonNamespacedResources(removalCtx, mizu.ClusterRoleName, mizu.ClusterRoleBindingName); err != nil { - mizu.Log.Infof("Error removing non-namespaced resources: %s (%v,%+v)", err, err, err) - return + if state.mizuServiceAccountExists { + if mizu.Config.IsOwnNamespace() { + if err := kubernetesProvider.RemoveNonNamespacedResources(removalCtx, mizu.ClusterRoleName, mizu.ClusterRoleBindingName); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing non-namespaced resources: %v", errormessage.FormatError(err))) + return + } + } else { + if err := kubernetesProvider.RemoveServicAccount(removalCtx, mizu.Config.ResourcesNamespace(), mizu.ServiceAccountName); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing Service Account %s in namespace %s: %v", mizu.ServiceAccountName, mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + return + } + + if err := kubernetesProvider.RemoveRole(removalCtx, mizu.Config.ResourcesNamespace(), mizu.RoleName); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing Role %s in namespace %s: %v", mizu.RoleName, mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + } + + if err := kubernetesProvider.RemoveRoleBinding(removalCtx, mizu.Config.ResourcesNamespace(), mizu.RoleBindingName); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing RoleBinding %s in namespace %s: %v", mizu.RoleBindingName, mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + } } } + if mizu.Config.IsOwnNamespace() { + waitUntilNamespaceDeleted(removalCtx, cancel, kubernetesProvider) + } +} + +func waitUntilNamespaceDeleted(ctx context.Context, cancel context.CancelFunc, kubernetesProvider *kubernetes.Provider) { // Call cancel if a terminating signal was received. Allows user to skip the wait. go func() { - waitForFinish(removalCtx, cancel) + waitForFinish(ctx, cancel) }() - if err := kubernetesProvider.WaitUtilNamespaceDeleted(removalCtx, mizu.ResourcesNamespace); err != nil { + if err := kubernetesProvider.WaitUtilNamespaceDeleted(ctx, mizu.Config.ResourcesNamespace()); err != nil { switch { - case removalCtx.Err() == context.Canceled: + case ctx.Err() == context.Canceled: // Do nothing. User interrupted the wait. case err == wait.ErrWaitTimeout: - mizu.Log.Infof("Timeout while removing Namespace %s", mizu.ResourcesNamespace) + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Timeout while removing Namespace %s", mizu.Config.ResourcesNamespace())) default: - mizu.Log.Infof("Error while waiting for Namespace %s to be deleted: %s (%v,%+v)", mizu.ResourcesNamespace, err, err, err) + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error while waiting for Namespace %s to be deleted: %v", mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) } } } @@ -275,7 +325,7 @@ func reportTappedPods() { tappedPodsUrl := fmt.Sprintf("http://%s/status/tappedPods", mizuProxiedUrl) podInfos := make([]shared.PodInfo, 0) - for _, pod := range currentlyTappedPods { + for _, pod := range state.currentlyTappedPods { podInfos = append(podInfos, shared.PodInfo{Name: pod.Name, Namespace: pod.Namespace}) } tapStatus := shared.TapStatus{Pods: podInfos} @@ -300,7 +350,7 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro restartTappers := func() { err, changeFound := updateCurrentlyTappedPods(kubernetesProvider, ctx, targetNamespace) if err != nil { - mizu.Log.Errorf("Error getting pods by regex: %s (%v,%+v)", err, err, err) + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error getting pods by regex: %v", errormessage.FormatError(err))) cancel() } @@ -311,13 +361,13 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro reportTappedPods() - nodeToTappedPodIPMap, err := getNodeHostToTappedPodIpsMap(currentlyTappedPods) + nodeToTappedPodIPMap := getNodeHostToTappedPodIpsMap(state.currentlyTappedPods) if err != nil { - mizu.Log.Errorf("Error building node to ips map: %s (%v,%+v)", err, err, err) + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error building node to ips map: %v", errormessage.FormatError(err))) cancel() } if err := updateMizuTappers(ctx, kubernetesProvider, nodeToTappedPodIPMap); err != nil { - mizu.Log.Errorf("Error updating daemonset: %s (%v,%+v)", err, err, err) + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error updating daemonset: %v", errormessage.FormatError(err))) cancel() } } @@ -356,10 +406,9 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro func updateCurrentlyTappedPods(kubernetesProvider *kubernetes.Provider, ctx context.Context, targetNamespace string) (error, bool) { changeFound := false if matchingPods, err := kubernetesProvider.GetAllRunningPodsMatchingRegex(ctx, mizu.Config.Tap.PodRegex(), targetNamespace); err != nil { - mizu.Log.Infof("Error getting pods by regex: %s (%v,%+v)", err, err, err) return err, false } else { - addedPods, removedPods := getPodArrayDiff(currentlyTappedPods, matchingPods) + addedPods, removedPods := getPodArrayDiff(state.currentlyTappedPods, matchingPods) for _, addedPod := range addedPods { changeFound = true mizu.Log.Infof(uiUtils.Green, fmt.Sprintf("+%s", addedPod.Name)) @@ -368,7 +417,7 @@ func updateCurrentlyTappedPods(kubernetesProvider *kubernetes.Provider, ctx cont changeFound = true mizu.Log.Infof(uiUtils.Red, fmt.Sprintf("-%s", removedPod.Name)) } - currentlyTappedPods = matchingPods + state.currentlyTappedPods = matchingPods } return nil, changeFound @@ -401,7 +450,7 @@ func getMissingPods(pods1 []core.Pod, pods2 []core.Pod) []core.Pod { func createProxyToApiServerPod(ctx context.Context, kubernetesProvider *kubernetes.Provider, cancel context.CancelFunc) { podExactRegex := regexp.MustCompile(fmt.Sprintf("^%s$", mizu.ApiServerPodName)) - added, modified, removed, errorChan := kubernetes.FilteredWatch(ctx, kubernetesProvider.GetPodWatcher(ctx, mizu.ResourcesNamespace), podExactRegex) + added, modified, removed, errorChan := kubernetes.FilteredWatch(ctx, kubernetesProvider.GetPodWatcher(ctx, mizu.Config.ResourcesNamespace()), podExactRegex) isPodReady := false timeAfter := time.After(25 * time.Second) for { @@ -420,24 +469,26 @@ func createProxyToApiServerPod(ctx context.Context, kubernetesProvider *kubernet if modifiedPod.Status.Phase == core.PodRunning && !isPodReady { isPodReady = true go func() { - err := kubernetes.StartProxy(kubernetesProvider, mizu.Config.Tap.GuiPort, mizu.ResourcesNamespace, mizu.ApiServerPodName) + err := kubernetes.StartProxy(kubernetesProvider, mizu.Config.Tap.GuiPort, mizu.Config.ResourcesNamespace(), mizu.ApiServerPodName) if err != nil { - mizu.Log.Errorf("Error occurred while running k8s proxy %v", err) + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error occured while running k8s proxy %v", errormessage.FormatError(err))) cancel() } }() - mizu.Log.Infof("Mizu is available at http://%s\n", kubernetes.GetMizuApiServerProxiedHostAndPath(mizu.Config.Tap.GuiPort)) + mizuProxiedUrl := kubernetes.GetMizuApiServerProxiedHostAndPath(mizu.Config.Tap.GuiPort) + mizu.Log.Infof("Mizu is available at http://%s\n", mizuProxiedUrl) + time.Sleep(time.Second * 5) // Waiting to be sure the proxy is ready requestForAnalysis() reportTappedPods() } case <-timeAfter: if !isPodReady { - mizu.Log.Errorf("Error: %s pod was not ready in time", mizu.ApiServerPodName) + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("%s pod was not ready in time", mizu.ApiServerPodName)) cancel() } case <-errorChan: - mizu.Log.Debugf("[ERROR] Agent creation, watching %v namespace", mizu.ResourcesNamespace) + mizu.Log.Debugf("[ERROR] Agent creation, watching %v namespace", mizu.Config.ResourcesNamespace()) cancel() } } @@ -465,23 +516,28 @@ func requestForAnalysis() { } } -func createRBACIfNecessary(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool { - mizuRBACExists, err := kubernetesProvider.DoesServiceAccountExist(ctx, mizu.ResourcesNamespace, mizu.ServiceAccountName) +func createRBACIfNecessary(ctx context.Context, kubernetesProvider *kubernetes.Provider) (bool, error) { + mizuRBACExists, err := kubernetesProvider.DoesServiceAccountExist(ctx, mizu.Config.ResourcesNamespace(), mizu.ServiceAccountName) if err != nil { - mizu.Log.Infof("warning: could not ensure mizu rbac resources exist %v", err) - return false + return false, err } if !mizuRBACExists { - err := kubernetesProvider.CreateMizuRBAC(ctx, mizu.ResourcesNamespace, mizu.ServiceAccountName, mizu.ClusterRoleName, mizu.ClusterRoleBindingName, mizu.RBACVersion) - if err != nil && !errors.IsAlreadyExists(err) { - mizu.Log.Infof("warning: could not create mizu rbac resources %v", err) - return false + if mizu.Config.IsOwnNamespace() { + err := kubernetesProvider.CreateMizuRBAC(ctx, mizu.Config.ResourcesNamespace(), mizu.ServiceAccountName, mizu.ClusterRoleName, mizu.ClusterRoleBindingName, mizu.RBACVersion) + if err != nil { + return false, err + } + } else { + err := kubernetesProvider.CreateMizuRBACNamespaceRestricted(ctx, mizu.Config.ResourcesNamespace(), mizu.ServiceAccountName, mizu.RoleName, mizu.RoleBindingName, mizu.RBACVersion) + if err != nil { + return false, err + } } } - return true + return true, nil } -func getNodeHostToTappedPodIpsMap(tappedPods []core.Pod) (map[string][]string, error) { +func getNodeHostToTappedPodIpsMap(tappedPods []core.Pod) map[string][]string { nodeToTappedPodIPMap := make(map[string][]string, 0) for _, pod := range tappedPods { existingList := nodeToTappedPodIPMap[pod.Spec.NodeName] @@ -491,7 +547,7 @@ func getNodeHostToTappedPodIpsMap(tappedPods []core.Pod) (map[string][]string, e nodeToTappedPodIPMap[pod.Spec.NodeName] = append(nodeToTappedPodIPMap[pod.Spec.NodeName], pod.Status.PodIP) } } - return nodeToTappedPodIPMap, nil + return nodeToTappedPodIPMap } func waitForFinish(ctx context.Context, cancel context.CancelFunc) { diff --git a/cli/cmd/viewRunner.go b/cli/cmd/viewRunner.go index c15c71be7..cdc2119f5 100644 --- a/cli/cmd/viewRunner.go +++ b/cli/cmd/viewRunner.go @@ -27,7 +27,7 @@ func runMizuView() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - exists, err := kubernetesProvider.DoesServicesExist(ctx, mizu.ResourcesNamespace, mizu.ApiServerPodName) + exists, err := kubernetesProvider.DoesServicesExist(ctx, mizu.Config.ResourcesNamespace(), mizu.ApiServerPodName) if err != nil { panic(err) } @@ -45,7 +45,7 @@ func runMizuView() { mizu.Log.Infof("Found service %s, creating k8s proxy", mizu.ApiServerPodName) mizu.Log.Infof("Mizu is available at http://%s\n", kubernetes.GetMizuApiServerProxiedHostAndPath(mizu.Config.View.GuiPort)) - err = kubernetes.StartProxy(kubernetesProvider, mizu.Config.View.GuiPort, mizu.ResourcesNamespace, mizu.ApiServerPodName) + err = kubernetes.StartProxy(kubernetesProvider, mizu.Config.View.GuiPort, mizu.Config.ResourcesNamespace(), mizu.ApiServerPodName) if err != nil { mizu.Log.Infof("Error occured while running k8s proxy %v", err) } diff --git a/cli/errormessage/errormessage.go b/cli/errormessage/errormessage.go new file mode 100644 index 000000000..510581e8d --- /dev/null +++ b/cli/errormessage/errormessage.go @@ -0,0 +1,29 @@ +package errormessage + +import ( + "errors" + "fmt" + regexpsyntax "regexp/syntax" + + k8serrors "k8s.io/apimachinery/pkg/api/errors" +) + +// formatError wraps error with a detailed message that is meant for the user. +// While the errors are meant to be displayed, they are not meant to be exported as classes outsite of CLI. +func FormatError(err error) error { + var errorNew error + if k8serrors.IsForbidden(err) { + errorNew = fmt.Errorf("Insufficient permissions: %w. Supply the required permission or control Mizu's access to namespaces by setting MizuNamespace in the config file or setting the tapped namespace with --set mizu-namespace=.", err) + } else if syntaxError, isSyntaxError := asRegexSyntaxError(err); isSyntaxError { + errorNew = fmt.Errorf("Regex %s is invalid: %w", syntaxError.Expr, err) + } else { + errorNew = err + } + + return errorNew +} + +func asRegexSyntaxError(err error) (*regexpsyntax.Error, bool) { + var syntaxError *regexpsyntax.Error + return syntaxError, errors.As(err, &syntaxError) +} diff --git a/cli/kubernetes/provider.go b/cli/kubernetes/provider.go index 38f6dc848..211d9ea1a 100644 --- a/cli/kubernetes/provider.go +++ b/cli/kubernetes/provider.go @@ -12,16 +12,13 @@ import ( "strconv" "github.com/up9inc/mizu/cli/mizu" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/util/homedir" - "github.com/up9inc/mizu/shared" core "k8s.io/api/core/v1" rbac "k8s.io/api/rbac/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" resource "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/watch" applyconfapp "k8s.io/client-go/applyconfigurations/apps/v1" @@ -33,9 +30,11 @@ import ( _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" _ "k8s.io/client-go/plugin/pkg/client/auth/openstack" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/clientcmd" _ "k8s.io/client-go/tools/portforward" watchtools "k8s.io/client-go/tools/watch" + "k8s.io/client-go/util/homedir" ) type Provider struct { @@ -126,8 +125,18 @@ func (provider *Provider) CreateNamespace(ctx context.Context, name string) (*co return provider.clientSet.CoreV1().Namespaces().Create(ctx, namespaceSpec, metav1.CreateOptions{}) } -func (provider *Provider) CreateMizuApiServerPod(ctx context.Context, namespace string, podName string, podImage string, serviceAccountName string, mizuApiFilteringOptions *shared.TrafficFilteringOptions, maxEntriesDBSizeBytes int64) (*core.Pod, error) { - marshaledFilteringOptions, err := json.Marshal(mizuApiFilteringOptions) +type ApiServerOptions struct { + Namespace string + PodName string + PodImage string + ServiceAccountName string + IsNamespaceRestricted bool + MizuApiFilteringOptions *shared.TrafficFilteringOptions + MaxEntriesDBSizeBytes int64 +} + +func (provider *Provider) CreateMizuApiServerPod(ctx context.Context, opts *ApiServerOptions) (*core.Pod, error) { + marshaledFilteringOptions, err := json.Marshal(opts.MizuApiFilteringOptions) if err != nil { return nil, err } @@ -138,32 +147,37 @@ func (provider *Provider) CreateMizuApiServerPod(ctx context.Context, namespace cpuLimit, err := resource.ParseQuantity("750m") if err != nil { - return nil, errors.New(fmt.Sprintf("invalid cpu limit for %s container", podName)) + return nil, errors.New(fmt.Sprintf("invalid cpu limit for %s container", opts.PodName)) } memLimit, err := resource.ParseQuantity("512Mi") if err != nil { - return nil, errors.New(fmt.Sprintf("invalid memory limit for %s container", podName)) + return nil, errors.New(fmt.Sprintf("invalid memory limit for %s container", opts.PodName)) } cpuRequests, err := resource.ParseQuantity("50m") if err != nil { - return nil, errors.New(fmt.Sprintf("invalid cpu request for %s container", podName)) + return nil, errors.New(fmt.Sprintf("invalid cpu request for %s container", opts.PodName)) } memRequests, err := resource.ParseQuantity("50Mi") if err != nil { - return nil, errors.New(fmt.Sprintf("invalid memory request for %s container", podName)) + return nil, errors.New(fmt.Sprintf("invalid memory request for %s container", opts.PodName)) + } + + command := []string{"./mizuagent", "--api-server"} + if opts.IsNamespaceRestricted { + command = append(command, "--namespace", opts.Namespace) } pod := &core.Pod{ ObjectMeta: metav1.ObjectMeta{ - Name: podName, - Namespace: namespace, - Labels: map[string]string{"app": podName}, + Name: opts.PodName, + Namespace: opts.Namespace, + Labels: map[string]string{"app": opts.PodName}, }, Spec: core.PodSpec{ Containers: []core.Container{ { - Name: podName, - Image: podImage, + Name: opts.PodName, + Image: opts.PodImage, ImagePullPolicy: core.PullAlways, VolumeMounts: []core.VolumeMount{ { @@ -171,7 +185,7 @@ func (provider *Provider) CreateMizuApiServerPod(ctx context.Context, namespace MountPath: shared.RulePolicyPath, }, }, - Command: []string{"./mizuagent", "--api-server"}, + Command: command, Env: []core.EnvVar{ { Name: shared.HostModeEnvVar, @@ -183,7 +197,7 @@ func (provider *Provider) CreateMizuApiServerPod(ctx context.Context, namespace }, { Name: shared.MaxEntriesDBSizeBytesEnvVar, - Value: strconv.FormatInt(maxEntriesDBSizeBytes, 10), + Value: strconv.FormatInt(opts.MaxEntriesDBSizeBytes, 10), }, }, Resources: core.ResourceRequirements{ @@ -211,10 +225,10 @@ func (provider *Provider) CreateMizuApiServerPod(ctx context.Context, namespace }, } //define the service account only when it exists to prevent pod crash - if serviceAccountName != "" { - pod.Spec.ServiceAccountName = serviceAccountName + if opts.ServiceAccountName != "" { + pod.Spec.ServiceAccountName = opts.ServiceAccountName } - return provider.clientSet.CoreV1().Pods(namespace).Create(ctx, pod, metav1.CreateOptions{}) + return provider.clientSet.CoreV1().Pods(opts.Namespace).Create(ctx, pod, metav1.CreateOptions{}) } func (provider *Provider) CreateService(ctx context.Context, namespace string, serviceName string, appLabelValue string) (*core.Service, error) { @@ -234,7 +248,55 @@ func (provider *Provider) CreateService(ctx context.Context, namespace string, s func (provider *Provider) DoesServiceAccountExist(ctx context.Context, namespace string, serviceAccountName string) (bool, error) { serviceAccount, err := provider.clientSet.CoreV1().ServiceAccounts(namespace).Get(ctx, serviceAccountName, metav1.GetOptions{}) + return provider.doesResourceExist(serviceAccount, err) +} +func (provider *Provider) DoesConfigMapExist(ctx context.Context, namespace string, name string) (bool, error) { + resource, err := provider.clientSet.CoreV1().ConfigMaps(namespace).Get(ctx, name, metav1.GetOptions{}) + return provider.doesResourceExist(resource, err) +} + +func (provider *Provider) DoesServicesExist(ctx context.Context, namespace string, name string) (bool, error) { + resource, err := provider.clientSet.CoreV1().Services(namespace).Get(ctx, name, metav1.GetOptions{}) + return provider.doesResourceExist(resource, err) +} + +func (provider *Provider) DoesNamespaceExist(ctx context.Context, name string) (bool, error) { + resource, err := provider.clientSet.CoreV1().Namespaces().Get(ctx, name, metav1.GetOptions{}) + return provider.doesResourceExist(resource, err) +} + +func (provider *Provider) DoesClusterRoleExist(ctx context.Context, name string) (bool, error) { + resource, err := provider.clientSet.RbacV1().ClusterRoles().Get(ctx, name, metav1.GetOptions{}) + return provider.doesResourceExist(resource, err) +} + +func (provider *Provider) DoesClusterRoleBindingExist(ctx context.Context, name string) (bool, error) { + resource, err := provider.clientSet.RbacV1().ClusterRoleBindings().Get(ctx, name, metav1.GetOptions{}) + return provider.doesResourceExist(resource, err) +} + +func (provider *Provider) DoesRoleExist(ctx context.Context, namespace string, name string) (bool, error) { + resource, err := provider.clientSet.RbacV1().Roles(namespace).Get(ctx, name, metav1.GetOptions{}) + return provider.doesResourceExist(resource, err) +} + +func (provider *Provider) DoesRoleBindingExist(ctx context.Context, namespace string, name string) (bool, error) { + resource, err := provider.clientSet.RbacV1().RoleBindings(namespace).Get(ctx, name, metav1.GetOptions{}) + return provider.doesResourceExist(resource, err) +} + +func (provider *Provider) DoesPodExist(ctx context.Context, namespace string, name string) (bool, error) { + resource, err := provider.clientSet.CoreV1().Pods(namespace).Get(ctx, name, metav1.GetOptions{}) + return provider.doesResourceExist(resource, err) +} + +func (provider *Provider) DoesDaemonSetExist(ctx context.Context, namespace string, name string) (bool, error) { + resource, err := provider.clientSet.AppsV1().DaemonSets(namespace).Get(ctx, name, metav1.GetOptions{}) + return provider.doesResourceExist(resource, err) +} + +func (provider *Provider) doesResourceExist(resource interface{}, err error) (bool, error) { var statusError *k8serrors.StatusError if errors.As(err, &statusError) { // expected behavior when resource does not exist @@ -245,22 +307,7 @@ func (provider *Provider) DoesServiceAccountExist(ctx context.Context, namespace if err != nil { return false, err } - return serviceAccount != nil, nil -} - -func (provider *Provider) DoesServicesExist(ctx context.Context, namespace string, serviceName string) (bool, error) { - service, err := provider.clientSet.CoreV1().Services(namespace).Get(ctx, serviceName, metav1.GetOptions{}) - - var statusError *k8serrors.StatusError - if errors.As(err, &statusError) { - if statusError.ErrStatus.Reason == metav1.StatusReasonNotFound { - return false, nil - } - } - if err != nil { - return false, err - } - return service != nil, nil + return resource != nil, nil } func (provider *Provider) CreateMizuRBAC(ctx context.Context, namespace string, serviceAccountName string, clusterRoleName string, clusterRoleBindingName string, version string) error { @@ -317,8 +364,62 @@ func (provider *Provider) CreateMizuRBAC(ctx context.Context, namespace string, return nil } +func (provider *Provider) CreateMizuRBACNamespaceRestricted(ctx context.Context, namespace string, serviceAccountName string, roleName string, roleBindingName string, version string) error { + serviceAccount := &core.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: serviceAccountName, + Namespace: namespace, + Labels: map[string]string{"mizu-cli-version": version}, + }, + } + role := &rbac.Role{ + ObjectMeta: metav1.ObjectMeta{ + Name: roleName, + Labels: map[string]string{"mizu-cli-version": version}, + }, + Rules: []rbac.PolicyRule{ + { + APIGroups: []string{"", "extensions", "apps"}, + Resources: []string{"pods", "services", "endpoints"}, + Verbs: []string{"list", "get", "watch"}, + }, + }, + } + roleBinding := &rbac.RoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: roleBindingName, + Labels: map[string]string{"mizu-cli-version": version}, + }, + RoleRef: rbac.RoleRef{ + Name: roleName, + Kind: "Role", + APIGroup: "rbac.authorization.k8s.io", + }, + Subjects: []rbac.Subject{ + { + Kind: "ServiceAccount", + Name: serviceAccountName, + Namespace: namespace, + }, + }, + } + _, err := provider.clientSet.CoreV1().ServiceAccounts(namespace).Create(ctx, serviceAccount, metav1.CreateOptions{}) + if err != nil { + return err + } + _, err = provider.clientSet.RbacV1().Roles(namespace).Create(ctx, role, metav1.CreateOptions{}) + if err != nil { + return err + } + _, err = provider.clientSet.RbacV1().RoleBindings(namespace).Create(ctx, roleBinding, metav1.CreateOptions{}) + if err != nil { + return err + } + return nil +} + func (provider *Provider) RemoveNamespace(ctx context.Context, name string) error { - if isFound, err := provider.CheckNamespaceExists(ctx, name); err != nil { + if isFound, err := provider.DoesNamespaceExist(ctx, name); err != nil { return err } else if !isFound { return nil @@ -340,7 +441,7 @@ func (provider *Provider) RemoveNonNamespacedResources(ctx context.Context, clus } func (provider *Provider) RemoveClusterRole(ctx context.Context, name string) error { - if isFound, err := provider.CheckClusterRoleExists(ctx, name); err != nil { + if isFound, err := provider.DoesClusterRoleExist(ctx, name); err != nil { return err } else if !isFound { return nil @@ -350,7 +451,7 @@ func (provider *Provider) RemoveClusterRole(ctx context.Context, name string) er } func (provider *Provider) RemoveClusterRoleBinding(ctx context.Context, name string) error { - if isFound, err := provider.CheckClusterRoleBindingExists(ctx, name); err != nil { + if isFound, err := provider.DoesClusterRoleBindingExist(ctx, name); err != nil { return err } else if !isFound { return nil @@ -359,8 +460,38 @@ func (provider *Provider) RemoveClusterRoleBinding(ctx context.Context, name str return provider.clientSet.RbacV1().ClusterRoleBindings().Delete(ctx, name, metav1.DeleteOptions{}) } +func (provider *Provider) RemoveRoleBinding(ctx context.Context, namespace string, name string) error { + if isFound, err := provider.DoesRoleBindingExist(ctx, namespace, name); err != nil { + return err + } else if !isFound { + return nil + } + + return provider.clientSet.RbacV1().RoleBindings(namespace).Delete(ctx, name, metav1.DeleteOptions{}) +} + +func (provider *Provider) RemoveRole(ctx context.Context, namespace string, name string) error { + if isFound, err := provider.DoesRoleExist(ctx, namespace, name); err != nil { + return err + } else if !isFound { + return nil + } + + return provider.clientSet.RbacV1().Roles(namespace).Delete(ctx, name, metav1.DeleteOptions{}) +} + +func (provider *Provider) RemoveServicAccount(ctx context.Context, namespace string, name string) error { + if isFound, err := provider.DoesServiceAccountExist(ctx, namespace, name); err != nil { + return err + } else if !isFound { + return nil + } + + return provider.clientSet.CoreV1().ServiceAccounts(namespace).Delete(ctx, name, metav1.DeleteOptions{}) +} + func (provider *Provider) RemovePod(ctx context.Context, namespace string, podName string) error { - if isFound, err := provider.CheckPodExists(ctx, namespace, podName); err != nil { + if isFound, err := provider.DoesPodExist(ctx, namespace, podName); err != nil { return err } else if !isFound { return nil @@ -369,8 +500,18 @@ func (provider *Provider) RemovePod(ctx context.Context, namespace string, podNa return provider.clientSet.CoreV1().Pods(namespace).Delete(ctx, podName, metav1.DeleteOptions{}) } +func (provider *Provider) RemoveConfigMap(ctx context.Context, namespace string, configMapName string) error { + if isFound, err := provider.DoesConfigMapExist(ctx, namespace, configMapName); err != nil { + return err + } else if !isFound { + return nil + } + + return provider.clientSet.CoreV1().ConfigMaps(namespace).Delete(ctx, configMapName, metav1.DeleteOptions{}) +} + func (provider *Provider) RemoveService(ctx context.Context, namespace string, serviceName string) error { - if isFound, err := provider.CheckServiceExists(ctx, namespace, serviceName); err != nil { + if isFound, err := provider.DoesServicesExist(ctx, namespace, serviceName); err != nil { return err } else if !isFound { return nil @@ -380,7 +521,7 @@ func (provider *Provider) RemoveService(ctx context.Context, namespace string, s } func (provider *Provider) RemoveDaemonSet(ctx context.Context, namespace string, daemonSetName string) error { - if isFound, err := provider.CheckDaemonSetExists(ctx, namespace, daemonSetName); err != nil { + if isFound, err := provider.DoesDaemonSetExist(ctx, namespace, daemonSetName); err != nil { return err } else if !isFound { return nil @@ -389,138 +530,11 @@ func (provider *Provider) RemoveDaemonSet(ctx context.Context, namespace string, return provider.clientSet.AppsV1().DaemonSets(namespace).Delete(ctx, daemonSetName, metav1.DeleteOptions{}) } -func (provider *Provider) RemoveConfigMap(ctx context.Context, namespace string, configMapName string) error { - if isFound, err := provider.CheckConfigMapExists(ctx, namespace, configMapName); err != nil { - return err - } else if !isFound { - return nil - } - return provider.clientSet.CoreV1().ConfigMaps(namespace).Delete(ctx, configMapName, metav1.DeleteOptions{}) -} - -func (provider *Provider) CheckNamespaceExists(ctx context.Context, name string) (bool, error) { - listOptions := metav1.ListOptions{ - FieldSelector: fmt.Sprintf("metadata.name=%s", name), - Limit: 1, - } - resourceList, err := provider.clientSet.CoreV1().Namespaces().List(ctx, listOptions) - if err != nil { - return false, err - } - - if len(resourceList.Items) > 0 { - return true, nil - } - - return false, nil -} - -func (provider *Provider) CheckClusterRoleExists(ctx context.Context, name string) (bool, error) { - listOptions := metav1.ListOptions{ - FieldSelector: fmt.Sprintf("metadata.name=%s", name), - Limit: 1, - } - resourceList, err := provider.clientSet.RbacV1().ClusterRoles().List(ctx, listOptions) - if err != nil { - return false, err - } - - if len(resourceList.Items) > 0 { - return true, nil - } - - return false, nil -} - -func (provider *Provider) CheckClusterRoleBindingExists(ctx context.Context, name string) (bool, error) { - listOptions := metav1.ListOptions{ - FieldSelector: fmt.Sprintf("metadata.name=%s", name), - Limit: 1, - } - resourceList, err := provider.clientSet.RbacV1().ClusterRoleBindings().List(ctx, listOptions) - if err != nil { - return false, err - } - - if len(resourceList.Items) > 0 { - return true, nil - } - - return false, nil -} - -func (provider *Provider) CheckPodExists(ctx context.Context, namespace string, name string) (bool, error) { - listOptions := metav1.ListOptions{ - FieldSelector: fmt.Sprintf("metadata.name=%s", name), - Limit: 1, - } - resourceList, err := provider.clientSet.CoreV1().Pods(namespace).List(ctx, listOptions) - if err != nil { - return false, err - } - - if len(resourceList.Items) > 0 { - return true, nil - } - - return false, nil -} - -func (provider *Provider) CheckServiceExists(ctx context.Context, namespace string, name string) (bool, error) { - listOptions := metav1.ListOptions{ - FieldSelector: fmt.Sprintf("metadata.name=%s", name), - Limit: 1, - } - resourceList, err := provider.clientSet.CoreV1().Services(namespace).List(ctx, listOptions) - if err != nil { - return false, err - } - - if len(resourceList.Items) > 0 { - return true, nil - } - - return false, nil -} - -func (provider *Provider) CheckDaemonSetExists(ctx context.Context, namespace string, name string) (bool, error) { - listOptions := metav1.ListOptions{ - FieldSelector: fmt.Sprintf("metadata.name=%s", name), - Limit: 1, - } - resourceList, err := provider.clientSet.AppsV1().DaemonSets(namespace).List(ctx, listOptions) - if err != nil { - return false, err - } - - if len(resourceList.Items) > 0 { - return true, nil - } - - return false, nil -} - -func (provider *Provider) CheckConfigMapExists(ctx context.Context, namespace string, name string) (bool, error) { - listOptions := metav1.ListOptions{ - FieldSelector: fmt.Sprintf("metadata.name=%s", name), - Limit: 1, - } - resourceList, err := provider.clientSet.CoreV1().ConfigMaps(namespace).List(ctx, listOptions) - if err != nil { - return false, err - } - - if len(resourceList.Items) > 0 { - return true, nil - } - - return false, nil -} - -func (provider *Provider) ApplyConfigMap(ctx context.Context, namespace string, configMapName string, data string) error { +func (provider *Provider) CreateConfigMap(ctx context.Context, namespace string, configMapName string, data string) error { if data == "" { return nil } + configMapData := make(map[string]string, 0) configMapData[shared.RulePolicyFileName] = data configMap := &core.ConfigMap{ @@ -534,14 +548,11 @@ func (provider *Provider) ApplyConfigMap(ctx context.Context, namespace string, }, Data: configMapData, } - _, err := provider.clientSet.CoreV1().ConfigMaps(namespace).Create(ctx, configMap, metav1.CreateOptions{}) - var statusError *k8serrors.StatusError - if errors.As(err, &statusError) { - if statusError.ErrStatus.Reason == metav1.StatusReasonForbidden { - return fmt.Errorf("User not authorized to create configmap, --test-rules will be ignored") - } + if _, err := provider.clientSet.CoreV1().ConfigMaps(namespace).Create(ctx, configMap, metav1.CreateOptions{}); err != nil { + return err } - return err + + return nil } func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespace string, daemonSetName string, podImage string, tapperPodName string, apiServerPodIp string, nodeToTappedPodIPMap map[string][]string, serviceAccountName string, tapOutgoing bool) error { @@ -671,7 +682,7 @@ func (provider *Provider) GetAllRunningPodsMatchingRegex(ctx context.Context, re matchingPods = append(matchingPods, pod) } } - return matchingPods, err + return matchingPods, nil } func getClientSet(config *restclient.Config) *kubernetes.Clientset { diff --git a/cli/mizu/configStruct.go b/cli/mizu/configStruct.go index d3c1d5864..a3e358e1b 100644 --- a/cli/mizu/configStruct.go +++ b/cli/mizu/configStruct.go @@ -7,14 +7,31 @@ import ( ) type ConfigStruct struct { - Tap configStructs.TapConfig `yaml:"tap"` - Fetch configStructs.FetchConfig `yaml:"fetch"` - Version configStructs.VersionConfig `yaml:"version"` - View configStructs.ViewConfig `yaml:"view"` - MizuImage string `yaml:"mizu-image"` - Telemetry bool `yaml:"telemetry" default:"true"` + Tap configStructs.TapConfig `yaml:"tap"` + Fetch configStructs.FetchConfig `yaml:"fetch"` + Version configStructs.VersionConfig `yaml:"version"` + View configStructs.ViewConfig `yaml:"view"` + MizuImage string `yaml:"mizu-image"` + MizuNamespace string `yaml:"mizu-namespace"` + Telemetry bool `yaml:"telemetry" default:"true"` } func (config *ConfigStruct) SetDefaults() { config.MizuImage = fmt.Sprintf("gcr.io/up9-docker-hub/mizu/%s:%s", Branch, SemVer) } + +func (config *ConfigStruct) ResourcesNamespace() string { + if config.MizuNamespace == "" { + return ResourcesDefaultNamespace + } + + return config.MizuNamespace +} + +func (config *ConfigStruct) IsOwnNamespace() bool { + if config.MizuNamespace == "" { + return true + } + + return false +} diff --git a/cli/mizu/consts.go b/cli/mizu/consts.go index f9ade7e5a..e1489a05d 100644 --- a/cli/mizu/consts.go +++ b/cli/mizu/consts.go @@ -14,15 +14,17 @@ var ( ) const ( - ApiServerPodName = "mizu-api-server" - ClusterRoleBindingName = "mizu-cluster-role-binding" - ClusterRoleName = "mizu-cluster-role" - K8sAllNamespaces = "" - ResourcesNamespace = "mizu" - ServiceAccountName = "mizu-service-account" - TapperDaemonSetName = "mizu-tapper-daemon-set" - TapperPodName = "mizu-tapper" - ConfigMapName = "mizu-policy" + ApiServerPodName = "mizu-api-server" + ClusterRoleBindingName = "mizu-cluster-role-binding" + ClusterRoleName = "mizu-cluster-role" + K8sAllNamespaces = "" + ResourcesDefaultNamespace = "mizu" + RoleBindingName = "mizu-role-binding" + RoleName = "mizu-role" + ServiceAccountName = "mizu-service-account" + TapperDaemonSetName = "mizu-tapper-daemon-set" + TapperPodName = "mizu-tapper" + ConfigMapName = "mizu-policy" ) func getMizuFolderPath() string { diff --git a/cli/uiUtils/colors.go b/cli/uiUtils/colors.go index e4c684dda..c7b0887c4 100644 --- a/cli/uiUtils/colors.go +++ b/cli/uiUtils/colors.go @@ -2,12 +2,14 @@ package uiUtils const ( - Black = "\033[1;30m%s\033[0m" - Red = "\033[1;31m%s\033[0m" - Green = "\033[1;32m%s\033[0m" - Yellow = "\033[1;33m%s\033[0m" - Purple = "\033[1;34m%s\033[0m" - Magenta = "\033[1;35m%s\033[0m" - Teal = "\033[1;36m%s\033[0m" - White = "\033[1;37m%s\033[0m" -) \ No newline at end of file + Black = "\033[1;30m%s\033[0m" + Red = "\033[1;31m%s\033[0m" + Green = "\033[1;32m%s\033[0m" + Yellow = "\033[1;33m%s\033[0m" + Purple = "\033[1;34m%s\033[0m" + Magenta = "\033[1;35m%s\033[0m" + Teal = "\033[1;36m%s\033[0m" + White = "\033[1;37m%s\033[0m" + Error = Red + Warning = Yellow +) diff --git a/examples/roles/permissions-all-namespaces-without-ip-resolution.yaml b/examples/roles/permissions-all-namespaces-without-ip-resolution.yaml index 3252abb89..c4e809ac3 100644 --- a/examples/roles/permissions-all-namespaces-without-ip-resolution.yaml +++ b/examples/roles/permissions-all-namespaces-without-ip-resolution.yaml @@ -7,16 +7,16 @@ metadata: rules: - apiGroups: [""] resources: ["pods"] - verbs: ["list", "watch", "create"] + verbs: ["list", "watch", "create", "delete"] - apiGroups: [""] resources: ["services"] - verbs: ["create"] + verbs: ["create", "delete"] - apiGroups: ["apps"] resources: ["daemonsets"] - verbs: ["create", "patch"] + verbs: ["create", "patch", "delete"] - apiGroups: [""] resources: ["namespaces"] - verbs: ["list", "watch", "create", "delete"] + verbs: ["get", "list", "watch", "create", "delete"] - apiGroups: [""] resources: ["services/proxy"] verbs: ["get"] diff --git a/examples/roles/permissions-all-namespaces.yaml b/examples/roles/permissions-all-namespaces.yaml index 0f3ba3dff..ff1060df0 100644 --- a/examples/roles/permissions-all-namespaces.yaml +++ b/examples/roles/permissions-all-namespaces.yaml @@ -6,28 +6,34 @@ metadata: rules: - apiGroups: [""] resources: ["pods"] - verbs: ["get", "list", "watch", "create"] + verbs: ["get", "list", "watch", "create", "delete"] - apiGroups: [""] resources: ["services"] - verbs: ["get", "list", "watch", "create"] + verbs: ["get", "list", "watch", "create", "delete"] - apiGroups: ["apps"] resources: ["daemonsets"] - verbs: ["create", "patch"] + verbs: ["create", "patch", "delete"] - apiGroups: [""] resources: ["namespaces"] - verbs: ["list", "watch", "create", "delete"] + verbs: ["get", "list", "watch", "create", "delete"] - apiGroups: [""] resources: ["services/proxy"] verbs: ["get"] - apiGroups: [""] resources: ["serviceaccounts"] - verbs: ["get", "create"] + verbs: ["get", "create", "delete"] - apiGroups: ["rbac.authorization.k8s.io"] resources: ["clusterroles"] - verbs: ["list", "create", "delete"] + verbs: ["get", "create", "delete"] - apiGroups: ["rbac.authorization.k8s.io"] resources: ["clusterrolebindings"] - verbs: ["list", "create", "delete"] + verbs: ["get", "create", "delete"] +- apiGroups: ["rbac.authorization.k8s.io"] + resources: ["roles"] + verbs: ["get", "create", "delete"] +- apiGroups: ["rbac.authorization.k8s.io"] + resources: ["rolebindings"] + verbs: ["get", "create", "delete"] - apiGroups: ["apps", "extensions"] resources: ["pods"] verbs: ["get", "list", "watch"] diff --git a/examples/roles/permissions-ns-with-validation.yaml b/examples/roles/permissions-ns-with-validation.yaml new file mode 100644 index 000000000..e2d6863ec --- /dev/null +++ b/examples/roles/permissions-ns-with-validation.yaml @@ -0,0 +1,54 @@ +# This example shows the roles required for a user to be able to use Mizu in a single namespace. +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: mizu-runner-role + namespace: user1 +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch", "create", "delete"] +- apiGroups: [""] + resources: ["services"] + verbs: ["get", "list", "watch", "create", "delete"] +- apiGroups: ["apps"] + resources: ["daemonsets"] + verbs: ["get", "create", "patch", "delete"] +- apiGroups: [""] + resources: ["services/proxy"] + verbs: ["get"] +- apiGroups: [""] + resources: ["configmaps"] + verbs: ["get", "create", "delete"] +- apiGroups: [""] + resources: ["serviceaccounts"] + verbs: ["get", "create", "delete"] +- apiGroups: ["rbac.authorization.k8s.io"] + resources: ["roles"] + verbs: ["get", "create", "delete"] +- apiGroups: ["rbac.authorization.k8s.io"] + resources: ["rolebindings"] + verbs: ["get", "create", "delete"] +- apiGroups: ["apps", "extensions"] + resources: ["pods"] + verbs: ["get", "list", "watch"] +- apiGroups: ["apps", "extensions"] + resources: ["services"] + verbs: ["get", "list", "watch"] +- apiGroups: ["", "apps", "extensions"] + resources: ["endpoints"] + verbs: ["get", "list", "watch"] +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: mizu-runner-rolebindings + namespace: user1 +subjects: +- kind: User + name: user1 + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: Role + name: mizu-runner-role + apiGroup: rbac.authorization.k8s.io diff --git a/examples/roles/permissions-ns-without-ip-resolution.yaml b/examples/roles/permissions-ns-without-ip-resolution.yaml new file mode 100644 index 000000000..4293f8979 --- /dev/null +++ b/examples/roles/permissions-ns-without-ip-resolution.yaml @@ -0,0 +1,33 @@ +# This example shows the roles required for a user to be able to use Mizu in a single namespace with IP resolution disabled. +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: mizu-runner-role + namespace: user1 +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch", "create", "delete"] +- apiGroups: [""] + resources: ["services"] + verbs: ["get", "create", "delete"] +- apiGroups: ["apps"] + resources: ["daemonsets"] + verbs: ["get", "create", "patch", "delete"] +- apiGroups: [""] + resources: ["services/proxy"] + verbs: ["get"] +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: mizu-runner-rolebindings + namespace: user1 +subjects: +- kind: User + name: user1 + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: Role + name: mizu-runner-role + apiGroup: rbac.authorization.k8s.io diff --git a/examples/roles/permissions-ns.yaml b/examples/roles/permissions-ns.yaml new file mode 100644 index 000000000..da60a02e1 --- /dev/null +++ b/examples/roles/permissions-ns.yaml @@ -0,0 +1,51 @@ +# This example shows the roles required for a user to be able to use Mizu in a single namespace. +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: mizu-runner-role + namespace: user1 +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch", "create", "delete"] +- apiGroups: [""] + resources: ["services"] + verbs: ["get", "list", "watch", "create", "delete"] +- apiGroups: ["apps"] + resources: ["daemonsets"] + verbs: ["get", "create", "patch", "delete"] +- apiGroups: [""] + resources: ["services/proxy"] + verbs: ["get"] +- apiGroups: [""] + resources: ["serviceaccounts"] + verbs: ["get", "create", "delete"] +- apiGroups: ["rbac.authorization.k8s.io"] + resources: ["roles"] + verbs: ["get", "create", "delete"] +- apiGroups: ["rbac.authorization.k8s.io"] + resources: ["rolebindings"] + verbs: ["get", "create", "delete"] +- apiGroups: ["apps", "extensions"] + resources: ["pods"] + verbs: ["get", "list", "watch"] +- apiGroups: ["apps", "extensions"] + resources: ["services"] + verbs: ["get", "list", "watch"] +- apiGroups: ["", "apps", "extensions"] + resources: ["endpoints"] + verbs: ["get", "list", "watch"] +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: mizu-runner-rolebindings + namespace: user1 +subjects: +- kind: User + name: user1 + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: Role + name: mizu-runner-role + apiGroup: rbac.authorization.k8s.io From fa632b49a7e7013d348eb16a164b86fa3deeee3e Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Thu, 5 Aug 2021 11:01:08 +0300 Subject: [PATCH 56/69] Introducing mizu logs dump & Log prints alignment in API server using rlog (#165) --- agent/pkg/api/socket_routes.go | 12 +-- agent/pkg/api/socket_server_handlers.go | 4 +- agent/pkg/database/size_enforcer.go | 16 ++-- agent/pkg/resolver/README.md | 8 +- agent/pkg/utils/truncating_logger.go | 9 +- cli/cmd/logs.go | 46 +++++++++++ cli/cmd/tapRunner.go | 24 +++--- cli/cmd/viewRunner.go | 15 +--- cli/kubernetes/provider.go | 46 +++++++++-- cli/logsUtils/mizuLogsUtils.go | 104 ++++++++++++++++++++++++ cli/mizu/config.go | 2 +- cli/mizu/configStruct.go | 1 + cli/mizu/consts.go | 2 +- cli/mizu/logger.go | 10 +-- 14 files changed, 241 insertions(+), 58 deletions(-) create mode 100644 cli/cmd/logs.go create mode 100644 cli/logsUtils/mizuLogsUtils.go diff --git a/agent/pkg/api/socket_routes.go b/agent/pkg/api/socket_routes.go index 140b07f6d..c44c1e047 100644 --- a/agent/pkg/api/socket_routes.go +++ b/agent/pkg/api/socket_routes.go @@ -2,9 +2,9 @@ package api import ( "errors" - "fmt" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" + "github.com/romana/rlog" "github.com/up9inc/mizu/shared/debounce" "net/http" "sync" @@ -50,7 +50,7 @@ func WebSocketRoutes(app *gin.Engine, eventHandlers EventHandlers) { func websocketHandler(w http.ResponseWriter, r *http.Request, eventHandlers EventHandlers, isTapper bool) { conn, err := websocketUpgrader.Upgrade(w, r, nil) if err != nil { - fmt.Println("Failed to set websocket upgrade: %+v", err) + rlog.Errorf("Failed to set websocket upgrade: %v", err) return } @@ -71,7 +71,7 @@ func websocketHandler(w http.ResponseWriter, r *http.Request, eventHandlers Even for { _, msg, err := conn.ReadMessage() if err != nil { - fmt.Printf("Conn err: %v\n", err) + rlog.Errorf("Error reading message, socket id: %d, error: %v", socketId, err) break } eventHandlers.WebSocketMessage(socketId, msg) @@ -81,7 +81,7 @@ func websocketHandler(w http.ResponseWriter, r *http.Request, eventHandlers Even func socketCleanup(socketId int, socketConnection *SocketConnection) { err := socketConnection.connection.Close() if err != nil { - fmt.Printf("Error closing socket connection for socket id %d: %v\n", socketId, err) + rlog.Errorf("Error closing socket connection for socket id %d: %v\n", socketId, err) } websocketIdsLock.Lock() @@ -92,7 +92,7 @@ func socketCleanup(socketId int, socketConnection *SocketConnection) { } var db = debounce.NewDebouncer(time.Second*5, func() { - fmt.Println("Successfully sent to socket") + rlog.Error("Successfully sent to socket") }) func SendToSocket(socketId int, message []byte) error { @@ -104,7 +104,7 @@ func SendToSocket(socketId int, message []byte) error { var sent = false time.AfterFunc(time.Second*5, func() { if !sent { - fmt.Println("Socket timed out") + rlog.Error("Socket timed out") socketCleanup(socketId, socketObj) } }) diff --git a/agent/pkg/api/socket_server_handlers.go b/agent/pkg/api/socket_server_handlers.go index 9e9600fd0..f6b4627c8 100644 --- a/agent/pkg/api/socket_server_handlers.go +++ b/agent/pkg/api/socket_server_handlers.go @@ -52,7 +52,7 @@ func BroadcastToBrowserClients(message []byte) { go func(socketId int) { err := SendToSocket(socketId, message) if err != nil { - fmt.Printf("error sending message to socket ID %d: %v", socketId, err) + rlog.Errorf("error sending message to socket ID %d: %v", socketId, err) } }(socketId) } @@ -114,7 +114,7 @@ func handleTLSLink(outboundLinkMessage models.WebsocketOutboundLinkMessage) { if err != nil { rlog.Errorf("Error marshaling outbound link message for broadcasting: %v", err) } else { - fmt.Printf("Broadcasting outboundlink message %s\n", string(marshaledMessage)) + rlog.Errorf("Broadcasting outboundlink message %s", string(marshaledMessage)) BroadcastToBrowserClients(marshaledMessage) } } diff --git a/agent/pkg/database/size_enforcer.go b/agent/pkg/database/size_enforcer.go index 26b923b10..c17c53d97 100644 --- a/agent/pkg/database/size_enforcer.go +++ b/agent/pkg/database/size_enforcer.go @@ -1,8 +1,8 @@ package database import ( - "fmt" "github.com/fsnotify/fsnotify" + "github.com/romana/rlog" "github.com/up9inc/mizu/shared" "github.com/up9inc/mizu/shared/debounce" "github.com/up9inc/mizu/shared/units" @@ -47,7 +47,7 @@ func StartEnforcingDatabaseSize() { if !ok { return // closed channel } - fmt.Printf("filesystem watcher encountered error:%v\n", err) + rlog.Errorf("filesystem watcher encountered error:%v", err) } } }() @@ -72,7 +72,7 @@ func getMaxEntriesDBByteSize() (int64, error) { func checkFileSize(maxSizeBytes int64) { fileStat, err := os.Stat(DBPath) if err != nil { - fmt.Printf("Error checking %s file size: %v\n", DBPath, err) + rlog.Errorf("Error checking %s file size: %v", DBPath, err) } else { if fileStat.Size() > maxSizeBytes { pruneOldEntries(fileStat.Size()) @@ -83,13 +83,13 @@ func checkFileSize(maxSizeBytes int64) { func pruneOldEntries(currentFileSize int64) { // sqlite locks the database while delete or VACUUM are running and sqlite is terrible at handling its own db lock while a lot of inserts are attempted, we prevent a significant bottleneck by handling the db lock ourselves here IsDBLocked = true - defer func() {IsDBLocked = false}() + defer func() { IsDBLocked = false }() amountOfBytesToTrim := currentFileSize / (100 / percentageOfMaxSizeBytesToPrune) rows, err := GetEntriesTable().Limit(10000).Order("id").Rows() if err != nil { - fmt.Printf("Error getting 10000 first db rows: %v\n", err) + rlog.Errorf("Error getting 10000 first db rows: %v", err) return } @@ -102,7 +102,7 @@ func pruneOldEntries(currentFileSize int64) { var entry models.MizuEntry err = DB.ScanRows(rows, &entry) if err != nil { - fmt.Printf("Error scanning db row: %v\n", err) + rlog.Errorf("Error scanning db row: %v", err) continue } @@ -114,8 +114,8 @@ func pruneOldEntries(currentFileSize int64) { GetEntriesTable().Where(entryIdsToRemove).Delete(models.MizuEntry{}) // VACUUM causes sqlite to shrink the db file after rows have been deleted, the db file will not shrink without this DB.Exec("VACUUM") - fmt.Printf("Removed %d rows and cleared %s\n", len(entryIdsToRemove), units.BytesToHumanReadable(bytesToBeRemoved)) + rlog.Errorf("Removed %d rows and cleared %s", len(entryIdsToRemove), units.BytesToHumanReadable(bytesToBeRemoved)) } else { - fmt.Println("Found no rows to remove when pruning") + rlog.Error("Found no rows to remove when pruning") } } diff --git a/agent/pkg/resolver/README.md b/agent/pkg/resolver/README.md index 0ce3b933c..747787d78 100644 --- a/agent/pkg/resolver/README.md +++ b/agent/pkg/resolver/README.md @@ -32,7 +32,7 @@ Now you will be able to import `github.com/up9inc/mizu/resolver` in any `.go` fi errOut := make(chan error, 100) k8sResolver, err := resolver.NewFromOutOfCluster("", errOut) if err != nil { - fmt.Printf("error creating k8s resolver %s", err) + rlog.Errorf("error creating k8s resolver %s", err) } ctx, cancel := context.WithCancel(context.Background()) @@ -40,15 +40,15 @@ k8sResolver.Start(ctx) resolvedName := k8sResolver.Resolve("10.107.251.91") // will always return `nil` in real scenarios as the internal map takes a moment to populate after `Start` is called if resolvedName != nil { - fmt.Printf("resolved 10.107.251.91=%s", *resolvedName) + rlog.Errorf("resolved 10.107.251.91=%s", *resolvedName) } else { - fmt.Printf("Could not find a resolved name for 10.107.251.91") + rlog.Error("Could not find a resolved name for 10.107.251.91") } for { select { case err := <- errOut: - fmt.Printf("name resolving error %s", err) + rlog.Errorf("name resolving error %s", err) } } ``` diff --git a/agent/pkg/utils/truncating_logger.go b/agent/pkg/utils/truncating_logger.go index f3a0c72a6..39aa834d3 100644 --- a/agent/pkg/utils/truncating_logger.go +++ b/agent/pkg/utils/truncating_logger.go @@ -3,6 +3,7 @@ package utils import ( "context" "fmt" + "github.com/romana/rlog" "gorm.io/gorm/logger" "gorm.io/gorm/utils" "time" @@ -10,7 +11,7 @@ import ( // TruncatingLogger implements the gorm logger.Interface interface. Its purpose is to act as gorm's logger while truncating logs to a max of 50 characters to minimise the performance impact type TruncatingLogger struct { - LogLevel logger.LogLevel + LogLevel logger.LogLevel SlowThreshold time.Duration } @@ -23,21 +24,21 @@ func (truncatingLogger *TruncatingLogger) Info(_ context.Context, message string if truncatingLogger.LogLevel < logger.Info { return } - fmt.Printf("gorm info: %.150s\n", message) + rlog.Errorf("gorm info: %.150s", message) } func (truncatingLogger *TruncatingLogger) Warn(_ context.Context, message string, __ ...interface{}) { if truncatingLogger.LogLevel < logger.Warn { return } - fmt.Printf("gorm warning: %.150s\n", message) + rlog.Errorf("gorm warning: %.150s", message) } func (truncatingLogger *TruncatingLogger) Error(_ context.Context, message string, __ ...interface{}) { if truncatingLogger.LogLevel < logger.Error { return } - fmt.Printf("gorm error: %.150s\n", message) + rlog.Errorf("gorm error: %.150s", message) } func (truncatingLogger *TruncatingLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { diff --git a/cli/cmd/logs.go b/cli/cmd/logs.go new file mode 100644 index 000000000..4997f4e10 --- /dev/null +++ b/cli/cmd/logs.go @@ -0,0 +1,46 @@ +package cmd + +import ( + "context" + "github.com/spf13/cobra" + "github.com/up9inc/mizu/cli/kubernetes" + "github.com/up9inc/mizu/cli/logsUtils" + "github.com/up9inc/mizu/cli/mizu" + "os" + "path" +) + +var filePath string + +var logsCmd = &cobra.Command{ + Use: "logs", + Short: "Create a zip file with logs for Github issue or troubleshoot", + RunE: func(cmd *cobra.Command, args []string) error { + kubernetesProvider, err := kubernetes.NewProvider(mizu.Config.View.KubeConfigPath) + if err != nil { + return nil + } + ctx, _ := context.WithCancel(context.Background()) + + if filePath == "" { + pwd, err := os.Getwd() + if err != nil { + mizu.Log.Errorf("Failed to get PWD, %v (try using `mizu logs -f )`", err) + return nil + } + filePath = path.Join(pwd, "mizu_logs.zip") + } + mizu.Log.Debugf("Using file path %s", filePath) + + if err := logsUtils.DumpLogs(kubernetesProvider, ctx, filePath); err != nil { + mizu.Log.Errorf("Failed dump logs %v", err) + } + + return nil + }, +} + +func init() { + rootCmd.AddCommand(logsCmd) + logsCmd.Flags().StringVarP(&filePath, "file", "f", "", "Path for zip file (default current \\mizu_logs.zip)") +} diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index 2a3868c1c..91c277376 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -9,12 +9,14 @@ import ( "net/url" "os" "os/signal" + "path" "regexp" "syscall" "time" "github.com/up9inc/mizu/cli/errormessage" "github.com/up9inc/mizu/cli/kubernetes" + "github.com/up9inc/mizu/cli/logsUtils" "github.com/up9inc/mizu/cli/mizu" "github.com/up9inc/mizu/cli/uiUtils" "github.com/up9inc/mizu/shared" @@ -22,7 +24,6 @@ import ( yaml "gopkg.in/yaml.v3" core "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/tools/clientcmd" ) const ( @@ -56,14 +57,8 @@ func RunMizuTap() { kubernetesProvider, err := kubernetes.NewProvider(mizu.Config.Tap.KubeConfigPath) if err != nil { - if clientcmd.IsEmptyConfig(err) { - mizu.Log.Errorf(uiUtils.Error, "Couldn't find the kube config file, or file is empty. Try adding '--kube-config='\n") - return - } - if clientcmd.IsConfigurationInvalid(err) { - mizu.Log.Errorf(uiUtils.Error, "Invalid kube config file. Try using a different config with '--kube-config='\n") - return - } + mizu.Log.Error(err) + return } defer cleanUpMizuResources(kubernetesProvider) @@ -244,11 +239,20 @@ func updateMizuTappers(ctx context.Context, kubernetesProvider *kubernetes.Provi } func cleanUpMizuResources(kubernetesProvider *kubernetes.Provider) { - mizu.Log.Infof("\nRemoving mizu resources\n") removalCtx, cancel := context.WithTimeout(context.Background(), cleanupTimeout) defer cancel() + if mizu.Config.DumpLogs { + mizuDir := mizu.GetMizuFolderPath() + filePath = path.Join(mizuDir, fmt.Sprintf("mizu_logs_%s.zip", time.Now().Format("2006_01_02__15_04_05"))) + if err := logsUtils.DumpLogs(kubernetesProvider, removalCtx, filePath); err != nil { + mizu.Log.Errorf("Failed dump logs %v", err) + } + } + + mizu.Log.Infof("\nRemoving mizu resources\n") + if mizu.Config.IsOwnNamespace() { if err := kubernetesProvider.RemoveNamespace(removalCtx, mizu.Config.ResourcesNamespace()); err != nil { mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing Namespace %s: %v", mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) diff --git a/cli/cmd/viewRunner.go b/cli/cmd/viewRunner.go index cdc2119f5..2c9e9d931 100644 --- a/cli/cmd/viewRunner.go +++ b/cli/cmd/viewRunner.go @@ -3,25 +3,16 @@ package cmd import ( "context" "fmt" - "net/http" - "github.com/up9inc/mizu/cli/kubernetes" "github.com/up9inc/mizu/cli/mizu" - "github.com/up9inc/mizu/cli/uiUtils" - "k8s.io/client-go/tools/clientcmd" + "net/http" ) func runMizuView() { kubernetesProvider, err := kubernetes.NewProvider(mizu.Config.View.KubeConfigPath) if err != nil { - if clientcmd.IsEmptyConfig(err) { - mizu.Log.Infof("Couldn't find the kube config file, or file is empty. Try adding '--kube-config='") - return - } - if clientcmd.IsConfigurationInvalid(err) { - mizu.Log.Infof(uiUtils.Red, "Invalid kube config file. Try using a different config with '--kube-config='") - return - } + mizu.Log.Error(err) + return } ctx, cancel := context.WithCancel(context.Background()) diff --git a/cli/kubernetes/provider.go b/cli/kubernetes/provider.go index 211d9ea1a..e31f54327 100644 --- a/cli/kubernetes/provider.go +++ b/cli/kubernetes/provider.go @@ -1,6 +1,7 @@ package kubernetes import ( + "bytes" _ "bytes" "context" "encoding/json" @@ -12,13 +13,17 @@ import ( "strconv" "github.com/up9inc/mizu/cli/mizu" + "io" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/homedir" + "github.com/up9inc/mizu/shared" core "k8s.io/api/core/v1" rbac "k8s.io/api/rbac/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" resource "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/watch" applyconfapp "k8s.io/client-go/applyconfigurations/apps/v1" @@ -30,11 +35,9 @@ import ( _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" _ "k8s.io/client-go/plugin/pkg/client/auth/openstack" restclient "k8s.io/client-go/rest" - "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/clientcmd" _ "k8s.io/client-go/tools/portforward" watchtools "k8s.io/client-go/tools/watch" - "k8s.io/client-go/util/homedir" ) type Provider struct { @@ -52,7 +55,12 @@ func NewProvider(kubeConfigPath string) (*Provider, error) { kubernetesConfig := loadKubernetesConfiguration(kubeConfigPath) restClientConfig, err := kubernetesConfig.ClientConfig() if err != nil { - return nil, err + if clientcmd.IsEmptyConfig(err) { + return nil, fmt.Errorf("Couldn't find the kube config file, or file is empty. Try adding '--kube-config='\n") + } + if clientcmd.IsConfigurationInvalid(err) { + return nil, fmt.Errorf("Invalid kube config file. Try using a different config with '--kube-config='\n") + } } clientSet := getClientSet(restClientConfig) @@ -551,10 +559,22 @@ func (provider *Provider) CreateConfigMap(ctx context.Context, namespace string, if _, err := provider.clientSet.CoreV1().ConfigMaps(namespace).Create(ctx, configMap, metav1.CreateOptions{}); err != nil { return err } - return nil } +func (provider *Provider) ListPods(ctx context.Context, namespace string) ([]shared.PodInfo, error) { + podInfos := make([]shared.PodInfo, 0) + listOptions := metav1.ListOptions{} + pods, err := provider.clientSet.CoreV1().Pods(namespace).List(ctx, listOptions) + if err != nil { + return podInfos, fmt.Errorf("error getting pods in ns: %s, %w", namespace, err) + } + for _, pod := range pods.Items { + podInfos = append(podInfos, shared.PodInfo{Name: pod.Name, Namespace: pod.Namespace}) + } + return podInfos, nil +} + func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespace string, daemonSetName string, podImage string, tapperPodName string, apiServerPodIp string, nodeToTappedPodIPMap map[string][]string, serviceAccountName string, tapOutgoing bool) error { mizu.Log.Debugf("Applying %d tapper deamonsets, ns: %s, daemonSetName: %s, podImage: %s, tapperPodName: %s", len(nodeToTappedPodIPMap), namespace, daemonSetName, podImage, tapperPodName) @@ -685,6 +705,22 @@ func (provider *Provider) GetAllRunningPodsMatchingRegex(ctx context.Context, re return matchingPods, nil } +func (provider *Provider) GetPodLogs(namespace string, podName string, ctx context.Context) (string, error) { + podLogOpts := core.PodLogOptions{} + req := provider.clientSet.CoreV1().Pods(namespace).GetLogs(podName, &podLogOpts) + podLogs, err := req.Stream(ctx) + if err != nil { + return "", fmt.Errorf("error opening log stream on ns: %s, pod: %s, %w", namespace, podName, err) + } + defer podLogs.Close() + buf := new(bytes.Buffer) + if _, err = io.Copy(buf, podLogs); err != nil { + return "", fmt.Errorf("error copy information from podLogs to buf, ns: %s, pod: %s, %w", namespace, podName, err) + } + str := buf.String() + return str, nil +} + func getClientSet(config *restclient.Config) *kubernetes.Clientset { clientSet, err := kubernetes.NewForConfig(config) if err != nil { diff --git a/cli/logsUtils/mizuLogsUtils.go b/cli/logsUtils/mizuLogsUtils.go new file mode 100644 index 000000000..96911875e --- /dev/null +++ b/cli/logsUtils/mizuLogsUtils.go @@ -0,0 +1,104 @@ +package logsUtils + +import ( + "archive/zip" + "context" + "fmt" + "github.com/up9inc/mizu/cli/kubernetes" + "github.com/up9inc/mizu/cli/mizu" + "io" + "os" + "path/filepath" +) + +func DumpLogs(provider *kubernetes.Provider, ctx context.Context, filePath string) error { + pods, err := provider.ListPods(ctx, mizu.Config.ResourcesNamespace()) + if err != nil { + return err + } + + if len(pods) == 0 { + return fmt.Errorf("no pods found in namespace %s", mizu.Config.ResourcesNamespace()) + } + + newZipFile, err := os.Create(filePath) + if err != nil { + return err + } + defer newZipFile.Close() + zipWriter := zip.NewWriter(newZipFile) + defer zipWriter.Close() + + for _, pod := range pods { + logs, err := provider.GetPodLogs(pod.Namespace, pod.Name, ctx) + if err != nil { + mizu.Log.Errorf("Failed to get logs, %v", err) + continue + } else { + mizu.Log.Debugf("Successfully read log length %d for pod: %s.%s", len(logs), pod.Namespace, pod.Name) + } + if err := addLogsToZip(zipWriter, logs, fmt.Sprintf("%s.%s.log", pod.Namespace, pod.Name)); err != nil { + mizu.Log.Errorf("Failed write logs, %v", err) + } else { + mizu.Log.Infof("Successfully added log length %d from pod: %s.%s", len(logs), pod.Namespace, pod.Name) + } + } + if err := addFileToZip(zipWriter, mizu.GetConfigFilePath()); err != nil { + mizu.Log.Errorf("Failed write file, %v", err) + } else { + mizu.Log.Infof("Successfully added file %s", mizu.GetConfigFilePath()) + } + if err := addFileToZip(zipWriter, mizu.GetLogFilePath()); err != nil { + mizu.Log.Errorf("Failed write file, %v", err) + } else { + mizu.Log.Infof("Successfully added file %s", mizu.GetLogFilePath()) + } + mizu.Log.Infof("You can find the zip with all logs in %s\n", filePath) + return nil +} + +func addFileToZip(zipWriter *zip.Writer, filename string) error { + + fileToZip, err := os.Open(filename) + if err != nil { + return fmt.Errorf("failed to open file %s, %w", filename, err) + } + defer fileToZip.Close() + + // Get the file information + info, err := fileToZip.Stat() + if err != nil { + return fmt.Errorf("failed to get file information %s, %w", filename, err) + } + + header, err := zip.FileInfoHeader(info) + if err != nil { + return err + } + + // Using FileInfoHeader() above only uses the basename of the file. If we want + // to preserve the folder structure we can overwrite this with the full path. + header.Name = filepath.Base(filename) + + // Change to deflate to gain better compression + // see http://golang.org/pkg/archive/zip/#pkg-constants + header.Method = zip.Deflate + + writer, err := zipWriter.CreateHeader(header) + if err != nil { + return fmt.Errorf("failed to create header in zip for %s, %w", filename, err) + } + _, err = io.Copy(writer, fileToZip) + return err +} + +func addLogsToZip(writer *zip.Writer, logs string, fileName string) error { + if zipFile, err := writer.Create(fileName); err != nil { + return fmt.Errorf("couldn't create a log file inside zip for %s, %w", fileName, err) + } else { + if _, err = zipFile.Write([]byte(logs)); err != nil { + return fmt.Errorf("couldn't write logs to zip file: %s, %w", fileName, err) + } + } + return nil +} diff --git a/cli/mizu/config.go b/cli/mizu/config.go index 38c342130..2babdbad6 100644 --- a/cli/mizu/config.go +++ b/cli/mizu/config.go @@ -51,7 +51,7 @@ func GetConfigWithDefaults() (string, error) { } func GetConfigFilePath() string { - return path.Join(getMizuFolderPath(), "config.yaml") + return path.Join(GetMizuFolderPath(), "config.yaml") } func mergeConfigFile() error { diff --git a/cli/mizu/configStruct.go b/cli/mizu/configStruct.go index a3e358e1b..f6b3ef4e5 100644 --- a/cli/mizu/configStruct.go +++ b/cli/mizu/configStruct.go @@ -14,6 +14,7 @@ type ConfigStruct struct { MizuImage string `yaml:"mizu-image"` MizuNamespace string `yaml:"mizu-namespace"` Telemetry bool `yaml:"telemetry" default:"true"` + DumpLogs bool `yaml:"dump-logs" default:"false"` } func (config *ConfigStruct) SetDefaults() { diff --git a/cli/mizu/consts.go b/cli/mizu/consts.go index e1489a05d..848f463b9 100644 --- a/cli/mizu/consts.go +++ b/cli/mizu/consts.go @@ -27,7 +27,7 @@ const ( ConfigMapName = "mizu-policy" ) -func getMizuFolderPath() string { +func GetMizuFolderPath() string { home, homeDirErr := os.UserHomeDir() if homeDirErr != nil { return "" diff --git a/cli/mizu/logger.go b/cli/mizu/logger.go index 20ca87856..9307c110a 100644 --- a/cli/mizu/logger.go +++ b/cli/mizu/logger.go @@ -13,12 +13,12 @@ var format = logging.MustStringFormatter( `%{time} %{level:.5s} â–¶ %{pid} %{shortfile} %{shortfunc} â–¶ %{message}`, ) +func GetLogFilePath() string { + return path.Join(GetMizuFolderPath(), "mizu_cli.log") +} + func InitLogger() { - mizuDirPath := getMizuFolderPath() - if err := os.MkdirAll(mizuDirPath, os.ModePerm); err != nil { - panic(fmt.Sprintf("Failed creating mizu dir: %v, err %v", mizuDirPath, err)) - } - logPath := path.Join(mizuDirPath, "log.log") + logPath := GetLogFilePath() f, err := os.OpenFile(logPath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) if err != nil { panic(fmt.Sprintf("Failed mizu log file: %v, err %v", logPath, err)) From 683d199774c7a969ab7a6d09c2ce5e7bc6daadae Mon Sep 17 00:00:00 2001 From: RoyUP9 <87927115+RoyUP9@users.noreply.github.com> Date: Thu, 5 Aug 2021 11:19:29 +0300 Subject: [PATCH 57/69] added support of multiple namespaces (#167) --- cli/cmd/tap.go | 2 +- cli/cmd/tapRunner.go | 49 ++++++++++--------- cli/kubernetes/provider.go | 16 ++++-- cli/kubernetes/watch.go | 75 +++++++++++++++++------------ cli/mizu/configStructs/tapConfig.go | 4 +- 5 files changed, 84 insertions(+), 62 deletions(-) diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go index bfb62dcc6..5538a0fd4 100644 --- a/cli/cmd/tap.go +++ b/cli/cmd/tap.go @@ -56,7 +56,7 @@ func init() { defaults.Set(&defaultTapConfig) tapCmd.Flags().Uint16P(configStructs.GuiPortTapName, "p", defaultTapConfig.GuiPort, "Provide a custom port for the web interface webserver") - tapCmd.Flags().StringP(configStructs.NamespaceTapName, "n", defaultTapConfig.Namespace, "Namespace selector") + tapCmd.Flags().StringArrayP(configStructs.NamespacesTapName, "n", defaultTapConfig.Namespaces, "Namespaces selector") tapCmd.Flags().Bool(configStructs.AnalysisTapName, defaultTapConfig.Analysis, "Uploads traffic to UP9 for further analysis (Beta)") tapCmd.Flags().BoolP(configStructs.AllNamespacesTapName, "A", defaultTapConfig.AllNamespaces, "Tap all namespaces") tapCmd.Flags().StringP(configStructs.KubeConfigPathTapName, "k", defaultTapConfig.KubeConfigPath, "Path to kube-config file") diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index 91c277376..c4f2ac23d 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -11,6 +11,7 @@ import ( "os/signal" "path" "regexp" + "strings" "syscall" "time" @@ -65,24 +66,25 @@ func RunMizuTap() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() // cancel will be called when this function exits - targetNamespace := getNamespace(kubernetesProvider) + targetNamespaces := getNamespaces(kubernetesProvider) + var namespacesStr string - if targetNamespace != mizu.K8sAllNamespaces { - namespacesStr = fmt.Sprintf("namespace \"%s\"", targetNamespace) + if targetNamespaces[0] != mizu.K8sAllNamespaces { + namespacesStr = fmt.Sprintf("namespaces \"%s\"", strings.Join(targetNamespaces, "\", \"")) } else { namespacesStr = "all namespaces" } mizu.CheckNewerVersion() mizu.Log.Infof("Tapping pods in %s", namespacesStr) - if err, _ := updateCurrentlyTappedPods(kubernetesProvider, ctx, targetNamespace); err != nil { + if err, _ := updateCurrentlyTappedPods(kubernetesProvider, ctx, targetNamespaces); err != nil { mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error getting pods by regex: %v", errormessage.FormatError(err))) return } if len(state.currentlyTappedPods) == 0 { var suggestionStr string - if targetNamespace != mizu.K8sAllNamespaces { + if targetNamespaces[0] != mizu.K8sAllNamespaces { suggestionStr = ". Select a different namespace with -n or tap all namespaces with -A" } mizu.Log.Warningf(uiUtils.Warning, fmt.Sprintf("Did not find any pods matching the regex argument%s", suggestionStr)) @@ -100,7 +102,7 @@ func RunMizuTap() { } go createProxyToApiServerPod(ctx, kubernetesProvider, cancel) - go watchPodsForTapping(ctx, kubernetesProvider, cancel) + go watchPodsForTapping(ctx, kubernetesProvider, targetNamespaces, cancel) //block until exit signal or error waitForFinish(ctx, cancel) @@ -166,13 +168,13 @@ func createMizuApiServer(ctx context.Context, kubernetesProvider *kubernetes.Pro } opts := &kubernetes.ApiServerOptions{ - Namespace: mizu.Config.ResourcesNamespace(), - PodName: mizu.ApiServerPodName, - PodImage: mizu.Config.MizuImage, - ServiceAccountName: serviceAccountName, - IsNamespaceRestricted: !mizu.Config.IsOwnNamespace(), + Namespace: mizu.Config.ResourcesNamespace(), + PodName: mizu.ApiServerPodName, + PodImage: mizu.Config.MizuImage, + ServiceAccountName: serviceAccountName, + IsNamespaceRestricted: !mizu.Config.IsOwnNamespace(), MizuApiFilteringOptions: mizuApiFilteringOptions, - MaxEntriesDBSizeBytes: mizu.Config.Tap.MaxEntriesDBSizeBytes(), + MaxEntriesDBSizeBytes: mizu.Config.Tap.MaxEntriesDBSizeBytes(), } _, err = kubernetesProvider.CreateMizuApiServerPod(ctx, opts) if err != nil { @@ -347,12 +349,11 @@ func reportTappedPods() { } } -func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Provider, cancel context.CancelFunc) { - targetNamespace := getNamespace(kubernetesProvider) - added, modified, removed, errorChan := kubernetes.FilteredWatch(ctx, kubernetesProvider.GetPodWatcher(ctx, targetNamespace), mizu.Config.Tap.PodRegex()) +func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Provider, targetNamespaces []string, cancel context.CancelFunc) { + added, modified, removed, errorChan := kubernetes.FilteredWatch(ctx, kubernetesProvider, targetNamespaces, mizu.Config.Tap.PodRegex()) restartTappers := func() { - err, changeFound := updateCurrentlyTappedPods(kubernetesProvider, ctx, targetNamespace) + err, changeFound := updateCurrentlyTappedPods(kubernetesProvider, ctx, targetNamespaces) if err != nil { mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error getting pods by regex: %v", errormessage.FormatError(err))) cancel() @@ -407,9 +408,9 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro } } -func updateCurrentlyTappedPods(kubernetesProvider *kubernetes.Provider, ctx context.Context, targetNamespace string) (error, bool) { +func updateCurrentlyTappedPods(kubernetesProvider *kubernetes.Provider, ctx context.Context, targetNamespaces []string) (error, bool) { changeFound := false - if matchingPods, err := kubernetesProvider.GetAllRunningPodsMatchingRegex(ctx, mizu.Config.Tap.PodRegex(), targetNamespace); err != nil { + if matchingPods, err := kubernetesProvider.GetAllRunningPodsMatchingRegex(ctx, mizu.Config.Tap.PodRegex(), targetNamespaces); err != nil { return err, false } else { addedPods, removedPods := getPodArrayDiff(state.currentlyTappedPods, matchingPods) @@ -454,7 +455,7 @@ func getMissingPods(pods1 []core.Pod, pods2 []core.Pod) []core.Pod { func createProxyToApiServerPod(ctx context.Context, kubernetesProvider *kubernetes.Provider, cancel context.CancelFunc) { podExactRegex := regexp.MustCompile(fmt.Sprintf("^%s$", mizu.ApiServerPodName)) - added, modified, removed, errorChan := kubernetes.FilteredWatch(ctx, kubernetesProvider.GetPodWatcher(ctx, mizu.Config.ResourcesNamespace()), podExactRegex) + added, modified, removed, errorChan := kubernetes.FilteredWatch(ctx, kubernetesProvider, []string{mizu.Config.ResourcesNamespace()}, podExactRegex) isPodReady := false timeAfter := time.After(25 * time.Second) for { @@ -567,12 +568,12 @@ func waitForFinish(ctx context.Context, cancel context.CancelFunc) { } } -func getNamespace(kubernetesProvider *kubernetes.Provider) string { +func getNamespaces(kubernetesProvider *kubernetes.Provider) []string { if mizu.Config.Tap.AllNamespaces { - return mizu.K8sAllNamespaces - } else if len(mizu.Config.Tap.Namespace) > 0 { - return mizu.Config.Tap.Namespace + return []string{mizu.K8sAllNamespaces} + } else if len(mizu.Config.Tap.Namespaces) > 0 { + return mizu.Config.Tap.Namespaces } else { - return kubernetesProvider.CurrentNamespace() + return []string{kubernetesProvider.CurrentNamespace()} } } diff --git a/cli/kubernetes/provider.go b/cli/kubernetes/provider.go index e31f54327..026c77d94 100644 --- a/cli/kubernetes/provider.go +++ b/cli/kubernetes/provider.go @@ -691,13 +691,19 @@ func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespac return err } -func (provider *Provider) GetAllRunningPodsMatchingRegex(ctx context.Context, regex *regexp.Regexp, namespace string) ([]core.Pod, error) { - pods, err := provider.clientSet.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{}) - if err != nil { - return nil, err +func (provider *Provider) GetAllRunningPodsMatchingRegex(ctx context.Context, regex *regexp.Regexp, namespaces []string) ([]core.Pod, error) { + var pods []core.Pod + for _, namespace := range namespaces { + namespacePods, err := provider.clientSet.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{}) + if err != nil { + return nil, fmt.Errorf("failed to get pods in ns: %s, %w", namespace, err) + } + + pods = append(pods, namespacePods.Items...) } + matchingPods := make([]core.Pod, 0) - for _, pod := range pods.Items { + for _, pod := range pods { if regex.MatchString(pod.Name) && isPodRunning(&pod) { matchingPods = append(matchingPods, pod) } diff --git a/cli/kubernetes/watch.go b/cli/kubernetes/watch.go index 9d914d4e5..7916feef6 100644 --- a/cli/kubernetes/watch.go +++ b/cli/kubernetes/watch.go @@ -4,49 +4,64 @@ import ( "context" "errors" "regexp" + "sync" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/watch" ) -func FilteredWatch(ctx context.Context, watcher watch.Interface, podFilter *regexp.Regexp) (chan *corev1.Pod, chan *corev1.Pod, chan *corev1.Pod, chan error) { +func FilteredWatch(ctx context.Context, kubernetesProvider *Provider, targetNamespaces []string, podFilter *regexp.Regexp) (chan *corev1.Pod, chan *corev1.Pod, chan *corev1.Pod, chan error) { addedChan := make(chan *corev1.Pod) modifiedChan := make(chan *corev1.Pod) removedChan := make(chan *corev1.Pod) errorChan := make(chan error) - go func() { - for { - select { - case e := <-watcher.ResultChan(): - if e.Object == nil { - errorChan <- errors.New("kubernetes pod watch failed") + var wg sync.WaitGroup + + for _, targetNamespace := range targetNamespaces { + wg.Add(1) + + go func(targetNamespace string) { + defer wg.Done() + watcher := kubernetesProvider.GetPodWatcher(ctx, targetNamespace) + + for { + select { + case e := <-watcher.ResultChan(): + if e.Object == nil { + errorChan <- errors.New("kubernetes pod watch failed") + return + } + + pod := e.Object.(*corev1.Pod) + + if !podFilter.MatchString(pod.Name) { + continue + } + + switch e.Type { + case watch.Added: + addedChan <- pod + case watch.Modified: + modifiedChan <- pod + case watch.Deleted: + removedChan <- pod + } + case <-ctx.Done(): + watcher.Stop() return } - - pod := e.Object.(*corev1.Pod) - - if !podFilter.MatchString(pod.Name) { - continue - } - - switch e.Type { - case watch.Added: - addedChan <- pod - case watch.Modified: - modifiedChan <- pod - case watch.Deleted: - removedChan <- pod - } - case <-ctx.Done(): - watcher.Stop() - close(addedChan) - close(modifiedChan) - close(removedChan) - close(errorChan) - return } - } + }(targetNamespace) + } + + go func() { + <-ctx.Done() + wg.Wait() + close(addedChan) + close(modifiedChan) + close(removedChan) + close(errorChan) }() return addedChan, modifiedChan, removedChan, errorChan diff --git a/cli/mizu/configStructs/tapConfig.go b/cli/mizu/configStructs/tapConfig.go index d00d5097a..2ac9352cd 100644 --- a/cli/mizu/configStructs/tapConfig.go +++ b/cli/mizu/configStructs/tapConfig.go @@ -11,7 +11,7 @@ import ( const ( GuiPortTapName = "gui-port" - NamespaceTapName = "namespace" + NamespacesTapName = "namespaces" AnalysisTapName = "analysis" AllNamespacesTapName = "all-namespaces" KubeConfigPathTapName = "kube-config" @@ -29,7 +29,7 @@ type TapConfig struct { SleepIntervalSec int `yaml:"upload-interval" default:"10"` PodRegexStr string `yaml:"regex" default:".*"` GuiPort uint16 `yaml:"gui-port" default:"8899"` - Namespace string `yaml:"namespace"` + Namespaces []string `yaml:"namespaces"` Analysis bool `yaml:"analysis" default:"false"` AllNamespaces bool `yaml:"all-namespaces" default:"false"` KubeConfigPath string `yaml:"kube-config"` From 90f0f603c7127530ab367519f1a030284f3acc09 Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Thu, 5 Aug 2021 12:12:01 +0300 Subject: [PATCH 58/69] Support getting logs in ns restricted mode (#168) --- cli/cmd/tap.go | 4 ++ cli/cmd/tapRunner.go | 80 ++++++++++++++++---------------- cli/cmd/viewRunner.go | 4 +- cli/errormessage/errormessage.go | 4 +- cli/kubernetes/provider.go | 32 +++++++------ cli/logsUtils/mizuLogsUtils.go | 6 ++- cli/mizu/config.go | 11 +++++ cli/mizu/configStruct.go | 34 +++++--------- cli/mizu/consts.go | 21 ++++----- 9 files changed, 102 insertions(+), 94 deletions(-) diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go index 5538a0fd4..9aa040134 100644 --- a/cli/cmd/tap.go +++ b/cli/cmd/tap.go @@ -31,6 +31,10 @@ Supported protocols are HTTP and gRPC.`, return errors.New("unexpected number of arguments") } + if err := mizu.Config.Validate(); err != nil { + return errormessage.FormatError(err) + } + if err := mizu.Config.Tap.Validate(); err != nil { return errormessage.FormatError(err) } diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index c4f2ac23d..a886144de 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -118,7 +118,7 @@ func readValidationRules(file string) (string, error) { } func createMizuResources(ctx context.Context, kubernetesProvider *kubernetes.Provider, nodeToTappedPodIPMap map[string][]string, mizuApiFilteringOptions *shared.TrafficFilteringOptions, mizuValidationRules string) error { - if mizu.Config.IsOwnNamespace() { + if !mizu.Config.IsNsRestrictedMode() { if err := createMizuNamespace(ctx, kubernetesProvider); err != nil { return err } @@ -143,12 +143,12 @@ func createMizuResources(ctx context.Context, kubernetesProvider *kubernetes.Pro } func createMizuConfigmap(ctx context.Context, kubernetesProvider *kubernetes.Provider, data string) error { - err := kubernetesProvider.CreateConfigMap(ctx, mizu.Config.ResourcesNamespace(), mizu.ConfigMapName, data) + err := kubernetesProvider.CreateConfigMap(ctx, mizu.Config.MizuResourcesNamespace, mizu.ConfigMapName, data) return err } func createMizuNamespace(ctx context.Context, kubernetesProvider *kubernetes.Provider) error { - _, err := kubernetesProvider.CreateNamespace(ctx, mizu.Config.ResourcesNamespace()) + _, err := kubernetesProvider.CreateNamespace(ctx, mizu.Config.MizuResourcesNamespace) return err } @@ -168,11 +168,11 @@ func createMizuApiServer(ctx context.Context, kubernetesProvider *kubernetes.Pro } opts := &kubernetes.ApiServerOptions{ - Namespace: mizu.Config.ResourcesNamespace(), + Namespace: mizu.Config.MizuResourcesNamespace, PodName: mizu.ApiServerPodName, - PodImage: mizu.Config.MizuImage, + PodImage: mizu.Config.AgentImage, ServiceAccountName: serviceAccountName, - IsNamespaceRestricted: !mizu.Config.IsOwnNamespace(), + IsNamespaceRestricted: mizu.Config.IsNsRestrictedMode(), MizuApiFilteringOptions: mizuApiFilteringOptions, MaxEntriesDBSizeBytes: mizu.Config.Tap.MaxEntriesDBSizeBytes(), } @@ -182,7 +182,7 @@ func createMizuApiServer(ctx context.Context, kubernetesProvider *kubernetes.Pro } mizu.Log.Debugf("Successfully created API server pod: %s", mizu.ApiServerPodName) - state.apiServerService, err = kubernetesProvider.CreateService(ctx, mizu.Config.ResourcesNamespace(), mizu.ApiServerPodName, mizu.ApiServerPodName) + state.apiServerService, err = kubernetesProvider.CreateService(ctx, mizu.Config.MizuResourcesNamespace, mizu.ApiServerPodName, mizu.ApiServerPodName) if err != nil { return err } @@ -219,9 +219,9 @@ func updateMizuTappers(ctx context.Context, kubernetesProvider *kubernetes.Provi if err := kubernetesProvider.ApplyMizuTapperDaemonSet( ctx, - mizu.Config.ResourcesNamespace(), + mizu.Config.MizuResourcesNamespace, mizu.TapperDaemonSetName, - mizu.Config.MizuImage, + mizu.Config.AgentImage, mizu.TapperPodName, fmt.Sprintf("%s.%s.svc.cluster.local", state.apiServerService.Name, state.apiServerService.Namespace), nodeToTappedPodIPMap, @@ -232,7 +232,7 @@ func updateMizuTappers(ctx context.Context, kubernetesProvider *kubernetes.Provi } mizu.Log.Debugf("Successfully created %v tappers", len(nodeToTappedPodIPMap)) } else { - if err := kubernetesProvider.RemoveDaemonSet(ctx, mizu.Config.ResourcesNamespace(), mizu.TapperDaemonSetName); err != nil { + if err := kubernetesProvider.RemoveDaemonSet(ctx, mizu.Config.MizuResourcesNamespace, mizu.TapperDaemonSetName); err != nil { return err } } @@ -255,55 +255,55 @@ func cleanUpMizuResources(kubernetesProvider *kubernetes.Provider) { mizu.Log.Infof("\nRemoving mizu resources\n") - if mizu.Config.IsOwnNamespace() { - if err := kubernetesProvider.RemoveNamespace(removalCtx, mizu.Config.ResourcesNamespace()); err != nil { - mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing Namespace %s: %v", mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + if !mizu.Config.IsNsRestrictedMode() { + if err := kubernetesProvider.RemoveNamespace(removalCtx, mizu.Config.MizuResourcesNamespace); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing Namespace %s: %v", mizu.Config.MizuResourcesNamespace, errormessage.FormatError(err))) return } } else { - if err := kubernetesProvider.RemovePod(removalCtx, mizu.Config.ResourcesNamespace(), mizu.ApiServerPodName); err != nil { - mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing Pod %s in namespace %s: %v", mizu.ApiServerPodName, mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + if err := kubernetesProvider.RemovePod(removalCtx, mizu.Config.MizuResourcesNamespace, mizu.ApiServerPodName); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing Pod %s in namespace %s: %v", mizu.ApiServerPodName, mizu.Config.MizuResourcesNamespace, errormessage.FormatError(err))) } - if err := kubernetesProvider.RemoveService(removalCtx, mizu.Config.ResourcesNamespace(), mizu.ApiServerPodName); err != nil { - mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing Service %s in namespace %s: %v", mizu.ApiServerPodName, mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + if err := kubernetesProvider.RemoveService(removalCtx, mizu.Config.MizuResourcesNamespace, mizu.ApiServerPodName); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing Service %s in namespace %s: %v", mizu.ApiServerPodName, mizu.Config.MizuResourcesNamespace, errormessage.FormatError(err))) } - if err := kubernetesProvider.RemoveDaemonSet(removalCtx, mizu.Config.ResourcesNamespace(), mizu.TapperDaemonSetName); err != nil { - mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing DaemonSet %s in namespace %s: %v", mizu.TapperDaemonSetName, mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + if err := kubernetesProvider.RemoveDaemonSet(removalCtx, mizu.Config.MizuResourcesNamespace, mizu.TapperDaemonSetName); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing DaemonSet %s in namespace %s: %v", mizu.TapperDaemonSetName, mizu.Config.MizuResourcesNamespace, errormessage.FormatError(err))) } if !state.doNotRemoveConfigMap { - if err := kubernetesProvider.RemoveConfigMap(removalCtx, mizu.Config.ResourcesNamespace(), mizu.ConfigMapName); err != nil { - mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing ConfigMap %s in namespace %s: %v", mizu.ConfigMapName, mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + if err := kubernetesProvider.RemoveConfigMap(removalCtx, mizu.Config.MizuResourcesNamespace, mizu.ConfigMapName); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing ConfigMap %s in namespace %s: %v", mizu.ConfigMapName, mizu.Config.MizuResourcesNamespace, errormessage.FormatError(err))) } } } if state.mizuServiceAccountExists { - if mizu.Config.IsOwnNamespace() { + if !mizu.Config.IsNsRestrictedMode() { if err := kubernetesProvider.RemoveNonNamespacedResources(removalCtx, mizu.ClusterRoleName, mizu.ClusterRoleBindingName); err != nil { mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing non-namespaced resources: %v", errormessage.FormatError(err))) return } } else { - if err := kubernetesProvider.RemoveServicAccount(removalCtx, mizu.Config.ResourcesNamespace(), mizu.ServiceAccountName); err != nil { - mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing Service Account %s in namespace %s: %v", mizu.ServiceAccountName, mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + if err := kubernetesProvider.RemoveServicAccount(removalCtx, mizu.Config.MizuResourcesNamespace, mizu.ServiceAccountName); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing Service Account %s in namespace %s: %v", mizu.ServiceAccountName, mizu.Config.MizuResourcesNamespace, errormessage.FormatError(err))) return } - if err := kubernetesProvider.RemoveRole(removalCtx, mizu.Config.ResourcesNamespace(), mizu.RoleName); err != nil { - mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing Role %s in namespace %s: %v", mizu.RoleName, mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + if err := kubernetesProvider.RemoveRole(removalCtx, mizu.Config.MizuResourcesNamespace, mizu.RoleName); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing Role %s in namespace %s: %v", mizu.RoleName, mizu.Config.MizuResourcesNamespace, errormessage.FormatError(err))) } - if err := kubernetesProvider.RemoveRoleBinding(removalCtx, mizu.Config.ResourcesNamespace(), mizu.RoleBindingName); err != nil { - mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing RoleBinding %s in namespace %s: %v", mizu.RoleBindingName, mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + if err := kubernetesProvider.RemoveRoleBinding(removalCtx, mizu.Config.MizuResourcesNamespace, mizu.RoleBindingName); err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error removing RoleBinding %s in namespace %s: %v", mizu.RoleBindingName, mizu.Config.MizuResourcesNamespace, errormessage.FormatError(err))) } } } - if mizu.Config.IsOwnNamespace() { + if !mizu.Config.IsNsRestrictedMode() { waitUntilNamespaceDeleted(removalCtx, cancel, kubernetesProvider) } } @@ -314,14 +314,14 @@ func waitUntilNamespaceDeleted(ctx context.Context, cancel context.CancelFunc, k waitForFinish(ctx, cancel) }() - if err := kubernetesProvider.WaitUtilNamespaceDeleted(ctx, mizu.Config.ResourcesNamespace()); err != nil { + if err := kubernetesProvider.WaitUtilNamespaceDeleted(ctx, mizu.Config.MizuResourcesNamespace); err != nil { switch { case ctx.Err() == context.Canceled: // Do nothing. User interrupted the wait. case err == wait.ErrWaitTimeout: - mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Timeout while removing Namespace %s", mizu.Config.ResourcesNamespace())) + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Timeout while removing Namespace %s", mizu.Config.MizuResourcesNamespace)) default: - mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error while waiting for Namespace %s to be deleted: %v", mizu.Config.ResourcesNamespace(), errormessage.FormatError(err))) + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error while waiting for Namespace %s to be deleted: %v", mizu.Config.MizuResourcesNamespace, errormessage.FormatError(err))) } } } @@ -410,7 +410,7 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro func updateCurrentlyTappedPods(kubernetesProvider *kubernetes.Provider, ctx context.Context, targetNamespaces []string) (error, bool) { changeFound := false - if matchingPods, err := kubernetesProvider.GetAllRunningPodsMatchingRegex(ctx, mizu.Config.Tap.PodRegex(), targetNamespaces); err != nil { + if matchingPods, err := kubernetesProvider.ListAllRunningPodsMatchingRegex(ctx, mizu.Config.Tap.PodRegex(), targetNamespaces); err != nil { return err, false } else { addedPods, removedPods := getPodArrayDiff(state.currentlyTappedPods, matchingPods) @@ -455,7 +455,7 @@ func getMissingPods(pods1 []core.Pod, pods2 []core.Pod) []core.Pod { func createProxyToApiServerPod(ctx context.Context, kubernetesProvider *kubernetes.Provider, cancel context.CancelFunc) { podExactRegex := regexp.MustCompile(fmt.Sprintf("^%s$", mizu.ApiServerPodName)) - added, modified, removed, errorChan := kubernetes.FilteredWatch(ctx, kubernetesProvider, []string{mizu.Config.ResourcesNamespace()}, podExactRegex) + added, modified, removed, errorChan := kubernetes.FilteredWatch(ctx, kubernetesProvider, []string{mizu.Config.MizuResourcesNamespace}, podExactRegex) isPodReady := false timeAfter := time.After(25 * time.Second) for { @@ -474,7 +474,7 @@ func createProxyToApiServerPod(ctx context.Context, kubernetesProvider *kubernet if modifiedPod.Status.Phase == core.PodRunning && !isPodReady { isPodReady = true go func() { - err := kubernetes.StartProxy(kubernetesProvider, mizu.Config.Tap.GuiPort, mizu.Config.ResourcesNamespace(), mizu.ApiServerPodName) + err := kubernetes.StartProxy(kubernetesProvider, mizu.Config.Tap.GuiPort, mizu.Config.MizuResourcesNamespace, mizu.ApiServerPodName) if err != nil { mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error occured while running k8s proxy %v", errormessage.FormatError(err))) cancel() @@ -493,7 +493,7 @@ func createProxyToApiServerPod(ctx context.Context, kubernetesProvider *kubernet cancel() } case <-errorChan: - mizu.Log.Debugf("[ERROR] Agent creation, watching %v namespace", mizu.Config.ResourcesNamespace()) + mizu.Log.Debugf("[ERROR] Agent creation, watching %v namespace", mizu.Config.MizuResourcesNamespace) cancel() } } @@ -522,18 +522,18 @@ func requestForAnalysis() { } func createRBACIfNecessary(ctx context.Context, kubernetesProvider *kubernetes.Provider) (bool, error) { - mizuRBACExists, err := kubernetesProvider.DoesServiceAccountExist(ctx, mizu.Config.ResourcesNamespace(), mizu.ServiceAccountName) + mizuRBACExists, err := kubernetesProvider.DoesServiceAccountExist(ctx, mizu.Config.MizuResourcesNamespace, mizu.ServiceAccountName) if err != nil { return false, err } if !mizuRBACExists { - if mizu.Config.IsOwnNamespace() { - err := kubernetesProvider.CreateMizuRBAC(ctx, mizu.Config.ResourcesNamespace(), mizu.ServiceAccountName, mizu.ClusterRoleName, mizu.ClusterRoleBindingName, mizu.RBACVersion) + if !mizu.Config.IsNsRestrictedMode() { + err := kubernetesProvider.CreateMizuRBAC(ctx, mizu.Config.MizuResourcesNamespace, mizu.ServiceAccountName, mizu.ClusterRoleName, mizu.ClusterRoleBindingName, mizu.RBACVersion) if err != nil { return false, err } } else { - err := kubernetesProvider.CreateMizuRBACNamespaceRestricted(ctx, mizu.Config.ResourcesNamespace(), mizu.ServiceAccountName, mizu.RoleName, mizu.RoleBindingName, mizu.RBACVersion) + err := kubernetesProvider.CreateMizuRBACNamespaceRestricted(ctx, mizu.Config.MizuResourcesNamespace, mizu.ServiceAccountName, mizu.RoleName, mizu.RoleBindingName, mizu.RBACVersion) if err != nil { return false, err } diff --git a/cli/cmd/viewRunner.go b/cli/cmd/viewRunner.go index 2c9e9d931..f2aae65a7 100644 --- a/cli/cmd/viewRunner.go +++ b/cli/cmd/viewRunner.go @@ -18,7 +18,7 @@ func runMizuView() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - exists, err := kubernetesProvider.DoesServicesExist(ctx, mizu.Config.ResourcesNamespace(), mizu.ApiServerPodName) + exists, err := kubernetesProvider.DoesServicesExist(ctx, mizu.Config.MizuResourcesNamespace, mizu.ApiServerPodName) if err != nil { panic(err) } @@ -36,7 +36,7 @@ func runMizuView() { mizu.Log.Infof("Found service %s, creating k8s proxy", mizu.ApiServerPodName) mizu.Log.Infof("Mizu is available at http://%s\n", kubernetes.GetMizuApiServerProxiedHostAndPath(mizu.Config.View.GuiPort)) - err = kubernetes.StartProxy(kubernetesProvider, mizu.Config.View.GuiPort, mizu.Config.ResourcesNamespace(), mizu.ApiServerPodName) + err = kubernetes.StartProxy(kubernetesProvider, mizu.Config.View.GuiPort, mizu.Config.MizuResourcesNamespace, mizu.ApiServerPodName) if err != nil { mizu.Log.Infof("Error occured while running k8s proxy %v", err) } diff --git a/cli/errormessage/errormessage.go b/cli/errormessage/errormessage.go index 510581e8d..657562dbf 100644 --- a/cli/errormessage/errormessage.go +++ b/cli/errormessage/errormessage.go @@ -13,7 +13,9 @@ import ( func FormatError(err error) error { var errorNew error if k8serrors.IsForbidden(err) { - errorNew = fmt.Errorf("Insufficient permissions: %w. Supply the required permission or control Mizu's access to namespaces by setting MizuNamespace in the config file or setting the tapped namespace with --set mizu-namespace=.", err) + errorNew = fmt.Errorf("Insufficient permissions: %w. "+ + "Supply the required permission or control Mizu's access to namespaces by setting MizuResourcesNamespace "+ + "in the config file or setting the tapped namespace with --set mizu-resources-namespace=.", err) } else if syntaxError, isSyntaxError := asRegexSyntaxError(err); isSyntaxError { errorNew = fmt.Errorf("Regex %s is invalid: %w", syntaxError.Expr, err) } else { diff --git a/cli/kubernetes/provider.go b/cli/kubernetes/provider.go index 026c77d94..d6c92754f 100644 --- a/cli/kubernetes/provider.go +++ b/cli/kubernetes/provider.go @@ -562,19 +562,6 @@ func (provider *Provider) CreateConfigMap(ctx context.Context, namespace string, return nil } -func (provider *Provider) ListPods(ctx context.Context, namespace string) ([]shared.PodInfo, error) { - podInfos := make([]shared.PodInfo, 0) - listOptions := metav1.ListOptions{} - pods, err := provider.clientSet.CoreV1().Pods(namespace).List(ctx, listOptions) - if err != nil { - return podInfos, fmt.Errorf("error getting pods in ns: %s, %w", namespace, err) - } - for _, pod := range pods.Items { - podInfos = append(podInfos, shared.PodInfo{Name: pod.Name, Namespace: pod.Namespace}) - } - return podInfos, nil -} - func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespace string, daemonSetName string, podImage string, tapperPodName string, apiServerPodIp string, nodeToTappedPodIPMap map[string][]string, serviceAccountName string, tapOutgoing bool) error { mizu.Log.Debugf("Applying %d tapper deamonsets, ns: %s, daemonSetName: %s, podImage: %s, tapperPodName: %s", len(nodeToTappedPodIPMap), namespace, daemonSetName, podImage, tapperPodName) @@ -691,7 +678,7 @@ func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespac return err } -func (provider *Provider) GetAllRunningPodsMatchingRegex(ctx context.Context, regex *regexp.Regexp, namespaces []string) ([]core.Pod, error) { +func (provider *Provider) ListAllPodsMatchingRegex(ctx context.Context, regex *regexp.Regexp, namespaces []string) ([]core.Pod, error) { var pods []core.Pod for _, namespace := range namespaces { namespacePods, err := provider.clientSet.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{}) @@ -704,7 +691,22 @@ func (provider *Provider) GetAllRunningPodsMatchingRegex(ctx context.Context, re matchingPods := make([]core.Pod, 0) for _, pod := range pods { - if regex.MatchString(pod.Name) && isPodRunning(&pod) { + if regex.MatchString(pod.Name) { + matchingPods = append(matchingPods, pod) + } + } + return matchingPods, nil +} + +func (provider *Provider) ListAllRunningPodsMatchingRegex(ctx context.Context, regex *regexp.Regexp, namespaces []string) ([]core.Pod, error) { + pods, err := provider.ListAllPodsMatchingRegex(ctx, regex, namespaces) + if err != nil { + return nil, err + } + + matchingPods := make([]core.Pod, 0) + for _, pod := range pods { + if isPodRunning(&pod) { matchingPods = append(matchingPods, pod) } } diff --git a/cli/logsUtils/mizuLogsUtils.go b/cli/logsUtils/mizuLogsUtils.go index 96911875e..aed8d9c9a 100644 --- a/cli/logsUtils/mizuLogsUtils.go +++ b/cli/logsUtils/mizuLogsUtils.go @@ -9,16 +9,18 @@ import ( "io" "os" "path/filepath" + "regexp" ) func DumpLogs(provider *kubernetes.Provider, ctx context.Context, filePath string) error { - pods, err := provider.ListPods(ctx, mizu.Config.ResourcesNamespace()) + podExactRegex := regexp.MustCompile(fmt.Sprintf("^mizu-")) + pods, err := provider.ListAllPodsMatchingRegex(ctx, podExactRegex, []string{mizu.Config.MizuResourcesNamespace}) if err != nil { return err } if len(pods) == 0 { - return fmt.Errorf("no pods found in namespace %s", mizu.Config.ResourcesNamespace()) + return fmt.Errorf("no pods found in namespace %s", mizu.Config.MizuResourcesNamespace) } newZipFile, err := os.Create(filePath) diff --git a/cli/mizu/config.go b/cli/mizu/config.go index 2babdbad6..f96f5b37b 100644 --- a/cli/mizu/config.go +++ b/cli/mizu/config.go @@ -24,6 +24,17 @@ const ( var Config = ConfigStruct{} +func (config *ConfigStruct) Validate() error { + if config.IsNsRestrictedMode() { + if config.Tap.AllNamespaces || len(config.Tap.Namespaces) != 1 || config.Tap.Namespaces[0] != config.MizuResourcesNamespace { + return fmt.Errorf("Not supported mode. Mizu can't resolve IPs in other namespaces when running in namespace restricted mode.\n" + + "You can use the same namespace for --namespace and --mizu-resources-namespace") + } + } + + return nil +} + func InitConfig(cmd *cobra.Command) error { if err := defaults.Set(&Config); err != nil { return err diff --git a/cli/mizu/configStruct.go b/cli/mizu/configStruct.go index f6b3ef4e5..da426caa0 100644 --- a/cli/mizu/configStruct.go +++ b/cli/mizu/configStruct.go @@ -7,32 +7,20 @@ import ( ) type ConfigStruct struct { - Tap configStructs.TapConfig `yaml:"tap"` - Fetch configStructs.FetchConfig `yaml:"fetch"` - Version configStructs.VersionConfig `yaml:"version"` - View configStructs.ViewConfig `yaml:"view"` - MizuImage string `yaml:"mizu-image"` - MizuNamespace string `yaml:"mizu-namespace"` - Telemetry bool `yaml:"telemetry" default:"true"` - DumpLogs bool `yaml:"dump-logs" default:"false"` + Tap configStructs.TapConfig `yaml:"tap"` + Fetch configStructs.FetchConfig `yaml:"fetch"` + Version configStructs.VersionConfig `yaml:"version"` + View configStructs.ViewConfig `yaml:"view"` + AgentImage string `yaml:"agent-image"` + MizuResourcesNamespace string `yaml:"mizu-resources-namespace" default:"mizu"` + Telemetry bool `yaml:"telemetry" default:"true"` + DumpLogs bool `yaml:"dump-logs" default:"false"` } func (config *ConfigStruct) SetDefaults() { - config.MizuImage = fmt.Sprintf("gcr.io/up9-docker-hub/mizu/%s:%s", Branch, SemVer) + config.AgentImage = fmt.Sprintf("gcr.io/up9-docker-hub/mizu/%s:%s", Branch, SemVer) } -func (config *ConfigStruct) ResourcesNamespace() string { - if config.MizuNamespace == "" { - return ResourcesDefaultNamespace - } - - return config.MizuNamespace -} - -func (config *ConfigStruct) IsOwnNamespace() bool { - if config.MizuNamespace == "" { - return true - } - - return false +func (config *ConfigStruct) IsNsRestrictedMode() bool { + return config.MizuResourcesNamespace != "mizu" // Notice "mizu" string must match the default MizuResourcesNamespace } diff --git a/cli/mizu/consts.go b/cli/mizu/consts.go index 848f463b9..576010709 100644 --- a/cli/mizu/consts.go +++ b/cli/mizu/consts.go @@ -14,17 +14,16 @@ var ( ) const ( - ApiServerPodName = "mizu-api-server" - ClusterRoleBindingName = "mizu-cluster-role-binding" - ClusterRoleName = "mizu-cluster-role" - K8sAllNamespaces = "" - ResourcesDefaultNamespace = "mizu" - RoleBindingName = "mizu-role-binding" - RoleName = "mizu-role" - ServiceAccountName = "mizu-service-account" - TapperDaemonSetName = "mizu-tapper-daemon-set" - TapperPodName = "mizu-tapper" - ConfigMapName = "mizu-policy" + ApiServerPodName = "mizu-api-server" + ClusterRoleBindingName = "mizu-cluster-role-binding" + ClusterRoleName = "mizu-cluster-role" + K8sAllNamespaces = "" + RoleBindingName = "mizu-role-binding" + RoleName = "mizu-role" + ServiceAccountName = "mizu-service-account" + TapperDaemonSetName = "mizu-tapper-daemon-set" + TapperPodName = "mizu-tapper" + ConfigMapName = "mizu-policy" ) func GetMizuFolderPath() string { From 60533a95910ecfe90ab2fb67ed82e718514540c1 Mon Sep 17 00:00:00 2001 From: RoyUP9 <87927115+RoyUP9@users.noreply.github.com> Date: Thu, 5 Aug 2021 14:23:16 +0300 Subject: [PATCH 59/69] added allowed set flag (#169) --- cli/cmd/tap.go | 2 +- cli/errormessage/errormessage.go | 11 +++++++---- cli/mizu/config.go | 23 +++++++++++++++++++---- cli/mizu/configStruct.go | 7 +++++++ cli/mizu/configStructs/tapConfig.go | 2 ++ cli/mizu/sliceUtils.go | 11 +++++++++++ 6 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 cli/mizu/sliceUtils.go diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go index 9aa040134..3f4e56370 100644 --- a/cli/cmd/tap.go +++ b/cli/cmd/tap.go @@ -70,5 +70,5 @@ func init() { tapCmd.Flags().String(configStructs.HumanMaxEntriesDBSizeTapName, defaultTapConfig.HumanMaxEntriesDBSize, "override the default max entries db size of 200mb") tapCmd.Flags().String(configStructs.DirectionTapName, defaultTapConfig.Direction, "Record traffic that goes in this direction (relative to the tapped pod): in/any") tapCmd.Flags().Bool(configStructs.DryRunTapName, defaultTapConfig.DryRun, "Preview of all pods matching the regex, without tapping them") - tapCmd.Flags().String(configStructs.EnforcePolicyFile, "", "Yaml file with policy rules") + tapCmd.Flags().String(configStructs.EnforcePolicyFile, defaultTapConfig.EnforcePolicyFile, "Yaml file with policy rules") } diff --git a/cli/errormessage/errormessage.go b/cli/errormessage/errormessage.go index 657562dbf..da0185dc5 100644 --- a/cli/errormessage/errormessage.go +++ b/cli/errormessage/errormessage.go @@ -3,6 +3,9 @@ package errormessage import ( "errors" "fmt" + + "github.com/up9inc/mizu/cli/mizu" + regexpsyntax "regexp/syntax" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -13,11 +16,11 @@ import ( func FormatError(err error) error { var errorNew error if k8serrors.IsForbidden(err) { - errorNew = fmt.Errorf("Insufficient permissions: %w. "+ - "Supply the required permission or control Mizu's access to namespaces by setting MizuResourcesNamespace "+ - "in the config file or setting the tapped namespace with --set mizu-resources-namespace=.", err) + errorNew = fmt.Errorf("insufficient permissions: %w. "+ + "supply the required permission or control Mizu's access to namespaces by setting MizuResourcesNamespace "+ + "in the config file or setting the tapped namespace with --%s %s=", err, mizu.SetCommandName, mizu.MizuResourcesNamespaceConfigName) } else if syntaxError, isSyntaxError := asRegexSyntaxError(err); isSyntaxError { - errorNew = fmt.Errorf("Regex %s is invalid: %w", syntaxError.Expr, err) + errorNew = fmt.Errorf("regex %s is invalid: %w", syntaxError.Expr, err) } else { errorNew = err } diff --git a/cli/mizu/config.go b/cli/mizu/config.go index f96f5b37b..52335f85d 100644 --- a/cli/mizu/config.go +++ b/cli/mizu/config.go @@ -13,6 +13,7 @@ import ( "github.com/creasty/defaults" "github.com/spf13/cobra" "github.com/spf13/pflag" + "github.com/up9inc/mizu/cli/mizu/configStructs" "github.com/up9inc/mizu/cli/uiUtils" "gopkg.in/yaml.v3" ) @@ -22,13 +23,22 @@ const ( SetCommandName = "set" ) +var allowedSetFlags = []string{ + AgentImageConfigName, + MizuResourcesNamespaceConfigName, + TelemetryConfigName, + DumpLogsConfigName, + configStructs.AnalysisDestinationTapName, + configStructs.SleepIntervalSecTapName, +} + var Config = ConfigStruct{} func (config *ConfigStruct) Validate() error { if config.IsNsRestrictedMode() { if config.Tap.AllNamespaces || len(config.Tap.Namespaces) != 1 || config.Tap.Namespaces[0] != config.MizuResourcesNamespace { return fmt.Errorf("Not supported mode. Mizu can't resolve IPs in other namespaces when running in namespace restricted mode.\n" + - "You can use the same namespace for --namespace and --mizu-resources-namespace") + "You can use the same namespace for --%s and --%s", configStructs.NamespacesTapName, MizuResourcesNamespaceConfigName) } } @@ -95,7 +105,7 @@ func initFlag(f *pflag.Flag) { if f.Name == SetCommandName { if setError := mergeSetFlag(sliceValue.GetSlice()); setError != nil { - Log.Infof(uiUtils.Red, "Invalid set argument") + Log.Warningf(uiUtils.Red, fmt.Sprintf("%v", setError)) } return } @@ -117,6 +127,11 @@ func mergeSetFlag(setValues []string) error { } argumentKey, argumentValue := split[0], split[1] + + if !Contains(allowedSetFlags, argumentKey) { + return errors.New(fmt.Sprintf("invalid set flag name %s, allowed set flag names: \"%s\"", argumentKey, strings.Join(allowedSetFlags, "\", \""))) + } + mergeFlagValue(configElem, argumentKey, argumentValue) } @@ -141,7 +156,7 @@ func mergeFlagValue(currentElem reflect.Value, flagKey string, flagValue string) parsedValue, err := getParsedValue(flagValueKind, flagValue) if err != nil { - Log.Warningf(uiUtils.Red, fmt.Sprintf("Invalid value %v for key %s, expected %s", flagValue, flagKey, flagValueKind)) + Log.Warningf(uiUtils.Red, fmt.Sprintf("Invalid value %v for flag name %s, expected %s", flagValue, flagKey, flagValueKind)) return } @@ -169,7 +184,7 @@ func mergeFlagValues(currentElem reflect.Value, flagKey string, flagValues []str for _, flagValue := range flagValues { parsedValue, err := getParsedValue(flagValueKind, flagValue) if err != nil { - Log.Warningf(uiUtils.Red, fmt.Sprintf("Invalid value %v for key %s, expected %s", flagValue, flagKey, flagValueKind)) + Log.Warningf(uiUtils.Red, fmt.Sprintf("Invalid value %v for flag name %s, expected %s", flagValue, flagKey, flagValueKind)) return } diff --git a/cli/mizu/configStruct.go b/cli/mizu/configStruct.go index da426caa0..6b45fc579 100644 --- a/cli/mizu/configStruct.go +++ b/cli/mizu/configStruct.go @@ -6,6 +6,13 @@ import ( "github.com/up9inc/mizu/cli/mizu/configStructs" ) +const ( + AgentImageConfigName = "agent-image" + MizuResourcesNamespaceConfigName = "mizu-resources-namespace" + TelemetryConfigName = "telemetry" + DumpLogsConfigName = "dump-logs" +) + type ConfigStruct struct { Tap configStructs.TapConfig `yaml:"tap"` Fetch configStructs.FetchConfig `yaml:"fetch"` diff --git a/cli/mizu/configStructs/tapConfig.go b/cli/mizu/configStructs/tapConfig.go index 2ac9352cd..1f8923667 100644 --- a/cli/mizu/configStructs/tapConfig.go +++ b/cli/mizu/configStructs/tapConfig.go @@ -10,6 +10,8 @@ import ( ) const ( + AnalysisDestinationTapName = "dest" + SleepIntervalSecTapName = "upload-interval" GuiPortTapName = "gui-port" NamespacesTapName = "namespaces" AnalysisTapName = "analysis" diff --git a/cli/mizu/sliceUtils.go b/cli/mizu/sliceUtils.go new file mode 100644 index 000000000..551e12603 --- /dev/null +++ b/cli/mizu/sliceUtils.go @@ -0,0 +1,11 @@ +package mizu + +func Contains(slice []string, containsValue string) bool { + for _, sliceValue := range slice { + if sliceValue == containsValue { + return true + } + } + + return false +} From 0244f12167225c7ecc43ab2ecf3ca73723cf2d49 Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Thu, 5 Aug 2021 19:29:06 +0300 Subject: [PATCH 60/69] Fixes (#171) --- agent/go.mod | 1 + agent/pkg/api/main.go | 4 +- agent/pkg/resolver/loader.go | 5 +- agent/pkg/resolver/resolver.go | 106 ++++++++++++++++----------------- cli/cmd/logs.go | 4 +- cli/cmd/root.go | 5 ++ cli/cmd/tapRunner.go | 20 +++++-- cli/fsUtils/dirUtils.go | 26 ++++++++ cli/fsUtils/mizuLogsUtils.go | 58 ++++++++++++++++++ cli/fsUtils/zipUtils.go | 55 +++++++++++++++++ cli/kubernetes/provider.go | 2 +- cli/logsUtils/mizuLogsUtils.go | 106 --------------------------------- cli/mizu.go | 2 - cli/mizu/config.go | 16 ++--- cli/mizu/logger.go | 3 +- shared/debounce/debounce.go | 24 ++++++-- 16 files changed, 245 insertions(+), 192 deletions(-) create mode 100644 cli/fsUtils/dirUtils.go create mode 100644 cli/fsUtils/mizuLogsUtils.go create mode 100644 cli/fsUtils/zipUtils.go delete mode 100644 cli/logsUtils/mizuLogsUtils.go diff --git a/agent/go.mod b/agent/go.mod index 290e85d76..9638a6e30 100644 --- a/agent/go.mod +++ b/agent/go.mod @@ -13,6 +13,7 @@ require ( github.com/go-playground/validator/v10 v10.5.0 github.com/google/martian v2.1.0+incompatible github.com/gorilla/websocket v1.4.2 + github.com/orcaman/concurrent-map v0.0.0-20210106121528-16402b402231 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/romana/rlog v0.0.0-20171115192701-f018bc92e7d7 github.com/up9inc/mizu/shared v0.0.0 diff --git a/agent/pkg/api/main.go b/agent/pkg/api/main.go index 5c41251fa..942f09569 100644 --- a/agent/pkg/api/main.go +++ b/agent/pkg/api/main.go @@ -28,13 +28,13 @@ var k8sResolver *resolver.Resolver func StartResolving(namespace string) { errOut := make(chan error, 100) - res, err := resolver.NewFromInCluster(errOut) + res, err := resolver.NewFromInCluster(errOut, namespace) if err != nil { rlog.Infof("error creating k8s resolver %s", err) return } ctx := context.Background() - res.Start(ctx, namespace) + res.Start(ctx) go func() { for { select { diff --git a/agent/pkg/resolver/loader.go b/agent/pkg/resolver/loader.go index 26de1dcc8..d3b1d353d 100644 --- a/agent/pkg/resolver/loader.go +++ b/agent/pkg/resolver/loader.go @@ -1,6 +1,7 @@ package resolver import ( + cmap "github.com/orcaman/concurrent-map" "k8s.io/client-go/kubernetes" _ "k8s.io/client-go/plugin/pkg/client/auth/azure" _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" @@ -9,7 +10,7 @@ import ( restclient "k8s.io/client-go/rest" ) -func NewFromInCluster(errOut chan error) (*Resolver, error) { +func NewFromInCluster(errOut chan error, namesapce string) (*Resolver, error) { config, err := restclient.InClusterConfig() if err != nil { return nil, err @@ -18,5 +19,5 @@ func NewFromInCluster(errOut chan error) (*Resolver, error) { if err != nil { return nil, err } - return &Resolver{clientConfig: config, clientSet: clientset, nameMap: make(map[string]string), serviceMap: make(map[string]string), errOut: errOut}, nil + return &Resolver{clientConfig: config, clientSet: clientset, nameMap: cmap.New(), serviceMap: cmap.New(), errOut: errOut, namespace: namesapce}, nil } diff --git a/agent/pkg/resolver/resolver.go b/agent/pkg/resolver/resolver.go index 6b8bd6e9f..d68896acb 100644 --- a/agent/pkg/resolver/resolver.go +++ b/agent/pkg/resolver/resolver.go @@ -7,12 +7,14 @@ import ( "github.com/romana/rlog" k8serrors "k8s.io/apimachinery/pkg/api/errors" + "github.com/orcaman/concurrent-map" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/kubernetes" restclient "k8s.io/client-go/rest" ) + const ( kubClientNullString = "None" ) @@ -20,17 +22,16 @@ const ( type Resolver struct { clientConfig *restclient.Config clientSet *kubernetes.Clientset - nameMap map[string]string - serviceMap map[string]string + nameMap cmap.ConcurrentMap + serviceMap cmap.ConcurrentMap isStarted bool errOut chan error namespace string } -func (resolver *Resolver) Start(ctx context.Context, namespace string) { +func (resolver *Resolver) Start(ctx context.Context) { if !resolver.isStarted { resolver.isStarted = true - resolver.namespace = namespace go resolver.infiniteErrorHandleRetryFunc(ctx, resolver.watchServices) go resolver.infiniteErrorHandleRetryFunc(ctx, resolver.watchEndpoints) @@ -39,19 +40,19 @@ func (resolver *Resolver) Start(ctx context.Context, namespace string) { } func (resolver *Resolver) Resolve(name string) string { - resolvedName, isFound := resolver.nameMap[name] + resolvedName, isFound := resolver.nameMap.Get(name) if !isFound { return "" } - return resolvedName + return resolvedName.(string) } -func (resolver *Resolver) GetMap() map[string]string { +func (resolver *Resolver) GetMap() cmap.ConcurrentMap { return resolver.nameMap } func (resolver *Resolver) CheckIsServiceIP(address string) bool { - _, isFound := resolver.serviceMap[address] + _, isFound := resolver.serviceMap.Get(address) return isFound } @@ -63,17 +64,17 @@ func (resolver *Resolver) watchPods(ctx context.Context) error { } for { select { - case event := <- watcher.ResultChan(): - if event.Object == nil { - return errors.New("error in kubectl pod watch") - } - if event.Type == watch.Deleted { - pod := event.Object.(*corev1.Pod) - resolver.saveResolvedName(pod.Status.PodIP, "", event.Type) - } - case <- ctx.Done(): - watcher.Stop() - return nil + case event := <-watcher.ResultChan(): + if event.Object == nil { + return errors.New("error in kubectl pod watch") + } + if event.Type == watch.Deleted { + pod := event.Object.(*corev1.Pod) + resolver.saveResolvedName(pod.Status.PodIP, "", event.Type) + } + case <-ctx.Done(): + watcher.Stop() + return nil } } } @@ -86,37 +87,37 @@ func (resolver *Resolver) watchEndpoints(ctx context.Context) error { } for { select { - case event := <- watcher.ResultChan(): - if event.Object == nil { - return errors.New("error in kubectl endpoint watch") - } - endpoint := event.Object.(*corev1.Endpoints) - serviceHostname := fmt.Sprintf("%s.%s", endpoint.Name, endpoint.Namespace) - if endpoint.Subsets != nil { - for _, subset := range endpoint.Subsets { - var ports []int32 - if subset.Ports != nil { - for _, portMapping := range subset.Ports { - if portMapping.Port > 0 { - ports = append(ports, portMapping.Port) - } + case event := <-watcher.ResultChan(): + if event.Object == nil { + return errors.New("error in kubectl endpoint watch") + } + endpoint := event.Object.(*corev1.Endpoints) + serviceHostname := fmt.Sprintf("%s.%s", endpoint.Name, endpoint.Namespace) + if endpoint.Subsets != nil { + for _, subset := range endpoint.Subsets { + var ports []int32 + if subset.Ports != nil { + for _, portMapping := range subset.Ports { + if portMapping.Port > 0 { + ports = append(ports, portMapping.Port) } } - if subset.Addresses != nil { - for _, address := range subset.Addresses { - resolver.saveResolvedName(address.IP, serviceHostname, event.Type) - for _, port := range ports { - ipWithPort := fmt.Sprintf("%s:%d", address.IP, port) - resolver.saveResolvedName(ipWithPort, serviceHostname, event.Type) - } - } - } - } + if subset.Addresses != nil { + for _, address := range subset.Addresses { + resolver.saveResolvedName(address.IP, serviceHostname, event.Type) + for _, port := range ports { + ipWithPort := fmt.Sprintf("%s:%d", address.IP, port) + resolver.saveResolvedName(ipWithPort, serviceHostname, event.Type) + } + } + } + } - case <- ctx.Done(): - watcher.Stop() - return nil + } + case <-ctx.Done(): + watcher.Stop() + return nil } } } @@ -129,7 +130,7 @@ func (resolver *Resolver) watchServices(ctx context.Context) error { } for { select { - case event := <- watcher.ResultChan(): + case event := <-watcher.ResultChan(): if event.Object == nil { return errors.New("error in kubectl service watch") } @@ -145,7 +146,7 @@ func (resolver *Resolver) watchServices(ctx context.Context) error { resolver.saveResolvedName(ingress.IP, serviceHostname, event.Type) } } - case <- ctx.Done(): + case <-ctx.Done(): watcher.Stop() return nil } @@ -154,19 +155,19 @@ func (resolver *Resolver) watchServices(ctx context.Context) error { func (resolver *Resolver) saveResolvedName(key string, resolved string, eventType watch.EventType) { if eventType == watch.Deleted { - delete(resolver.nameMap, key) + resolver.nameMap.Remove(key) rlog.Infof("setting %s=nil\n", key) } else { - resolver.nameMap[key] = resolved + resolver.nameMap.Set(key, resolved) rlog.Infof("setting %s=%s\n", key, resolved) } } func (resolver *Resolver) saveServiceIP(key string, resolved string, eventType watch.EventType) { if eventType == watch.Deleted { - delete(resolver.serviceMap, key) + resolver.serviceMap.Remove(key) } else { - resolver.serviceMap[key] = resolved + resolver.serviceMap.Set(key, resolved) } } @@ -189,4 +190,3 @@ func (resolver *Resolver) infiniteErrorHandleRetryFunc(ctx context.Context, fun } } } - diff --git a/cli/cmd/logs.go b/cli/cmd/logs.go index 4997f4e10..ec639fc7e 100644 --- a/cli/cmd/logs.go +++ b/cli/cmd/logs.go @@ -3,8 +3,8 @@ package cmd import ( "context" "github.com/spf13/cobra" + "github.com/up9inc/mizu/cli/fsUtils" "github.com/up9inc/mizu/cli/kubernetes" - "github.com/up9inc/mizu/cli/logsUtils" "github.com/up9inc/mizu/cli/mizu" "os" "path" @@ -32,7 +32,7 @@ var logsCmd = &cobra.Command{ } mizu.Log.Debugf("Using file path %s", filePath) - if err := logsUtils.DumpLogs(kubernetesProvider, ctx, filePath); err != nil { + if err := fsUtils.DumpLogs(kubernetesProvider, ctx, filePath); err != nil { mizu.Log.Errorf("Failed dump logs %v", err) } diff --git a/cli/cmd/root.go b/cli/cmd/root.go index 434248263..6773a9781 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "github.com/spf13/cobra" + "github.com/up9inc/mizu/cli/fsUtils" "github.com/up9inc/mizu/cli/mizu" ) @@ -13,6 +14,10 @@ var rootCmd = &cobra.Command{ Long: `A web traffic viewer for kubernetes Further info is available at https://github.com/up9inc/mizu`, PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + if err := fsUtils.EnsureDir(mizu.GetMizuFolderPath()); err != nil { + mizu.Log.Errorf("Failed to use mizu folder, %v", err) + } + mizu.InitLogger() if err := mizu.InitConfig(cmd); err != nil { mizu.Log.Errorf("Invalid config, Exit %s", err) return errors.New(fmt.Sprintf("%v", err)) diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index a886144de..3bb0ca7fa 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -5,6 +5,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/up9inc/mizu/cli/fsUtils" "net/http" "net/url" "os" @@ -17,7 +18,6 @@ import ( "github.com/up9inc/mizu/cli/errormessage" "github.com/up9inc/mizu/cli/kubernetes" - "github.com/up9inc/mizu/cli/logsUtils" "github.com/up9inc/mizu/cli/mizu" "github.com/up9inc/mizu/cli/uiUtils" "github.com/up9inc/mizu/shared" @@ -62,7 +62,6 @@ func RunMizuTap() { return } - defer cleanUpMizuResources(kubernetesProvider) ctx, cancel := context.WithCancel(context.Background()) defer cancel() // cancel will be called when this function exits @@ -96,6 +95,7 @@ func RunMizuTap() { nodeToTappedPodIPMap := getNodeHostToTappedPodIpsMap(state.currentlyTappedPods) + defer cleanUpMizuResources(kubernetesProvider) if err := createMizuResources(ctx, kubernetesProvider, nodeToTappedPodIPMap, mizuApiFilteringOptions, mizuValidationRules); err != nil { mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error creating resources: %v", errormessage.FormatError(err))) return @@ -248,7 +248,7 @@ func cleanUpMizuResources(kubernetesProvider *kubernetes.Provider) { if mizu.Config.DumpLogs { mizuDir := mizu.GetMizuFolderPath() filePath = path.Join(mizuDir, fmt.Sprintf("mizu_logs_%s.zip", time.Now().Format("2006_01_02__15_04_05"))) - if err := logsUtils.DumpLogs(kubernetesProvider, removalCtx, filePath); err != nil { + if err := fsUtils.DumpLogs(kubernetesProvider, removalCtx, filePath); err != nil { mizu.Log.Errorf("Failed dump logs %v", err) } } @@ -355,7 +355,7 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro restartTappers := func() { err, changeFound := updateCurrentlyTappedPods(kubernetesProvider, ctx, targetNamespaces) if err != nil { - mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error getting pods by regex: %v", errormessage.FormatError(err))) + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Failed to update currently tapped pods: %v", err)) cancel() } @@ -398,11 +398,15 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro restartTappersDebouncer.SetOn() } - case <-errorChan: + case err := <-errorChan: + mizu.Log.Debugf("Watching pods loop, got error %v, stopping restart tappers debouncer", err) + restartTappersDebouncer.Cancel() // TODO: Does this also perform cleanup? cancel() case <-ctx.Done(): + mizu.Log.Debugf("Watching pods loop, context done, stopping restart tappers debouncer") + restartTappersDebouncer.Cancel() return } } @@ -470,6 +474,10 @@ func createProxyToApiServerPod(ctx context.Context, kubernetesProvider *kubernet cancel() return case modifiedPod := <-modified: + if modifiedPod == nil { + mizu.Log.Debugf("Got agent pod modified event, status phase: %v", modifiedPod.Status.Phase) + continue + } mizu.Log.Debugf("Got agent pod modified event, status phase: %v", modifiedPod.Status.Phase) if modifiedPod.Status.Phase == core.PodRunning && !isPodReady { isPodReady = true @@ -489,7 +497,7 @@ func createProxyToApiServerPod(ctx context.Context, kubernetesProvider *kubernet } case <-timeAfter: if !isPodReady { - mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("%s pod was not ready in time", mizu.ApiServerPodName)) + mizu.Log.Errorf(uiUtils.Error, "Mizu API server was not ready in time") cancel() } case <-errorChan: diff --git a/cli/fsUtils/dirUtils.go b/cli/fsUtils/dirUtils.go new file mode 100644 index 000000000..716e1472c --- /dev/null +++ b/cli/fsUtils/dirUtils.go @@ -0,0 +1,26 @@ +package fsUtils + +import ( + "errors" + "fmt" + "os" +) + +func EnsureDir(dirName string) error { + err := os.Mkdir(dirName, 0700) + if err == nil { + return nil + } + if os.IsExist(err) { + // check that the existing path is a directory + info, err := os.Stat(dirName) + if err != nil { + return err + } + if !info.IsDir() { + return errors.New(fmt.Sprintf("path exists but is not a directory: %s", dirName)) + } + return nil + } + return err +} diff --git a/cli/fsUtils/mizuLogsUtils.go b/cli/fsUtils/mizuLogsUtils.go new file mode 100644 index 000000000..a65058711 --- /dev/null +++ b/cli/fsUtils/mizuLogsUtils.go @@ -0,0 +1,58 @@ +package fsUtils + +import ( + "archive/zip" + "context" + "fmt" + "github.com/up9inc/mizu/cli/kubernetes" + "github.com/up9inc/mizu/cli/mizu" + "os" + "regexp" +) + +func DumpLogs(provider *kubernetes.Provider, ctx context.Context, filePath string) error { + podExactRegex := regexp.MustCompile(fmt.Sprintf("^mizu-")) + pods, err := provider.ListAllPodsMatchingRegex(ctx, podExactRegex, []string{mizu.Config.MizuResourcesNamespace}) + if err != nil { + return err + } + + if len(pods) == 0 { + return fmt.Errorf("no pods found in namespace %s", mizu.Config.MizuResourcesNamespace) + } + + newZipFile, err := os.Create(filePath) + if err != nil { + return err + } + defer newZipFile.Close() + zipWriter := zip.NewWriter(newZipFile) + defer zipWriter.Close() + + for _, pod := range pods { + logs, err := provider.GetPodLogs(pod.Namespace, pod.Name, ctx) + if err != nil { + mizu.Log.Errorf("Failed to get logs, %v", err) + continue + } else { + mizu.Log.Debugf("Successfully read log length %d for pod: %s.%s", len(logs), pod.Namespace, pod.Name) + } + if err := AddStrToZip(zipWriter, logs, fmt.Sprintf("%s.%s.log", pod.Namespace, pod.Name)); err != nil { + mizu.Log.Errorf("Failed write logs, %v", err) + } else { + mizu.Log.Infof("Successfully added log length %d from pod: %s.%s", len(logs), pod.Namespace, pod.Name) + } + } + if err := AddFileToZip(zipWriter, mizu.GetConfigFilePath()); err != nil { + mizu.Log.Debugf("Failed write file, %v", err) + } else { + mizu.Log.Infof("Successfully added file %s", mizu.GetConfigFilePath()) + } + if err := AddFileToZip(zipWriter, mizu.GetLogFilePath()); err != nil { + mizu.Log.Errorf("Failed write file, %v", err) + } else { + mizu.Log.Infof("Successfully added file %s", mizu.GetLogFilePath()) + } + mizu.Log.Infof("You can find the zip with all logs in %s\n", filePath) + return nil +} diff --git a/cli/fsUtils/zipUtils.go b/cli/fsUtils/zipUtils.go new file mode 100644 index 000000000..be64e644c --- /dev/null +++ b/cli/fsUtils/zipUtils.go @@ -0,0 +1,55 @@ +package fsUtils + +import ( + "archive/zip" + "fmt" + "io" + "os" + "path/filepath" +) + +func AddFileToZip(zipWriter *zip.Writer, filename string) error { + + fileToZip, err := os.Open(filename) + if err != nil { + return fmt.Errorf("failed to open file %s, %w", filename, err) + } + defer fileToZip.Close() + + // Get the file information + info, err := fileToZip.Stat() + if err != nil { + return fmt.Errorf("failed to get file information %s, %w", filename, err) + } + + header, err := zip.FileInfoHeader(info) + if err != nil { + return err + } + + // Using FileInfoHeader() above only uses the basename of the file. If we want + // to preserve the folder structure we can overwrite this with the full path. + header.Name = filepath.Base(filename) + + // Change to deflate to gain better compression + // see http://golang.org/pkg/archive/zip/#pkg-constants + header.Method = zip.Deflate + + writer, err := zipWriter.CreateHeader(header) + if err != nil { + return fmt.Errorf("failed to create header in zip for %s, %w", filename, err) + } + _, err = io.Copy(writer, fileToZip) + return err +} + +func AddStrToZip(writer *zip.Writer, logs string, fileName string) error { + if zipFile, err := writer.Create(fileName); err != nil { + return fmt.Errorf("couldn't create a log file inside zip for %s, %w", fileName, err) + } else { + if _, err = zipFile.Write([]byte(logs)); err != nil { + return fmt.Errorf("couldn't write logs to zip file: %s, %w", fileName, err) + } + } + return nil +} diff --git a/cli/kubernetes/provider.go b/cli/kubernetes/provider.go index d6c92754f..24f3e064a 100644 --- a/cli/kubernetes/provider.go +++ b/cli/kubernetes/provider.go @@ -683,7 +683,7 @@ func (provider *Provider) ListAllPodsMatchingRegex(ctx context.Context, regex *r for _, namespace := range namespaces { namespacePods, err := provider.clientSet.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{}) if err != nil { - return nil, fmt.Errorf("failed to get pods in ns: %s, %w", namespace, err) + return nil, fmt.Errorf("failed to get pods in ns: [%s], %w", namespace, err) } pods = append(pods, namespacePods.Items...) diff --git a/cli/logsUtils/mizuLogsUtils.go b/cli/logsUtils/mizuLogsUtils.go deleted file mode 100644 index aed8d9c9a..000000000 --- a/cli/logsUtils/mizuLogsUtils.go +++ /dev/null @@ -1,106 +0,0 @@ -package logsUtils - -import ( - "archive/zip" - "context" - "fmt" - "github.com/up9inc/mizu/cli/kubernetes" - "github.com/up9inc/mizu/cli/mizu" - "io" - "os" - "path/filepath" - "regexp" -) - -func DumpLogs(provider *kubernetes.Provider, ctx context.Context, filePath string) error { - podExactRegex := regexp.MustCompile(fmt.Sprintf("^mizu-")) - pods, err := provider.ListAllPodsMatchingRegex(ctx, podExactRegex, []string{mizu.Config.MizuResourcesNamespace}) - if err != nil { - return err - } - - if len(pods) == 0 { - return fmt.Errorf("no pods found in namespace %s", mizu.Config.MizuResourcesNamespace) - } - - newZipFile, err := os.Create(filePath) - if err != nil { - return err - } - defer newZipFile.Close() - zipWriter := zip.NewWriter(newZipFile) - defer zipWriter.Close() - - for _, pod := range pods { - logs, err := provider.GetPodLogs(pod.Namespace, pod.Name, ctx) - if err != nil { - mizu.Log.Errorf("Failed to get logs, %v", err) - continue - } else { - mizu.Log.Debugf("Successfully read log length %d for pod: %s.%s", len(logs), pod.Namespace, pod.Name) - } - if err := addLogsToZip(zipWriter, logs, fmt.Sprintf("%s.%s.log", pod.Namespace, pod.Name)); err != nil { - mizu.Log.Errorf("Failed write logs, %v", err) - } else { - mizu.Log.Infof("Successfully added log length %d from pod: %s.%s", len(logs), pod.Namespace, pod.Name) - } - } - if err := addFileToZip(zipWriter, mizu.GetConfigFilePath()); err != nil { - mizu.Log.Errorf("Failed write file, %v", err) - } else { - mizu.Log.Infof("Successfully added file %s", mizu.GetConfigFilePath()) - } - if err := addFileToZip(zipWriter, mizu.GetLogFilePath()); err != nil { - mizu.Log.Errorf("Failed write file, %v", err) - } else { - mizu.Log.Infof("Successfully added file %s", mizu.GetLogFilePath()) - } - mizu.Log.Infof("You can find the zip with all logs in %s\n", filePath) - return nil -} - -func addFileToZip(zipWriter *zip.Writer, filename string) error { - - fileToZip, err := os.Open(filename) - if err != nil { - return fmt.Errorf("failed to open file %s, %w", filename, err) - } - defer fileToZip.Close() - - // Get the file information - info, err := fileToZip.Stat() - if err != nil { - return fmt.Errorf("failed to get file information %s, %w", filename, err) - } - - header, err := zip.FileInfoHeader(info) - if err != nil { - return err - } - - // Using FileInfoHeader() above only uses the basename of the file. If we want - // to preserve the folder structure we can overwrite this with the full path. - header.Name = filepath.Base(filename) - - // Change to deflate to gain better compression - // see http://golang.org/pkg/archive/zip/#pkg-constants - header.Method = zip.Deflate - - writer, err := zipWriter.CreateHeader(header) - if err != nil { - return fmt.Errorf("failed to create header in zip for %s, %w", filename, err) - } - _, err = io.Copy(writer, fileToZip) - return err -} - -func addLogsToZip(writer *zip.Writer, logs string, fileName string) error { - if zipFile, err := writer.Create(fileName); err != nil { - return fmt.Errorf("couldn't create a log file inside zip for %s, %w", fileName, err) - } else { - if _, err = zipFile.Write([]byte(logs)); err != nil { - return fmt.Errorf("couldn't write logs to zip file: %s, %w", fileName, err) - } - } - return nil -} diff --git a/cli/mizu.go b/cli/mizu.go index d3ff3c55b..e635ad429 100644 --- a/cli/mizu.go +++ b/cli/mizu.go @@ -2,10 +2,8 @@ package main import ( "github.com/up9inc/mizu/cli/cmd" - "github.com/up9inc/mizu/cli/mizu" ) func main() { - mizu.InitLogger() cmd.Execute() } diff --git a/cli/mizu/config.go b/cli/mizu/config.go index 52335f85d..e463352e0 100644 --- a/cli/mizu/config.go +++ b/cli/mizu/config.go @@ -37,7 +37,7 @@ var Config = ConfigStruct{} func (config *ConfigStruct) Validate() error { if config.IsNsRestrictedMode() { if config.Tap.AllNamespaces || len(config.Tap.Namespaces) != 1 || config.Tap.Namespaces[0] != config.MizuResourcesNamespace { - return fmt.Errorf("Not supported mode. Mizu can't resolve IPs in other namespaces when running in namespace restricted mode.\n" + + return fmt.Errorf("Not supported mode. Mizu can't resolve IPs in other namespaces when running in namespace restricted mode.\n"+ "You can use the same namespace for --%s and --%s", configStructs.NamespacesTapName, MizuResourcesNamespaceConfigName) } } @@ -104,38 +104,34 @@ func initFlag(f *pflag.Flag) { } if f.Name == SetCommandName { - if setError := mergeSetFlag(sliceValue.GetSlice()); setError != nil { - Log.Warningf(uiUtils.Red, fmt.Sprintf("%v", setError)) - } + mergeSetFlag(sliceValue.GetSlice()) return } mergeFlagValues(configElem, f.Name, sliceValue.GetSlice()) } -func mergeSetFlag(setValues []string) error { +func mergeSetFlag(setValues []string) { configElem := reflect.ValueOf(&Config).Elem() for _, setValue := range setValues { if !strings.Contains(setValue, Separator) { - return errors.New(fmt.Sprintf("invalid set argument %s", setValue)) + Log.Warningf(uiUtils.Warning, fmt.Sprintf("Ignoring set argument %s (set argument format: =)", setValue)) } split := strings.SplitN(setValue, Separator, 2) if len(split) != 2 { - return errors.New(fmt.Sprintf("invalid set argument %s", setValue)) + Log.Warningf(uiUtils.Warning, fmt.Sprintf("Ignoring set argument %s (set argument format: =)", setValue)) } argumentKey, argumentValue := split[0], split[1] if !Contains(allowedSetFlags, argumentKey) { - return errors.New(fmt.Sprintf("invalid set flag name %s, allowed set flag names: \"%s\"", argumentKey, strings.Join(allowedSetFlags, "\", \""))) + Log.Warningf(uiUtils.Warning, fmt.Sprintf("Ignoring set argument %s, flag name must be one of the following: \"%s\"", setValue, strings.Join(allowedSetFlags, "\", \""))) } mergeFlagValue(configElem, argumentKey, argumentValue) } - - return nil } func mergeFlagValue(currentElem reflect.Value, flagKey string, flagValue string) { diff --git a/cli/mizu/logger.go b/cli/mizu/logger.go index 9307c110a..251922263 100644 --- a/cli/mizu/logger.go +++ b/cli/mizu/logger.go @@ -1,7 +1,6 @@ package mizu import ( - "fmt" "github.com/op/go-logging" "os" "path" @@ -21,7 +20,7 @@ func InitLogger() { logPath := GetLogFilePath() f, err := os.OpenFile(logPath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) if err != nil { - panic(fmt.Sprintf("Failed mizu log file: %v, err %v", logPath, err)) + Log.Infof("Failed to open mizu log file: %v, err %v", logPath, err) } fileLog := logging.NewLogBackend(f, "", 0) diff --git a/shared/debounce/debounce.go b/shared/debounce/debounce.go index 7772591ef..74e15e2c6 100644 --- a/shared/debounce/debounce.go +++ b/shared/debounce/debounce.go @@ -1,6 +1,7 @@ package debounce import ( + "fmt" "time" ) @@ -13,9 +14,10 @@ func NewDebouncer(timeout time.Duration, callback func()) *Debouncer { type Debouncer struct { callback func() - running bool - timeout time.Duration - timer *time.Timer + running bool + canceled bool + timeout time.Duration + timer *time.Timer } func (d *Debouncer) setTimeout(timeout time.Duration) { @@ -25,18 +27,28 @@ func (d *Debouncer) setTimeout(timeout time.Duration) { func (d *Debouncer) setCallback(callback func()) { callbackWrapped := func() { - callback() + if !d.canceled { + callback() + } d.running = false } d.callback = callbackWrapped } -func (d *Debouncer) SetOn() { +func (d *Debouncer) Cancel() { + d.canceled = true +} + +func (d *Debouncer) SetOn() error { + if d.canceled { + return fmt.Errorf("debouncer cancelled") + } if d.running == true { - return + return nil } d.running = true d.timer = time.AfterFunc(d.timeout, d.callback) + return nil } From 824945141aaae8d9a20302482db23bfb4dd7b11b Mon Sep 17 00:00:00 2001 From: RoyUP9 <87927115+RoyUP9@users.noreply.github.com> Date: Thu, 5 Aug 2021 21:45:18 +0300 Subject: [PATCH 61/69] fixed config parsing of int and uint (#172) --- cli/mizu/config.go | 60 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/cli/mizu/config.go b/cli/mizu/config.go index e463352e0..a4dd222ca 100644 --- a/cli/mizu/config.go +++ b/cli/mizu/config.go @@ -202,14 +202,70 @@ func getParsedValue(kind reflect.Kind, value string) (reflect.Value, error) { } return reflect.ValueOf(boolArgumentValue), nil - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + case reflect.Int: + intArgumentValue, err := strconv.ParseInt(value, 10, 64) + if err != nil { + break + } + + return reflect.ValueOf(int(intArgumentValue)), nil + case reflect.Int8: + intArgumentValue, err := strconv.ParseInt(value, 10, 8) + if err != nil { + break + } + + return reflect.ValueOf(int8(intArgumentValue)), nil + case reflect.Int16: + intArgumentValue, err := strconv.ParseInt(value, 10, 16) + if err != nil { + break + } + + return reflect.ValueOf(int16(intArgumentValue)), nil + case reflect.Int32: + intArgumentValue, err := strconv.ParseInt(value, 10, 32) + if err != nil { + break + } + + return reflect.ValueOf(int32(intArgumentValue)), nil + case reflect.Int64: intArgumentValue, err := strconv.ParseInt(value, 10, 64) if err != nil { break } return reflect.ValueOf(intArgumentValue), nil - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + case reflect.Uint: + uintArgumentValue, err := strconv.ParseUint(value, 10, 64) + if err != nil { + break + } + + return reflect.ValueOf(uint(uintArgumentValue)), nil + case reflect.Uint8: + uintArgumentValue, err := strconv.ParseUint(value, 10, 8) + if err != nil { + break + } + + return reflect.ValueOf(uint8(uintArgumentValue)), nil + case reflect.Uint16: + uintArgumentValue, err := strconv.ParseUint(value, 10, 16) + if err != nil { + break + } + + return reflect.ValueOf(uint16(uintArgumentValue)), nil + case reflect.Uint32: + uintArgumentValue, err := strconv.ParseUint(value, 10, 32) + if err != nil { + break + } + + return reflect.ValueOf(uint32(uintArgumentValue)), nil + case reflect.Uint64: uintArgumentValue, err := strconv.ParseUint(value, 10, 64) if err != nil { break From 7f2021c312ddc5249ba2f02dc7c6332acb12bb21 Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Sun, 8 Aug 2021 10:32:21 +0300 Subject: [PATCH 62/69] Several fixes for the release (#175) --- cli/cmd/root.go | 4 +-- cli/cmd/tap.go | 1 - cli/cmd/tapRunner.go | 46 ++++++++++++++--------------- cli/cmd/viewRunner.go | 2 +- cli/fsUtils/mizuLogsUtils.go | 4 +-- cli/goUtils/funcWrappers.go | 25 ++++++++++++++++ cli/kubernetes/provider.go | 21 +++++++------ cli/mizu.go | 3 +- cli/mizu/config.go | 5 ++-- cli/mizu/configStruct.go | 2 ++ cli/mizu/configStructs/tapConfig.go | 2 -- 11 files changed, 68 insertions(+), 47 deletions(-) create mode 100644 cli/goUtils/funcWrappers.go diff --git a/cli/cmd/root.go b/cli/cmd/root.go index 6773a9781..84f6dde3b 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -1,7 +1,6 @@ package cmd import ( - "errors" "fmt" "github.com/spf13/cobra" "github.com/up9inc/mizu/cli/fsUtils" @@ -19,8 +18,7 @@ Further info is available at https://github.com/up9inc/mizu`, } mizu.InitLogger() if err := mizu.InitConfig(cmd); err != nil { - mizu.Log.Errorf("Invalid config, Exit %s", err) - return errors.New(fmt.Sprintf("%v", err)) + mizu.Log.Fatal(err) } return nil diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go index 3f4e56370..17dc116d1 100644 --- a/cli/cmd/tap.go +++ b/cli/cmd/tap.go @@ -63,7 +63,6 @@ func init() { tapCmd.Flags().StringArrayP(configStructs.NamespacesTapName, "n", defaultTapConfig.Namespaces, "Namespaces selector") tapCmd.Flags().Bool(configStructs.AnalysisTapName, defaultTapConfig.Analysis, "Uploads traffic to UP9 for further analysis (Beta)") tapCmd.Flags().BoolP(configStructs.AllNamespacesTapName, "A", defaultTapConfig.AllNamespaces, "Tap all namespaces") - tapCmd.Flags().StringP(configStructs.KubeConfigPathTapName, "k", defaultTapConfig.KubeConfigPath, "Path to kube-config file") tapCmd.Flags().StringArrayP(configStructs.PlainTextFilterRegexesTapName, "r", defaultTapConfig.PlainTextFilterRegexes, "List of regex expressions that are used to filter matching values from text/plain http bodies") tapCmd.Flags().Bool(configStructs.HideHealthChecksTapName, defaultTapConfig.HideHealthChecks, "hides requests with kube-probe or prometheus user-agent headers") tapCmd.Flags().Bool(configStructs.DisableRedactionTapName, defaultTapConfig.DisableRedaction, "Disables redaction of potentially sensitive request/response headers and body values") diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index 3bb0ca7fa..030740fce 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -6,6 +6,8 @@ import ( "encoding/json" "fmt" "github.com/up9inc/mizu/cli/fsUtils" + "github.com/up9inc/mizu/cli/goUtils" + "github.com/up9inc/mizu/cli/mizu/configStructs" "net/http" "net/url" "os" @@ -56,7 +58,7 @@ func RunMizuTap() { } } - kubernetesProvider, err := kubernetes.NewProvider(mizu.Config.Tap.KubeConfigPath) + kubernetesProvider, err := kubernetes.NewProvider(mizu.Config.KubeConfigPath) if err != nil { mizu.Log.Error(err) return @@ -101,8 +103,8 @@ func RunMizuTap() { return } - go createProxyToApiServerPod(ctx, kubernetesProvider, cancel) - go watchPodsForTapping(ctx, kubernetesProvider, targetNamespaces, cancel) + go goUtils.HandleExcWrapper(createProxyToApiServerPod, ctx, kubernetesProvider, cancel) + go goUtils.HandleExcWrapper(watchPodsForTapping, ctx, kubernetesProvider, targetNamespaces, cancel) //block until exit signal or error waitForFinish(ctx, cancel) @@ -399,13 +401,13 @@ func watchPodsForTapping(ctx context.Context, kubernetesProvider *kubernetes.Pro } case err := <-errorChan: - mizu.Log.Debugf("Watching pods loop, got error %v, stopping restart tappers debouncer", err) + mizu.Log.Debugf("Watching pods loop, got error %v, stopping `restart tappers debouncer`", err) restartTappersDebouncer.Cancel() // TODO: Does this also perform cleanup? cancel() case <-ctx.Done(): - mizu.Log.Debugf("Watching pods loop, context done, stopping restart tappers debouncer") + mizu.Log.Debugf("Watching pods loop, context done, stopping `restart tappers debouncer`") restartTappersDebouncer.Cancel() return } @@ -465,9 +467,10 @@ func createProxyToApiServerPod(ctx context.Context, kubernetesProvider *kubernet for { select { case <-ctx.Done(): + mizu.Log.Debugf("Watching API Server pod loop, ctx done") return case <-added: - mizu.Log.Debugf("Got agent pod added event") + mizu.Log.Debugf("Watching API Server pod loop, added") continue case <-removed: mizu.Log.Infof("%s removed", mizu.ApiServerPodName) @@ -475,16 +478,17 @@ func createProxyToApiServerPod(ctx context.Context, kubernetesProvider *kubernet return case modifiedPod := <-modified: if modifiedPod == nil { - mizu.Log.Debugf("Got agent pod modified event, status phase: %v", modifiedPod.Status.Phase) + mizu.Log.Debugf("Watching API Server pod loop, modifiedPod with nil") continue } - mizu.Log.Debugf("Got agent pod modified event, status phase: %v", modifiedPod.Status.Phase) + mizu.Log.Debugf("Watching API Server pod loop, modified: %v", modifiedPod.Status.Phase) if modifiedPod.Status.Phase == core.PodRunning && !isPodReady { isPodReady = true go func() { err := kubernetes.StartProxy(kubernetesProvider, mizu.Config.Tap.GuiPort, mizu.Config.MizuResourcesNamespace, mizu.ApiServerPodName) if err != nil { - mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error occured while running k8s proxy %v", errormessage.FormatError(err))) + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error occured while running k8s proxy %v\n"+ + "Try setting different port by using --%s", errormessage.FormatError(err), configStructs.GuiPortTapName)) cancel() } }() @@ -530,21 +534,15 @@ func requestForAnalysis() { } func createRBACIfNecessary(ctx context.Context, kubernetesProvider *kubernetes.Provider) (bool, error) { - mizuRBACExists, err := kubernetesProvider.DoesServiceAccountExist(ctx, mizu.Config.MizuResourcesNamespace, mizu.ServiceAccountName) - if err != nil { - return false, err - } - if !mizuRBACExists { - if !mizu.Config.IsNsRestrictedMode() { - err := kubernetesProvider.CreateMizuRBAC(ctx, mizu.Config.MizuResourcesNamespace, mizu.ServiceAccountName, mizu.ClusterRoleName, mizu.ClusterRoleBindingName, mizu.RBACVersion) - if err != nil { - return false, err - } - } else { - err := kubernetesProvider.CreateMizuRBACNamespaceRestricted(ctx, mizu.Config.MizuResourcesNamespace, mizu.ServiceAccountName, mizu.RoleName, mizu.RoleBindingName, mizu.RBACVersion) - if err != nil { - return false, err - } + if !mizu.Config.IsNsRestrictedMode() { + err := kubernetesProvider.CreateMizuRBAC(ctx, mizu.Config.MizuResourcesNamespace, mizu.ServiceAccountName, mizu.ClusterRoleName, mizu.ClusterRoleBindingName, mizu.RBACVersion) + if err != nil { + return false, err + } + } else { + err := kubernetesProvider.CreateMizuRBACNamespaceRestricted(ctx, mizu.Config.MizuResourcesNamespace, mizu.ServiceAccountName, mizu.RoleName, mizu.RoleBindingName, mizu.RBACVersion) + if err != nil { + return false, err } } return true, nil diff --git a/cli/cmd/viewRunner.go b/cli/cmd/viewRunner.go index f2aae65a7..587c7e384 100644 --- a/cli/cmd/viewRunner.go +++ b/cli/cmd/viewRunner.go @@ -38,6 +38,6 @@ func runMizuView() { mizu.Log.Infof("Mizu is available at http://%s\n", kubernetes.GetMizuApiServerProxiedHostAndPath(mizu.Config.View.GuiPort)) err = kubernetes.StartProxy(kubernetesProvider, mizu.Config.View.GuiPort, mizu.Config.MizuResourcesNamespace, mizu.ApiServerPodName) if err != nil { - mizu.Log.Infof("Error occured while running k8s proxy %v", err) + mizu.Log.Errorf("Error occurred while running k8s proxy %v", err) } } diff --git a/cli/fsUtils/mizuLogsUtils.go b/cli/fsUtils/mizuLogsUtils.go index a65058711..701c8b25f 100644 --- a/cli/fsUtils/mizuLogsUtils.go +++ b/cli/fsUtils/mizuLogsUtils.go @@ -18,7 +18,7 @@ func DumpLogs(provider *kubernetes.Provider, ctx context.Context, filePath strin } if len(pods) == 0 { - return fmt.Errorf("no pods found in namespace %s", mizu.Config.MizuResourcesNamespace) + return fmt.Errorf("no mizu pods found in namespace %s", mizu.Config.MizuResourcesNamespace) } newZipFile, err := os.Create(filePath) @@ -49,7 +49,7 @@ func DumpLogs(provider *kubernetes.Provider, ctx context.Context, filePath strin mizu.Log.Infof("Successfully added file %s", mizu.GetConfigFilePath()) } if err := AddFileToZip(zipWriter, mizu.GetLogFilePath()); err != nil { - mizu.Log.Errorf("Failed write file, %v", err) + mizu.Log.Debugf("Failed write file, %v", err) } else { mizu.Log.Infof("Successfully added file %s", mizu.GetLogFilePath()) } diff --git a/cli/goUtils/funcWrappers.go b/cli/goUtils/funcWrappers.go new file mode 100644 index 000000000..ad71b684b --- /dev/null +++ b/cli/goUtils/funcWrappers.go @@ -0,0 +1,25 @@ +package goUtils + +import ( + "github.com/up9inc/mizu/cli/mizu" + "reflect" + "runtime/debug" +) + +func HandleExcWrapper(fn interface{}, params ...interface{}) (result []reflect.Value) { + defer func() { + if panicMessage := recover(); panicMessage != nil { + stack := debug.Stack() + mizu.Log.Fatalf("Unhandled panic: %v\n stack: %s", panicMessage, stack) + } + }() + f := reflect.ValueOf(fn) + if f.Type().NumIn() != len(params) { + panic("incorrect number of parameters!") + } + inputs := make([]reflect.Value, len(params)) + for k, in := range params { + inputs[k] = reflect.ValueOf(in) + } + return f.Call(inputs) +} diff --git a/cli/kubernetes/provider.go b/cli/kubernetes/provider.go index 24f3e064a..fcbb78502 100644 --- a/cli/kubernetes/provider.go +++ b/cli/kubernetes/provider.go @@ -13,17 +13,14 @@ import ( "strconv" "github.com/up9inc/mizu/cli/mizu" - "io" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/util/homedir" - "github.com/up9inc/mizu/shared" + "io" core "k8s.io/api/core/v1" rbac "k8s.io/api/rbac/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" resource "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/watch" applyconfapp "k8s.io/client-go/applyconfigurations/apps/v1" @@ -35,9 +32,11 @@ import ( _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" _ "k8s.io/client-go/plugin/pkg/client/auth/openstack" restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/clientcmd" _ "k8s.io/client-go/tools/portforward" watchtools "k8s.io/client-go/tools/watch" + "k8s.io/client-go/util/homedir" ) type Provider struct { @@ -358,15 +357,15 @@ func (provider *Provider) CreateMizuRBAC(ctx context.Context, namespace string, }, } _, err := provider.clientSet.CoreV1().ServiceAccounts(namespace).Create(ctx, serviceAccount, metav1.CreateOptions{}) - if err != nil { + if err != nil && !k8serrors.IsAlreadyExists(err) { return err } _, err = provider.clientSet.RbacV1().ClusterRoles().Create(ctx, clusterRole, metav1.CreateOptions{}) - if err != nil { + if err != nil && !k8serrors.IsAlreadyExists(err) { return err } _, err = provider.clientSet.RbacV1().ClusterRoleBindings().Create(ctx, clusterRoleBinding, metav1.CreateOptions{}) - if err != nil { + if err != nil && !k8serrors.IsAlreadyExists(err) { return err } return nil @@ -412,15 +411,15 @@ func (provider *Provider) CreateMizuRBACNamespaceRestricted(ctx context.Context, }, } _, err := provider.clientSet.CoreV1().ServiceAccounts(namespace).Create(ctx, serviceAccount, metav1.CreateOptions{}) - if err != nil { + if err != nil && !k8serrors.IsAlreadyExists(err) { return err } _, err = provider.clientSet.RbacV1().Roles(namespace).Create(ctx, role, metav1.CreateOptions{}) - if err != nil { + if err != nil && !k8serrors.IsAlreadyExists(err) { return err } _, err = provider.clientSet.RbacV1().RoleBindings(namespace).Create(ctx, roleBinding, metav1.CreateOptions{}) - if err != nil { + if err != nil && !k8serrors.IsAlreadyExists(err) { return err } return nil diff --git a/cli/mizu.go b/cli/mizu.go index e635ad429..6dc698567 100644 --- a/cli/mizu.go +++ b/cli/mizu.go @@ -2,8 +2,9 @@ package main import ( "github.com/up9inc/mizu/cli/cmd" + "github.com/up9inc/mizu/cli/goUtils" ) func main() { - cmd.Execute() + goUtils.HandleExcWrapper(cmd.Execute) } diff --git a/cli/mizu/config.go b/cli/mizu/config.go index a4dd222ca..2c2712af5 100644 --- a/cli/mizu/config.go +++ b/cli/mizu/config.go @@ -28,6 +28,7 @@ var allowedSetFlags = []string{ MizuResourcesNamespaceConfigName, TelemetryConfigName, DumpLogsConfigName, + KubeConfigPathName, configStructs.AnalysisDestinationTapName, configStructs.SleepIntervalSecTapName, } @@ -51,8 +52,8 @@ func InitConfig(cmd *cobra.Command) error { } if err := mergeConfigFile(); err != nil { - Log.Errorf("Could not load config file, error %v", err) - Log.Fatalf("You can regenerate the file using `mizu config -r` or just remove it %v", GetConfigFilePath()) + return fmt.Errorf("invalid config %w\n"+ + "you can regenerate the file using `mizu config -r` or just remove it %v", err, GetConfigFilePath()) } cmd.Flags().Visit(initFlag) diff --git a/cli/mizu/configStruct.go b/cli/mizu/configStruct.go index 6b45fc579..24ee0d49e 100644 --- a/cli/mizu/configStruct.go +++ b/cli/mizu/configStruct.go @@ -11,6 +11,7 @@ const ( MizuResourcesNamespaceConfigName = "mizu-resources-namespace" TelemetryConfigName = "telemetry" DumpLogsConfigName = "dump-logs" + KubeConfigPathName = "kube-config-path" ) type ConfigStruct struct { @@ -22,6 +23,7 @@ type ConfigStruct struct { MizuResourcesNamespace string `yaml:"mizu-resources-namespace" default:"mizu"` Telemetry bool `yaml:"telemetry" default:"true"` DumpLogs bool `yaml:"dump-logs" default:"false"` + KubeConfigPath string `yaml:"kube-config-path" default:""` } func (config *ConfigStruct) SetDefaults() { diff --git a/cli/mizu/configStructs/tapConfig.go b/cli/mizu/configStructs/tapConfig.go index 1f8923667..67582e467 100644 --- a/cli/mizu/configStructs/tapConfig.go +++ b/cli/mizu/configStructs/tapConfig.go @@ -16,7 +16,6 @@ const ( NamespacesTapName = "namespaces" AnalysisTapName = "analysis" AllNamespacesTapName = "all-namespaces" - KubeConfigPathTapName = "kube-config" PlainTextFilterRegexesTapName = "regex-masking" HideHealthChecksTapName = "hide-healthchecks" DisableRedactionTapName = "no-redact" @@ -34,7 +33,6 @@ type TapConfig struct { Namespaces []string `yaml:"namespaces"` Analysis bool `yaml:"analysis" default:"false"` AllNamespaces bool `yaml:"all-namespaces" default:"false"` - KubeConfigPath string `yaml:"kube-config"` PlainTextFilterRegexes []string `yaml:"regex-masking"` HideHealthChecks bool `yaml:"hide-healthchecks" default:"false"` DisableRedaction bool `yaml:"no-redact" default:"false"` From ebbe6458a85b285a6a8c0448af42b3056a710ae8 Mon Sep 17 00:00:00 2001 From: Nimrod Gilboa Markevich <59927337+nimrod-up9@users.noreply.github.com> Date: Sun, 8 Aug 2021 10:51:39 +0300 Subject: [PATCH 63/69] Do not tap pods whose names start with "mizu-". (#176) --- cli/cmd/tapRunner.go | 18 ++++++++++++++++-- cli/fsUtils/mizuLogsUtils.go | 2 +- cli/mizu/consts.go | 19 ++++++++++--------- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index 030740fce..7faeac86b 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -419,7 +419,8 @@ func updateCurrentlyTappedPods(kubernetesProvider *kubernetes.Provider, ctx cont if matchingPods, err := kubernetesProvider.ListAllRunningPodsMatchingRegex(ctx, mizu.Config.Tap.PodRegex(), targetNamespaces); err != nil { return err, false } else { - addedPods, removedPods := getPodArrayDiff(state.currentlyTappedPods, matchingPods) + podsToTap := excludeMizuPods(matchingPods) + addedPods, removedPods := getPodArrayDiff(state.currentlyTappedPods, podsToTap) for _, addedPod := range addedPods { changeFound = true mizu.Log.Infof(uiUtils.Green, fmt.Sprintf("+%s", addedPod.Name)) @@ -428,12 +429,25 @@ func updateCurrentlyTappedPods(kubernetesProvider *kubernetes.Provider, ctx cont changeFound = true mizu.Log.Infof(uiUtils.Red, fmt.Sprintf("-%s", removedPod.Name)) } - state.currentlyTappedPods = matchingPods + state.currentlyTappedPods = podsToTap } return nil, changeFound } +func excludeMizuPods(pods []core.Pod) []core.Pod { + mizuPrefixRegex := regexp.MustCompile("^" + mizu.MizuResourcesPrefix) + + nonMizuPods := make([]core.Pod, 0) + for _, pod := range pods { + if !mizuPrefixRegex.MatchString(pod.Name) { + nonMizuPods = append(nonMizuPods, pod) + } + } + + return nonMizuPods +} + func getPodArrayDiff(oldPods []core.Pod, newPods []core.Pod) (added []core.Pod, removed []core.Pod) { added = getMissingPods(newPods, oldPods) removed = getMissingPods(oldPods, newPods) diff --git a/cli/fsUtils/mizuLogsUtils.go b/cli/fsUtils/mizuLogsUtils.go index 701c8b25f..b48cc2aa6 100644 --- a/cli/fsUtils/mizuLogsUtils.go +++ b/cli/fsUtils/mizuLogsUtils.go @@ -11,7 +11,7 @@ import ( ) func DumpLogs(provider *kubernetes.Provider, ctx context.Context, filePath string) error { - podExactRegex := regexp.MustCompile(fmt.Sprintf("^mizu-")) + podExactRegex := regexp.MustCompile("^" + mizu.MizuResourcesPrefix) pods, err := provider.ListAllPodsMatchingRegex(ctx, podExactRegex, []string{mizu.Config.MizuResourcesNamespace}) if err != nil { return err diff --git a/cli/mizu/consts.go b/cli/mizu/consts.go index 576010709..c90c78179 100644 --- a/cli/mizu/consts.go +++ b/cli/mizu/consts.go @@ -14,16 +14,17 @@ var ( ) const ( - ApiServerPodName = "mizu-api-server" - ClusterRoleBindingName = "mizu-cluster-role-binding" - ClusterRoleName = "mizu-cluster-role" + MizuResourcesPrefix = "mizu-" + ApiServerPodName = MizuResourcesPrefix + "api-server" + ClusterRoleBindingName = MizuResourcesPrefix + "cluster-role-binding" + ClusterRoleName = MizuResourcesPrefix + "cluster-role" K8sAllNamespaces = "" - RoleBindingName = "mizu-role-binding" - RoleName = "mizu-role" - ServiceAccountName = "mizu-service-account" - TapperDaemonSetName = "mizu-tapper-daemon-set" - TapperPodName = "mizu-tapper" - ConfigMapName = "mizu-policy" + RoleBindingName = MizuResourcesPrefix + "role-binding" + RoleName = MizuResourcesPrefix + "role" + ServiceAccountName = MizuResourcesPrefix + "service-account" + TapperDaemonSetName = MizuResourcesPrefix + "tapper-daemon-set" + TapperPodName = MizuResourcesPrefix + "tapper" + ConfigMapName = MizuResourcesPrefix + "policy" ) func GetMizuFolderPath() string { From 0595df8b87cb0f91af2e2f9381aa4bb095d52457 Mon Sep 17 00:00:00 2001 From: Nimrod Gilboa Markevich <59927337+nimrod-up9@users.noreply.github.com> Date: Sun, 8 Aug 2021 12:23:11 +0300 Subject: [PATCH 64/69] Adds Namespace-Restricted Mode to README. (#178) --- README.md | 34 ++++++++++++++++++++++---------- cli/errormessage/errormessage.go | 8 ++++++-- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index e09ab9988..cf5a2fab8 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,9 @@ A simple-yet-powerful API traffic viewer for Kubernetes to help you troubleshoot ## Download -Download `mizu` for your platform and operating system +Download Mizu for your platform and operating system -### Latest stable release +### Latest Stable Release * for MacOS - Intel ``` @@ -34,12 +34,12 @@ https://github.com/up9inc/mizu/releases/latest/download/mizu_linux_amd64 \ SHA256 checksums are available on the [Releases](https://github.com/up9inc/mizu/releases) page. -### Development (unstable) build +### Development (unstable) Build Pick one from the [Releases](https://github.com/up9inc/mizu/releases) page. ## Prerequisites -1. Set `KUBECONFIG` environment variable to your kubernetes configuration. If this is not set, mizu assumes that configuration is at `${HOME}/.kube/config` -2. mizu needs following permissions on your kubernetes cluster to run +1. Set `KUBECONFIG` environment variable to your Kubernetes configuration. If this is not set, Mizu assumes that configuration is at `${HOME}/.kube/config` +2. Mizu needs following permissions on your Kubernetes cluster to run ```yaml - apiGroups: @@ -84,7 +84,7 @@ Pick one from the [Releases](https://github.com/up9inc/mizu/releases) page. - get ``` -3. Optionally, for resolving traffic IP to kubernetes service name, mizu needs below permissions +3. Optionally, for resolving traffic IP to Kubernetes service name, Mizu needs below permissions ```yaml - apiGroups: @@ -201,7 +201,7 @@ Pick one from the [Releases](https://github.com/up9inc/mizu/releases) page. - watch ``` -4. Optionally, in order to use the policy rules validation feature, mizu requires the following additional permissions: +4. Optionally, in order to use the policy rules validation feature, Mizu requires the following additional permissions: ```yaml - apiGroups: @@ -214,7 +214,7 @@ Pick one from the [Releases](https://github.com/up9inc/mizu/releases) page. - delete ``` -5. Alternatively, in order to restrict mizu to one namespace only (by setting `agent.namespace` in the config file), mizu needs the following permissions in that namespace: +5. Alternatively, in order to restrict Mizu to one namespace only (by setting `agent.namespace` in the config file), Mizu needs the following permissions in that namespace: ```yaml - apiGroups: @@ -252,7 +252,7 @@ Pick one from the [Releases](https://github.com/up9inc/mizu/releases) page. - get ``` -6. To restrict mizu to one namespace while also resolving IPs, mizu needs the following permissions in that namespace: +6. To restrict Mizu to one namespace while also resolving IPs, Mizu needs the following permissions in that namespace: ```yaml - apiGroups: @@ -346,7 +346,7 @@ Pick one from the [Releases](https://github.com/up9inc/mizu/releases) page. See `examples/roles` for example `clusterroles`. -## How to run +## How to Run 1. Find pods you'd like to tap to in your Kubernetes cluster 2. Run `mizu tap PODNAME` or `mizu tap REGEX` @@ -388,3 +388,17 @@ To tap multiple pods using regex - ^C ``` +## Advanced Usage + +### Namespace-Restricted Mode + +Some users have permission to only manage resources in one particular namespace assigned to them. +By default `mizu tap` creates a new namespace `mizu` for all of its Kubernetes resources. In order to instead install +Mizu in an existing namespace, set the `mizu-resources-namespace` config option. + +If `mizu-resources-namespace` is set to a value other than the default `mizu`, Mizu will operate in a +Namespace-Restricted mode. It will only tap pods in `mizu-resources-namespace`. This way Mizu only requires permissions +to the namespace set by `mizu-resources-namespace`. The user must set the tapped namespace to the same namespace by +using the `--namespace` flag or by setting `tap.namespaces` in the config file. + +Setting `mizu-resources-namespace=mizu` resets Mizu to its default behavior. diff --git a/cli/errormessage/errormessage.go b/cli/errormessage/errormessage.go index da0185dc5..1268f835d 100644 --- a/cli/errormessage/errormessage.go +++ b/cli/errormessage/errormessage.go @@ -17,8 +17,12 @@ func FormatError(err error) error { var errorNew error if k8serrors.IsForbidden(err) { errorNew = fmt.Errorf("insufficient permissions: %w. "+ - "supply the required permission or control Mizu's access to namespaces by setting MizuResourcesNamespace "+ - "in the config file or setting the tapped namespace with --%s %s=", err, mizu.SetCommandName, mizu.MizuResourcesNamespaceConfigName) + "supply the required permission or control Mizu's access to namespaces by setting %s "+ + "in the config file or setting the tapped namespace with --%s %s=", + err, + mizu.MizuResourcesNamespaceConfigName, + mizu.SetCommandName, + mizu.MizuResourcesNamespaceConfigName) } else if syntaxError, isSyntaxError := asRegexSyntaxError(err); isSyntaxError { errorNew = fmt.Errorf("regex %s is invalid: %w", syntaxError.Expr, err) } else { From d34dacbbe205757889fbe33edbdc4e97cf2b3722 Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Sun, 8 Aug 2021 12:26:58 +0300 Subject: [PATCH 65/69] View command - moving version check after proxy creation (#177) --- cli/cmd/tapRunner.go | 24 ++++++++++++------------ cli/cmd/view.go | 5 ----- cli/cmd/viewRunner.go | 23 +++++++++++++++++------ cli/mizu/versionCheck.go | 2 +- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index 7faeac86b..401b7f77d 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -329,7 +329,7 @@ func waitUntilNamespaceDeleted(ctx context.Context, cancel context.CancelFunc, k } func reportTappedPods() { - mizuProxiedUrl := kubernetes.GetMizuApiServerProxiedHostAndPath(mizu.Config.Fetch.MizuPort) + mizuProxiedUrl := kubernetes.GetMizuApiServerProxiedHostAndPath(mizu.Config.Tap.GuiPort) tappedPodsUrl := fmt.Sprintf("http://%s/status/tappedPods", mizuProxiedUrl) podInfos := make([]shared.PodInfo, 0) @@ -498,17 +498,8 @@ func createProxyToApiServerPod(ctx context.Context, kubernetesProvider *kubernet mizu.Log.Debugf("Watching API Server pod loop, modified: %v", modifiedPod.Status.Phase) if modifiedPod.Status.Phase == core.PodRunning && !isPodReady { isPodReady = true - go func() { - err := kubernetes.StartProxy(kubernetesProvider, mizu.Config.Tap.GuiPort, mizu.Config.MizuResourcesNamespace, mizu.ApiServerPodName) - if err != nil { - mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error occured while running k8s proxy %v\n"+ - "Try setting different port by using --%s", errormessage.FormatError(err), configStructs.GuiPortTapName)) - cancel() - } - }() - mizuProxiedUrl := kubernetes.GetMizuApiServerProxiedHostAndPath(mizu.Config.Tap.GuiPort) - mizu.Log.Infof("Mizu is available at http://%s\n", mizuProxiedUrl) - + go startProxyReportErrorIfAny(kubernetesProvider, cancel) + mizu.Log.Infof("Mizu is available at http://%s\n", kubernetes.GetMizuApiServerProxiedHostAndPath(mizu.Config.Tap.GuiPort)) time.Sleep(time.Second * 5) // Waiting to be sure the proxy is ready requestForAnalysis() reportTappedPods() @@ -525,6 +516,15 @@ func createProxyToApiServerPod(ctx context.Context, kubernetesProvider *kubernet } } +func startProxyReportErrorIfAny(kubernetesProvider *kubernetes.Provider, cancel context.CancelFunc) { + err := kubernetes.StartProxy(kubernetesProvider, mizu.Config.Tap.GuiPort, mizu.Config.MizuResourcesNamespace, mizu.ApiServerPodName) + if err != nil { + mizu.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error occured while running k8s proxy %v\n"+ + "Try setting different port by using --%s", errormessage.FormatError(err), configStructs.GuiPortTapName)) + cancel() + } +} + func requestForAnalysis() { if !mizu.Config.Tap.Analysis { return diff --git a/cli/cmd/view.go b/cli/cmd/view.go index 86ee5bf42..8f9742e2a 100644 --- a/cli/cmd/view.go +++ b/cli/cmd/view.go @@ -12,11 +12,6 @@ var viewCmd = &cobra.Command{ Short: "Open GUI in browser", RunE: func(cmd *cobra.Command, args []string) error { go mizu.ReportRun("view", mizu.Config.View) - if isCompatible, err := mizu.CheckVersionCompatibility(mizu.Config.View.GuiPort); err != nil { - return err - } else if !isCompatible { - return nil - } runMizuView() return nil }, diff --git a/cli/cmd/viewRunner.go b/cli/cmd/viewRunner.go index 587c7e384..4b2b11a0d 100644 --- a/cli/cmd/viewRunner.go +++ b/cli/cmd/viewRunner.go @@ -20,10 +20,13 @@ func runMizuView() { exists, err := kubernetesProvider.DoesServicesExist(ctx, mizu.Config.MizuResourcesNamespace, mizu.ApiServerPodName) if err != nil { - panic(err) + mizu.Log.Errorf("Failed to found mizu service %v", err) + cancel() + return } if !exists { - mizu.Log.Infof("The %s service not found", mizu.ApiServerPodName) + mizu.Log.Infof("%s service not found, you should run `mizu tap` command first", mizu.ApiServerPodName) + cancel() return } @@ -33,11 +36,19 @@ func runMizuView() { mizu.Log.Infof("Found a running service %s and open port %d", mizu.ApiServerPodName, mizu.Config.View.GuiPort) return } - mizu.Log.Infof("Found service %s, creating k8s proxy", mizu.ApiServerPodName) + mizu.Log.Debugf("Found service %s, creating k8s proxy", mizu.ApiServerPodName) + + go startProxyReportErrorIfAny(kubernetesProvider, cancel) mizu.Log.Infof("Mizu is available at http://%s\n", kubernetes.GetMizuApiServerProxiedHostAndPath(mizu.Config.View.GuiPort)) - err = kubernetes.StartProxy(kubernetesProvider, mizu.Config.View.GuiPort, mizu.Config.MizuResourcesNamespace, mizu.ApiServerPodName) - if err != nil { - mizu.Log.Errorf("Error occurred while running k8s proxy %v", err) + if isCompatible, err := mizu.CheckVersionCompatibility(mizu.Config.View.GuiPort); err != nil { + mizu.Log.Errorf("Failed to check versions compatibility %v", err) + cancel() + return + } else if !isCompatible { + cancel() + return } + + waitForFinish(ctx, cancel) } diff --git a/cli/mizu/versionCheck.go b/cli/mizu/versionCheck.go index d4a791629..74a5c84e3 100644 --- a/cli/mizu/versionCheck.go +++ b/cli/mizu/versionCheck.go @@ -46,7 +46,7 @@ func CheckVersionCompatibility(port uint16) (bool, error) { return true, nil } - Log.Infof(uiUtils.Red, fmt.Sprintf("cli version (%s) is not compatible with api version (%s)", SemVer, apiSemVer)) + Log.Errorf(uiUtils.Red, fmt.Sprintf("cli version (%s) is not compatible with api version (%s)", SemVer, apiSemVer)) return false, nil } From dfea8884d426606bbfb4dba7d79685b6b138196a Mon Sep 17 00:00:00 2001 From: RoyUP9 <87927115+RoyUP9@users.noreply.github.com> Date: Sun, 8 Aug 2021 14:05:15 +0300 Subject: [PATCH 66/69] Adding 'configuration' section in readme (#180) --- README.md | 16 ++++++++++++++++ cli/README.md | 26 -------------------------- cli/cmd/fetch.go | 4 ++-- cli/cmd/fetchRunner.go | 2 +- cli/cmd/tap.go | 4 ++-- cli/mizu/configStructs/fetchConfig.go | 4 ++-- 6 files changed, 23 insertions(+), 33 deletions(-) delete mode 100644 cli/README.md diff --git a/README.md b/README.md index cf5a2fab8..aa9d7493f 100644 --- a/README.md +++ b/README.md @@ -388,6 +388,22 @@ To tap multiple pods using regex - ^C ``` +## Configuration + +Mizu can work with config file which should be stored in ${HOME}/.mizu/config.yaml (macOS: ~/.mizu/config.yaml)
+In case no config file found, defaults will be used.
+In case of partial configuration defined, all other fields will be used with defaults.
+You can always override the defaults or config file with CLI flags. + +To get the default config params run `mizu config`
+To generate a new config file with default values use `mizu config -r` + +Mizu has several undocumented flags which can be set by using --set flag (e.g., `mizu tap --set dump-logs=true`) +* **mizu-resources-namespace**: Type - String, See [Namespace-Restricted Mode](#namespace-restricted-mode) +* **telemetry**: Type - Boolean, Reports telemetry +* **dump-logs**: Type - Boolean, At the end of the execution it creates a zip file with logs (in .mizu folder) +* **kube-config-path**: Type - String, Setting the path to kube config (which isn't in standard path) + ## Advanced Usage ### Namespace-Restricted Mode diff --git a/cli/README.md b/cli/README.md deleted file mode 100644 index 5dd208131..000000000 --- a/cli/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# mizu CLI -## Usage -`./mizu {pod_name_regex}` - -### Optional Flags - -| flag | default | purpose | -|----------------------|------------------|--------------------------------------------------------------------------------------------------------------| -| `--no-gui` | `false` | Don't host the web interface (not applicable at the moment) | -| `--gui-port` | `8899` | local port that web interface will be forwarded to | -| `--namespace` | | use namespace different than the one found in kubeconfig | -| `--kubeconfig` | | Path to custom kubeconfig file | - -There are some extra flags defined in code that will show up in `./mizu --help`, these are non functional stubs for now - -## Installation -Make sure your go version is at least 1.11 -1. cd to `mizu/cli` -2. Run `go mod download` (may take a moment) -3. Run `go build mizu.go` - -Alternatively, you can build+run directly using `go run mizu.go {pod_name_regex}` - - -## Known issues -* mid-flight port forwarding failures are not detected and no indication will be shown when this occurs diff --git a/cli/cmd/fetch.go b/cli/cmd/fetch.go index 184dc1450..3b9b4cc09 100644 --- a/cli/cmd/fetch.go +++ b/cli/cmd/fetch.go @@ -12,7 +12,7 @@ var fetchCmd = &cobra.Command{ Short: "Download recorded traffic to files", RunE: func(cmd *cobra.Command, args []string) error { go mizu.ReportRun("fetch", mizu.Config.Fetch) - if isCompatible, err := mizu.CheckVersionCompatibility(mizu.Config.Fetch.MizuPort); err != nil { + if isCompatible, err := mizu.CheckVersionCompatibility(mizu.Config.Fetch.GuiPort); err != nil { return err } else if !isCompatible { return nil @@ -31,5 +31,5 @@ func init() { fetchCmd.Flags().StringP(configStructs.DirectoryFetchName, "d", defaultFetchConfig.Directory, "Provide a custom directory for fetched entries") fetchCmd.Flags().Int(configStructs.FromTimestampFetchName, defaultFetchConfig.FromTimestamp, "Custom start timestamp for fetched entries") fetchCmd.Flags().Int(configStructs.ToTimestampFetchName, defaultFetchConfig.ToTimestamp, "Custom end timestamp fetched entries") - fetchCmd.Flags().Uint16P(configStructs.MizuPortFetchName, "p", defaultFetchConfig.MizuPort, "Custom port for mizu") + fetchCmd.Flags().Uint16P(configStructs.GuiPortFetchName, "p", defaultFetchConfig.GuiPort, "Provide a custom port for the web interface webserver") } diff --git a/cli/cmd/fetchRunner.go b/cli/cmd/fetchRunner.go index 3cc966481..9c372a632 100644 --- a/cli/cmd/fetchRunner.go +++ b/cli/cmd/fetchRunner.go @@ -16,7 +16,7 @@ import ( ) func RunMizuFetch() { - mizuProxiedUrl := kubernetes.GetMizuApiServerProxiedHostAndPath(mizu.Config.Fetch.MizuPort) + mizuProxiedUrl := kubernetes.GetMizuApiServerProxiedHostAndPath(mizu.Config.Fetch.GuiPort) resp, err := http.Get(fmt.Sprintf("http://%s/api/har?from=%v&to=%v", mizuProxiedUrl, mizu.Config.Fetch.FromTimestamp, mizu.Config.Fetch.ToTimestamp)) if err != nil { log.Fatal(err) diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go index 17dc116d1..72e71f3fb 100644 --- a/cli/cmd/tap.go +++ b/cli/cmd/tap.go @@ -64,9 +64,9 @@ func init() { tapCmd.Flags().Bool(configStructs.AnalysisTapName, defaultTapConfig.Analysis, "Uploads traffic to UP9 for further analysis (Beta)") tapCmd.Flags().BoolP(configStructs.AllNamespacesTapName, "A", defaultTapConfig.AllNamespaces, "Tap all namespaces") tapCmd.Flags().StringArrayP(configStructs.PlainTextFilterRegexesTapName, "r", defaultTapConfig.PlainTextFilterRegexes, "List of regex expressions that are used to filter matching values from text/plain http bodies") - tapCmd.Flags().Bool(configStructs.HideHealthChecksTapName, defaultTapConfig.HideHealthChecks, "hides requests with kube-probe or prometheus user-agent headers") + tapCmd.Flags().Bool(configStructs.HideHealthChecksTapName, defaultTapConfig.HideHealthChecks, "Hides requests with kube-probe or prometheus user-agent headers") tapCmd.Flags().Bool(configStructs.DisableRedactionTapName, defaultTapConfig.DisableRedaction, "Disables redaction of potentially sensitive request/response headers and body values") - tapCmd.Flags().String(configStructs.HumanMaxEntriesDBSizeTapName, defaultTapConfig.HumanMaxEntriesDBSize, "override the default max entries db size of 200mb") + tapCmd.Flags().String(configStructs.HumanMaxEntriesDBSizeTapName, defaultTapConfig.HumanMaxEntriesDBSize, "Override the default max entries db size") tapCmd.Flags().String(configStructs.DirectionTapName, defaultTapConfig.Direction, "Record traffic that goes in this direction (relative to the tapped pod): in/any") tapCmd.Flags().Bool(configStructs.DryRunTapName, defaultTapConfig.DryRun, "Preview of all pods matching the regex, without tapping them") tapCmd.Flags().String(configStructs.EnforcePolicyFile, defaultTapConfig.EnforcePolicyFile, "Yaml file with policy rules") diff --git a/cli/mizu/configStructs/fetchConfig.go b/cli/mizu/configStructs/fetchConfig.go index 8d2eab946..e84fba8b6 100644 --- a/cli/mizu/configStructs/fetchConfig.go +++ b/cli/mizu/configStructs/fetchConfig.go @@ -4,12 +4,12 @@ const ( DirectoryFetchName = "directory" FromTimestampFetchName = "from" ToTimestampFetchName = "to" - MizuPortFetchName = "port" + GuiPortFetchName = "gui-port" ) type FetchConfig struct { Directory string `yaml:"directory" default:"."` FromTimestamp int `yaml:"from" default:"0"` ToTimestamp int `yaml:"to" default:"0"` - MizuPort uint16 `yaml:"port" default:"8899"` + GuiPort uint16 `yaml:"gui-port" default:"8899"` } From efbb432df9914bec839dd22235607f5bc97aeb48 Mon Sep 17 00:00:00 2001 From: Alex Haiut Date: Sun, 8 Aug 2021 14:19:49 +0300 Subject: [PATCH 67/69] TRA-3547 separated permissions section into separate file (#181) --- PERMISSIONS.md | 328 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 325 +++--------------------------------------------- 2 files changed, 348 insertions(+), 305 deletions(-) create mode 100644 PERMISSIONS.md diff --git a/PERMISSIONS.md b/PERMISSIONS.md new file mode 100644 index 000000000..808b2a232 --- /dev/null +++ b/PERMISSIONS.md @@ -0,0 +1,328 @@ +![Mizu: The API Traffic Viewer for Kubernetes](assets/mizu-logo.svg) +# Kubernetes permissions for MIZU + +This document describes in details all permissions required for full and correct operation of Mizu + +We broke down this list into few categories: +- Required - what is needed for `mizu` to run properly on your k8s cluster +- Optional - permissions needed for proper name resolving for service & pod IPs + - addition required for policy validation + + + +# Required permissions + +Mizu needs following permissions on your Kubernetes cluster to run properly + +```yaml +- apiGroups: + - "" + resources: + - pods + verbs: + - list + - watch + - create + - delete +- apiGroups: + - "" + resources: + - services + verbs: + - create + - delete +- apiGroups: + - apps + resources: + - daemonsets + verbs: + - create + - patch + - delete +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch + - create + - delete +- apiGroups: + - "" + resources: + - services/proxy + verbs: + - get +``` + +## Permissions required for service / pod name resolving (opt) + +Optionally, for proper resolving of IP addresses to Kubernetes service name, Mizu needs below permissions: + +```yaml +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + - create + - delete +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch + - create + - delete +- apiGroups: + - apps + resources: + - daemonsets + verbs: + - create + - patch + - delete +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - list + - watch + - create + - delete +- apiGroups: + - "" + resources: + - services/proxy + verbs: + - get +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - get + - create + - delete +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + verbs: + - get + - create + - delete +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + verbs: + - get + - create + - delete +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - get + - create + - delete +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - get + - create + - delete +- apiGroups: + - apps + - extensions + resources: + - pods + verbs: + - get + - list + - watch +- apiGroups: + - apps + - extensions + resources: + - services + verbs: + - get + - list + - watch +- apiGroups: + - "" + - apps + - extensions + resources: + - endpoints + verbs: + - get + - list + - watch +``` + +## Permissions for Policy rules validation feature (opt) + +Optionally, in order to use the policy rules validation feature, Mizu requires the following additional permissions: + +```yaml +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - create + - delete +``` + +- - - + +## Namespace-Restricted mode + +Alternatively, in order to restrict Mizu to one namespace only (by setting `agent.namespace` in the config file), Mizu needs the following permissions in that namespace: + +```yaml +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + - create + - delete +- apiGroups: + - "" + resources: + - services + verbs: + - get + - create + - delete +- apiGroups: + - apps + resources: + - daemonsets + verbs: + - get + - create + - patch + - delete +- apiGroups: + - "" + resources: + - services/proxy + verbs: + - get +``` + +### Name resolving in Namespace-Restricted mode (opt) + +To restrict Mizu to one namespace while also resolving IPs, Mizu needs the following permissions in that namespace: + +```yaml +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + - create + - delete +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch + - create + - delete +- apiGroups: + - apps + resources: + - daemonsets + verbs: + - get + - create + - patch + - delete +- apiGroups: + - "" + resources: + - services/proxy + verbs: + - get +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - get + - create + - delete +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - get + - create + - delete +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - get + - create + - delete +- apiGroups: + - apps + - extensions + resources: + - pods + verbs: + - get + - list + - watch +- apiGroups: + - apps + - extensions + resources: + - services + verbs: + - get + - list + - watch +- apiGroups: + - "" + - apps + - extensions + resources: + - endpoints + verbs: + - get + - list + - watch +``` diff --git a/README.md b/README.md index aa9d7493f..91734b4c0 100644 --- a/README.md +++ b/README.md @@ -39,317 +39,15 @@ Pick one from the [Releases](https://github.com/up9inc/mizu/releases) page. ## Prerequisites 1. Set `KUBECONFIG` environment variable to your Kubernetes configuration. If this is not set, Mizu assumes that configuration is at `${HOME}/.kube/config` -2. Mizu needs following permissions on your Kubernetes cluster to run +2. `mizu` assumes user running the command has permissions to create resources (such as pods, services, namespaces) on your Kubernetes cluster (no worries - `mizu` resources are cleaned up upon termination) -```yaml -- apiGroups: - - "" - resources: - - pods - verbs: - - list - - watch - - create - - delete -- apiGroups: - - "" - resources: - - services - verbs: - - create - - delete -- apiGroups: - - apps - resources: - - daemonsets - verbs: - - create - - patch - - delete -- apiGroups: - - "" - resources: - - namespaces - verbs: - - get - - list - - watch - - create - - delete -- apiGroups: - - "" - resources: - - services/proxy - verbs: - - get -``` +For detailed list of k8s permissions see [PERMISSIONS](PERMISSIONS.md) document -3. Optionally, for resolving traffic IP to Kubernetes service name, Mizu needs below permissions - -```yaml -- apiGroups: - - "" - resources: - - pods - verbs: - - get - - list - - watch - - create - - delete -- apiGroups: - - "" - resources: - - services - verbs: - - get - - list - - watch - - create - - delete -- apiGroups: - - apps - resources: - - daemonsets - verbs: - - create - - patch - - delete -- apiGroups: - - "" - resources: - - namespaces - verbs: - - get - - list - - watch - - create - - delete -- apiGroups: - - "" - resources: - - services/proxy - verbs: - - get -- apiGroups: - - "" - resources: - - serviceaccounts - verbs: - - get - - create - - delete -- apiGroups: - - rbac.authorization.k8s.io - resources: - - clusterroles - verbs: - - get - - create - - delete -- apiGroups: - - rbac.authorization.k8s.io - resources: - - clusterrolebindings - verbs: - - get - - create - - delete -- apiGroups: - - rbac.authorization.k8s.io - resources: - - roles - verbs: - - get - - create - - delete -- apiGroups: - - rbac.authorization.k8s.io - resources: - - rolebindings - verbs: - - get - - create - - delete -- apiGroups: - - apps - - extensions - resources: - - pods - verbs: - - get - - list - - watch -- apiGroups: - - apps - - extensions - resources: - - services - verbs: - - get - - list - - watch -- apiGroups: - - "" - - apps - - extensions - resources: - - endpoints - verbs: - - get - - list - - watch -``` - -4. Optionally, in order to use the policy rules validation feature, Mizu requires the following additional permissions: - -```yaml -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - create - - delete -``` - -5. Alternatively, in order to restrict Mizu to one namespace only (by setting `agent.namespace` in the config file), Mizu needs the following permissions in that namespace: - -```yaml -- apiGroups: - - "" - resources: - - pods - verbs: - - get - - list - - watch - - create - - delete -- apiGroups: - - "" - resources: - - services - verbs: - - get - - create - - delete -- apiGroups: - - apps - resources: - - daemonsets - verbs: - - get - - create - - patch - - delete -- apiGroups: - - "" - resources: - - services/proxy - verbs: - - get -``` - -6. To restrict Mizu to one namespace while also resolving IPs, Mizu needs the following permissions in that namespace: - -```yaml -- apiGroups: - - "" - resources: - - pods - verbs: - - get - - list - - watch - - create - - delete -- apiGroups: - - "" - resources: - - services - verbs: - - get - - list - - watch - - create - - delete -- apiGroups: - - apps - resources: - - daemonsets - verbs: - - get - - create - - patch - - delete -- apiGroups: - - "" - resources: - - services/proxy - verbs: - - get -- apiGroups: - - "" - resources: - - serviceaccounts - verbs: - - get - - create - - delete -- apiGroups: - - rbac.authorization.k8s.io - resources: - - roles - verbs: - - get - - create - - delete -- apiGroups: - - rbac.authorization.k8s.io - resources: - - rolebindings - verbs: - - get - - create - - delete -- apiGroups: - - apps - - extensions - resources: - - pods - verbs: - - get - - list - - watch -- apiGroups: - - apps - - extensions - resources: - - services - verbs: - - get - - list - - watch -- apiGroups: - - "" - - apps - - extensions - resources: - - endpoints - verbs: - - get - - list - - watch -``` - -See `examples/roles` for example `clusterroles`. ## How to Run 1. Find pods you'd like to tap to in your Kubernetes cluster -2. Run `mizu tap PODNAME` or `mizu tap REGEX` +2. Run `mizu tap` or `mizu tap PODNAME` 3. Open browser on `http://localhost:8899/mizu` **or** as instructed in the CLI .. 4. Watch the API traffic flowing .. 5. Type ^C to stop @@ -358,6 +56,23 @@ See `examples/roles` for example `clusterroles`. Run `mizu help` for usage options +To tap all pods in current namespace - +``` + $ kubectl get pods + NAME READY STATUS RESTARTS AGE + carts-66c77f5fbb-fq65r 2/2 Running 0 20m + catalogue-5f4cb7cf5-7zrmn 2/2 Running 0 20m + front-end-649fc5fd6-kqbtn 2/2 Running 0 20m + .. + + $ mizu tap + +carts-66c77f5fbb-fq65r + +catalogue-5f4cb7cf5-7zrmn + +front-end-649fc5fd6-kqbtn + Web interface is now available at http://localhost:8899 + ^C +``` + To tap specific pod - ``` From 1a0517f46b3703fb9648feeb5c62b32c51f07913 Mon Sep 17 00:00:00 2001 From: Alex Haiut Date: Sun, 8 Aug 2021 14:21:33 +0300 Subject: [PATCH 68/69] TRA-3547 separated permissions section into separate file (#181) From 02e02718d2097061778667befcf491a32a5a9998 Mon Sep 17 00:00:00 2001 From: Nimrod Gilboa Markevich <59927337+nimrod-up9@users.noreply.github.com> Date: Sun, 8 Aug 2021 14:36:24 +0300 Subject: [PATCH 69/69] Fixed fetch not using from/to options (#179) --- agent/pkg/controllers/entries_controller.go | 16 ++++++++-------- agent/pkg/models/models.go | 14 +++++++------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/agent/pkg/controllers/entries_controller.go b/agent/pkg/controllers/entries_controller.go index 7eda00063..a1ad22d42 100644 --- a/agent/pkg/controllers/entries_controller.go +++ b/agent/pkg/controllers/entries_controller.go @@ -57,7 +57,7 @@ func GetEntries(c *gin.Context) { } func GetHARs(c *gin.Context) { - entriesFilter := &models.HarFetchRequestBody{} + entriesFilter := &models.HarFetchRequestQuery{} order := database.OrderDesc if err := c.BindQuery(entriesFilter); err != nil { c.JSON(http.StatusBadRequest, err) @@ -146,12 +146,12 @@ func GetHARs(c *gin.Context) { func UploadEntries(c *gin.Context) { rlog.Infof("Upload entries - started\n") - uploadRequestBody := &models.UploadEntriesRequestBody{} - if err := c.BindQuery(uploadRequestBody); err != nil { + uploadParams := &models.UploadEntriesRequestQuery{} + if err := c.BindQuery(uploadParams); err != nil { c.JSON(http.StatusBadRequest, err) return } - if err := validation.Validate(uploadRequestBody); err != nil { + if err := validation.Validate(uploadParams); err != nil { c.JSON(http.StatusBadRequest, err) return } @@ -160,19 +160,19 @@ func UploadEntries(c *gin.Context) { return } - rlog.Infof("Upload entries - creating token. dest %s\n", uploadRequestBody.Dest) - token, err := up9.CreateAnonymousToken(uploadRequestBody.Dest) + rlog.Infof("Upload entries - creating token. dest %s\n", uploadParams.Dest) + token, err := up9.CreateAnonymousToken(uploadParams.Dest) if err != nil { c.String(http.StatusServiceUnavailable, "Cannot analyze, mizu is already analyzing") return } rlog.Infof("Upload entries - uploading. token: %s model: %s\n", token.Token, token.Model) - go up9.UploadEntriesImpl(token.Token, token.Model, uploadRequestBody.Dest, uploadRequestBody.SleepIntervalSec) + go up9.UploadEntriesImpl(token.Token, token.Model, uploadParams.Dest, uploadParams.SleepIntervalSec) c.String(http.StatusOK, "OK") } func GetFullEntries(c *gin.Context) { - entriesFilter := &models.HarFetchRequestBody{} + entriesFilter := &models.HarFetchRequestQuery{} if err := c.BindQuery(entriesFilter); err != nil { c.JSON(http.StatusBadRequest, err) } diff --git a/agent/pkg/models/models.go b/agent/pkg/models/models.go index 13013f819..0648d4f5c 100644 --- a/agent/pkg/models/models.go +++ b/agent/pkg/models/models.go @@ -119,19 +119,19 @@ func (fedex *FullEntryDetailsExtra) UnmarshalData(entry *MizuEntry) error { } type EntriesFilter struct { - Limit int `query:"limit" validate:"required,min=1,max=200"` - Operator string `query:"operator" validate:"required,oneof='lt' 'gt'"` - Timestamp int64 `query:"timestamp" validate:"required,min=1"` + Limit int `form:"limit" validate:"required,min=1,max=200"` + Operator string `form:"operator" validate:"required,oneof='lt' 'gt'"` + Timestamp int64 `form:"timestamp" validate:"required,min=1"` } -type UploadEntriesRequestBody struct { +type UploadEntriesRequestQuery struct { Dest string `form:"dest"` SleepIntervalSec int `form:"interval"` } -type HarFetchRequestBody struct { - From int64 `query:"from"` - To int64 `query:"to"` +type HarFetchRequestQuery struct { + From int64 `form:"from"` + To int64 `form:"to"` } type WebSocketEntryMessage struct {