diff --git a/.dockerignore b/.dockerignore index eaf9b38c6..8baaf6053 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,3 +5,5 @@ bin/nebraska backend/tools/ backend/bin charts/ +frontend/**/*.stories.* +frontend/**/*.test.* diff --git a/backend/api/spec.yaml b/backend/api/spec.yaml index 721456b34..532696dd3 100644 --- a/backend/api/spec.yaml +++ b/backend/api/spec.yaml @@ -1823,6 +1823,7 @@ components: activity: type: object required: + - id - appID - groupID - createdTs @@ -1834,6 +1835,8 @@ components: - channelName - instanceID properties: + id: + type: string appID: type: string x-oapi-codegen-extra-tags: diff --git a/backend/pkg/api/activity.go b/backend/pkg/api/activity.go index 50383f82e..e99720e3a 100644 --- a/backend/pkg/api/activity.go +++ b/backend/pkg/api/activity.go @@ -25,6 +25,7 @@ const ( // Activity represents a Nebraska activity entry. type Activity struct { + ID string `db:"id" json:"id"` AppID null.String `db:"application_id" json:"app_id"` GroupID null.String `db:"group_id" json:"group_id"` CreatedTs time.Time `db:"created_ts" json:"created_ts"` @@ -115,7 +116,7 @@ func (api *API) activityQuery(teamID string, p ActivityQueryParams, countSelect query = query.Select(goqu.L(`count(a)`)) } else { query = query.Select( - "a.application_id", "a.group_id", "a.created_ts", "a.class", + "a.id", "a.application_id", "a.group_id", "a.created_ts", "a.class", "a.severity", "a.version", "a.instance_id", goqu.I("app.name").As("application_name"), goqu.I("g.name"). As("group_name"), goqu.I("c.name").As("channel_name")) diff --git a/backend/pkg/api/groups_test.go b/backend/pkg/api/groups_test.go index 375a07140..f8622d7a8 100644 --- a/backend/pkg/api/groups_test.go +++ b/backend/pkg/api/groups_test.go @@ -189,6 +189,26 @@ func TestGetGroupsFiltered(t *testing.T) { } } +func TestVersionBreakDownEmpty(t *testing.T) { + a := newForTest(t) + defer a.Close() + + tTeam, _ := a.AddTeam(&Team{Name: "test_team"}) + tApp, _ := a.AddApp(&Application{Name: "test_app", TeamID: tTeam.ID}) + tPkg, _ := a.AddPackage(&Package{Type: PkgTypeOther, URL: "http://sample.url/pkg", Version: "12.1.0", ApplicationID: tApp.ID}) + tChannel, _ := a.AddChannel(&Channel{Name: "test_channel", Color: "blue", ApplicationID: tApp.ID, PackageID: null.StringFrom(tPkg.ID)}) + _, err := a.AddGroup(&Group{Name: "test_group1", ApplicationID: tApp.ID, ChannelID: null.StringFrom(tChannel.ID), PolicyUpdatesEnabled: true, PolicySafeMode: true, PolicyPeriodInterval: "15 minutes", PolicyMaxUpdatesPerPeriod: 2, PolicyUpdateTimeout: "60 minutes"}) + assert.NoError(t, err) + + groups, err := a.GetGroups(tApp.ID, 0, 0) + assert.NoError(t, err) + g := groups[0] + + versionBreakdown, vbErr := a.GetGroupVersionBreakdown(g.ID) + assert.NoError(t, vbErr) + assert.Len(t, versionBreakdown, 0) +} + func TestGetVersionCountTimeline(t *testing.T) { a := newForTest(t) defer a.Close() diff --git a/backend/pkg/codegen/spec.gen.go b/backend/pkg/codegen/spec.gen.go index 29ca69dca..af5433ce8 100644 --- a/backend/pkg/codegen/spec.gen.go +++ b/backend/pkg/codegen/spec.gen.go @@ -18,74 +18,74 @@ import ( // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+xdWXPbtvb/Khz+/4+y5aRJH/R0HbdxfLvEUyftncl4NBAJSahJgAVBL/Hou9/BRoAk", - "QEG7fJOHTh0RODg453c2LORznJC8IBhiVsaj57hM5jAH4k+QMHSP2BP/u6CkgJQhKJ8UxdVP/A/2VMB4", - "FJeMIjyLB/HjCQEFOklICmcQn8BHRsEJAzPR6++S4HjEO49RGi8WA/5nhhLAEMG/gxxuQFGTGWNOh9NO", - "5gBjmG1CV5GwaGagLC1qCDM4gzTmjygEDKafxOMpoTlg8ShOAYMnDOUwHqzGQTrh40uaY1bGg5on8xvn", - "aEZJtYEuRHetDfGPTeQlqdXSQrhkACdwffY0Bc1hCe8hVYjsquAe0hLxfu3BeFcK/6kQhWk8+qLga4Rn", - "a08r2RrMUO4i1pZaE3ON+d/W6ieTv2HCOLvavK7BDDpMTD5V/0IM5uKP/6dwGo/i/xsaqx0qkx3W9rqo", - "RwOUAvHvhFSYucXGCAPZhe95S3RWY010YPPqnGhRXBA8RbPuLFNYJhQVzK22QYydaFwMOJm0ShgHxug5", - "xlWWgUkG4xGjFRwsUb8g6mFUK7fLqtJtuDpUB6c2tuss3K5hmWwFcMOnI5q7JiNV0CGv0V86RBkINtnO", - "palluLhK13U5FrAWbX5QGquhm9Jt+g8l14FBjC0Mm0UPBkuPRzDoXMEnWJDeu1uwGXbOlSZzTzRVttMn", - "hI0ykDpf0JmIYqVXlryNEFpGqBN9e7Frj71pk8jB468Qz9g8Hr09GzgsBCR3Cl99k9XNTI/15a0ILLUp", - "KdimNTUVbjOjlNYBVlBmpX2zwZovRLXA4hK9B8eckRk5Ub9WCLN+9PidmpFfSG5js6uYM7L1Bj8lBrfv", - "2Wrw26XPqRl1TtGn4iSBZfkbwGAGc4jZZ5q59Vyx+W8kdStpDkEK6Q17ytzPMzJD2Ec5IzPifVB5GcJw", - "QkF5B/70Zr6DmCHm5KiNG4cM7OG7gymu9QhNCVjzteTmUoqwzvcoayW6TQ3NQTl3ZxmpG0leWyrRV480", - "Opw1gBvm6cSP46mYDac5zQBLAD1PfDklJTn8eOPVX2idysmQcqzrlMX+ckyQZgi7RZ2ikifl1+ApIyB9", - "B5I7Mp1aLSeEZBDgwJEVtXEhyY0nih5nA97Dhsvw4MP6ufwJZgyszQwqx6kgwEfPIQMpYOAGzTBgFYV/", - "lGBdVWpa41ITG9OyPcxXuAXyX2WRjiFMy/M0R3htYQgSYyBoiCp9Dl6//XG5yxHhSapu0DGFmkyDRaM5", - "H7w86miJz0KubSmr5hJKAMrKx0Caecfwr03K1bR/Dzr7BLgl/mQ1t7f02srnA7MG9ef6XOjFO83BMZTc", - "S1L3buJHMpQ8/QYePxec0/Ia0mtIERFkcoRRXuXxyGT5duYZkJYL6uMcPI4rSX9cQMr/4yMs6vE/Tqco", - "gR9IRcu1fYQaiwhS47mgZUaQk7rCDNJ7kK1dZsgxJP9jpKmZYW7AFLbyt7VmUYIpHOeckKH9CeXwK8Fw", - "Q+aZJmMoS91z+qRiG5KXehajcGLtQcqfMXep6aYC0nCCipzw/CTLSMWu8DUlMwrL9bGkKI0RHhealnCN", - "FCR3gWFn6SpOl91uLWp8lEeMHeC5TKqDII9V9LkDN1a0SFxptwgAvprX8p3OxK7p5qwVh9fOJYfgpYle", - "h+TM811+pYsr07DtHPxe17LyPoLMa/emTcvqlrY0huMcucZ5Q/A/Bi17LxOyV1DdCfum50XblVoEvWGA", - "OVeF8yKDDLoVnZIHzPM8mPY/5zN3NoCUNtZdrEdidTbLfKQJ/kCytGfFwv2owimcIuyjKqV2SQFmziZh", - "vlDJfqbILJyLJLHNTHtkLZmBUYAtkYbkm2KuJePVuGcxyb8AtK09ic0XkhQn3qlxEFel6MXdbasIttJz", - "swKYg+ILN5JT3uGW/wthJv4vLfa2Qpj9+KYeQpVC7ygEd1zuwWK5b3X8GTPq3BW0h9lwKp0p6C0PR5GR", - "IVC6F9iaG3B9c9Tkz5sbHIdcgUdFYPKBiv6q05Leed+W5M6qtX0IcZsnF7Z/0iADJbuYw+TuPaEq29qq", - "MDj9ccIHGE8J1ZG4Hvqz7aI/7WDoZtzQOjFDb7giaY9hL0qWwmv2BcQt1Adq3HZ5cL/ZlMw02iZtwNct", - "EcwRE3OGxC4zlEDcgHNjwaUmh/TWXMtqbBhbplUH07BY3t374lEheH9fj+pOIBpHC4IiYh2MfLlCaJrQ", - "2Mvv41zmBx9QyQhFa3Bq93fGbnfDroL24ctFBnnh3BkL2Y0V3ceJLJD1Tor5bZnjuIcUlSHnvmpj0z2a", - "tmhm4VKs2M+6wlPSlXEByvKBUHdWUJWQehb4WuzVLQeGoosTkoM5+AP+U8GSdRO15hb/EZ6eUDu07zKQ", - "3GVITqE2je725eqbcHqE8aQe4mhWgJu7nX3yslouBvEUZdC7TNzZZeyj22y8GATurS7dQdXic4Z2z/51", - "8IlNkTaLJnYgrcTuci2a9nJeKXd6xPxaRzw7GOxGbvfhEmNd2z8vYhmHBd1w63h58Ls2h4y8KDwE3LyH", - "aLrqaYPOQqMCnoKhQq/ErOakB18rr52ofuGphnXEa/vrJzU3rinqZFWnlh5L8qwTtJUlmrmGca+D9KeT", - "DrlCmkDMlDpM4CDVJLOiBq7yyYrn0I0nq/PTxnDdOYkz8ElFEXu64VqUPM8Qm1eTC0LuEDyv2FxOigcn", - "8ZPe7hiphoZnUKBfoFA4QWnyDgIKqSYwEf96r6f7778+cSyLQXlFJp4aSnPGCk0ngBHerMuGrDdkhpUQ", - "zEAi4AdzgDI+Bswy8q87hO9JdneKiCH3i/xNmZfkZjQcWk3bvjH+XZ1milAZARxJREa5OP9ET+tTTaah", - "ZbWj+Oz07PSVmG8BMShQPIp/OD07PRPAZ3OhlSEo0NC+QzODrHPmPS7ADGE+dN1SEKUyEKXxKL5WLc5N", - "gwJQkEMGaRmPvigR/1NB+mREou84SGN3YtHd0VSsK3e198NW7twoo1fubUxp5a7WPY9OX8vleTozQLm7", - "M2YtbyAYSrXDqNPKQL4gTndDuOC+xabUc5LATwRSP51XLkK3fDJlQXApvdbrszNt6Or0lhV2h3+ris5Q", - "D7n6IoLmopOIx7+iktUWFpWVOOwYaXa4Ib85e9M1Tm1yESYsmpIKp40+b+UM+oYSNaXVyXLgwnTbfvfL", - "LRd424vKX7tu/svt4paTlK6mkDsnTjczgyw6L8S1BI93kQ8DPMv/Inz0pQsHdC6l5DygcQDgHeAoEdV5", - "AMKKonSiawdAGcQFKR3YkJVRBIqig44L8ehcPAmARpIRDMdTSvJeR3wr3Ros2TuSPm1TiyqVdKhRHRuN", - "poRGjQk3HexityizllY7HEpZbwdrTs9kDbBntzR8FunIQvKkN/mb3MnfnSj8STzyo5CnXN3Mxx85nXjs", - "Kr3Jn2TCq563S/rsQeIDv+t3SfUSsr2LdB92dCnnu0KUL4pVArwOCHvRaFE5NKqKFZdS5bbQjvV6QNfd", - "mPrRuG4p9R267s/1tA/luof2FbD+Sla3jMiUl9YumOqs88Jckd0FWr+dAsi+vefxibVagh2j0s6qzrEe", - "aD8esi+n1RcK3HntRf30BbnK5nXVsEzXiGF/LtNcsfVluqrFbrNdPcih3ebwuV4dC0mDNduTp0hsQLgS", - "4t3Cd+CkYy/x7SbB7kPF24B+h020+/V2CdmLV9qunYMVQfYVqQ6fyvfDRmZ/Lww53yOfv1DYWuTbljG0", - "+DpUsDTH//srDNkuoL641O/i+V5dbIJoc5nDgWke9qScw/21ar8CQq1RDl9WCHlECPesmQteX1ZlYV8J", - "DPOuMzXJ/flWdePHW1MIse+2opBDHNZFDp/VNn1ILSHROkP3EEeIlZHqGgGcRhp8rvpilxB2pxvm7MFu", - "aos+dPi81CpOqjHMYQuR1ZV+CdmL1vhu/culjj87hI8Z4+AFyerw0ddUXgyCDhpAbTEfRwBVJcCKAbTR", - "a6UqZWXraAx1LOF32Dg86vXGdStRs2zgnK/sF4ketY35D8zJOzhLKS2vkQ5TaPkmRih7jzImTsWuLhZC", - "2UeartkZAprMNxhc9P8TZBVcp3taSaBuAx4h5zh3Gf8bFw89acBV05j9HtMb5J0Ujs+lDZ/NodxFkH/b", - "wL1dWUfgX4Rja1JqHF8+jlzWXHp147hWWnBGq3W0alJbj3TkGB/K6DSem9u0yyHf7HPah+3mXd1vCuge", - "f5+hHLHwIL4Pc2nf3F5qPaJ9pPS/R2NqDXx8tjUu9Zuewqxoa9mxfMPUC82Q10qndr4m0hStwyZqON9o", - "Tc52vFziG/H4DKG+tbncDkTTrVWJF/VtzO+GsL0IIaW6pDqwNblBidAlczTwVokPs94Z5sW3ilW67aYA", - "lzG6flvZd4Bv0dO73mznwLpsFn2yNLprh+8d8mhMQi1fjCf2O/u8RqFaR3XrTc2i88bAb34rpyMRB5JV", - "m+idrYZdY7ln0KNDc5CH12DelotXAvru43doFkudvEbpPr28f8xDGYb9ZpX+g2m6ZcDRtGtN9Fs4nNa/", - "8XDgNX/7hTue821aWeGwr3scx+Vu/a4f92G16/rpCzqu1nwPV9iBNSOG/e24169Z8h5aU+IP33Vv9Zus", - "cYpNcXVwnzp8rr/oF3KWTbNtMoq6+9LzbLtFuTuTsD9XuJszbf3g8XumNc617REzPSfb1oPAJWQvXv+7", - "dkeXJtLtFE72OAc/6bYenORhpBeGqAPH4KbAjyUGq2Nl+8D95ybi9hh6/Uc6+kzDeiuhC/0rndjY5HzE", - "9nHrfAFlGHwtoewPv31HOT43+QrfZmh33BMezVd4+15XE6lmriu0+snubvB5ASHu+IqnPYLqmfwcgky+", - "F9M5efk4gjgtCBI7d83Zf5DdQ9JDRcrHpWRHvNTcy414Gk0oeSghjaYZeegw9KsgEPRyMEFtTGGKKEzY", - "WL4Id/2c6Iez1z6Ol9ZPVsHktQ7x5SsMsqiE9B5SaR2y9atuax4FUF5k4tvJUDoMTHDErSMCFZtHOUnV", - "Bz7cWhgmkyWKSECWTUBy51bCxSQIForUJLzYbAnrjWv6FeZzJBR9hemqEvVLhJE7KD9741zakFMRjXrA", - "+UkQCQ0jjycPDw8nU0Lzk4pmECdEfXEszHGYjwQsCSYW76GBxD/5pZ5+71i+BxmSH4XTKnTiWjerBdHU", - "35/qsVHhMqk0CYY4v+EDnMwJuVsGswc4iUQ7J8j+UkTcjlB+GN14wv+cfKgmJ/X3idcqCro0L0XUOflZ", - "fVB5y6sNtRT4PJcI9v6VSrD8QhXfsPDHuY/8ca/RMvjIho95Fm6bjc9mLDHPDntrWKiYQ/RHyBVUxVWE", - "pvU6Xom+wgiVESMkygCduUS9WPw3AAD//4ksx1G+jQAA", + "H4sIAAAAAAAC/+xdWXPbtvb/Khz+/4+y5aRJH/x0HbdxfLvE0yTtncl4OBAJSahJgAVBL8nou9/BRoAk", + "QEG7fJOHTh0RODg453c2LOTXOCVFSTDErIrPv8ZVOocFEH+ClKF7xJ743yUlJaQMQfmkLK9/4n+wpxLG", + "53HFKMKzeBQ/nhBQopOUZHAG8Ql8ZBScMDATvf6uCI7PeecEZfFiMeJ/5igFDBH8OyjgBhQ1mQRzOpx2", + "OgcYw3wTuoqERTMHVWVRQ5jBGaQxf0QhYDD7KB5PCS0Ai8/jDDB4wlAB49FqHGQTPr6kmbAqHjU8md84", + "RzNK6g10IbprbYh/bCIvSa2RFsr6hPjPuGIAp3B9rjUFzXgF7yFVQO1r5h7SCvF+PV4Wo5jCf2pEYRaf", + "f+b8jhS0jWBtzWoAWCMa8n002xJt47ElhNsGGmTyN0wZ51mb3g2YQYf5yafqX4jBQvzx/xRO4/P4/8bG", + "osfKnMeNLS+a0QClQPw7JTVmbtkxwkB+6XvekZ/VWBMd2bw6J1qWlwRP0aw/ywxWKUUlc+tuFGMnUhcj", + "TiarU5ZI/OE6z8Ekh/E5ozUcLcGAIOphVCu3z6rSbbg6VAenNrbrSNxuY5lsBXDDpyOauyazxAVUDlEG", + "gk22c2lqGS6us3X9jgWshdN5YGnctnTb/kPJdWQQYwvDZtGDwcrjEQw6V/AJFqT37hZshp1zpencE2mV", + "7QwJYaPspMkldJaiWBmUJW8jhJYT6kTfXuzaY2/aJArw+CvEMzaPz1+fjRwWAtI7ha+hyepmpsf68lYE", + "ltqUFGzbmtoKt5lRSusBKyjr0r7ZYM0XojpgcYneg2POyIycqF9rhNkwevxOzchvaYLTYVcxZ2TrDX5K", + "DG7fs9Xgt0uf0zDqnKJPxWkKq+o3gMEMFhCzTzR367lm899I5lbSHIIM0g/sKXc/z8kMYR/lnMyI90Ht", + "ZQjDCQXVHfjTm/6OYoaYk6MubhwysIfvD6a41iO0JWDN15KbSynCOt+ivJPotjU0B9XcnWVkbiR5balC", + "XzzS6HHWAm6YpxM/JlMxG05zmgOWAnqR+nJKSgr4/oNXf6E1LCdDqkTXKYv95ZggyxF2izpDFU/Kb8BT", + "TkD2BqR3ZDq1Wk4IySHAgSMrakkpySUTRY+zAe9hy2V48GH9XP0EcwbWZgZVSSYI8NELyEAGGPiAZhiw", + "msI/KrCuKjWtpNLEElp1h/kCt0D+iyzgMYRZdZEVCK8tDEEiAYKGKNXn4OXrHwNrcam6Uc8UGjItFo3m", + "fPDyqKMjPgu5tqWsmksoASgrT4A0857h35iUq23/HnQOCXBL/Mlqbm/ptZXPB2YN6s/1udALe5qDYyi5", + "l6Tu/cSP5Ch9+g08fio5p9UNpDeQIiLIFAijoi7ic5Pl25lnQFouqCcFeExqST8pIeX/8REWzfjvp1OU", + "wnekptXaPkKNRQSpZC5omRHkpK4xg/Qe5GuXGXIMyX+CNDUzzAcwhZ38ba1ZVGAKk4ITMrQ/ogJ+IRhu", + "yDzTZAxlqXtOn9RsQ/JSz2IUTqw7SPUz5i4121RAGk5QkROen+Q5qdk1vqFkRmG1PpYUpQThpNS0hGuk", + "IL0LDDtLV3H67PZrUeOjPGLsAc9lUj0EeaxiyB24saJF4kq7RQDw1byW73Qmdm03Z604vHQuOQQvTQw6", + "JGee7/IrfVyZhl3n4Pe6lpUPEWReuzdtOla3tKUxHOfIDc5bgv8xaNl7mZC9gupP2Dc9L9qu1SLoBwaY", + "c1W4KHPIoFvRGXnAPM+D2fBzPnNnA0hpa93FeiRWZ/PcR5rgdyTPBlYs3I9qnMEpwj6qUmpXFGDmbBLm", + "C5XsZ4rMwrlIEtvMdEfWkhkZBdgSaUm+LeZGMl6NexaT/AtA29qT2HwhSXHinRoHcV2JXtzddopgKz03", + "K4AFKD9zIznlHW75vxBm4v/SYm9rhNmPr5ohVCn0hkJwx+UeLJb7TsefMaPOXUF7mA2n0puC3vJwFBk5", + "ApV7ga29ATc0R03+or3BccgVeFQGJh+oHK46LeldDG1J7qxa24cQt3mqYfvHDXJQscs5TO/eEqqyra0K", + "g9NPUj5AMiVUR+Jm6E+2i/64g6HbcUPrxAy94YqkPYa9KFkJrzkUELdQH6hxu+XB/WZTMtPomrQBX79E", + "MEdMzBkSu8xQAnEDzo0Fl5oc0ltzLau1YWyZVhNMw2J5f++LR4Xg/X09qjuBaB0tCIqITTDy5QqhaUJr", + "L3+Ic5kfvEMVIxStwand3xm73Q37CtqHLxcZ5KVzZyxkN1Z0T1JZIOudFPPbMsdxDymqQg5/Ncame7Rt", + "0czCpVixn3WNp6Qv4xJU1QOh7qygriD1LPB12GtajgxFFyekAHPwB/ynhhXrJ2rtLf4jPD2hdmjf5CC9", + "y5GcQmMa/e3L1Tfh9AjJpBniaFaA27udQ/KyWi5G8RTl0LtM3NtlHKLbbrwYBe6tLt1B1eJzhnbP/vVq", + "xzZFEzuQ1mJ3uRFNdzmvkjs9Yn6dI549DPYjt/twibGu7Z8XsYzDgm64dTw/+N2YQ0ZeFB4Cbt5DNH31", + "dEFnoVEBT8FQoVdiVnMygK+V105Uv/BUwzritf31k4Yb1xR1sqpTS48ledYJusoSzVzDuNdBhtNJh1wh", + "TSFmSh0mcJB6kltRA9fFZMXD6MaTNflpa7j+nMRB+LSmiD194FqUPM8Qm9eTS0LuELyo2VxOigcn8ZPe", + "7jhXDQ3PoES/QKFwgrL0DQQUUk1gIv71Vk/333995FgWg/KKTDw1lOaMlZpOACO8WZ8NWW/IDCslmIFU", + "wA8WAOV8DJjn5F93CN+T/O4UEUPuF/mbMi/Jzfl4bDXt+sb4d3WaKUJVBHAkERkV4vwTPW1ONZmGltWe", + "x2enZ6cvxHxLiEGJ4vP4h9Oz0zMBfDYXWhmDEo3t+zUzyHpn3uMSzBDmQzctBVEqA1EWn8c3qsWFaVAC", + "CgrIIK3i889KxP/UkD4Zkeg7DtLYnVh0dzQV68pd7f2wlTu3yuiVextTWrmrdc+j19dyeZ7ODFDu7oxZ", + "yxsIhlLjMJq0MpAviLPdEC65b7EpDZwk8BOB1E/nhYvQLZ9MVRJcSa/18uxMG7o6vWWF3fHfqqIz1EOu", + "voiguegl4vGvqGKNhUVVLQ47Rpodbsivzl71jVObXIQJi6akxlmrz2s5g6GhRE1pdbIcuDDdrt/9fMsF", + "3vWi8te+m/98u7jlJKWrKeXOidPNzCCLLkpxLcHjXeTDAM/yvwgffenCAZ0rKTkPaBwAeAM4SkR1HoCw", + "sqyc6NoBUEZxSSoHNmRlFIGy7KHjUjy6EE8CoJHmBMNkSkkx6IhvpVuDFXtDsqdtalGlkg41qmOj0ZTQ", + "qDXhtoNd7BZl1tJqj0Mp6+1gzemZrAH27JbGX0U6spA86U3+NnfydycKfxKP/CjkKVc/8/FHTice+0pv", + "8yeZ8Krn9ZI+e5D4yO/6XVK9gmzvIt2HHV3J+a4Q5ctylQCvA8JeNFrWDo2qYsWlVLkttGO9HtB1t6Z+", + "NK5bSn2HrvtTM+1Due6xfQVsuJLVLSMy5aW1C6Y667w0V2R3gdZvpwCyb+95fGKjlmDHqLSzqnNsBtqP", + "hxzKafWFAndee9k8fUausn1dNSzTNWLYn8s0V2x9ma5qsdtsVw9yaLc5/tqsjoWkwZrtyVMkNiBcCfFu", + "4Tty0rGX+HaTYA+h4nVAv8Mm2sN6u4Ls2Stt187BiiD7ilSHT+WHYSOzv2eGnO+Rz18obC3ybcsYOnwd", + "Klia4//DFYZsF1BfXOl38XyvLjZBtLnM4cA0D3tSzuH+WrVfAaHWKIcvK4Q8IoQH1swFr8+rsrCvBIZ5", + "15ma5P58q7rx460phNh3W1HIIQ7rIsdf1TZ9SC0h0TpD9xBHiFWR6hoBnEUafK76YpcQdqcb5uzBbmqL", + "IXT4vNQqTqo1zGELkdWVfgXZs9b4bv3LlY4/O4SPGePgBcnq8NHXVJ4Ngg4aQG0xH0cAVSXAigG01Wul", + "KmVl62gNdSzhd9w6POr1xk0rUbNs4Jyv7ReJHrWN+Q/MyTs4Syktr5EOU2j5JkYoe4tyJk7Fri4WQtl7", + "mq3ZGQKazjcYXPT/E+Q1XKd7VkugbgMeIec4dxn/WxcPPWnAdduY/R7TG+SdFI7PpY2/mkO5iyD/toF7", + "u7aOwD8Lx9am1Dq+fBy5rLn06sZxo7TgjFbraNWkthnpyDE+ltEpmZvbtMsh3+5zOoTt9l3dbwroHn+f", + "owKx8CC+D3Pp3txeaj2ifaT0v0dj6gx8fLaVVPpNT2FWtLXsWL5h6plmyGulUztfE2mL1mETDZw/aE3O", + "drxc4hvx+AyhubW53A5E061ViZfNbczvhrC9CCGluqQ6sDW5QYnQJ3M08FaJD7PeGebFt4pVuu2mAJcx", + "unlb2XeAb9HTu95s58C6bBZ9tDS6a4fvHfJoTEItXyQT+519XqNQraOm9aZm0Xtj4De/ldOTiAPJqk30", + "xlbDrrE8MOjRoTnIw2swb8vFKwF99/E7NIulTl6jdJ9e3j/moQzDfrPK8ME03TLgaNqNJvotHE4b3ng4", + "8Jq//cIdz/k2raxw2Dc9juNyt37Xj/uw2k3z9BkdV2u/hyvswJoRw/523JvXLHkPrSnxh++6d/pN1jjF", + "prg6uE8df22+6Bdylk2zbTKKpvvS82y7Rbk7k7A/V7ibM23D4PF7pjXOte0RMwMn29aDwBVkz17/u3ZH", + "VybS7RRO9jgHP+m2HpzkYaRnhqgDx+C2wI8lBqtjZfvA/ac24vYYev1HOoZMw3oroQv9K53Y2OR8xPZx", + "63wBZRh8LaHsD79DRzk+tfkK32bodtwTHs1XeIdeVxOpZq4rtPrJ7m7weQEh7viKpwOCGpj8HIJcvhfT", + "OXn5OII4KwkSO3ft2b+T3UPSQ0XKx6VkR7zU3MuNeBpNKHmoII2mOXnoMfSrIBD0cjBBLaEwQxSmLJEv", + "wl0/J/rh7KWP46X1k1Uwea1DfPkKgzyqIL2HVFqHbP2i35pHAVSUufh2MpQOAxMcceuIQM3mUUEy9YEP", + "txbG6WSJIlKQ5xOQ3rmVcDkJgoUiNQkvNjvCeuWafo35HAlFX2C2qkT9EmHkDsrP3jiXNuRURKMBcH4U", + "RELDyOPJw8PDyZTQ4qSmOcQpUV8cC3Mc5iMBS4KJxXtoIPFPfqmn3zuW70GO5EfhtAqduNbNGkG09fen", + "emxUuEwqbYIhzm/8ACdzQu6WwewBTiLRzgmyvxQRtyOUH0Y3nvA/J+/qyUnzfeK1ioI+zSsRdU5+Vh9U", + "3vJqQyMFPs8lgr1/oRIsv1DFNyz8ce49fzxotAw+svFjkYfbZuuzGUvMs8feGhYq5hD9EXIFVXEVoWmz", + "jlehLzBCVcQIiXJAZy5RLxb/DQAA//89WcrB2o0AAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/backend/pkg/codegen/types.gen.go b/backend/pkg/codegen/types.gen.go index 3d74e860b..5c9c0ae2b 100644 --- a/backend/pkg/codegen/types.gen.go +++ b/backend/pkg/codegen/types.gen.go @@ -22,6 +22,7 @@ type Activity struct { CreatedTs time.Time `db:"created_ts" json:"created_ts"` GroupID string `json:"group_id"` GroupName string `json:"group_name"` + Id string `json:"id"` InstanceID string `json:"instance_id"` Severity int `json:"severity"` Version string `json:"version"` diff --git a/backend/pkg/handler/groups.go b/backend/pkg/handler/groups.go index 3e8e951ca..1507404e0 100644 --- a/backend/pkg/handler/groups.go +++ b/backend/pkg/handler/groups.go @@ -188,6 +188,7 @@ func (h *Handler) GetGroupInstanceStats(ctx echo.Context, appID string, groupID func (h *Handler) GetGroupVersionBreakdown(ctx echo.Context, appID string, groupID string) error { versionBreakdown, err := h.db.GetGroupVersionBreakdown(groupID) + if err != nil { if err == sql.ErrNoRows { return ctx.NoContent(http.StatusNotFound) @@ -196,6 +197,10 @@ func (h *Handler) GetGroupVersionBreakdown(ctx echo.Context, appID string, group return ctx.NoContent(http.StatusInternalServerError) } + if len(versionBreakdown) == 0 { + // WAT?: because otherwise it serializes to null not [] + return ctx.JSON(http.StatusOK, []string{}) + } return ctx.JSON(http.StatusOK, versionBreakdown) } diff --git a/backend/test/api/flatcar_package_test.go b/backend/test/api/flatcar_package_test.go index 3bd21bd6e..5fdc1aa23 100644 --- a/backend/test/api/flatcar_package_test.go +++ b/backend/test/api/flatcar_package_test.go @@ -10,10 +10,11 @@ import ( "testing" "github.com/google/uuid" - "github.com/kinvolk/nebraska/backend/pkg/config" - "github.com/kinvolk/nebraska/backend/pkg/server" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/kinvolk/nebraska/backend/pkg/config" + "github.com/kinvolk/nebraska/backend/pkg/server" ) func TestHostFlatcarPackage(t *testing.T) { diff --git a/frontend/.storybook/NebraskaTheme.js b/frontend/.storybook/NebraskaTheme.js new file mode 100644 index 000000000..55f885894 --- /dev/null +++ b/frontend/.storybook/NebraskaTheme.js @@ -0,0 +1,12 @@ +// https://storybook.js.org/docs/react/configure/theming#create-a-theme-quickstart +// To workaround a bug at time of writing, where theme is not refreshed, +// you may need to `npm run storybook --no-manager-cache` +import { create } from '@storybook/theming'; +import logoUrl from '../../docs/nebraska-logo.svg'; + +export default create({ + base: 'light', + brandTitle: 'Nebraska is an update manager for Flatcar Container Linux and Kubernetes.', + brandUrl: 'https://kinvolk.io/docs/nebraska/latest/development/', + brandImage: logoUrl, +}); diff --git a/frontend/.storybook/main.js b/frontend/.storybook/main.js new file mode 100644 index 000000000..7e2f2b5d0 --- /dev/null +++ b/frontend/.storybook/main.js @@ -0,0 +1,8 @@ +module.exports = { + stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], + addons: [ + '@storybook/addon-links', + '@storybook/addon-essentials', + '@storybook/preset-create-react-app', + ], +}; diff --git a/frontend/.storybook/manager.js b/frontend/.storybook/manager.js new file mode 100644 index 000000000..aef93ce62 --- /dev/null +++ b/frontend/.storybook/manager.js @@ -0,0 +1,6 @@ +import { addons } from '@storybook/addons'; +import theme from './NebraskaTheme'; + +addons.setConfig({ + theme: theme, +}); diff --git a/frontend/.storybook/preview.js b/frontend/.storybook/preview.js new file mode 100644 index 000000000..14f8c0578 --- /dev/null +++ b/frontend/.storybook/preview.js @@ -0,0 +1,52 @@ +import React from 'react'; +import themesConf from '../src/lib/themes'; +import { StylesProvider } from '@material-ui/core/styles'; +import '../src/i18n/config'; +import ThemeProviderNexti18n from '../src/i18n/ThemeProviderNexti18n'; + +const darkTheme = themesConf['dark']; +const lightTheme = themesConf['light']; + +const withThemeProvider = (Story, context) => { + const backgroundColor = context.globals.backgrounds ? context.globals.backgrounds.value : 'light'; + const theme = backgroundColor !== 'dark' ? lightTheme : darkTheme; + + const ourThemeProvider = ( + + + + ); + if (process.env.NODE_ENV !== 'test') { + return ourThemeProvider; + } else { + const generateClassName = (rule, styleSheet) => + `${styleSheet?.options.classNamePrefix}-${rule.key}`; + + return ( + {ourThemeProvider} + ); + } +}; +export const decorators = [withThemeProvider]; + +export const globalTypes = { + theme: { + name: 'Theme', + description: 'Global theme for components', + defaultValue: 'light', + toolbar: { + icon: 'circlehollow', + items: ['light', 'dark'], + }, + }, +}; + +export const parameters = { + backgrounds: { + values: [ + { name: 'light', value: 'light' }, + { name: 'dark', value: 'dark' }, + ], + }, + actions: { argTypesRegex: '^on[A-Z].*' }, +}; diff --git a/frontend/Makefile b/frontend/Makefile index ca34f79ae..e0c12a1f3 100644 --- a/frontend/Makefile +++ b/frontend/Makefile @@ -21,7 +21,7 @@ build: install .PHONY: test test: - npm run test + npm run test -- --coverage .PHONY: lint lint: diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 59cbd222d..6eebbaba9 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -385,6 +385,24 @@ "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, + "@babel/plugin-proposal-export-default-from": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.14.5.tgz", + "integrity": "sha512-T8KZ5abXvKMjF6JcoXjgac3ElmXf0AWzJwi2O/42Jk+HmCky3D9+i1B7NPP1FblyceqTevKeV/9szeikFoaMDg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-export-default-from": "^7.14.5" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "dev": true + } + } + }, "@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", @@ -538,6 +556,23 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-export-default-from": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.14.5.tgz", + "integrity": "sha512-snWDxjuaPEobRBnhpqEfZ8RMxDbHt8+87fiEioGuE+Uc0xAKgSD8QiuL3lF93hPVQfZFAcYwrrf+H5qUhike3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "dev": true + } + } + }, "@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", @@ -1115,6 +1150,50 @@ } } }, + "@babel/preset-flow": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.14.5.tgz", + "integrity": "sha512-pP5QEb4qRUSVGzzKx9xqRuHUrM/jEzMqdrZpdMA+oUCRgd5zM1qGr5y5+ZgAL/1tVv1H0dyk5t4SKJntqyiVtg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-flow-strip-types": "^7.14.5" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true + }, + "@babel/plugin-syntax-flow": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.14.5.tgz", + "integrity": "sha512-9WK5ZwKCdWHxVuU13XNT6X73FGmutAXeor5lGFq6qhOFtMFUF4jkbijuyUdZZlpYq6E2hZeZf/u3959X9wsv0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-flow-strip-types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.14.5.tgz", + "integrity": "sha512-KhcolBKfXbvjwI3TV7r7TkYm8oNXHNBqGOy6JDVwtecFaRoKYsUUqJdS10q0YDKW1c6aZQgO+Ys3LfGkox8pXA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-flow": "^7.14.5" + } + } + } + }, "@babel/preset-modules": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", @@ -1149,6 +1228,19 @@ "@babel/plugin-transform-typescript": "^7.12.1" } }, + "@babel/register": { + "version": "7.15.3", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.15.3.tgz", + "integrity": "sha512-mj4IY1ZJkorClxKTImccn4T81+UKTo4Ux0+OFSV9hME1ooqS9UV+pJ6BjD0qXPK4T3XW/KNa79XByjeEMZz+fw==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "find-cache-dir": "^2.0.0", + "make-dir": "^2.1.0", + "pirates": "^4.0.0", + "source-map-support": "^0.5.16" + } + }, "@babel/runtime": { "version": "7.14.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", @@ -1200,6 +1292,12 @@ "to-fast-properties": "^2.0.0" } }, + "@base2/pretty-print-object": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@base2/pretty-print-object/-/pretty-print-object-1.0.0.tgz", + "integrity": "sha512-4Th98KlMHr5+JkxfcoDT//6vY8vM+iSPrLNpHhRyLx2CFYi8e2RfqPLdpbnpo0Q5lQC5hNB79yes07zb02fvCw==", + "dev": true + }, "@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", @@ -1224,11 +1322,134 @@ "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz", "integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg==" }, + "@discoveryjs/json-ext": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz", + "integrity": "sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA==", + "dev": true + }, + "@emotion/cache": { + "version": "10.0.29", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz", + "integrity": "sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==", + "dev": true, + "requires": { + "@emotion/sheet": "0.9.4", + "@emotion/stylis": "0.8.5", + "@emotion/utils": "0.11.3", + "@emotion/weak-memoize": "0.2.5" + } + }, + "@emotion/core": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.1.1.tgz", + "integrity": "sha512-ZMLG6qpXR8x031NXD8HJqugy/AZSkAuMxxqB46pmAR7ze47MhNJ56cdoX243QPZdGctrdfo+s08yZTiwaUcRKA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.5.5", + "@emotion/cache": "^10.0.27", + "@emotion/css": "^10.0.27", + "@emotion/serialize": "^0.11.15", + "@emotion/sheet": "0.9.4", + "@emotion/utils": "0.11.3" + } + }, + "@emotion/css": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/css/-/css-10.0.27.tgz", + "integrity": "sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw==", + "dev": true, + "requires": { + "@emotion/serialize": "^0.11.15", + "@emotion/utils": "0.11.3", + "babel-plugin-emotion": "^10.0.27" + } + }, "@emotion/hash": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" }, + "@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "dev": true, + "requires": { + "@emotion/memoize": "0.7.4" + } + }, + "@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "dev": true + }, + "@emotion/serialize": { + "version": "0.11.16", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz", + "integrity": "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==", + "dev": true, + "requires": { + "@emotion/hash": "0.8.0", + "@emotion/memoize": "0.7.4", + "@emotion/unitless": "0.7.5", + "@emotion/utils": "0.11.3", + "csstype": "^2.5.7" + } + }, + "@emotion/sheet": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-0.9.4.tgz", + "integrity": "sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA==", + "dev": true + }, + "@emotion/styled": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-10.0.27.tgz", + "integrity": "sha512-iK/8Sh7+NLJzyp9a5+vIQIXTYxfT4yB/OJbjzQanB2RZpvmzBQOHZWhpAMZWYEKRNNbsD6WfBw5sVWkb6WzS/Q==", + "dev": true, + "requires": { + "@emotion/styled-base": "^10.0.27", + "babel-plugin-emotion": "^10.0.27" + } + }, + "@emotion/styled-base": { + "version": "10.0.31", + "resolved": "https://registry.npmjs.org/@emotion/styled-base/-/styled-base-10.0.31.tgz", + "integrity": "sha512-wTOE1NcXmqMWlyrtwdkqg87Mu6Rj1MaukEoEmEkHirO5IoHDJ8LgCQL4MjJODgxWxXibGR3opGp1p7YvkNEdXQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.5.5", + "@emotion/is-prop-valid": "0.8.8", + "@emotion/serialize": "^0.11.15", + "@emotion/utils": "0.11.3" + } + }, + "@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==", + "dev": true + }, + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==", + "dev": true + }, + "@emotion/utils": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz", + "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==", + "dev": true + }, + "@emotion/weak-memoize": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", + "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==", + "dev": true + }, "@eslint/eslintrc": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.1.tgz", @@ -2580,6 +2801,113 @@ "react-is": "^16.8.0 || ^17.0.0" } }, + "@mdx-js/loader": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/@mdx-js/loader/-/loader-1.6.22.tgz", + "integrity": "sha512-9CjGwy595NaxAYp0hF9B/A0lH6C8Rms97e2JS9d3jVUtILn6pT5i5IV965ra3lIWc7Rs1GG1tBdVF7dCowYe6Q==", + "dev": true, + "requires": { + "@mdx-js/mdx": "1.6.22", + "@mdx-js/react": "1.6.22", + "loader-utils": "2.0.0" + } + }, + "@mdx-js/mdx": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz", + "integrity": "sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==", + "dev": true, + "requires": { + "@babel/core": "7.12.9", + "@babel/plugin-syntax-jsx": "7.12.1", + "@babel/plugin-syntax-object-rest-spread": "7.8.3", + "@mdx-js/util": "1.6.22", + "babel-plugin-apply-mdx-type-prop": "1.6.22", + "babel-plugin-extract-import-names": "1.6.22", + "camelcase-css": "2.0.1", + "detab": "2.0.4", + "hast-util-raw": "6.0.1", + "lodash.uniq": "4.5.0", + "mdast-util-to-hast": "10.0.1", + "remark-footnotes": "2.0.0", + "remark-mdx": "1.6.22", + "remark-parse": "8.0.3", + "remark-squeeze-paragraphs": "4.0.0", + "style-to-object": "0.3.0", + "unified": "9.2.0", + "unist-builder": "2.0.3", + "unist-util-visit": "2.0.3" + }, + "dependencies": { + "@babel/core": { + "version": "7.12.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz", + "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.5", + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helpers": "^7.12.5", + "@babel/parser": "^7.12.7", + "@babel/template": "^7.12.7", + "@babel/traverse": "^7.12.9", + "@babel/types": "^7.12.7", + "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" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", + "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@mdx-js/react": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz", + "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==", + "dev": true + }, + "@mdx-js/util": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.22.tgz", + "integrity": "sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==", + "dev": true + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + } + }, "@nodelib/fs.scandir": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", @@ -2639,6 +2967,24 @@ } } }, + "@popperjs/core": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.2.tgz", + "integrity": "sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ==", + "dev": true + }, + "@reach/router": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@reach/router/-/router-1.3.4.tgz", + "integrity": "sha512-+mtn9wjlB9NN2CNnnC/BRYtwdKBfSyyasPYraNAyvaV1occr/5NnB4CVzjEZipNHwYebQwcndGUmpFzxAUoqSA==", + "dev": true, + "requires": { + "create-react-context": "0.3.0", + "invariant": "^2.2.3", + "prop-types": "^15.6.1", + "react-lifecycles-compat": "^3.0.4" + } + }, "@reduxjs/toolkit": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.6.0.tgz", @@ -2711,126 +3057,3558 @@ "@sinonjs/commons": "^1.7.0" } }, - "@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==", - "requires": { - "ejs": "^2.6.1", - "magic-string": "^0.25.0" - } - }, - "@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==" - }, - "@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==" - }, - "@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==" - }, - "@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==" - }, - "@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==" - }, - "@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==" - }, - "@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==" - }, - "@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==" - }, - "@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==", - "requires": { - "@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" - } - }, - "@svgr/core": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", - "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "@storybook/addon-actions": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.3.12.tgz", + "integrity": "sha512-mzuN4Ano4eyicwycM2PueGzzUCAEzt9/6vyptWEIVJu0sjK0J9KtBRlqFi1xGQxmCfimDR/n/vWBBkc7fp2uJA==", + "dev": true, "requires": { - "@svgr/plugin-jsx": "^5.5.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^7.0.0" + "@storybook/addons": "6.3.12", + "@storybook/api": "6.3.12", + "@storybook/client-api": "6.3.12", + "@storybook/components": "6.3.12", + "@storybook/core-events": "6.3.12", + "@storybook/theming": "6.3.12", + "core-js": "^3.8.2", + "fast-deep-equal": "^3.1.3", + "global": "^4.4.0", + "lodash": "^4.17.20", + "polished": "^4.0.5", + "prop-types": "^15.7.2", + "react-inspector": "^5.1.0", + "regenerator-runtime": "^0.13.7", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2", + "uuid-browser": "^3.1.0" } }, - "@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==", + "@storybook/addon-backgrounds": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-6.3.12.tgz", + "integrity": "sha512-51cHBx0HV7K/oRofJ/1pE05qti6sciIo8m4iPred1OezXIrJ/ckzP+gApdaUdzgcLAr6/MXQWLk0sJuImClQ6w==", + "dev": true, "requires": { - "@babel/types": "^7.12.6" + "@storybook/addons": "6.3.12", + "@storybook/api": "6.3.12", + "@storybook/client-logger": "6.3.12", + "@storybook/components": "6.3.12", + "@storybook/core-events": "6.3.12", + "@storybook/theming": "6.3.12", + "core-js": "^3.8.2", + "global": "^4.4.0", + "memoizerific": "^1.11.3", + "regenerator-runtime": "^0.13.7", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" } }, - "@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==", + "@storybook/addon-controls": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-6.3.12.tgz", + "integrity": "sha512-WO/PbygE4sDg3BbstJ49q0uM3Xu5Nw4lnHR5N4hXSvRAulZt1d1nhphRTHjfX+CW+uBcfzkq9bksm6nKuwmOyw==", + "dev": true, "requires": { - "@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" + "@storybook/addons": "6.3.12", + "@storybook/api": "6.3.12", + "@storybook/client-api": "6.3.12", + "@storybook/components": "6.3.12", + "@storybook/node-logger": "6.3.12", + "@storybook/theming": "6.3.12", + "core-js": "^3.8.2", + "ts-dedent": "^2.0.0" } }, - "@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==", + "@storybook/addon-docs": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-6.3.12.tgz", + "integrity": "sha512-iUrqJBMTOn2PgN8AWNQkfxfIPkh8pEg27t8UndMgfOpeGK/VWGw2UEifnA82flvntcilT4McxmVbRHkeBY9K5A==", + "dev": true, "requires": { - "cosmiconfig": "^7.0.0", - "deepmerge": "^4.2.2", - "svgo": "^1.2.2" + "@babel/core": "^7.12.10", + "@babel/generator": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/plugin-transform-react-jsx": "^7.12.12", + "@babel/preset-env": "^7.12.11", + "@jest/transform": "^26.6.2", + "@mdx-js/loader": "^1.6.22", + "@mdx-js/mdx": "^1.6.22", + "@mdx-js/react": "^1.6.22", + "@storybook/addons": "6.3.12", + "@storybook/api": "6.3.12", + "@storybook/builder-webpack4": "6.3.12", + "@storybook/client-api": "6.3.12", + "@storybook/client-logger": "6.3.12", + "@storybook/components": "6.3.12", + "@storybook/core": "6.3.12", + "@storybook/core-events": "6.3.12", + "@storybook/csf": "0.0.1", + "@storybook/csf-tools": "6.3.12", + "@storybook/node-logger": "6.3.12", + "@storybook/postinstall": "6.3.12", + "@storybook/source-loader": "6.3.12", + "@storybook/theming": "6.3.12", + "acorn": "^7.4.1", + "acorn-jsx": "^5.3.1", + "acorn-walk": "^7.2.0", + "core-js": "^3.8.2", + "doctrine": "^3.0.0", + "escodegen": "^2.0.0", + "fast-deep-equal": "^3.1.3", + "global": "^4.4.0", + "html-tags": "^3.1.0", + "js-string-escape": "^1.0.1", + "loader-utils": "^2.0.0", + "lodash": "^4.17.20", + "p-limit": "^3.1.0", + "prettier": "~2.2.1", + "prop-types": "^15.7.2", + "react-element-to-jsx-string": "^14.3.2", + "regenerator-runtime": "^0.13.7", + "remark-external-links": "^8.0.0", + "remark-slug": "^6.0.0", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" }, "dependencies": { - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" - } - } - }, - "@svgr/webpack": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", - "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", - "requires": { - "@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", + "@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/compat-data": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "dev": true + }, + "@babel/core": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", + "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.15.8", + "@babel/generator": "^7.15.8", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.8", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.8", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/generator": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", + "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", + "dev": true, + "requires": { + "@babel/types": "^7.15.6", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", + "dev": true + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", + "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + } + }, + "@babel/helper-function-name": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", + "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", + "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", + "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", + "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-module-imports": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", + "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", + "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", + "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-replace-supers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", + "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", + "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", + "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true + }, + "@babel/helpers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "dev": true, + "requires": { + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/template": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "dependencies": { + "@babel/parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", + "dev": true + } + } + }, + "@babel/traverse": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", + "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/generator": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", + "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", + "dev": true, + "requires": { + "@babel/types": "^7.15.6", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.15.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", + "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.9", + "to-fast-properties": "^2.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@storybook/addon-essentials": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-6.3.12.tgz", + "integrity": "sha512-PK0pPE0xkq00kcbBcFwu/5JGHQTu4GvLIHfwwlEGx6GWNQ05l6Q+1Z4nE7xJGv2PSseSx3CKcjn8qykNLe6O6g==", + "dev": true, + "requires": { + "@storybook/addon-actions": "6.3.12", + "@storybook/addon-backgrounds": "6.3.12", + "@storybook/addon-controls": "6.3.12", + "@storybook/addon-docs": "6.3.12", + "@storybook/addon-measure": "^2.0.0", + "@storybook/addon-toolbars": "6.3.12", + "@storybook/addon-viewport": "6.3.12", + "@storybook/addons": "6.3.12", + "@storybook/api": "6.3.12", + "@storybook/node-logger": "6.3.12", + "core-js": "^3.8.2", + "regenerator-runtime": "^0.13.7", + "storybook-addon-outline": "^1.4.1", + "ts-dedent": "^2.0.0" + } + }, + "@storybook/addon-links": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-6.3.12.tgz", + "integrity": "sha512-NfOGEm0+QxIrAXCa05LOXmxLtI+RlcDqHXZ1jNNj8mjeRoG1nX3qhkB8PWWIBbPuz+bktLV9ox8UZj0W6+ZPOQ==", + "dev": true, + "requires": { + "@storybook/addons": "6.3.12", + "@storybook/client-logger": "6.3.12", + "@storybook/core-events": "6.3.12", + "@storybook/csf": "0.0.1", + "@storybook/router": "6.3.12", + "@types/qs": "^6.9.5", + "core-js": "^3.8.2", + "global": "^4.4.0", + "prop-types": "^15.7.2", + "qs": "^6.10.0", + "regenerator-runtime": "^0.13.7", + "ts-dedent": "^2.0.0" + }, + "dependencies": { + "qs": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + } + } + }, + "@storybook/addon-measure": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-2.0.0.tgz", + "integrity": "sha512-ZhdT++cX+L9LwjhGYggvYUUVQH/MGn2rwbrAwCMzA/f2QTFvkjxzX8nDgMxIhaLCDC+gHIxfJG2wrWN0jkBr3g==", + "dev": true + }, + "@storybook/addon-storyshots": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-storyshots/-/addon-storyshots-6.3.12.tgz", + "integrity": "sha512-plpy/q3pPpXtK9DyofE0trTeCZIyU0Z+baybbxltsM/tKFuQxbHSxTwgluq/7LOMkaRPgbddGyHForHoRLjsWg==", + "dev": true, + "requires": { + "@jest/transform": "^26.6.2", + "@storybook/addons": "6.3.12", + "@storybook/client-api": "6.3.12", + "@storybook/core": "6.3.12", + "@storybook/core-common": "6.3.12", + "@types/glob": "^7.1.3", + "@types/jest": "^26.0.16", + "@types/jest-specific-snapshot": "^0.5.3", + "babel-plugin-require-context-hook": "^1.0.0", + "core-js": "^3.8.2", + "glob": "^7.1.6", + "global": "^4.4.0", + "jest-specific-snapshot": "^4.0.0", + "preact-render-to-string": "^5.1.19", + "pretty-format": "^26.6.2", + "react-test-renderer": "^16.8.0 || ^17.0.0", + "read-pkg-up": "^7.0.1", + "regenerator-runtime": "^0.13.7", + "ts-dedent": "^2.0.0" + }, + "dependencies": { + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "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==", + "dev": true + } + } + }, + "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==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "@storybook/addon-toolbars": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-6.3.12.tgz", + "integrity": "sha512-8GvP6zmAfLPRnYRARSaIwLkQClLIRbflRh4HZoFk6IMjQLXZb4NL3JS5OLFKG+HRMMU2UQzfoSDqjI7k7ptyRw==", + "dev": true, + "requires": { + "@storybook/addons": "6.3.12", + "@storybook/api": "6.3.12", + "@storybook/client-api": "6.3.12", + "@storybook/components": "6.3.12", + "@storybook/theming": "6.3.12", + "core-js": "^3.8.2", + "regenerator-runtime": "^0.13.7" + } + }, + "@storybook/addon-viewport": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-6.3.12.tgz", + "integrity": "sha512-TRjyfm85xouOPmXxeLdEIzXLfJZZ1ePQ7p/5yphDGBHdxMU4m4qiZr8wYpUaxHsRu/UB3dKfaOyGT+ivogbnbw==", + "dev": true, + "requires": { + "@storybook/addons": "6.3.12", + "@storybook/api": "6.3.12", + "@storybook/client-logger": "6.3.12", + "@storybook/components": "6.3.12", + "@storybook/core-events": "6.3.12", + "@storybook/theming": "6.3.12", + "core-js": "^3.8.2", + "global": "^4.4.0", + "memoizerific": "^1.11.3", + "prop-types": "^15.7.2", + "regenerator-runtime": "^0.13.7" + } + }, + "@storybook/addons": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-6.3.12.tgz", + "integrity": "sha512-UgoMyr7Qr0FS3ezt8u6hMEcHgyynQS9ucr5mAwZky3wpXRPFyUTmMto9r4BBUdqyUvTUj/LRKIcmLBfj+/l0Fg==", + "dev": true, + "requires": { + "@storybook/api": "6.3.12", + "@storybook/channels": "6.3.12", + "@storybook/client-logger": "6.3.12", + "@storybook/core-events": "6.3.12", + "@storybook/router": "6.3.12", + "@storybook/theming": "6.3.12", + "core-js": "^3.8.2", + "global": "^4.4.0", + "regenerator-runtime": "^0.13.7" + } + }, + "@storybook/api": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/api/-/api-6.3.12.tgz", + "integrity": "sha512-LScRXUeCWEW/OP+jiooNMQICVdusv7azTmULxtm72fhkXFRiQs2CdRNTiqNg46JLLC9z95f1W+pGK66X6HiiQA==", + "dev": true, + "requires": { + "@reach/router": "^1.3.4", + "@storybook/channels": "6.3.12", + "@storybook/client-logger": "6.3.12", + "@storybook/core-events": "6.3.12", + "@storybook/csf": "0.0.1", + "@storybook/router": "6.3.12", + "@storybook/semver": "^7.3.2", + "@storybook/theming": "6.3.12", + "@types/reach__router": "^1.3.7", + "core-js": "^3.8.2", + "fast-deep-equal": "^3.1.3", + "global": "^4.4.0", + "lodash": "^4.17.20", + "memoizerific": "^1.11.3", + "qs": "^6.10.0", + "regenerator-runtime": "^0.13.7", + "store2": "^2.12.0", + "telejson": "^5.3.2", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + }, + "dependencies": { + "@storybook/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@storybook/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg==", + "dev": true, + "requires": { + "core-js": "^3.6.5", + "find-up": "^4.1.0" + } + }, + "qs": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + } + } + }, + "@storybook/builder-webpack4": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/builder-webpack4/-/builder-webpack4-6.3.12.tgz", + "integrity": "sha512-Dlm5Fc1svqpFDnVPZdAaEBiM/IDZHMV3RfEGbUTY/ZC0q8b/Ug1czzp/w0aTIjOFRuBDcG6IcplikaqHL8CJLg==", + "dev": true, + "requires": { + "@babel/core": "^7.12.10", + "@babel/plugin-proposal-class-properties": "^7.12.1", + "@babel/plugin-proposal-decorators": "^7.12.12", + "@babel/plugin-proposal-export-default-from": "^7.12.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", + "@babel/plugin-proposal-object-rest-spread": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.12.7", + "@babel/plugin-proposal-private-methods": "^7.12.1", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-arrow-functions": "^7.12.1", + "@babel/plugin-transform-block-scoping": "^7.12.12", + "@babel/plugin-transform-classes": "^7.12.1", + "@babel/plugin-transform-destructuring": "^7.12.1", + "@babel/plugin-transform-for-of": "^7.12.1", + "@babel/plugin-transform-parameters": "^7.12.1", + "@babel/plugin-transform-shorthand-properties": "^7.12.1", + "@babel/plugin-transform-spread": "^7.12.1", + "@babel/plugin-transform-template-literals": "^7.12.1", + "@babel/preset-env": "^7.12.11", + "@babel/preset-react": "^7.12.10", + "@babel/preset-typescript": "^7.12.7", + "@storybook/addons": "6.3.12", + "@storybook/api": "6.3.12", + "@storybook/channel-postmessage": "6.3.12", + "@storybook/channels": "6.3.12", + "@storybook/client-api": "6.3.12", + "@storybook/client-logger": "6.3.12", + "@storybook/components": "6.3.12", + "@storybook/core-common": "6.3.12", + "@storybook/core-events": "6.3.12", + "@storybook/node-logger": "6.3.12", + "@storybook/router": "6.3.12", + "@storybook/semver": "^7.3.2", + "@storybook/theming": "6.3.12", + "@storybook/ui": "6.3.12", + "@types/node": "^14.0.10", + "@types/webpack": "^4.41.26", + "autoprefixer": "^9.8.6", + "babel-loader": "^8.2.2", + "babel-plugin-macros": "^2.8.0", + "babel-plugin-polyfill-corejs3": "^0.1.0", + "case-sensitive-paths-webpack-plugin": "^2.3.0", + "core-js": "^3.8.2", + "css-loader": "^3.6.0", + "dotenv-webpack": "^1.8.0", + "file-loader": "^6.2.0", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^4.1.6", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "glob-promise": "^3.4.0", + "global": "^4.4.0", + "html-webpack-plugin": "^4.0.0", + "pnp-webpack-plugin": "1.6.4", + "postcss": "^7.0.36", + "postcss-flexbugs-fixes": "^4.2.1", + "postcss-loader": "^4.2.0", + "raw-loader": "^4.0.2", + "react-dev-utils": "^11.0.3", + "stable": "^0.1.8", + "style-loader": "^1.3.0", + "terser-webpack-plugin": "^4.2.3", + "ts-dedent": "^2.0.0", + "url-loader": "^4.1.1", + "util-deprecate": "^1.0.2", + "webpack": "4", + "webpack-dev-middleware": "^3.7.3", + "webpack-filter-warnings-plugin": "^1.2.1", + "webpack-hot-middleware": "^2.25.0", + "webpack-virtual-modules": "^0.2.2" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/compat-data": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "dev": true + }, + "@babel/core": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", + "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.15.8", + "@babel/generator": "^7.15.8", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.8", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.8", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", + "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", + "dev": true, + "requires": { + "@babel/types": "^7.15.6", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz", + "integrity": "sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", + "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.4.tgz", + "integrity": "sha512-7ZmzFi+DwJx6A7mHRwbuucEYpyBwmh2Ca0RvI6z2+WLZYCqV0JOaLb+u0zbtmDicebgKBZgqbYfLaKNqSgv5Pw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4" + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz", + "integrity": "sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg==", + "dev": true, + "requires": { + "@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" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/helper-function-name": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", + "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", + "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", + "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", + "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-module-imports": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", + "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", + "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", + "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", + "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", + "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", + "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true + }, + "@babel/helpers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "dev": true, + "requires": { + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", + "dev": true + }, + "@babel/plugin-proposal-decorators": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.15.8.tgz", + "integrity": "sha512-5n8+xGK7YDrXF+WAORg3P7LlCCdiaAyKLZi22eP2BwTy4kJ0kFUMMDCj4nQ8YrKyNZgjhU/9eRVqONnjB3us8g==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-decorators": "^7.14.5" + } + }, + "@babel/plugin-syntax-decorators": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.14.5.tgz", + "integrity": "sha512-c4sZMRWL4GSvP1EXy0woIP7m4jkVcEuG8R1TOZxPBPtp4FSM/kiPZub9UIs/Jrb5ZAOzvTUSGYrWsrSu1JvoPw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", + "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.8.tgz", + "integrity": "sha512-ZXIkJpbaf6/EsmjeTbiJN/yMxWPFWvlr7sEG1P95Xb4S4IBcrf2n7s/fItIhsAmOf8oSh3VJPDppO6ExfAfKRQ==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-typescript": "^7.14.5" + } + }, + "@babel/preset-typescript": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.15.0.tgz", + "integrity": "sha512-lt0Y/8V3y06Wq/8H/u0WakrqciZ7Fz7mwPDHWUJAXlABL5hiUG42BNlRXiELNjeWjO5rWmnNKlx+yzJvxezHow==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-typescript": "^7.15.0" + } + }, + "@babel/template": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/traverse": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", + "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.15.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", + "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.9", + "to-fast-properties": "^2.0.0" + } + }, + "@storybook/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@storybook/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg==", + "dev": true, + "requires": { + "core-js": "^3.6.5", + "find-up": "^4.1.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + } + } + }, + "@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "babel-loader": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz", + "integrity": "sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g==", + "dev": true, + "requires": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^1.4.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz", + "integrity": "sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.1.5", + "core-js-compat": "^3.8.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "css-loader": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", + "integrity": "sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "cssesc": "^3.0.0", + "icss-utils": "^4.1.1", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.32", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^3.0.2", + "postcss-modules-scope": "^2.2.0", + "postcss-modules-values": "^3.0.0", + "postcss-value-parser": "^4.1.0", + "schema-utils": "^2.7.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "dependencies": { + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + } + } + }, + "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==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "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==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + } + } + }, + "postcss-loader": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-4.3.0.tgz", + "integrity": "sha512-M/dSoIiNDOo8Rk0mUqoj4kpGq91gcxCfb9PoyZVdZ76/AuhxylHDYZblNE8o+EQ9AMSASeMFEKxZf5aU6wlx1Q==", + "dev": true, + "requires": { + "cosmiconfig": "^7.0.0", + "klona": "^2.0.4", + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0", + "semver": "^7.3.4" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@storybook/channel-postmessage": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.3.12.tgz", + "integrity": "sha512-Ou/2Ga3JRTZ/4sSv7ikMgUgLTeZMsXXWLXuscz4oaYhmOqAU9CrJw0G1NitwBgK/+qC83lEFSLujHkWcoQDOKg==", + "dev": true, + "requires": { + "@storybook/channels": "6.3.12", + "@storybook/client-logger": "6.3.12", + "@storybook/core-events": "6.3.12", + "core-js": "^3.8.2", + "global": "^4.4.0", + "qs": "^6.10.0", + "telejson": "^5.3.2" + }, + "dependencies": { + "qs": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + } + } + }, + "@storybook/channels": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.3.12.tgz", + "integrity": "sha512-l4sA+g1PdUV8YCbgs47fIKREdEQAKNdQIZw0b7BfTvY9t0x5yfBywgQhYON/lIeiNGz2OlIuD+VUtqYfCtNSyw==", + "dev": true, + "requires": { + "core-js": "^3.8.2", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + } + }, + "@storybook/client-api": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.3.12.tgz", + "integrity": "sha512-xnW+lKKK2T774z+rOr9Wopt1aYTStfb86PSs9p3Fpnc2Btcftln+C3NtiHZl8Ccqft8Mz/chLGgewRui6tNI8g==", + "dev": true, + "requires": { + "@storybook/addons": "6.3.12", + "@storybook/channel-postmessage": "6.3.12", + "@storybook/channels": "6.3.12", + "@storybook/client-logger": "6.3.12", + "@storybook/core-events": "6.3.12", + "@storybook/csf": "0.0.1", + "@types/qs": "^6.9.5", + "@types/webpack-env": "^1.16.0", + "core-js": "^3.8.2", + "global": "^4.4.0", + "lodash": "^4.17.20", + "memoizerific": "^1.11.3", + "qs": "^6.10.0", + "regenerator-runtime": "^0.13.7", + "stable": "^0.1.8", + "store2": "^2.12.0", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + }, + "dependencies": { + "qs": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + } + } + }, + "@storybook/client-logger": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.3.12.tgz", + "integrity": "sha512-zNDsamZvHnuqLznDdP9dUeGgQ9TyFh4ray3t1VGO7ZqWVZ2xtVCCXjDvMnOXI2ifMpX5UsrOvshIPeE9fMBmiQ==", + "dev": true, + "requires": { + "core-js": "^3.8.2", + "global": "^4.4.0" + } + }, + "@storybook/components": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-6.3.12.tgz", + "integrity": "sha512-kdQt8toUjynYAxDLrJzuG7YSNL6as1wJoyzNUaCfG06YPhvIAlKo7le9tS2mThVFN5e9nbKrW3N1V1sp6ypZXQ==", + "dev": true, + "requires": { + "@popperjs/core": "^2.6.0", + "@storybook/client-logger": "6.3.12", + "@storybook/csf": "0.0.1", + "@storybook/theming": "6.3.12", + "@types/color-convert": "^2.0.0", + "@types/overlayscrollbars": "^1.12.0", + "@types/react-syntax-highlighter": "11.0.5", + "color-convert": "^2.0.1", + "core-js": "^3.8.2", + "fast-deep-equal": "^3.1.3", + "global": "^4.4.0", + "lodash": "^4.17.20", + "markdown-to-jsx": "^7.1.3", + "memoizerific": "^1.11.3", + "overlayscrollbars": "^1.13.1", + "polished": "^4.0.5", + "prop-types": "^15.7.2", + "react-colorful": "^5.1.2", + "react-popper-tooltip": "^3.1.1", + "react-syntax-highlighter": "^13.5.3", + "react-textarea-autosize": "^8.3.0", + "regenerator-runtime": "^0.13.7", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2" + }, + "dependencies": { + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "@storybook/core": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-6.3.12.tgz", + "integrity": "sha512-FJm2ns8wk85hXWKslLWiUWRWwS9KWRq7jlkN6M9p57ghFseSGr4W71Orcoab4P3M7jI97l5yqBfppbscinE74g==", + "dev": true, + "requires": { + "@storybook/core-client": "6.3.12", + "@storybook/core-server": "6.3.12" + } + }, + "@storybook/core-client": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/core-client/-/core-client-6.3.12.tgz", + "integrity": "sha512-8Smd9BgZHJpAdevLKQYinwtjSyCZAuBMoetP4P5hnn53mWl0NFbrHFaAdT+yNchDLZQUbf7Y18VmIqEH+RCR5w==", + "dev": true, + "requires": { + "@storybook/addons": "6.3.12", + "@storybook/channel-postmessage": "6.3.12", + "@storybook/client-api": "6.3.12", + "@storybook/client-logger": "6.3.12", + "@storybook/core-events": "6.3.12", + "@storybook/csf": "0.0.1", + "@storybook/ui": "6.3.12", + "airbnb-js-shims": "^2.2.1", + "ansi-to-html": "^0.6.11", + "core-js": "^3.8.2", + "global": "^4.4.0", + "lodash": "^4.17.20", + "qs": "^6.10.0", + "regenerator-runtime": "^0.13.7", + "ts-dedent": "^2.0.0", + "unfetch": "^4.2.0", + "util-deprecate": "^1.0.2" + }, + "dependencies": { + "qs": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + } + } + }, + "@storybook/core-common": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-6.3.12.tgz", + "integrity": "sha512-xlHs2QXELq/moB4MuXjYOczaxU64BIseHsnFBLyboJYN6Yso3qihW5RB7cuJlGohkjb4JwY74dvfT4Ww66rkBA==", + "dev": true, + "requires": { + "@babel/core": "^7.12.10", + "@babel/plugin-proposal-class-properties": "^7.12.1", + "@babel/plugin-proposal-decorators": "^7.12.12", + "@babel/plugin-proposal-export-default-from": "^7.12.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", + "@babel/plugin-proposal-object-rest-spread": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.12.7", + "@babel/plugin-proposal-private-methods": "^7.12.1", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-arrow-functions": "^7.12.1", + "@babel/plugin-transform-block-scoping": "^7.12.12", + "@babel/plugin-transform-classes": "^7.12.1", + "@babel/plugin-transform-destructuring": "^7.12.1", + "@babel/plugin-transform-for-of": "^7.12.1", + "@babel/plugin-transform-parameters": "^7.12.1", + "@babel/plugin-transform-shorthand-properties": "^7.12.1", + "@babel/plugin-transform-spread": "^7.12.1", + "@babel/preset-env": "^7.12.11", + "@babel/preset-react": "^7.12.10", + "@babel/preset-typescript": "^7.12.7", + "@babel/register": "^7.12.1", + "@storybook/node-logger": "6.3.12", + "@storybook/semver": "^7.3.2", + "@types/glob-base": "^0.3.0", + "@types/micromatch": "^4.0.1", + "@types/node": "^14.0.10", + "@types/pretty-hrtime": "^1.0.0", + "babel-loader": "^8.2.2", + "babel-plugin-macros": "^3.0.1", + "babel-plugin-polyfill-corejs3": "^0.1.0", + "chalk": "^4.1.0", + "core-js": "^3.8.2", + "express": "^4.17.1", + "file-system-cache": "^1.0.5", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.0.4", + "glob": "^7.1.6", + "glob-base": "^0.3.0", + "interpret": "^2.2.0", + "json5": "^2.1.3", + "lazy-universal-dotenv": "^3.0.1", + "micromatch": "^4.0.2", + "pkg-dir": "^5.0.0", + "pretty-hrtime": "^1.0.3", + "resolve-from": "^5.0.0", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2", + "webpack": "4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/compat-data": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "dev": true + }, + "@babel/core": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", + "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.15.8", + "@babel/generator": "^7.15.8", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.8", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.8", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", + "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", + "dev": true, + "requires": { + "@babel/types": "^7.15.6", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz", + "integrity": "sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", + "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.4.tgz", + "integrity": "sha512-7ZmzFi+DwJx6A7mHRwbuucEYpyBwmh2Ca0RvI6z2+WLZYCqV0JOaLb+u0zbtmDicebgKBZgqbYfLaKNqSgv5Pw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4" + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz", + "integrity": "sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg==", + "dev": true, + "requires": { + "@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" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/helper-function-name": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", + "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", + "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", + "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", + "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-module-imports": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", + "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", + "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", + "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", + "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", + "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", + "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true + }, + "@babel/helpers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "dev": true, + "requires": { + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "@babel/parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", + "dev": true + }, + "@babel/plugin-proposal-decorators": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.15.8.tgz", + "integrity": "sha512-5n8+xGK7YDrXF+WAORg3P7LlCCdiaAyKLZi22eP2BwTy4kJ0kFUMMDCj4nQ8YrKyNZgjhU/9eRVqONnjB3us8g==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-decorators": "^7.14.5" + } + }, + "@babel/plugin-syntax-decorators": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.14.5.tgz", + "integrity": "sha512-c4sZMRWL4GSvP1EXy0woIP7m4jkVcEuG8R1TOZxPBPtp4FSM/kiPZub9UIs/Jrb5ZAOzvTUSGYrWsrSu1JvoPw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", + "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.8.tgz", + "integrity": "sha512-ZXIkJpbaf6/EsmjeTbiJN/yMxWPFWvlr7sEG1P95Xb4S4IBcrf2n7s/fItIhsAmOf8oSh3VJPDppO6ExfAfKRQ==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-typescript": "^7.14.5" + } + }, + "@babel/preset-typescript": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.15.0.tgz", + "integrity": "sha512-lt0Y/8V3y06Wq/8H/u0WakrqciZ7Fz7mwPDHWUJAXlABL5hiUG42BNlRXiELNjeWjO5rWmnNKlx+yzJvxezHow==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-typescript": "^7.15.0" + } + }, + "@babel/template": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/traverse": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", + "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.15.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", + "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.9", + "to-fast-properties": "^2.0.0" + } + }, + "@storybook/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@storybook/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg==", + "dev": true, + "requires": { + "core-js": "^3.6.5", + "find-up": "^4.1.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + } + } + }, + "babel-loader": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz", + "integrity": "sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g==", + "dev": true, + "requires": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^1.4.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + } + }, + "babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz", + "integrity": "sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.1.5", + "core-js-compat": "^3.8.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + } + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "dependencies": { + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + } + } + }, + "fork-ts-checker-webpack-plugin": { + "version": "6.3.4", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.3.4.tgz", + "integrity": "sha512-z0dns2NXH9NHH0wpW6iuUmyXYRN9BI2Lqnv+RCdL+9GXSW6tKUqYnwf+h3ZaucJsbsrdobdxuOELGgm1xVZITA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "requires": { + "@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" + } + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + } + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "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==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "pkg-dir": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "dev": true, + "requires": { + "find-up": "^5.0.0" + } + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@storybook/core-events": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.3.12.tgz", + "integrity": "sha512-SXfD7xUUMazaeFkB92qOTUV8Y/RghE4SkEYe5slAdjeocSaH7Nz2WV0rqNEgChg0AQc+JUI66no8L9g0+lw4Gw==", + "dev": true, + "requires": { + "core-js": "^3.8.2" + } + }, + "@storybook/core-server": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-6.3.12.tgz", + "integrity": "sha512-T/Mdyi1FVkUycdyOnhXvoo3d9nYXLQFkmaJkltxBFLzAePAJUSgAsPL9odNC3+p8Nr2/UDsDzvu/Ow0IF0mzLQ==", + "dev": true, + "requires": { + "@discoveryjs/json-ext": "^0.5.3", + "@storybook/builder-webpack4": "6.3.12", + "@storybook/core-client": "6.3.12", + "@storybook/core-common": "6.3.12", + "@storybook/csf-tools": "6.3.12", + "@storybook/manager-webpack4": "6.3.12", + "@storybook/node-logger": "6.3.12", + "@storybook/semver": "^7.3.2", + "@types/node": "^14.0.10", + "@types/node-fetch": "^2.5.7", + "@types/pretty-hrtime": "^1.0.0", + "@types/webpack": "^4.41.26", + "better-opn": "^2.1.1", + "boxen": "^4.2.0", + "chalk": "^4.1.0", + "cli-table3": "0.6.0", + "commander": "^6.2.1", + "compression": "^1.7.4", + "core-js": "^3.8.2", + "cpy": "^8.1.1", + "detect-port": "^1.3.0", + "express": "^4.17.1", + "file-system-cache": "^1.0.5", + "fs-extra": "^9.0.1", + "globby": "^11.0.2", + "ip": "^1.1.5", + "node-fetch": "^2.6.1", + "pretty-hrtime": "^1.0.3", + "prompts": "^2.4.0", + "regenerator-runtime": "^0.13.7", + "serve-favicon": "^2.5.0", + "ts-dedent": "^2.0.0", + "util-deprecate": "^1.0.2", + "webpack": "4" + }, + "dependencies": { + "@storybook/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@storybook/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg==", + "dev": true, + "requires": { + "core-js": "^3.6.5", + "find-up": "^4.1.0" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "detect-port": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", + "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", + "dev": true, + "requires": { + "address": "^1.0.1", + "debug": "^2.6.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@storybook/csf": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.1.tgz", + "integrity": "sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, + "@storybook/csf-tools": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-6.3.12.tgz", + "integrity": "sha512-wNrX+99ajAXxLo0iRwrqw65MLvCV6SFC0XoPLYrtBvyKr+hXOOnzIhO2f5BNEii8velpC2gl2gcLKeacpVYLqA==", + "dev": true, + "requires": { + "@babel/generator": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/plugin-transform-react-jsx": "^7.12.12", + "@babel/preset-env": "^7.12.11", + "@babel/traverse": "^7.12.11", + "@babel/types": "^7.12.11", + "@mdx-js/mdx": "^1.6.22", + "@storybook/csf": "^0.0.1", + "core-js": "^3.8.2", + "fs-extra": "^9.0.1", + "js-string-escape": "^1.0.1", + "lodash": "^4.17.20", + "prettier": "~2.2.1", + "regenerator-runtime": "^0.13.7" + }, + "dependencies": { + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + } + } + }, + "@storybook/manager-webpack4": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/manager-webpack4/-/manager-webpack4-6.3.12.tgz", + "integrity": "sha512-OkPYNrHXg2yZfKmEfTokP6iKx4OLTr0gdI5yehi/bLEuQCSHeruxBc70Dxm1GBk1Mrf821wD9WqMXNDjY5Qtug==", + "dev": true, + "requires": { + "@babel/core": "^7.12.10", + "@babel/plugin-transform-template-literals": "^7.12.1", + "@babel/preset-react": "^7.12.10", + "@storybook/addons": "6.3.12", + "@storybook/core-client": "6.3.12", + "@storybook/core-common": "6.3.12", + "@storybook/node-logger": "6.3.12", + "@storybook/theming": "6.3.12", + "@storybook/ui": "6.3.12", + "@types/node": "^14.0.10", + "@types/webpack": "^4.41.26", + "babel-loader": "^8.2.2", + "case-sensitive-paths-webpack-plugin": "^2.3.0", + "chalk": "^4.1.0", + "core-js": "^3.8.2", + "css-loader": "^3.6.0", + "dotenv-webpack": "^1.8.0", + "express": "^4.17.1", + "file-loader": "^6.2.0", + "file-system-cache": "^1.0.5", + "find-up": "^5.0.0", + "fs-extra": "^9.0.1", + "html-webpack-plugin": "^4.0.0", + "node-fetch": "^2.6.1", + "pnp-webpack-plugin": "1.6.4", + "read-pkg-up": "^7.0.1", + "regenerator-runtime": "^0.13.7", + "resolve-from": "^5.0.0", + "style-loader": "^1.3.0", + "telejson": "^5.3.2", + "terser-webpack-plugin": "^4.2.3", + "ts-dedent": "^2.0.0", + "url-loader": "^4.1.1", + "util-deprecate": "^1.0.2", + "webpack": "4", + "webpack-dev-middleware": "^3.7.3", + "webpack-virtual-modules": "^0.2.2" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/compat-data": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "dev": true + }, + "@babel/core": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", + "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.15.8", + "@babel/generator": "^7.15.8", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.8", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.8", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", + "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", + "dev": true, + "requires": { + "@babel/types": "^7.15.6", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", + "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + } + }, + "@babel/helper-function-name": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", + "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", + "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", + "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", + "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-module-imports": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", + "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", + "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", + "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-replace-supers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", + "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", + "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", + "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true + }, + "@babel/helpers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "dev": true, + "requires": { + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "@babel/parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", + "dev": true + }, + "@babel/template": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/traverse": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", + "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.15.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", + "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.9", + "to-fast-properties": "^2.0.0" + } + }, + "@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "babel-loader": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz", + "integrity": "sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g==", + "dev": true, + "requires": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^1.4.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "css-loader": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", + "integrity": "sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "cssesc": "^3.0.0", + "icss-utils": "^4.1.1", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.32", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^3.0.2", + "postcss-modules-scope": "^2.2.0", + "postcss-modules-values": "^3.0.0", + "postcss-value-parser": "^4.1.0", + "schema-utils": "^2.7.0", + "semver": "^6.3.0" + } + }, + "file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "dependencies": { + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + } + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "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==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + } + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "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==", + "dev": true + } + } + }, + "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==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + } + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "@storybook/node-logger": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-6.3.12.tgz", + "integrity": "sha512-iktOem/Ls2+dsZY9PhPeC6T1QhX/y7OInP88neLsqEPEbB2UXca3Ydv7OZBhBVbvN25W45b05MRzbtNUxYLNRw==", + "dev": true, + "requires": { + "@types/npmlog": "^4.1.2", + "chalk": "^4.1.0", + "core-js": "^3.8.2", + "npmlog": "^4.1.2", + "pretty-hrtime": "^1.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@storybook/postinstall": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-6.3.12.tgz", + "integrity": "sha512-HkZ+abtZ3W6JbGPS6K7OSnNXbwaTwNNd5R02kRs4gV9B29XsBPDtFT6vIwzM3tmVQC7ihL5a8ceWp2OvzaNOuw==", + "dev": true, + "requires": { + "core-js": "^3.8.2" + } + }, + "@storybook/preset-create-react-app": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@storybook/preset-create-react-app/-/preset-create-react-app-3.2.0.tgz", + "integrity": "sha512-lLoWCGr5cV+JNDRKYHC2gD+P2eyBqdN8qhmBa+PxDgPSNKfgUf9Wnoh+C7WTG5q2DEeR9SvUpQpZomX9DDQa4Q==", + "dev": true, + "requires": { + "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3", + "@types/babel__core": "^7.1.7", + "@types/webpack": "^4.41.13", + "babel-plugin-react-docgen": "^4.1.0", + "pnp-webpack-plugin": "^1.6.4", + "react-docgen-typescript-plugin": "^1.0.0", + "semver": "^7.3.5" + } + }, + "@storybook/react": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-6.3.12.tgz", + "integrity": "sha512-c1Y/3/eNzye+ZRwQ3BXJux6pUMVt3lhv1/M9Qagl9JItP3jDSj5Ed3JHCgwEqpprP8mvNNXwEJ8+M7vEQyDuHg==", + "dev": true, + "requires": { + "@babel/preset-flow": "^7.12.1", + "@babel/preset-react": "^7.12.10", + "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3", + "@storybook/addons": "6.3.12", + "@storybook/core": "6.3.12", + "@storybook/core-common": "6.3.12", + "@storybook/node-logger": "6.3.12", + "@storybook/react-docgen-typescript-plugin": "1.0.2-canary.253f8c1.0", + "@storybook/semver": "^7.3.2", + "@types/webpack-env": "^1.16.0", + "babel-plugin-add-react-displayname": "^0.0.5", + "babel-plugin-named-asset-import": "^0.3.1", + "babel-plugin-react-docgen": "^4.2.1", + "core-js": "^3.8.2", + "global": "^4.4.0", + "lodash": "^4.17.20", + "prop-types": "^15.7.2", + "react-dev-utils": "^11.0.3", + "react-refresh": "^0.8.3", + "read-pkg-up": "^7.0.1", + "regenerator-runtime": "^0.13.7", + "ts-dedent": "^2.0.0", + "webpack": "4" + }, + "dependencies": { + "@storybook/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@storybook/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg==", + "dev": true, + "requires": { + "core-js": "^3.6.5", + "find-up": "^4.1.0" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "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==", + "dev": true + } + } + }, + "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==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "@storybook/react-docgen-typescript-plugin": { + "version": "1.0.2-canary.253f8c1.0", + "resolved": "https://registry.npmjs.org/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.2-canary.253f8c1.0.tgz", + "integrity": "sha512-mmoRG/rNzAiTbh+vGP8d57dfcR2aP+5/Ll03KKFyfy5FqWFm/Gh7u27ikx1I3LmVMI8n6jh5SdWMkMKon7/tDw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "endent": "^2.0.1", + "find-cache-dir": "^3.3.1", + "flat-cache": "^3.0.4", + "micromatch": "^4.0.2", + "react-docgen-typescript": "^2.0.0", + "tslib": "^2.0.0" + }, + "dependencies": { + "find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "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==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "react-docgen-typescript": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-2.1.1.tgz", + "integrity": "sha512-XWe8bsYqVjxciKdpNoufaHiB7FgUHIOnVQgxUolRL3Zlof2zkdTzuQH6SU2n3Ek9kfy3O1c63ojMtNfpiuNeZQ==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, + "@storybook/router": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.3.12.tgz", + "integrity": "sha512-G/pNGCnrJRetCwyEZulHPT+YOcqEj/vkPVDTUfii2qgqukup6K0cjwgd7IukAURnAnnzTi1gmgFuEKUi8GE/KA==", + "dev": true, + "requires": { + "@reach/router": "^1.3.4", + "@storybook/client-logger": "6.3.12", + "@types/reach__router": "^1.3.7", + "core-js": "^3.8.2", + "fast-deep-equal": "^3.1.3", + "global": "^4.4.0", + "lodash": "^4.17.20", + "memoizerific": "^1.11.3", + "qs": "^6.10.0", + "ts-dedent": "^2.0.0" + }, + "dependencies": { + "qs": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + } + } + }, + "@storybook/source-loader": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/source-loader/-/source-loader-6.3.12.tgz", + "integrity": "sha512-Lfe0LOJGqAJYkZsCL8fhuQOeFSCgv8xwQCt4dkcBd0Rw5zT2xv0IXDOiIOXGaWBMDtrJUZt/qOXPEPlL81Oaqg==", + "dev": true, + "requires": { + "@storybook/addons": "6.3.12", + "@storybook/client-logger": "6.3.12", + "@storybook/csf": "0.0.1", + "core-js": "^3.8.2", + "estraverse": "^5.2.0", + "global": "^4.4.0", + "loader-utils": "^2.0.0", + "lodash": "^4.17.20", + "prettier": "~2.2.1", + "regenerator-runtime": "^0.13.7" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + } + } + }, + "@storybook/theming": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.3.12.tgz", + "integrity": "sha512-wOJdTEa/VFyFB2UyoqyYGaZdym6EN7RALuQOAMT6zHA282FBmKw8nL5DETHEbctpnHdcrMC/391teK4nNSrdOA==", + "dev": true, + "requires": { + "@emotion/core": "^10.1.1", + "@emotion/is-prop-valid": "^0.8.6", + "@emotion/styled": "^10.0.27", + "@storybook/client-logger": "6.3.12", + "core-js": "^3.8.2", + "deep-object-diff": "^1.1.0", + "emotion-theming": "^10.0.27", + "global": "^4.4.0", + "memoizerific": "^1.11.3", + "polished": "^4.0.5", + "resolve-from": "^5.0.0", + "ts-dedent": "^2.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@storybook/ui": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/@storybook/ui/-/ui-6.3.12.tgz", + "integrity": "sha512-PC2yEz4JMfarq7rUFbeA3hCA+31p5es7YPEtxLRvRwIZhtL0P4zQUfHpotb3KgWdoAIfZesAuoIQwMPQmEFYrw==", + "dev": true, + "requires": { + "@emotion/core": "^10.1.1", + "@storybook/addons": "6.3.12", + "@storybook/api": "6.3.12", + "@storybook/channels": "6.3.12", + "@storybook/client-logger": "6.3.12", + "@storybook/components": "6.3.12", + "@storybook/core-events": "6.3.12", + "@storybook/router": "6.3.12", + "@storybook/semver": "^7.3.2", + "@storybook/theming": "6.3.12", + "@types/markdown-to-jsx": "^6.11.3", + "copy-to-clipboard": "^3.3.1", + "core-js": "^3.8.2", + "core-js-pure": "^3.8.2", + "downshift": "^6.0.15", + "emotion-theming": "^10.0.27", + "fuse.js": "^3.6.1", + "global": "^4.4.0", + "lodash": "^4.17.20", + "markdown-to-jsx": "^6.11.4", + "memoizerific": "^1.11.3", + "polished": "^4.0.5", + "qs": "^6.10.0", + "react-draggable": "^4.4.3", + "react-helmet-async": "^1.0.7", + "react-sizeme": "^3.0.1", + "regenerator-runtime": "^0.13.7", + "resolve-from": "^5.0.0", + "store2": "^2.12.0" + }, + "dependencies": { + "@storybook/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@storybook/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg==", + "dev": true, + "requires": { + "core-js": "^3.6.5", + "find-up": "^4.1.0" + } + }, + "markdown-to-jsx": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-6.11.4.tgz", + "integrity": "sha512-3lRCD5Sh+tfA52iGgfs/XZiw33f7fFX9Bn55aNnVNUd2GzLDkOWyKYYD8Yju2B1Vn+feiEdgJs8T6Tg0xNokPw==", + "dev": true, + "requires": { + "prop-types": "^15.6.2", + "unquote": "^1.1.0" + } + }, + "qs": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@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==", + "requires": { + "ejs": "^2.6.1", + "magic-string": "^0.25.0" + } + }, + "@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==" + }, + "@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==" + }, + "@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==" + }, + "@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==" + }, + "@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==" + }, + "@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==" + }, + "@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==" + }, + "@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==" + }, + "@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==", + "requires": { + "@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" + } + }, + "@svgr/core": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", + "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "requires": { + "@svgr/plugin-jsx": "^5.5.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.0" + } + }, + "@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==", + "requires": { + "@babel/types": "^7.12.6" + } + }, + "@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==", + "requires": { + "@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" + } + }, + "@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==", + "requires": { + "cosmiconfig": "^7.0.0", + "deepmerge": "^4.2.2", + "svgo": "^1.2.2" + }, + "dependencies": { + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + } + } + }, + "@svgr/webpack": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", + "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", + "requires": { + "@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" @@ -3070,6 +6848,27 @@ "@babel/types": "^7.3.0" } }, + "@types/braces": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/braces/-/braces-3.0.1.tgz", + "integrity": "sha512-+euflG6ygo4bn0JHtn4pYqcXwRtLvElQ7/nnjDu7iYG56H0+OhCd7d6Ug0IE3WcFpZozBKW2+80FUbv5QGk5AQ==", + "dev": true + }, + "@types/color-convert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/color-convert/-/color-convert-2.0.0.tgz", + "integrity": "sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ==", + "dev": true, + "requires": { + "@types/color-name": "*" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, "@types/d3-scale": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz", @@ -3114,6 +6913,12 @@ "@types/node": "*" } }, + "@types/glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@types/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-pYHWiDR+EOUN18F9byiAoQNUMZ0=", + "dev": true + }, "@types/graceful-fs": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", @@ -3122,6 +6927,15 @@ "@types/node": "*" } }, + "@types/hast": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", + "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==", + "dev": true, + "requires": { + "@types/unist": "*" + } + }, "@types/history": { "version": "4.7.8", "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.8.tgz", @@ -3151,6 +6965,12 @@ "@types/node": "*" } }, + "@types/is-function": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/is-function/-/is-function-1.0.1.tgz", + "integrity": "sha512-A79HEEiwXTFtfY+Bcbo58M2GRYzCr9itHWzbzHVFNEYCcoU/MMGwYYf721gBrnhpj1s6RGVVha/IgNFnR0Iw/Q==", + "dev": true + }, "@types/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", @@ -3181,6 +7001,15 @@ "pretty-format": "^26.0.0" } }, + "@types/jest-specific-snapshot": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@types/jest-specific-snapshot/-/jest-specific-snapshot-0.5.5.tgz", + "integrity": "sha512-AaPPw2tE8ewfjD6qGLkEd4DOfM6pPOK7ob/RSOe1Z8Oo70r9Jgo0SlWyfxslPAOvLfQukQtiVPm6DcnjSoZU5A==", + "dev": true, + "requires": { + "@types/jest": "*" + } + }, "@types/json-schema": { "version": "7.0.7", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", @@ -3196,6 +7025,33 @@ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.170.tgz", "integrity": "sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q==" }, + "@types/markdown-to-jsx": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/@types/markdown-to-jsx/-/markdown-to-jsx-6.11.3.tgz", + "integrity": "sha512-30nFYpceM/ZEvhGiqWjm5quLUxNeld0HCzJEXMZZDpq53FPkS85mTwkWtCXzCqq8s5JYLgM5W392a02xn8Bdaw==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/mdast": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", + "integrity": "sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==", + "dev": true, + "requires": { + "@types/unist": "*" + } + }, + "@types/micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-oqXqVb0ci19GtH0vOA/U2TmHTcRY9kuZl4mqUxe0QmJAlIW13kzhuK5pi1i9+ngav8FjpSb9FVS/GE00GLX1VA==", + "dev": true, + "requires": { + "@types/braces": "*" + } + }, "@types/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", @@ -3206,21 +7062,68 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.4.tgz", "integrity": "sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A==" }, + "@types/node-fetch": { + "version": "2.5.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz", + "integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==", + "dev": true, + "requires": { + "@types/node": "*", + "form-data": "^3.0.0" + }, + "dependencies": { + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, "@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==" }, + "@types/npmlog": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/npmlog/-/npmlog-4.1.3.tgz", + "integrity": "sha512-1TcL7YDYCtnHmLhTWbum+IIwLlvpaHoEKS2KNIngEwLzwgDeHaebaEHHbQp8IqzNQ9IYiboLKUjAf7MZqG63+w==", + "dev": true + }, + "@types/overlayscrollbars": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@types/overlayscrollbars/-/overlayscrollbars-1.12.1.tgz", + "integrity": "sha512-V25YHbSoKQN35UasHf0EKD9U2vcmexRSp78qa8UglxFH8H3D+adEa9zGZwrqpH4TdvqeMrgMqVqsLB4woAryrQ==", + "dev": true + }, "@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==" }, + "@types/parse5": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", + "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==", + "dev": true + }, "@types/prettier": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==" }, + "@types/pretty-hrtime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/pretty-hrtime/-/pretty-hrtime-1.0.1.tgz", + "integrity": "sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ==", + "dev": true + }, "@types/prop-types": { "version": "15.7.3", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", @@ -3236,6 +7139,21 @@ "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "@types/reach__router": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.3.9.tgz", + "integrity": "sha512-N6rqQqTTAV/zKLfK3iq9Ww3wqCEhTZvsilhl0zI09zETdVq1QGmJH6+/xnj8AFUWIrle2Cqo+PGM/Ltr1vBb9w==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/react": { "version": "17.0.13", "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.13.tgz", @@ -3302,6 +7220,15 @@ "@types/react-router": "*" } }, + "@types/react-syntax-highlighter": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.5.tgz", + "integrity": "sha512-VIOi9i2Oj5XsmWWoB72p3KlZoEbdRAcechJa8Ztebw7bDl2YmR+odxIqhtJGp1q2EozHs02US+gzxJ9nuf56qg==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/react-transition-group": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.1.tgz", @@ -3397,6 +7324,12 @@ "integrity": "sha512-Fl1TX1dapfXyDqFg2ic9M+vlXRktcPJrc4PR7sRc7sdVrjavg/JHlbUXBt8qWWqhJrmSqg3RNAkAPRiOYw6Ahw==", "dev": true }, + "@types/unist": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", + "dev": true + }, "@types/webpack": { "version": "4.41.28", "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.28.tgz", @@ -3410,6 +7343,12 @@ "source-map": "^0.6.0" } }, + "@types/webpack-env": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.3.tgz", + "integrity": "sha512-9gtOPPkfyNoEqCQgx4qJKkuNm/x0R2hKR7fdl7zvTJyHnIisuE/LfvXOsYWL0o3qq6uiBnKZNNNzi3l0y/X+xw==", + "dev": true + }, "@types/webpack-sources": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.0.tgz", @@ -3769,6 +7708,31 @@ "indent-string": "^4.0.0" } }, + "airbnb-js-shims": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/airbnb-js-shims/-/airbnb-js-shims-2.2.1.tgz", + "integrity": "sha512-wJNXPH66U2xjgo1Zwyjf9EydvJ2Si94+vSdk6EERcBfB2VZkeltpqIats0cqIZMLCXP3zcyaUKGYQeIBT6XjsQ==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "array.prototype.flat": "^1.2.1", + "array.prototype.flatmap": "^1.2.1", + "es5-shim": "^4.5.13", + "es6-shim": "^0.35.5", + "function.prototype.name": "^1.1.0", + "globalthis": "^1.0.0", + "object.entries": "^1.1.0", + "object.fromentries": "^2.0.0 || ^1.0.0", + "object.getownpropertydescriptors": "^2.0.3", + "object.values": "^1.1.0", + "promise.allsettled": "^1.0.0", + "promise.prototype.finally": "^3.1.0", + "string.prototype.matchall": "^4.0.0 || ^3.0.1", + "string.prototype.padend": "^3.0.0", + "string.prototype.padstart": "^3.0.0", + "symbol.prototype.description": "^1.0.0" + } + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -3795,6 +7759,15 @@ "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" }, + "ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "requires": { + "string-width": "^4.1.0" + } + }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -3826,6 +7799,15 @@ "color-convert": "^1.9.0" } }, + "ansi-to-html": { + "version": "0.6.15", + "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.15.tgz", + "integrity": "sha512-28ijx2aHJGdzbs+O5SNQF65r6rrKYnkuwTYm8lZlChuoJ9P1vVzIpWO20sQTqTPDXYp6NFwk326vApTtLVFXpQ==", + "dev": true, + "requires": { + "entities": "^2.0.0" + } + }, "anymatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", @@ -3835,6 +7817,12 @@ "picomatch": "^2.0.4" } }, + "app-root-dir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/app-root-dir/-/app-root-dir-1.0.2.tgz", + "integrity": "sha1-OBh+wt6nV3//Az/8sSFyaS/24Rg=", + "dev": true + }, "append-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", @@ -3844,11 +7832,53 @@ "buffer-equal": "^1.0.0" } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "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==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -3939,6 +7969,80 @@ "function-bind": "^1.1.1" } }, + "array.prototype.map": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.map/-/array.prototype.map-1.0.4.tgz", + "integrity": "sha512-Qds9QnX7A0qISY7JT5WuJO0NJPE9CMlC6JzHQfhpqAAQQzufVRoeH7EzUY5GcPTx72voG8LV/5eo+b8Qi8hmhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "dependencies": { + "es-abstract": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.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.1" + } + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "dev": true + } + } + }, "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", @@ -4009,6 +8113,23 @@ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" }, + "ast-types": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", + "integrity": "sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==", + "dev": true, + "requires": { + "tslib": "^2.0.1" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, "ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", @@ -4229,6 +8350,30 @@ } } }, + "babel-plugin-add-react-displayname": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/babel-plugin-add-react-displayname/-/babel-plugin-add-react-displayname-0.0.5.tgz", + "integrity": "sha1-M51M3be2X9YtHfnbn+BN4TQSK9U=", + "dev": true + }, + "babel-plugin-apply-mdx-type-prop": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz", + "integrity": "sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.10.4", + "@mdx-js/util": "1.6.22" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } + } + }, "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", @@ -4237,6 +8382,49 @@ "object.assign": "^4.1.0" } }, + "babel-plugin-emotion": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.2.2.tgz", + "integrity": "sha512-SMSkGoqTbTyUTDeuVuPIWifPdUGkTk1Kf9BWRiXIOIcuyMfsdp2EjeiiFvOzX8NOBvEh/ypKYvUh2rkgAJMCLA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@emotion/hash": "0.8.0", + "@emotion/memoize": "0.7.4", + "@emotion/serialize": "^0.11.16", + "babel-plugin-macros": "^2.0.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^1.0.5", + "find-root": "^1.1.0", + "source-map": "^0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "babel-plugin-extract-import-names": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.22.tgz", + "integrity": "sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "7.10.4" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + } + } + }, "babel-plugin-istanbul": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", @@ -4323,6 +8511,29 @@ "@babel/helper-define-polyfill-provider": "^0.2.0" } }, + "babel-plugin-react-docgen": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/babel-plugin-react-docgen/-/babel-plugin-react-docgen-4.2.1.tgz", + "integrity": "sha512-UQ0NmGHj/HAqi5Bew8WvNfCk8wSsmdgNd8ZdMjBCICtyCJCq9LiqgqvjCYe570/Wg7AQArSq1VQ60Dd/CHN7mQ==", + "dev": true, + "requires": { + "ast-types": "^0.14.2", + "lodash": "^4.17.15", + "react-docgen": "^5.0.0" + } + }, + "babel-plugin-require-context-hook": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-require-context-hook/-/babel-plugin-require-context-hook-1.0.0.tgz", + "integrity": "sha512-EMZD1563QUqLhzrqcThk759RhuNVX/ZJdrtGK6drwzgvnR+ARjWyXIHPbu+tUNaMGtPz/gQeAM2M6VUw2UiUeA==", + "dev": true + }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", + "dev": true + }, "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", @@ -4565,6 +8776,12 @@ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" }, + "bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "dev": true + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -4630,6 +8847,12 @@ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" }, + "batch-processor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/batch-processor/-/batch-processor-1.0.0.tgz", + "integrity": "sha1-dclcMrdI4IUNEMKxaPa9vpiRrOg=", + "dev": true + }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", @@ -4638,6 +8861,15 @@ "tweetnacl": "^0.14.3" } }, + "better-opn": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-2.1.1.tgz", + "integrity": "sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA==", + "dev": true, + "requires": { + "open": "^7.0.3" + } + }, "bfj": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", @@ -4657,8 +8889,7 @@ "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 + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, "bindings": { "version": "1.5.0", @@ -4739,6 +8970,85 @@ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, + "boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4979,6 +9289,126 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, + "c8": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/c8/-/c8-7.10.0.tgz", + "integrity": "sha512-OAwfC5+emvA6R7pkYFVBTOtI5ruf9DahffGmIqUc9l6wEh0h7iAFP6dt/V9Ioqlr2zW5avX9U9/w1I4alTRHkA==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.2", + "find-up": "^5.0.0", + "foreground-child": "^2.0.0", + "istanbul-lib-coverage": "^3.0.1", + "istanbul-lib-report": "^3.0.0", + "istanbul-reports": "^3.0.2", + "rimraf": "^3.0.0", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^8.0.0", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.7" + }, + "dependencies": { + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + }, + "v8-to-istanbul": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", + "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + } + } + }, "cacache": { "version": "15.0.6", "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.6.tgz", @@ -5035,6 +9465,12 @@ "get-intrinsic": "^1.0.2" } }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", + "dev": true + }, "caller-callsite": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", @@ -5084,6 +9520,12 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" }, + "camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true + }, "caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -5118,6 +9560,12 @@ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, + "ccount": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", + "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", + "dev": true + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -5133,6 +9581,24 @@ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==" }, + "character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true + }, + "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==", + "dev": true + }, + "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==", + "dev": true + }, "check-types": { "version": "11.1.2", "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.1.2.tgz", @@ -5292,7 +9758,6 @@ "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, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", @@ -5372,6 +9837,12 @@ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true + }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -5381,6 +9852,17 @@ "restore-cursor": "^3.1.0" } }, + "cli-table3": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.0.tgz", + "integrity": "sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ==", + "dev": true, + "requires": { + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^4.2.0" + } + }, "cli-truncate": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", @@ -5446,6 +9928,17 @@ "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", "dev": true }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, "clone-stats": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", @@ -5515,6 +10008,18 @@ "q": "^1.1.2" } }, + "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=", + "dev": true + }, + "collapse-white-space": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", + "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", + "dev": true + }, "collect-v8-coverage": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", @@ -5579,6 +10084,12 @@ "delayed-stream": "~1.0.0" } }, + "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==", + "dev": true + }, "commander": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", @@ -5716,6 +10227,12 @@ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -5785,6 +10302,15 @@ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, + "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==", + "dev": true, + "requires": { + "toggle-selection": "^1.0.6" + } + }, "core-js": { "version": "3.12.1", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.12.1.tgz", @@ -5828,6 +10354,270 @@ "yaml": "^1.10.0" } }, + "cp-file": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-7.0.0.tgz", + "integrity": "sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "nested-error-stacks": "^2.0.0", + "p-event": "^4.1.0" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "cpy": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/cpy/-/cpy-8.1.2.tgz", + "integrity": "sha512-dmC4mUesv0OYH2kNFEidtf/skUwv4zePmGeepjyyJ0qTo5+8KhA1o99oIAwVVLzQMAeDJml74d6wPPKb6EZUTg==", + "dev": true, + "requires": { + "arrify": "^2.0.1", + "cp-file": "^7.0.0", + "globby": "^9.2.0", + "has-glob": "^1.0.0", + "junk": "^3.1.0", + "nested-error-stacks": "^2.1.0", + "p-all": "^2.1.0", + "p-filter": "^2.1.0", + "p-map": "^3.0.0" + }, + "dependencies": { + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "requires": { + "path-type": "^3.0.0" + } + }, + "fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "globby": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "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=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, "create-ecdh": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", @@ -5869,6 +10659,24 @@ "sha.js": "^2.4.8" } }, + "create-react-context": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.3.0.tgz", + "integrity": "sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==", + "dev": true, + "requires": { + "gud": "^1.0.0", + "warning": "^4.0.3" + } + }, + "cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "requires": { + "cross-spawn": "^7.0.1" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -6380,6 +11188,12 @@ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, + "deep-object-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/deep-object-diff/-/deep-object-diff-1.1.0.tgz", + "integrity": "sha512-b+QLs5vHgS+IoSNcUE4n9HP2NwcHj7aqnJWsjPtuG75Rh5TOaGt0OjAYInh77d5T16V5cRDC+Pw/6ZZZiETBGw==", + "dev": true + }, "deepmerge": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", @@ -6580,6 +11394,12 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -6599,6 +11419,15 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "detab": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.4.tgz", + "integrity": "sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g==", + "dev": true, + "requires": { + "repeat-string": "^1.5.4" + } + }, "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -6738,6 +11567,12 @@ } } }, + "dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", + "dev": true + }, "domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", @@ -6822,11 +11657,37 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" }, + "dotenv-defaults": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/dotenv-defaults/-/dotenv-defaults-1.1.1.tgz", + "integrity": "sha512-6fPRo9o/3MxKvmRZBD3oNFdxODdhJtIy1zcJeUSCs6HCy4tarUpd+G67UTU9tF6OWXeSPqsm4fPAB+2eY9Rt9Q==", + "dev": true, + "requires": { + "dotenv": "^6.2.0" + }, + "dependencies": { + "dotenv": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", + "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==", + "dev": true + } + } + }, "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==" }, + "dotenv-webpack": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/dotenv-webpack/-/dotenv-webpack-1.8.0.tgz", + "integrity": "sha512-o8pq6NLBehtrqA8Jv8jFQNtG9nhRtVqmoD4yWbgUyoU3+9WBlPe+c2EAiaJok9RB28QvrWvdWLZGeTT5aATDMg==", + "dev": true, + "requires": { + "dotenv-defaults": "^1.0.2" + } + }, "downshift": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/downshift/-/downshift-6.1.3.tgz", @@ -6907,6 +11768,15 @@ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz", "integrity": "sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg==" }, + "element-resize-detector": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/element-resize-detector/-/element-resize-detector-1.2.3.tgz", + "integrity": "sha512-+dhNzUgLpq9ol5tyhoG7YLoXL3ssjfFW+0gpszXPwRU6NjGr1fVHMEAF8fVzIiRJq57Nre0RFeIjJwI8Nh2NmQ==", + "dev": true, + "requires": { + "batch-processor": "1.0.0" + } + }, "elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -6943,6 +11813,17 @@ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" }, + "emotion-theming": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/emotion-theming/-/emotion-theming-10.0.27.tgz", + "integrity": "sha512-MlF1yu/gYh8u+sLUqA0YuA9JX0P4Hb69WlKc/9OLo+WCXuX6sy/KoIa+qJimgmr2dWqnypYKYPX37esjDBbhdw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.5.5", + "@emotion/weak-memoize": "0.2.5", + "hoist-non-react-statics": "^3.3.0" + } + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -6956,6 +11837,17 @@ "once": "^1.4.0" } }, + "endent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/endent/-/endent-2.1.0.tgz", + "integrity": "sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w==", + "dev": true, + "requires": { + "dedent": "^0.7.0", + "fast-json-parse": "^1.0.3", + "objectorarray": "^1.0.5" + } + }, "enhanced-resolve": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", @@ -7076,6 +11968,36 @@ "unbox-primitive": "^1.0.0" } }, + "es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, + "es-get-iterator": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz", + "integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.0", + "has-symbols": "^1.0.1", + "is-arguments": "^1.1.0", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.5", + "isarray": "^2.0.5" + }, + "dependencies": { + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + } + } + }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -7096,6 +12018,12 @@ "next-tick": "~1.0.0" } }, + "es5-shim": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/es5-shim/-/es5-shim-4.6.2.tgz", + "integrity": "sha512-n0XTVMGps+Deyr38jtqKPR5F5hb9owYeRQcKJW39eFvzUk/u/9Ww315werRzbiNMnHCUw/YHDPBphTlEnzdi+A==", + "dev": true + }, "es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", @@ -7106,6 +12034,12 @@ "es6-symbol": "^3.1.1" } }, + "es6-shim": { + "version": "0.35.6", + "resolved": "https://registry.npmjs.org/es6-shim/-/es6-shim-0.35.6.tgz", + "integrity": "sha512-EmTr31wppcaIAgblChZiuN/l9Y7DPyw8Xtbg7fIVngn6zMW+IEBJDJngeKC3x6wr0V/vcA2wqeFnaw1bFJbDdA==", + "dev": true + }, "es6-symbol": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", @@ -7793,6 +12727,17 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" }, + "estree-to-babel": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/estree-to-babel/-/estree-to-babel-3.2.1.tgz", + "integrity": "sha512-YNF+mZ/Wu2FU/gvmzuWtYc8rloubL7wfXCTgouFrnjGVXPA/EeYYA7pupXWrb3Iv1cTBeSSxxJIbK23l4MRNqg==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.6", + "@babel/types": "^7.2.0", + "c8": "^7.6.0" + } + }, "estree-walker": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", @@ -8233,6 +13178,12 @@ "picomatch": "^2.2.1" } }, + "fast-json-parse": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fast-json-parse/-/fast-json-parse-1.0.3.tgz", + "integrity": "sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw==", + "dev": true + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -8251,6 +13202,15 @@ "reusify": "^1.0.4" } }, + "fault": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", + "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", + "dev": true, + "requires": { + "format": "^0.2.0" + } + }, "faye-websocket": { "version": "0.11.3", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", @@ -8301,6 +13261,50 @@ } } }, + "file-system-cache": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/file-system-cache/-/file-system-cache-1.0.5.tgz", + "integrity": "sha1-hCWbNqK7uNPW6xAh0xMv/mTP/08=", + "dev": true, + "requires": { + "bluebird": "^3.3.5", + "fs-extra": "^0.30.0", + "ramda": "^0.21.0" + }, + "dependencies": { + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, "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", @@ -8359,6 +13363,12 @@ "pkg-dir": "^3.0.0" } }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "dev": true + }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -8435,15 +13445,25 @@ } }, "follow-redirects": { - "version": "1.14.8", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", - "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==" + "version": "1.14.7", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", + "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==" }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + } + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -8575,6 +13595,12 @@ "mime-types": "^2.1.12" } }, + "format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=", + "dev": true + }, "formik": { "version": "2.2.9", "resolved": "https://registry.npmjs.org/formik/-/formik-2.2.9.tgz", @@ -8720,6 +13746,12 @@ "through2": "^2.0.3" } }, + "fs-monkey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", + "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", + "dev": true + }, "fs-tree-diff": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fs-tree-diff/-/fs-tree-diff-2.0.1.tgz", @@ -8789,11 +13821,149 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "dependencies": { + "es-abstract": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.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.1" + } + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "dev": true + } + } + }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, + "functions-have-names": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.2.tgz", + "integrity": "sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA==", + "dev": true + }, + "fuse.js": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-3.6.1.tgz", + "integrity": "sha512-hT9yh/tiinkmirKrlv4KWOjztdoZo1mx9Qh4KvWqC7isoXwdUY3PNWUxceF4/qO9R6riA2C29jdTOeQOIROjgw==", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -8832,6 +14002,16 @@ "pump": "^3.0.0" } }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -8845,6 +14025,12 @@ "assert-plus": "^1.0.0" } }, + "github-slugger": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.4.0.tgz", + "integrity": "sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ==", + "dev": true + }, "glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -8858,6 +14044,42 @@ "path-is-absolute": "^1.0.0" } }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "^2.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", @@ -8866,6 +14088,15 @@ "is-glob": "^4.0.1" } }, + "glob-promise": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-3.4.0.tgz", + "integrity": "sha512-q08RJ6O+eJn+dVanerAndJwIcumgbDdYiUT7zFQl3Wm1xD6fBKtah7H8ZJChj4wP+8C+QfeVy8xautR7rdmKEw==", + "dev": true, + "requires": { + "@types/glob": "*" + } + }, "glob-stream": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", @@ -8935,6 +14166,22 @@ } } }, + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "dev": true + }, + "global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dev": true, + "requires": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, "global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -8968,6 +14215,15 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, + "globalthis": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz", + "integrity": "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3" + } + }, "globby": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", @@ -8992,6 +14248,12 @@ "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", "optional": true }, + "gud": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", + "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==", + "dev": true + }, "gulp-sort": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/gulp-sort/-/gulp-sort-2.0.0.tgz", @@ -9052,11 +14314,46 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, + "has-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-1.0.0.tgz", + "integrity": "sha1-mqqe7b/7G6OZCnsAEPtnjuAIEgc=", + "dev": true, + "requires": { + "is-glob": "^3.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, "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==" }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -9130,6 +14427,85 @@ "minimalistic-assert": "^1.0.1" } }, + "hast-to-hyperscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz", + "integrity": "sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA==", + "dev": true, + "requires": { + "@types/unist": "^2.0.3", + "comma-separated-tokens": "^1.0.0", + "property-information": "^5.3.0", + "space-separated-tokens": "^1.0.0", + "style-to-object": "^0.3.0", + "unist-util-is": "^4.0.0", + "web-namespaces": "^1.0.0" + } + }, + "hast-util-from-parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz", + "integrity": "sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==", + "dev": true, + "requires": { + "@types/parse5": "^5.0.0", + "hastscript": "^6.0.0", + "property-information": "^5.0.0", + "vfile": "^4.0.0", + "vfile-location": "^3.2.0", + "web-namespaces": "^1.0.0" + } + }, + "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==", + "dev": true + }, + "hast-util-raw": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-6.0.1.tgz", + "integrity": "sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig==", + "dev": true, + "requires": { + "@types/hast": "^2.0.0", + "hast-util-from-parse5": "^6.0.0", + "hast-util-to-parse5": "^6.0.0", + "html-void-elements": "^1.0.0", + "parse5": "^6.0.0", + "unist-util-position": "^3.0.0", + "vfile": "^4.0.0", + "web-namespaces": "^1.0.0", + "xtend": "^4.0.0", + "zwitch": "^1.0.0" + } + }, + "hast-util-to-parse5": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz", + "integrity": "sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ==", + "dev": true, + "requires": { + "hast-to-hyperscript": "^9.0.0", + "property-information": "^5.0.0", + "web-namespaces": "^1.0.0", + "xtend": "^4.0.0", + "zwitch": "^1.0.0" + } + }, + "hastscript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "dev": true, + "requires": { + "@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" + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -9184,6 +14560,12 @@ "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" }, + "highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "dev": true + }, "history": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", @@ -9329,6 +14711,18 @@ "void-elements": "3.1.0" } }, + "html-tags": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", + "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", + "dev": true + }, + "html-void-elements": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz", + "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==", + "dev": true + }, "html-webpack-plugin": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz", @@ -9913,6 +15307,12 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, + "inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", + "dev": true + }, "internal-ip": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", @@ -9937,6 +15337,21 @@ "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" }, + "interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "dev": true + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", @@ -9985,6 +15400,22 @@ } } }, + "is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true + }, + "is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, "is-arguments": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", @@ -10007,7 +15438,6 @@ "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, "requires": { "binary-extensions": "^2.0.0" } @@ -10082,6 +15512,12 @@ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==" }, + "is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true + }, "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", @@ -10109,6 +15545,16 @@ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" }, + "is-dom": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-dom/-/is-dom-1.1.0.tgz", + "integrity": "sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ==", + "dev": true, + "requires": { + "is-object": "^1.0.1", + "is-window": "^1.0.2" + } + }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -10124,6 +15570,12 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, + "is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", + "dev": true + }, "is-generator-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", @@ -10137,11 +15589,23 @@ "is-extglob": "^2.1.1" } }, + "is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true + }, "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=" }, + "is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "dev": true + }, "is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", @@ -10173,6 +15637,12 @@ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" }, + "is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "dev": true + }, "is-path-cwd": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", @@ -10245,6 +15715,18 @@ "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==" }, + "is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "dev": true + }, + "is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true + }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -10295,11 +15777,38 @@ "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", "dev": true }, + "is-weakref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", + "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-whitespace-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", + "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", + "dev": true + }, + "is-window": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-window/-/is-window-1.0.2.tgz", + "integrity": "sha1-LIlspT25feRdPDMTOmXYyfVjSA0=", + "dev": true + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" }, + "is-word-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", + "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", + "dev": true + }, "is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -10408,6 +15917,22 @@ "istanbul-lib-report": "^3.0.0" } }, + "iterate-iterator": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/iterate-iterator/-/iterate-iterator-1.0.2.tgz", + "integrity": "sha512-t91HubM4ZDQ70M9wqp+pcNpu8OyJ9UAtXntT/Bcsvp5tZMnz9vRa+IunKXeI8AnfZMTv0jNuVEmGeLSMjVvfPw==", + "dev": true + }, + "iterate-value": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/iterate-value/-/iterate-value-1.0.2.tgz", + "integrity": "sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==", + "dev": true, + "requires": { + "es-get-iterator": "^1.0.2", + "iterate-iterator": "^1.0.1" + } + }, "jest": { "version": "26.6.0", "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.0.tgz", @@ -12524,6 +18049,15 @@ } } }, + "jest-specific-snapshot": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jest-specific-snapshot/-/jest-specific-snapshot-4.0.0.tgz", + "integrity": "sha512-YdW5P/MVwOizWR0MJwURxdrjdXvdG2MMpXKVGr7dZ2YrBmE6E6Ab74UL3DOYmGmzaCnNAW1CL02pY5MTHE3ulQ==", + "dev": true, + "requires": { + "jest-snapshot": "^26.3.0" + } + }, "jest-util": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", @@ -12888,6 +18422,12 @@ } } }, + "js-string-escape": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", + "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -13110,6 +18650,12 @@ "object.assign": "^4.1.2" } }, + "junk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", + "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", + "dev": true + }, "jwt-decode": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", @@ -13125,6 +18671,15 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -13157,6 +18712,19 @@ "webpack-sources": "^1.1.0" } }, + "lazy-universal-dotenv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lazy-universal-dotenv/-/lazy-universal-dotenv-3.0.1.tgz", + "integrity": "sha512-prXSYk799h3GY3iOWnC6ZigYzMPjxN2svgjJ9shk7oMadSNX3wXy0B6F32PMJv7qtMnrIbUxoEHzbutvxR2LBQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.5.0", + "app-root-dir": "^1.0.2", + "core-js": "^3.0.4", + "dotenv": "^8.0.0", + "dotenv-expand": "^5.1.0" + } + }, "lazystream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", @@ -13647,6 +19215,16 @@ } } }, + "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==", + "dev": true, + "requires": { + "fault": "^1.0.0", + "highlight.js": "~10.7.0" + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -13697,6 +19275,12 @@ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" }, + "map-or-similar": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/map-or-similar/-/map-or-similar-1.5.0.tgz", + "integrity": "sha1-beJlMXSt+12e3DPGnT6Sobdvrwg=", + "dev": true + }, "map-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", @@ -13705,6 +19289,18 @@ "object-visit": "^1.0.0" } }, + "markdown-escapes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", + "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", + "dev": true + }, + "markdown-to-jsx": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.1.3.tgz", + "integrity": "sha512-jtQ6VyT7rMT5tPV0g2EJakEnXLiPksnvlYtwQsVVZ611JsWGN8bQ1tVSDX4s6JllfEH6wmsYxNjTUAMrPmNA8w==", + "dev": true + }, "matcher-collection": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-2.0.1.tgz", @@ -13730,21 +19326,85 @@ "safe-buffer": "^5.1.2" } }, + "mdast-squeeze-paragraphs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz", + "integrity": "sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ==", + "dev": true, + "requires": { + "unist-util-remove": "^2.0.0" + } + }, + "mdast-util-definitions": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz", + "integrity": "sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==", + "dev": true, + "requires": { + "unist-util-visit": "^2.0.0" + } + }, + "mdast-util-to-hast": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz", + "integrity": "sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA==", + "dev": true, + "requires": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "mdast-util-definitions": "^4.0.0", + "mdurl": "^1.0.0", + "unist-builder": "^2.0.0", + "unist-util-generated": "^1.0.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^2.0.0" + } + }, + "mdast-util-to-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", + "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", + "dev": true + }, "mdn-data": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, + "memfs": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.3.0.tgz", + "integrity": "sha512-BEE62uMfKOavX3iG7GYX43QJ+hAeeWnwIAuJ/R6q96jaMtiLzhsxHJC8B1L7fK7Pt/vXDRwb3SG/yBpNGDPqzg==", + "dev": true, + "requires": { + "fs-monkey": "1.0.3" + } + }, "memoize-one": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" }, + "memoizerific": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz", + "integrity": "sha1-fIekZGREwy11Q4VwkF8tvRsagFo=", + "dev": true, + "requires": { + "map-or-similar": "^1.5.0" + } + }, "memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", @@ -13856,6 +19516,15 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "dev": true, + "requires": { + "dom-walk": "^0.1.0" + } + }, "min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -14137,6 +19806,12 @@ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, + "nested-error-stacks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", + "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", + "dev": true + }, "next-tick": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", @@ -14163,6 +19838,48 @@ } } }, + "node-dir": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", + "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", + "dev": true, + "requires": { + "minimatch": "^3.0.2" + } + }, + "node-fetch": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", + "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } + }, "node-forge": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", @@ -14327,7 +20044,19 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "requires": { - "path-key": "^3.0.0" + "path-key": "^3.0.0" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "nth-check": { @@ -14343,6 +20072,12 @@ "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" }, + "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=", + "dev": true + }, "nwsapi": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", @@ -14475,6 +20210,12 @@ "has": "^1.0.3" } }, + "objectorarray": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/objectorarray/-/objectorarray-1.0.5.tgz", + "integrity": "sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg==", + "dev": true + }, "obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", @@ -14621,11 +20362,60 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, + "overlayscrollbars": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/overlayscrollbars/-/overlayscrollbars-1.13.1.tgz", + "integrity": "sha512-gIQfzgGgu1wy80EB4/6DaJGHMEGmizq27xHIESrzXq0Y/J0Ay1P3DWk6tuVmEPIZH15zaBlxeEJOqdJKmowHCQ==", + "dev": true + }, + "p-all": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-all/-/p-all-2.1.0.tgz", + "integrity": "sha512-HbZxz5FONzz/z2gJfk6bFca0BCiSRF8jU3yCsWOen/vR6lZjfPOu/e7L3uFzTW1i0H8TlC3vqQstEJPQL4/uLA==", + "dev": true, + "requires": { + "p-map": "^2.0.0" + }, + "dependencies": { + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + } + } + }, "p-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==" }, + "p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "dev": true, + "requires": { + "p-timeout": "^3.1.0" + } + }, + "p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "requires": { + "p-map": "^2.0.0" + }, + "dependencies": { + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + } + } + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -14663,6 +20453,15 @@ "retry": "^0.12.0" } }, + "p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "requires": { + "p-finally": "^1.0.0" + } + }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -14748,6 +20547,20 @@ "safe-buffer": "^5.1.1" } }, + "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==", + "dev": true, + "requires": { + "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" + } + }, "parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -14998,6 +20811,15 @@ "ts-pnp": "^1.1.6" } }, + "polished": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/polished/-/polished-4.1.3.tgz", + "integrity": "sha512-ocPAcVBUOryJEKe0z2KLd1l9EBa1r5mSwlKpExmrLzsnIzJo4axsoU9O2BjOTkDGDT4mZ0WFE5XKTlR3nLnZOA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.14.0" + } + }, "popper.js": { "version": "1.16.1-lts", "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz", @@ -16011,6 +21833,23 @@ "uniq": "^1.0.1" } }, + "preact-render-to-string": { + "version": "5.1.19", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.1.19.tgz", + "integrity": "sha512-bj8sn/oytIKO6RtOGSS/1+5CrQyRSC99eLUnEVbqUa6MzJX5dYh7wu9bmT0d6lm/Vea21k9KhCQwvr2sYN3rrQ==", + "dev": true, + "requires": { + "pretty-format": "^3.8.0" + }, + "dependencies": { + "pretty-format": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", + "integrity": "sha1-v77VbV6ad2ZF9LH/eqGjrE+jw4U=", + "dev": true + } + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -16075,6 +21914,18 @@ } } }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "dev": true + }, + "prismjs": { + "version": "1.25.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.25.0.tgz", + "integrity": "sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg==", + "dev": true + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -16109,6 +21960,153 @@ "integrity": "sha512-3npG2NGhTc8BWBolLLf8l/92OxMGaRLbqvIh9wjCHhDXNvk4zsxaTaCpiCunW09qWPrN2zeNSNwRLVBrQQtutA==", "dev": true }, + "promise.allsettled": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.5.tgz", + "integrity": "sha512-tVDqeZPoBC0SlzJHzWGZ2NKAguVq2oiYj7gbggbiTvH2itHohijTp7njOUA0aQ/nl+0lr/r6egmhoYu63UZ/pQ==", + "dev": true, + "requires": { + "array.prototype.map": "^1.0.4", + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "iterate-value": "^1.0.2" + }, + "dependencies": { + "es-abstract": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.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.1" + } + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "dev": true + } + } + }, + "promise.prototype.finally": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/promise.prototype.finally/-/promise.prototype.finally-3.1.3.tgz", + "integrity": "sha512-EXRF3fC9/0gz4qkt/f5EP5iW4kj9oFpBICNpCNOb/52+8nlHIX07FPLbi/q4qYBQ1xZqivMzTpNQSnArVASolQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.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.1" + } + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "dev": true + } + } + }, "prompts": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", @@ -16135,6 +22133,15 @@ } } }, + "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==", + "dev": true, + "requires": { + "xtend": "^4.0.0" + } + }, "proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", @@ -16283,6 +22290,12 @@ "performance-now": "^2.1.0" } }, + "ramda": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.21.0.tgz", + "integrity": "sha1-oAGr7bP/YQd9T/HVd9RN536NCjU=", + "dev": true + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -16323,6 +22336,35 @@ } } }, + "raw-loader": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz", + "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "dependencies": { + "@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, "react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", @@ -16359,6 +22401,12 @@ "tinycolor2": "^1.4.1" } }, + "react-colorful": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.5.0.tgz", + "integrity": "sha512-BuzrlrM0ylg7coPkXOrRqlf2BgHLw5L44sybbr9Lg4xy7w9e5N7fGYbojOO0s8J0nvrM3PERN2rVFkvSa24lnQ==", + "dev": true + }, "react-dev-utils": { "version": "11.0.4", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz", @@ -16403,28 +22451,129 @@ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.2.tgz", "integrity": "sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw==", "requires": { - "caniuse-lite": "^1.0.30001125", - "electron-to-chromium": "^1.3.564", - "escalade": "^3.0.2", - "node-releases": "^1.1.61" + "caniuse-lite": "^1.0.30001125", + "electron-to-chromium": "^1.3.564", + "escalade": "^3.0.2", + "node-releases": "^1.1.61" + } + }, + "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==" + }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "requires": { + "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" + } + } + } + }, + "react-docgen": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-5.4.0.tgz", + "integrity": "sha512-JBjVQ9cahmNlfjMGxWUxJg919xBBKAoy3hgDgKERbR+BcF4ANpDuzWAScC7j27hZfd8sJNmMPOLWo9+vB/XJEQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@babel/generator": "^7.12.11", + "@babel/runtime": "^7.7.6", + "ast-types": "^0.14.2", + "commander": "^2.19.0", + "doctrine": "^3.0.0", + "estree-to-babel": "^3.1.0", + "neo-async": "^2.6.1", + "node-dir": "^0.1.10", + "strip-indent": "^3.0.0" + }, + "dependencies": { + "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==", + "dev": true + } + } + }, + "react-docgen-typescript": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-1.22.0.tgz", + "integrity": "sha512-MPLbF8vzRwAG3GcjdL+OHQlhgtWsLTXs+7uJiHfEeT3Ur7IsZaNYqRTLQ9sj2nB6M6jylcPCeCmH7qbszJmecg==", + "dev": true + }, + "react-docgen-typescript-plugin": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.0.tgz", + "integrity": "sha512-Akc7EtryOA4d2yOX27B5ii+hyf/k15ymb01uB+VnRgtTAdfeDCmNPvyLbRJ6pRNYOuFlEBe1YfCH73bTPtpYVQ==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "endent": "^2.0.1", + "find-cache-dir": "^3.3.1", + "flat-cache": "^3.0.4", + "micromatch": "^4.0.2", + "react-docgen-typescript": "^1.22.0", + "tslib": "^2.0.0", + "webpack-sources": "^2.2.0" + }, + "dependencies": { + "find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "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==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" } }, - "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==" + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true }, - "globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + }, + "webpack-sources": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", + "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", + "dev": true, "requires": { - "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" + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" } } } @@ -16439,6 +22588,34 @@ "scheduler": "^0.20.2" } }, + "react-draggable": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.4.tgz", + "integrity": "sha512-6e0WdcNLwpBx/YIDpoyd2Xb04PB0elrDrulKUgdrIlwuYvxh5Ok9M+F8cljm8kPXXs43PmMzek9RrB1b7mLMqA==", + "dev": true, + "requires": { + "clsx": "^1.1.1", + "prop-types": "^15.6.0" + } + }, + "react-element-to-jsx-string": { + "version": "14.3.2", + "resolved": "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-14.3.2.tgz", + "integrity": "sha512-WZbvG72cjLXAxV7VOuSzuHEaI3RHj10DZu8EcKQpkKcAj7+qAkG5XUeSdX5FXrA0vPrlx0QsnAzZEBJwzV0e+w==", + "dev": true, + "requires": { + "@base2/pretty-print-object": "1.0.0", + "is-plain-object": "3.0.1" + }, + "dependencies": { + "is-plain-object": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", + "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", + "dev": true + } + } + }, "react-error-overlay": { "version": "6.0.9", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz", @@ -16449,6 +22626,27 @@ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==" }, + "react-helmet-async": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.1.2.tgz", + "integrity": "sha512-LTTzDDkyIleT/JJ6T/uqx7Y8qi1EuPPSiJawQY/nHHz0h7SPDT6HxP1YDDQx/fzcVxCqpWEEMS3QdrSrNkJYhg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" + }, + "dependencies": { + "react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==", + "dev": true + } + } + }, "react-i18next": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.11.0.tgz", @@ -16468,6 +22666,17 @@ } } }, + "react-inspector": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-5.1.1.tgz", + "integrity": "sha512-GURDaYzoLbW8pMGXwYPDBIv6nqei4kK7LPRZ9q9HCZF54wqXz/dnylBp/kfE9XmekBhHvLDdcYeyIwSrvtOiWg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "is-dom": "^1.0.0", + "prop-types": "^15.0.0" + } + }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -16478,6 +22687,35 @@ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, + "react-popper": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.2.5.tgz", + "integrity": "sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw==", + "dev": true, + "requires": { + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" + }, + "dependencies": { + "react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==", + "dev": true + } + } + }, + "react-popper-tooltip": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/react-popper-tooltip/-/react-popper-tooltip-3.1.1.tgz", + "integrity": "sha512-EnERAnnKRptQBJyaee5GJScWNUKQPDD2ywvzZyUjst/wj5U64C8/CnSYLNEmP2hG0IJ3ZhtDxE8oDN+KOyavXQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5", + "@popperjs/core": "^2.5.4", + "react-popper": "^2.2.4" + } + }, "react-redux": { "version": "7.2.4", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.4.tgz", @@ -16630,6 +22868,28 @@ } } }, + "react-shallow-renderer": { + "version": "16.14.1", + "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.14.1.tgz", + "integrity": "sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "react-is": "^16.12.0 || ^17.0.0" + } + }, + "react-sizeme": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/react-sizeme/-/react-sizeme-3.0.2.tgz", + "integrity": "sha512-xOIAOqqSSmKlKFJLO3inBQBdymzDuXx4iuwkNcJmC96jeiOg5ojByvL+g3MW9LPEsojLbC6pf68zOfobK8IPlw==", + "dev": true, + "requires": { + "element-resize-detector": "^1.2.2", + "invariant": "^2.2.4", + "shallowequal": "^1.1.0", + "throttle-debounce": "^3.0.1" + } + }, "react-smooth": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.0.tgz", @@ -16661,6 +22921,42 @@ } } }, + "react-syntax-highlighter": { + "version": "13.5.3", + "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-13.5.3.tgz", + "integrity": "sha512-crPaF+QGPeHNIblxxCdf2Lg936NAHKhNhuMzRL3F9ct6aYXL3NcZtCL0Rms9+qVo6Y1EQLdXGypBNSbPL/r+qg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.3.1", + "highlight.js": "^10.1.1", + "lowlight": "^1.14.0", + "prismjs": "^1.21.0", + "refractor": "^3.1.0" + } + }, + "react-test-renderer": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-17.0.2.tgz", + "integrity": "sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "react-is": "^17.0.2", + "react-shallow-renderer": "^16.13.1", + "scheduler": "^0.20.2" + } + }, + "react-textarea-autosize": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.3.tgz", + "integrity": "sha512-2XlHXK2TDxS6vbQaoPbMOfQ8GK7+irc2fVK6QFIcC8GOnH3zI/v481n+j1L0WaPVvKxwesnY93fEfH++sus2rQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.2", + "use-composed-ref": "^1.0.0", + "use-latest": "^1.0.0" + } + }, "react-transition-group": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", @@ -16782,7 +23078,6 @@ "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, "requires": { "picomatch": "^2.2.1" } @@ -16881,6 +23176,17 @@ "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==" }, + "refractor": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.5.0.tgz", + "integrity": "sha512-QwPJd3ferTZ4cSPPjdP5bsYHMytwWYnAN5EEnLtGvkqp/FCCnGsBgxrm9EuIDnjUC3Uc/kETtvVi7fSIVC74Dg==", + "dev": true, + "requires": { + "hastscript": "^6.0.0", + "parse-entities": "^2.0.0", + "prismjs": "~1.25.0" + } + }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -16973,6 +23279,157 @@ "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=" }, + "remark-external-links": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/remark-external-links/-/remark-external-links-8.0.0.tgz", + "integrity": "sha512-5vPSX0kHoSsqtdftSHhIYofVINC8qmp0nctkeU9YoJwV3YfiBRiI6cbFRJ0oI/1F9xS+bopXG0m2KS8VFscuKA==", + "dev": true, + "requires": { + "extend": "^3.0.0", + "is-absolute-url": "^3.0.0", + "mdast-util-definitions": "^4.0.0", + "space-separated-tokens": "^1.0.0", + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true + } + } + }, + "remark-footnotes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-2.0.0.tgz", + "integrity": "sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ==", + "dev": true + }, + "remark-mdx": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-1.6.22.tgz", + "integrity": "sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ==", + "dev": true, + "requires": { + "@babel/core": "7.12.9", + "@babel/helper-plugin-utils": "7.10.4", + "@babel/plugin-proposal-object-rest-spread": "7.12.1", + "@babel/plugin-syntax-jsx": "7.12.1", + "@mdx-js/util": "1.6.22", + "is-alphabetical": "1.0.4", + "remark-parse": "8.0.3", + "unified": "9.2.0" + }, + "dependencies": { + "@babel/core": { + "version": "7.12.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz", + "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.5", + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helpers": "^7.12.5", + "@babel/parser": "^7.12.7", + "@babel/template": "^7.12.7", + "@babel/traverse": "^7.12.9", + "@babel/types": "^7.12.7", + "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" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", + "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-transform-parameters": "^7.12.1" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", + "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "remark-parse": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.3.tgz", + "integrity": "sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==", + "dev": true, + "requires": { + "ccount": "^1.0.0", + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^2.0.0", + "vfile-location": "^3.0.0", + "xtend": "^4.0.1" + } + }, + "remark-slug": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/remark-slug/-/remark-slug-6.1.0.tgz", + "integrity": "sha512-oGCxDF9deA8phWvxFuyr3oSJsdyUAxMFbA0mZ7Y1Sas+emILtO+e5WutF9564gDsEN4IXaQXm5pFo6MLH+YmwQ==", + "dev": true, + "requires": { + "github-slugger": "^1.0.0", + "mdast-util-to-string": "^1.0.0", + "unist-util-visit": "^2.0.0" + } + }, + "remark-squeeze-paragraphs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz", + "integrity": "sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw==", + "dev": true, + "requires": { + "mdast-squeeze-paragraphs": "^4.0.0" + } + }, "remove-bom-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", @@ -17868,6 +24325,33 @@ "randombytes": "^2.1.0" } }, + "serve-favicon": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz", + "integrity": "sha1-k10kDN/g9YBTB/3+ln2IlCosvPA=", + "dev": true, + "requires": { + "etag": "~1.8.1", + "fresh": "0.5.2", + "ms": "2.1.1", + "parseurl": "~1.3.2", + "safe-buffer": "5.1.1" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + } + } + }, "serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", @@ -17974,6 +24458,21 @@ "safe-buffer": "^5.0.1" } }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "dev": true + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -18285,6 +24784,12 @@ "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" }, + "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==", + "dev": true + }, "spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -18400,6 +24905,12 @@ "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==" }, + "state-toggle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", + "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", + "dev": true + }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -18429,6 +24940,25 @@ "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" }, + "store2": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/store2/-/store2-2.12.0.tgz", + "integrity": "sha512-7t+/wpKLanLzSnQPX8WAcuLCCeuSHoWdQuh9SB3xD0kNOM38DNf+0Oa+wmvxmYueRzkmh6IcdKFtvTa+ecgPDw==", + "dev": true + }, + "storybook-addon-outline": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/storybook-addon-outline/-/storybook-addon-outline-1.4.1.tgz", + "integrity": "sha512-Qvv9X86CoONbi+kYY78zQcTGmCgFaewYnOVR6WL7aOFJoW7TrLiIc/O4hH5X9PsEPZFqjfXEPUPENWVUQim6yw==", + "dev": true, + "requires": { + "@storybook/addons": "^6.3.0", + "@storybook/api": "^6.3.0", + "@storybook/components": "^6.3.0", + "@storybook/core-events": "^6.3.0", + "ts-dedent": "^2.1.1" + } + }, "stream-browserify": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", @@ -18557,43 +25087,187 @@ "strip-ansi": "^6.0.0" } }, - "string.prototype.matchall": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz", - "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==", + "string.prototype.matchall": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz", + "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.3.1", + "side-channel": "^1.0.4" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "requires": { + "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.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "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.1" + } + } + } + }, + "string.prototype.padend": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz", + "integrity": "sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.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.1" + } + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "dev": true + } + } + }, + "string.prototype.padstart": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/string.prototype.padstart/-/string.prototype.padstart-3.1.3.tgz", + "integrity": "sha512-NZydyOMtYxpTjGqp0VN5PYUF/tsU15yDMZnUdj16qRUIUiMJkHHSDElYyQFrMu+/WloTpA7MQSiADhBicDfaoA==", + "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.2", - "get-intrinsic": "^1.1.1", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.3.1", - "side-channel": "^1.0.4" + "es-abstract": "^1.19.1" }, "dependencies": { "es-abstract": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", - "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "dev": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", "has": "^1.0.3", "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", - "object-inspect": "^1.10.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.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.1" } + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "dev": true } } }, @@ -18701,6 +25375,15 @@ "schema-utils": "^2.7.0" } }, + "style-to-object": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", + "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", + "dev": true, + "requires": { + "inline-style-parser": "0.1.1" + } + }, "stylehacks": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", @@ -18790,6 +25473,18 @@ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, + "symbol.prototype.description": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/symbol.prototype.description/-/symbol.prototype.description-1.0.5.tgz", + "integrity": "sha512-x738iXRYsrAt9WBhRCVG5BtIC3B7CUkFwbHW2zOvGtwM33s7JjrCDyq8V0zgMYVb5ymsL8+qkzzpANH63CPQaQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-symbol-description": "^1.0.0", + "has-symbols": "^1.0.2", + "object.getownpropertydescriptors": "^2.1.2" + } + }, "symlink-or-copy": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/symlink-or-copy/-/symlink-or-copy-1.3.1.tgz", @@ -18883,6 +25578,30 @@ } } }, + "telejson": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/telejson/-/telejson-5.3.3.tgz", + "integrity": "sha512-PjqkJZpzEggA9TBpVtJi1LVptP7tYtXB6rEubwlHap76AMjzvOdKX41CxyaW7ahhzDU1aftXnMCx5kAPDZTQBA==", + "dev": true, + "requires": { + "@types/is-function": "^1.0.0", + "global": "^4.4.0", + "is-function": "^1.0.2", + "is-regex": "^1.1.2", + "is-symbol": "^1.0.3", + "isobject": "^4.0.0", + "lodash": "^4.17.21", + "memoizerific": "^1.11.3" + }, + "dependencies": { + "isobject": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "dev": true + } + } + }, "temp-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", @@ -18905,6 +25624,12 @@ } } }, + "term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true + }, "terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -19040,6 +25765,12 @@ "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" }, + "throttle-debounce": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", + "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==", + "dev": true + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -19207,6 +25938,12 @@ "through2": "^2.0.3" } }, + "toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=", + "dev": true + }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", @@ -19242,11 +25979,41 @@ "punycode": "^2.1.1" } }, + "trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "dev": true + }, + "trim-trailing-lines": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", + "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", + "dev": true + }, + "trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "dev": true + }, "tryer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" }, + "ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "dev": true + }, + "ts-essentials": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-2.0.12.tgz", + "integrity": "sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w==", + "dev": true + }, "ts-pnp": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", @@ -19386,6 +26153,22 @@ "util-deprecate": "^1.0.2" } }, + "unfetch": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", + "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==", + "dev": true + }, + "unherit": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", + "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", + "dev": true, + "requires": { + "inherits": "^2.0.0", + "xtend": "^4.0.0" + } + }, "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", @@ -19410,6 +26193,34 @@ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==" }, + "unified": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", + "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", + "dev": true, + "requires": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", + "trough": "^1.0.0", + "vfile": "^4.0.0" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + } + } + }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -19465,6 +26276,78 @@ "crypto-random-string": "^1.0.0" } }, + "unist-builder": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz", + "integrity": "sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==", + "dev": true + }, + "unist-util-generated": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz", + "integrity": "sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==", + "dev": true + }, + "unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "dev": true + }, + "unist-util-position": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", + "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", + "dev": true + }, + "unist-util-remove": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-2.1.0.tgz", + "integrity": "sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q==", + "dev": true, + "requires": { + "unist-util-is": "^4.0.0" + } + }, + "unist-util-remove-position": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz", + "integrity": "sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==", + "dev": true, + "requires": { + "unist-util-visit": "^2.0.0" + } + }, + "unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "requires": { + "@types/unist": "^2.0.2" + } + }, + "unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -19583,9 +26466,9 @@ } }, "url-parse": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.7.tgz", - "integrity": "sha512-HxWkieX+STA38EDk7CE9MEryFeHCKzgagxlGvsdS7WBImq9Mk+PGwiT56w82WI3aicwJA8REp42Cxo98c8FZMA==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz", + "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==", "requires": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -19596,6 +26479,30 @@ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, + "use-composed-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.1.0.tgz", + "integrity": "sha512-my1lNHGWsSDAhhVAT4MKs6IjBUtG6ZG11uUqexPH9PptiIZDQOzaF4f5tEbJ2+7qvNbtXNBbU3SfmN+fXlWDhg==", + "dev": true, + "requires": { + "ts-essentials": "^2.0.3" + } + }, + "use-isomorphic-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.1.tgz", + "integrity": "sha512-L7Evj8FGcwo/wpbv/qvSfrkHFtOpCzvM5yl2KVyDJoylVuSvzphiiasmjgQPttIGBAy2WKiBNR98q8w7PiNgKQ==", + "dev": true + }, + "use-latest": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.0.tgz", + "integrity": "sha512-d2TEuG6nSLKQLAfW3By8mKr8HurOlTkul0sOpxbClIv4SQ4iOd7BYr7VIzdbktUCnv7dua/60xzd8igMU6jmyw==", + "dev": true, + "requires": { + "use-isomorphic-layout-effect": "^1.0.0" + } + }, "util": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", @@ -19643,6 +26550,12 @@ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "optional": true }, + "uuid-browser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid-browser/-/uuid-browser-3.1.0.tgz", + "integrity": "sha1-DwWkCu90+eWVHiDvv0SxGHHlZBA=", + "dev": true + }, "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -19705,6 +26618,42 @@ "extsprintf": "^1.2.0" } }, + "vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true + } + } + }, + "vfile-location": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", + "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==", + "dev": true + }, + "vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + } + }, "vinyl": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", @@ -19858,6 +26807,15 @@ "makeerror": "1.0.x" } }, + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, "watchpack": { "version": "1.7.5", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", @@ -20119,6 +27077,12 @@ "minimalistic-assert": "^1.0.0" } }, + "web-namespaces": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", + "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==", + "dev": true + }, "webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", @@ -20886,6 +27850,38 @@ } } }, + "webpack-filter-warnings-plugin": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/webpack-filter-warnings-plugin/-/webpack-filter-warnings-plugin-1.2.1.tgz", + "integrity": "sha512-Ez6ytc9IseDMLPo0qCuNNYzgtUl8NovOqjIq4uAU8LTD4uoa1w1KpZyyzFtLTEMZpkkOkLfL9eN+KGYdk1Qtwg==", + "dev": true + }, + "webpack-hot-middleware": { + "version": "2.25.1", + "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.25.1.tgz", + "integrity": "sha512-Koh0KyU/RPYwel/khxbsDz9ibDivmUbrRuKSSQvW42KSDdO4w23WI3SkHpSUKHE76LrFnnM/L7JCrpBwu8AXYw==", + "dev": true, + "requires": { + "ansi-html-community": "0.0.8", + "html-entities": "^2.1.0", + "querystring": "^0.2.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true + }, + "html-entities": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.2.tgz", + "integrity": "sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==", + "dev": true + } + } + }, "webpack-log": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", @@ -20952,6 +27948,26 @@ "source-map": "~0.6.1" } }, + "webpack-virtual-modules": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.2.2.tgz", + "integrity": "sha512-kDUmfm3BZrei0y+1NTHJInejzxfhtU8eDj2M7OKb2IWrPFAeO1SOH2KuQ68MSZu9IGEHcxbkKKR1v18FrUSOmA==", + "dev": true, + "requires": { + "debug": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, "websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", @@ -21026,6 +28042,24 @@ "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", "dev": true }, + "wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "requires": { + "string-width": "^4.0.0" + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -21399,6 +28433,12 @@ "integrity": "sha512-sFPkHQjVKheDNnPvotjQmm3KD3uk1fWKUN7CrpdbwmUx3CrG3QiM8QpTSimvig5vTXmTvjz7+TDvXOI9+4rkcg==" } } + }, + "zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "dev": true } } } diff --git a/frontend/package.json b/frontend/package.json index fc8b79224..fa272d00f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -24,6 +24,7 @@ "@types/react-window": "^1.8.2", "@types/semver": "^7.3.6", "@types/yup": "^0.29.12", + "cross-env": "^7.0.3", "dompurify": "^2.2.9", "downshift": "^6.1.3", "formik": "^2.2.9", @@ -54,6 +55,13 @@ "@iconify/react": "^1.1.3", "@iconify/tools": "^1.3.9", "@kinvolk/eslint-config": "^0.5.0", + "@storybook/addon-actions": "6.3.12", + "@storybook/addon-essentials": "6.3.12", + "@storybook/addon-links": "6.3.12", + "@storybook/addon-storyshots": "6.3.12", + "@storybook/node-logger": "6.3.12", + "@storybook/preset-create-react-app": "^3.2.0", + "@storybook/react": "^6.3.12", "@types/react-router-dom": "^5.1.7", "@types/underscore": "^1.11.3", "eslint-config-prettier": "^8.3.0", @@ -69,17 +77,19 @@ "prettier": "^2.3.2" }, "scripts": { - "build-icons": "node tools/build-icons.js ./src/img ./src/js/icons", - "start": "npm run build-icons && react-scripts start", - "build": "npm run build-icons && react-scripts build", - "test": "react-scripts test --silent", - "test:coverage": "react-scripts test --silent --watchAll=false --env=jsdom --coverage --reporters=default --coverageDirectory=coverage/report", + "build-icons": "node tools/build-icons.js ./src/img ./src/icons && npm run format", + "start": "react-scripts start", + "build": "react-scripts build", + "test": "cross-env TEST_TZ=true react-scripts test --silent", + "test:coverage": "cross-env TEST_TZ=true react-scripts test --silent --watchAll=false --env=jsdom --coverage --reporters=default --coverageDirectory=coverage/report", "eject": "react-scripts eject", "lint": "eslint -c package.json 'src/**/*.{js,jsx,ts,tsx}' && prettier --config package.json --check src/", "format": "prettier --config package.json --write src/", "lint:fix": "eslint -c package.json --fix 'src/**/*.{js,jsx,ts,tsx}'", "i18n": "npx --no-install i18next ./src/**/ts* ./src/**/**/*.ts* ./src/**/**/**/*.ts* -c ./src/i18n/i18next-parser.config.js", - "tsc": "tsc" + "tsc": "tsc", + "storybook": "start-storybook -p 6006 -s public", + "build-storybook": "build-storybook -s public" }, "browserslist": { "production": [ @@ -111,7 +121,36 @@ "@kinvolk", "prettier", "plugin:jsx-a11y/recommended" + ], + "overrides": [ + { + "files": [ + "**/*.stories.*" + ], + "rules": { + "import/no-anonymous-default-export": "off" + } + } ] }, - "prettier": "@kinvolk/eslint-config/prettier-config" + "prettier": "@kinvolk/eslint-config/prettier-config", + "jest": { + "collectCoverageFrom": [ + "src/**/*.{js,jsx,ts,tsx}", + "!/node_modules/", + "!/build/", + "!src/**/*.stories*.{js,jsx,ts,tsx}" + ], + "coverageThreshold": { + "global": { + "statements": 34.95, + "branches": 26.29, + "functions": 30.35, + "lines": 35.3 + } + }, + "coverageReporters": [ + "text" + ] + } } diff --git a/frontend/src/js/App.tsx b/frontend/src/App.tsx similarity index 89% rename from frontend/src/js/App.tsx rename to frontend/src/App.tsx index eefdebd74..9a10945dd 100644 --- a/frontend/src/js/App.tsx +++ b/frontend/src/App.tsx @@ -2,7 +2,7 @@ import './i18n/config'; import React from 'react'; import { Provider } from 'react-redux'; import { Route } from 'react-router-dom'; -import Main from './components/Main.'; +import Main from './components/Main'; import store from './stores/redux/store'; var AppRoutes = function () { diff --git a/frontend/src/js/TestHelpers/theme.ts b/frontend/src/TestHelpers/theme.ts similarity index 100% rename from frontend/src/js/TestHelpers/theme.ts rename to frontend/src/TestHelpers/theme.ts diff --git a/frontend/src/js/__tests__/Common/ConfirmationContent.spec.js b/frontend/src/__tests__/Common/ConfirmationContent.spec.js similarity index 78% rename from frontend/src/js/__tests__/Common/ConfirmationContent.spec.js rename to frontend/src/__tests__/Common/ConfirmationContent.spec.js index 0c9149876..618002605 100644 --- a/frontend/src/js/__tests__/Common/ConfirmationContent.spec.js +++ b/frontend/src/__tests__/Common/ConfirmationContent.spec.js @@ -1,7 +1,7 @@ import '../../i18n/config.ts'; import { fireEvent, render } from '@testing-library/react'; import React from 'react'; -import ConfirmationContent from '../../components/Common/ConfirmationContent'; +import ConfirmationContent from '../../components/common/ConfirmationContent'; import { applicationsStore } from '../../stores/Stores'; function mockResolver() { @@ -20,11 +20,11 @@ describe('Confirmation Content', () => { expect(asFragment()).toMatchSnapshot(); }); it('should call delete handler function on yes confirmation', () => { - applicationsStore.deleteApplication = mockResolver; - const deleteApp = applicationsStore.deleteApplication; + applicationsStore().deleteApplication = mockResolver; + const deleteApp = applicationsStore().deleteApplication; const { getByText } = render(); fireEvent.click(getByText('Yes')); expect(mockResolver).toHaveBeenCalled(); - applicationsStore.deleteApplication = deleteApp; + applicationsStore().deleteApplication = deleteApp; }); }); diff --git a/frontend/src/js/__tests__/Common/EmptyContent.spec.js b/frontend/src/__tests__/Common/EmptyContent.spec.js similarity index 82% rename from frontend/src/js/__tests__/Common/EmptyContent.spec.js rename to frontend/src/__tests__/Common/EmptyContent.spec.js index 8c00f2188..1f3352d9f 100644 --- a/frontend/src/js/__tests__/Common/EmptyContent.spec.js +++ b/frontend/src/__tests__/Common/EmptyContent.spec.js @@ -1,6 +1,6 @@ import { render } from '@testing-library/react'; import React from 'react'; -import Empty from '../../components/Common/EmptyContent'; +import Empty from '../../components/common/EmptyContent'; describe('Empty', () => { it('renders correct content', () => { diff --git a/frontend/src/js/__tests__/Common/Label.spec.js b/frontend/src/__tests__/Common/Label.spec.js similarity index 88% rename from frontend/src/js/__tests__/Common/Label.spec.js rename to frontend/src/__tests__/Common/Label.spec.js index 03d1f3cec..e202213ba 100644 --- a/frontend/src/js/__tests__/Common/Label.spec.js +++ b/frontend/src/__tests__/Common/Label.spec.js @@ -1,6 +1,6 @@ import { render } from '@testing-library/react'; import React from 'react'; -import Label from '../../components/Common/Label'; +import Label from '../../components/common/Label'; describe('Label', () => { const minProps = { diff --git a/frontend/src/js/__tests__/Common/ListHeader.spec.js b/frontend/src/__tests__/Common/ListHeader.spec.js similarity index 84% rename from frontend/src/js/__tests__/Common/ListHeader.spec.js rename to frontend/src/__tests__/Common/ListHeader.spec.js index a77b22923..ec5c559eb 100644 --- a/frontend/src/js/__tests__/Common/ListHeader.spec.js +++ b/frontend/src/__tests__/Common/ListHeader.spec.js @@ -1,8 +1,8 @@ import '../../i18n/config.ts'; import { render } from '@testing-library/react'; import React from 'react'; -import ListHeader from '../../components/Common/ListHeader'; -import ModalButton from '../../components/Common/ModalButton'; +import ListHeader from '../../components/common/ListHeader'; +import ModalButton from '../../components/common/ModalButton'; describe('List Header', () => { const minProps = { diff --git a/frontend/src/js/__tests__/Common/ListItem.spec.js b/frontend/src/__tests__/Common/ListItem.spec.js similarity index 82% rename from frontend/src/js/__tests__/Common/ListItem.spec.js rename to frontend/src/__tests__/Common/ListItem.spec.js index b0d2912d8..30e187337 100644 --- a/frontend/src/js/__tests__/Common/ListItem.spec.js +++ b/frontend/src/__tests__/Common/ListItem.spec.js @@ -1,6 +1,6 @@ import { render } from '@testing-library/react'; import React from 'react'; -import ListItem from '../../components/Common/ListItem'; +import ListItem from '../../components/common/ListItem'; describe('List Item', () => { it('should render correct list item', () => { diff --git a/frontend/src/js/__tests__/Common/ListSearch.spec.js b/frontend/src/__tests__/Common/ListSearch.spec.js similarity index 82% rename from frontend/src/js/__tests__/Common/ListSearch.spec.js rename to frontend/src/__tests__/Common/ListSearch.spec.js index 13ceba2fc..eb75442f4 100644 --- a/frontend/src/js/__tests__/Common/ListSearch.spec.js +++ b/frontend/src/__tests__/Common/ListSearch.spec.js @@ -1,7 +1,7 @@ import '../../i18n/config.ts'; import { render } from '@testing-library/react'; import React from 'react'; -import SearchInput from '../../components/Common/ListSearch'; +import SearchInput from '../../components/common/ListSearch'; describe('List Search', () => { it('should render correct ListSearch', () => { diff --git a/frontend/src/js/__tests__/Common/Loader.spec.js b/frontend/src/__tests__/Common/Loader.spec.js similarity index 89% rename from frontend/src/js/__tests__/Common/Loader.spec.js rename to frontend/src/__tests__/Common/Loader.spec.js index c20cd0bdd..da8566ff1 100644 --- a/frontend/src/js/__tests__/Common/Loader.spec.js +++ b/frontend/src/__tests__/Common/Loader.spec.js @@ -1,6 +1,6 @@ import { render } from '@testing-library/react'; import React from 'react'; -import Loader from '../../components/Common/Loader'; +import Loader from '../../components/common/Loader'; describe('Loader', () => { it('should render loader without container', () => { diff --git a/frontend/src/js/__tests__/Common/ModalButton.spec.js b/frontend/src/__tests__/Common/ModalButton.spec.js similarity index 95% rename from frontend/src/js/__tests__/Common/ModalButton.spec.js rename to frontend/src/__tests__/Common/ModalButton.spec.js index d74c3933c..a19ea21fe 100644 --- a/frontend/src/js/__tests__/Common/ModalButton.spec.js +++ b/frontend/src/__tests__/Common/ModalButton.spec.js @@ -1,7 +1,7 @@ import { MuiThemeProvider } from '@material-ui/core/styles'; import { fireEvent, render } from '@testing-library/react'; import React from 'react'; -import ModalButton from '../../components/Common/ModalButton'; +import ModalButton from '../../components/common/ModalButton'; import { theme } from '../../TestHelpers/theme'; describe('Modal Button', () => { diff --git a/frontend/src/js/__tests__/Common/MoreMenu.spec.js b/frontend/src/__tests__/Common/MoreMenu.spec.js similarity index 89% rename from frontend/src/js/__tests__/Common/MoreMenu.spec.js rename to frontend/src/__tests__/Common/MoreMenu.spec.js index a66b2e2dc..bfeb6a1d4 100644 --- a/frontend/src/js/__tests__/Common/MoreMenu.spec.js +++ b/frontend/src/__tests__/Common/MoreMenu.spec.js @@ -1,6 +1,6 @@ import { render } from '@testing-library/react'; import React from 'react'; -import MoreMenu from '../../components/Common/MoreMenu'; +import MoreMenu from '../../components/common/MoreMenu'; describe('More Menu', () => { it('should render correct list of menu item', () => { diff --git a/frontend/src/js/__tests__/Common/SectionHeader.spec.js b/frontend/src/__tests__/Common/SectionHeader.spec.js similarity index 89% rename from frontend/src/js/__tests__/Common/SectionHeader.spec.js rename to frontend/src/__tests__/Common/SectionHeader.spec.js index f37b8756b..4efd3f65c 100644 --- a/frontend/src/js/__tests__/Common/SectionHeader.spec.js +++ b/frontend/src/__tests__/Common/SectionHeader.spec.js @@ -2,7 +2,7 @@ import '../../i18n/config.ts'; import { render } from '@testing-library/react'; import React from 'react'; import { BrowserRouter } from 'react-router-dom'; -import SectionHeader from '../../components/Common/SectionHeader'; +import SectionHeader from '../../components/common/SectionHeader'; describe('Section Header', () => { const minProps = { diff --git a/frontend/src/js/__tests__/Common/SimpleTable.spec.js b/frontend/src/__tests__/Common/SimpleTable.spec.js similarity index 91% rename from frontend/src/js/__tests__/Common/SimpleTable.spec.js rename to frontend/src/__tests__/Common/SimpleTable.spec.js index c1a9da7a5..a71bc2df1 100644 --- a/frontend/src/js/__tests__/Common/SimpleTable.spec.js +++ b/frontend/src/__tests__/Common/SimpleTable.spec.js @@ -1,6 +1,6 @@ import { render } from '@testing-library/react'; import React from 'react'; -import SimpleTable from '../../components/Common/SimpleTable'; +import SimpleTable from '../../components/common/SimpleTable'; describe('Simple Table', () => { const minProps = { diff --git a/frontend/src/js/__tests__/Common/TimeIntervalLinks.spec.js b/frontend/src/__tests__/Common/TimeIntervalLinks.spec.js similarity index 88% rename from frontend/src/js/__tests__/Common/TimeIntervalLinks.spec.js rename to frontend/src/__tests__/Common/TimeIntervalLinks.spec.js index 879089f7e..78937c400 100644 --- a/frontend/src/js/__tests__/Common/TimeIntervalLinks.spec.js +++ b/frontend/src/__tests__/Common/TimeIntervalLinks.spec.js @@ -1,6 +1,6 @@ import { render } from '@testing-library/react'; import React from 'react'; -import TimeIntervalLinks from '../../components/Common/TimeIntervalLinks'; +import TimeIntervalLinks from '../../components/common/TimeIntervalLinks'; import { defaultTimeInterval, timeIntervalsDefault } from '../../utils/helpers'; describe('TimeIntervalLinks', () => { diff --git a/frontend/src/js/__tests__/Common/TimeZonePicker.spec.js b/frontend/src/__tests__/Common/TimeZonePicker.spec.js similarity index 89% rename from frontend/src/js/__tests__/Common/TimeZonePicker.spec.js rename to frontend/src/__tests__/Common/TimeZonePicker.spec.js index 19068685a..42a95b480 100644 --- a/frontend/src/js/__tests__/Common/TimeZonePicker.spec.js +++ b/frontend/src/__tests__/Common/TimeZonePicker.spec.js @@ -1,7 +1,7 @@ import '../../i18n/config.ts'; import { fireEvent, render } from '@testing-library/react'; import React from 'react'; -import TimezonePicker from '../../components/Common/TimezonePicker'; +import TimezonePicker from '../../components/common/TimezonePicker'; describe('TimeZonePicker', () => { it('should render suggestions on inputing timezone', () => { diff --git a/frontend/src/js/__tests__/Common/__snapshots__/ConfirmationContent.spec.js.snap b/frontend/src/__tests__/Common/__snapshots__/ConfirmationContent.spec.js.snap similarity index 100% rename from frontend/src/js/__tests__/Common/__snapshots__/ConfirmationContent.spec.js.snap rename to frontend/src/__tests__/Common/__snapshots__/ConfirmationContent.spec.js.snap diff --git a/frontend/src/js/__tests__/Common/__snapshots__/EmptyContent.spec.js.snap b/frontend/src/__tests__/Common/__snapshots__/EmptyContent.spec.js.snap similarity index 100% rename from frontend/src/js/__tests__/Common/__snapshots__/EmptyContent.spec.js.snap rename to frontend/src/__tests__/Common/__snapshots__/EmptyContent.spec.js.snap diff --git a/frontend/src/js/__tests__/Common/__snapshots__/Label.spec.js.snap b/frontend/src/__tests__/Common/__snapshots__/Label.spec.js.snap similarity index 100% rename from frontend/src/js/__tests__/Common/__snapshots__/Label.spec.js.snap rename to frontend/src/__tests__/Common/__snapshots__/Label.spec.js.snap diff --git a/frontend/src/js/__tests__/Common/__snapshots__/ListHeader.spec.js.snap b/frontend/src/__tests__/Common/__snapshots__/ListHeader.spec.js.snap similarity index 100% rename from frontend/src/js/__tests__/Common/__snapshots__/ListHeader.spec.js.snap rename to frontend/src/__tests__/Common/__snapshots__/ListHeader.spec.js.snap diff --git a/frontend/src/js/__tests__/Common/__snapshots__/ListSearch.spec.js.snap b/frontend/src/__tests__/Common/__snapshots__/ListSearch.spec.js.snap similarity index 100% rename from frontend/src/js/__tests__/Common/__snapshots__/ListSearch.spec.js.snap rename to frontend/src/__tests__/Common/__snapshots__/ListSearch.spec.js.snap diff --git a/frontend/src/js/__tests__/Common/__snapshots__/SectionHeader.spec.js.snap b/frontend/src/__tests__/Common/__snapshots__/SectionHeader.spec.js.snap similarity index 100% rename from frontend/src/js/__tests__/Common/__snapshots__/SectionHeader.spec.js.snap rename to frontend/src/__tests__/Common/__snapshots__/SectionHeader.spec.js.snap diff --git a/frontend/src/js/api/API.ts b/frontend/src/api/API.ts similarity index 98% rename from frontend/src/js/api/API.ts rename to frontend/src/api/API.ts index f4d57abf5..02fee216a 100644 --- a/frontend/src/js/api/API.ts +++ b/frontend/src/api/API.ts @@ -1,5 +1,6 @@ import PubSub from 'pubsub-js'; import queryString from 'querystring'; +import { createContext } from 'react'; import _ from 'underscore'; import { CONFIG_STORAGE_KEY, NebraskaConfig } from '../stores/redux/features/config'; import { getToken, setToken } from '../utils/auth'; @@ -18,6 +19,7 @@ import { type WithCount = T & { count: number; + totalCount: number; }; const MAIN_PROGRESS_BAR = 'main_progress_bar'; @@ -33,7 +35,7 @@ type REQUEST_DATA_TYPE = | null | undefined; -class API { +export default class API { // Applications static getApplications(): Promise> { @@ -374,4 +376,4 @@ class API { } } -export default API; +export const APIContext = createContext(API); diff --git a/frontend/src/js/api/apiDataTypes.ts b/frontend/src/api/apiDataTypes.ts similarity index 95% rename from frontend/src/js/api/apiDataTypes.ts rename to frontend/src/api/apiDataTypes.ts index bc647f5f7..c18810b5a 100644 --- a/frontend/src/js/api/apiDataTypes.ts +++ b/frontend/src/api/apiDataTypes.ts @@ -28,7 +28,7 @@ export interface Channel { created_ts: string; application_id: string; package_id: null | string; - package: Package; + package: null | Package; arch: Arch; } @@ -50,9 +50,9 @@ export interface Package { size: null | string; hash: null | string; created_ts: string; - channels_blacklist: string[]; + channels_blacklist: null | string[]; application_id: string; - flatcar_action?: FlatcarAction; + flatcar_action?: null | FlatcarAction; arch: Arch; extra_files: File[]; } @@ -88,6 +88,7 @@ export interface Application { } export interface Activity { + id: number; app_id: string; group_id: string; created_ts: string; diff --git a/frontend/src/components/Activity/ActivityContainer.stories.tsx b/frontend/src/components/Activity/ActivityContainer.stories.tsx new file mode 100644 index 000000000..0458aaa3f --- /dev/null +++ b/frontend/src/components/Activity/ActivityContainer.stories.tsx @@ -0,0 +1,153 @@ +import { Meta, Story } from '@storybook/react/types-6-0'; +import { MemoryRouter } from 'react-router-dom'; +import { activityStore } from '../../stores/Stores'; +import ActivityContainer, { ActivityContainerProps } from './ActivityContainer'; + +export default { + title: 'activity/ActivityContainer', +} as Meta; + +const TemplateEmpty: Story = args => { + activityStore(true).stopRefreshing(); + activityStore(true).setActivity([]); + return ( + + + + ); +}; + +export const Empty = TemplateEmpty.bind({}); +Empty.args = {}; + +const TemplateList: Story = args => { + activityStore(true).stopRefreshing(); + activityStore(true).setActivity([ + { + id: 1, + app_id: '', + group_id: '', + created_ts: '2020-05-13T20:26:03.837688+05:30', + class: 6, + severity: 2, + version: '0.0.0', + application_name: 'ABC', + group_name: null, + channel_name: 'beta', + instance_id: null, + }, + { + id: 2, + app_id: '', + group_id: '', + created_ts: '2020-05-13T20:25:52.589886+05:30', + class: 6, + severity: 2, + version: '0.0.0', + application_name: 'DEF', + group_name: null, + channel_name: 'beta', + instance_id: null, + }, + ]); + return ( + + + + ); +}; + +export const List = TemplateList.bind({}); +List.args = {}; + +const TemplateMultipleDays: Story = args => { + activityStore(true).stopRefreshing(); + activityStore(true).setActivity([ + { + id: 1, + app_id: '', + group_id: '', + created_ts: '2020-05-13T20:26:03.837688+05:30', + class: 6, + severity: 2, + version: '0.0.0', + application_name: 'ABC', + group_name: null, + channel_name: 'beta', + instance_id: null, + }, + { + id: 2, + app_id: '', + group_id: '', + created_ts: '2020-05-13T20:25:52.589886+05:30', + class: 6, + severity: 2, + version: '0.0.0', + application_name: 'DEF', + group_name: null, + channel_name: 'beta', + instance_id: null, + }, + { + id: 3, + app_id: '', + group_id: '', + created_ts: '2020-05-14T20:26:03.837688+05:30', + class: 6, + severity: 1, + version: '0.0.1', + application_name: 'DEB', + group_name: null, + channel_name: 'beta', + instance_id: null, + }, + { + id: 4, + app_id: '', + group_id: '', + created_ts: '2020-05-14T20:25:52.589886+05:30', + class: 6, + severity: 3, + version: '0.0.1', + application_name: 'DOF', + group_name: null, + channel_name: 'beta', + instance_id: null, + }, + { + id: 5, + app_id: '', + group_id: '', + created_ts: '2020-05-14T20:26:03.837688+05:30', + class: 6, + severity: 1, + version: '0.0.1', + application_name: 'DAL', + group_name: null, + channel_name: 'alpha', + instance_id: null, + }, + { + id: 6, + app_id: '', + group_id: '', + created_ts: '2020-05-14T20:25:52.589886+05:30', + class: 6, + severity: 3, + version: '0.0.1', + application_name: 'DOP', + group_name: null, + channel_name: 'alpha', + instance_id: null, + }, + ]); + return ( + + + + ); +}; + +export const MultipleDays = TemplateMultipleDays.bind({}); +MultipleDays.args = {}; diff --git a/frontend/src/js/components/Activity/Container.tsx b/frontend/src/components/Activity/ActivityContainer.tsx similarity index 85% rename from frontend/src/js/components/Activity/Container.tsx rename to frontend/src/components/Activity/ActivityContainer.tsx index 86d3b1ce3..5fc838e29 100644 --- a/frontend/src/js/components/Activity/Container.tsx +++ b/frontend/src/components/Activity/ActivityContainer.tsx @@ -8,10 +8,10 @@ import { Trans, useTranslation } from 'react-i18next'; import _ from 'underscore'; import { Activity } from '../../api/apiDataTypes'; import { activityStore } from '../../stores/Stores'; -import Empty from '../Common/EmptyContent'; -import ListHeader from '../Common/ListHeader'; -import Loader from '../Common/Loader'; -import List from './List'; +import Empty from '../common/EmptyContent'; +import ListHeader from '../common/ListHeader'; +import Loader from '../common/Loader'; +import ActivityList from './ActivityList'; const useStyles = makeStyles({ toolbar: { @@ -25,6 +25,8 @@ const useStyles = makeStyles({ }, }); +export interface ActivityContainerProps {} + function Container() { const classes = useStyles(); const { t } = useTranslation(); @@ -35,10 +37,10 @@ function Container() { const [rowsPerPage, setRowsPerPage] = React.useState(rowsOptions[0]); React.useEffect(() => { - activityStore.addChangeListener(onChange); + activityStore().addChangeListener(onChange); return function cleanup() { - activityStore.removeChangeListener(onChange); + activityStore().removeChangeListener(onChange); }; }, [activity]); @@ -62,7 +64,7 @@ function Container() { } function getPagedActivity() { - const entriesPerTime: { [key: string]: any } = {}; + const entriesPerTime: { [key: string]: Activity[] } = {}; let timestamp = null; if (!activity) { return entriesPerTime; @@ -86,7 +88,7 @@ function Container() { } function getActivityEntries() { - const activityObj = activityStore.getCachedActivity(); + const activityObj = activityStore().getCachedActivity(); if (_.isNull(activityObj)) { return null; } @@ -121,8 +123,8 @@ function Container() { {Object.values( - _.mapObject(getPagedActivity(), (entry, timestamp) => { - return ; + _.mapObject(getPagedActivity(), (entries, timestamp) => { + return ; }) )} diff --git a/frontend/src/components/Activity/ActivityItem.stories.tsx b/frontend/src/components/Activity/ActivityItem.stories.tsx new file mode 100644 index 000000000..9451c7e93 --- /dev/null +++ b/frontend/src/components/Activity/ActivityItem.stories.tsx @@ -0,0 +1,38 @@ +import { Meta, Story } from '@storybook/react/types-6-0'; +import { MemoryRouter } from 'react-router-dom'; +import { ActivityItemPure, ActivityItemPureProps } from './ActivityItem'; + +export default { + title: 'activity/ActivityItem', +} as Meta; + +const Template: Story = args => ( + + + +); +export const Warning = Template.bind({}); + +Warning.args = { + createdTs: '2020-05-13T20:26:03.837688+05:30', + appId: 'XXXX-XXX', + groupId: 'YYYY-YYYY', + classType: 'someType', + groupName: 'some group', + appName: 'some app', + description: 'A description', + severityName: 'warning', +}; + +export const ActivityChannelPackageUpdated = Template.bind({}); + +ActivityChannelPackageUpdated.args = { + createdTs: '2020-05-13T20:26:03.837688+05:30', + appId: 'XXXX-XXX', + groupId: 'YYYY-YYYY', + classType: 'activityChannelPackageUpdated', + groupName: 'some group', + appName: 'some app', + description: 'A description', + severityName: 'info', +}; diff --git a/frontend/src/components/Activity/ActivityItem.tsx b/frontend/src/components/Activity/ActivityItem.tsx new file mode 100644 index 000000000..84287707e --- /dev/null +++ b/frontend/src/components/Activity/ActivityItem.tsx @@ -0,0 +1,118 @@ +import { Box, makeStyles } from '@material-ui/core'; +import Grid from '@material-ui/core/Grid'; +import Link from '@material-ui/core/Link'; +import ListItem from '@material-ui/core/ListItem'; +import Typography from '@material-ui/core/Typography'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { Link as RouterLink } from 'react-router-dom'; +import { Activity } from '../../api/apiDataTypes'; +import { toLocaleString } from '../../i18n/dateTime'; +import { activityStore } from '../../stores/Stores'; +import ActivityItemIcon from './ActivityItemIcon'; + +const useStyles = makeStyles({ + groupLink: { + color: '#1b5c91', + }, + appName: { + fontWeight: 'bold', + fontSize: '1.1rem', + color: '#474747', + }, + time: { + fontSize: '.7rem', + }, + list: { + paddingTop: '15px', + paddingLeft: '15px', + }, +}); + +export interface ActivityItemProps { + entry: Activity; +} + +export default function ActivityItem(props: ActivityItemProps) { + const entryClass = activityStore().makeActivityEntryClass(props.entry.class, props.entry); + const entrySeverity = activityStore().makeActivityEntrySeverity(props.entry.severity); + + return ( + + ); +} + +export interface ActivityItemPureProps { + appId: string; + appName: string; + classType: string; + createdTs: string; + description: string | React.ReactElement>; + groupId: string; + groupName: string | null; + severityName: string; +} + +export function ActivityItemPure(props: ActivityItemPureProps) { + const classes = useStyles(); + const { t } = useTranslation(); + + const time = toLocaleString(props.createdTs, undefined, { + hour: '2-digit', + minute: '2-digit', + }); + let subtitle = ''; + let name: React.ReactNode = ''; + + if (props.classType !== 'activityChannelPackageUpdated') { + const groupPath = `apps/${props.appId}/groups/${props.groupId}`; + subtitle = t('activity|GROUP'); + name = ( + + {props.groupName} + + ); + } + + return ( + + + + + + + + + {props.appName} + + + + + + {time} + + + {subtitle && ( + + + + {subtitle} + + + {name} + + )} + {props.description} + + + ); +} diff --git a/frontend/src/components/Activity/ActivityItemIcon.stories.tsx b/frontend/src/components/Activity/ActivityItemIcon.stories.tsx new file mode 100644 index 000000000..06983f3b5 --- /dev/null +++ b/frontend/src/components/Activity/ActivityItemIcon.stories.tsx @@ -0,0 +1,12 @@ +import { Meta } from '@storybook/react/types-6-0'; +import ActivityItemIcon from './ActivityItemIcon'; + +export default { + title: 'activity/ActivityItemIcon', +} as Meta; + +export const Default = () => ; +export const Warning = () => ; +export const Info = () => ; +export const Error = () => ; +export const Success = () => ; diff --git a/frontend/src/components/Activity/ActivityItemIcon.tsx b/frontend/src/components/Activity/ActivityItemIcon.tsx new file mode 100644 index 000000000..b1b8d120a --- /dev/null +++ b/frontend/src/components/Activity/ActivityItemIcon.tsx @@ -0,0 +1,39 @@ +import alertCircleOutline from '@iconify/icons-mdi/alert-circle-outline'; +import alertOutline from '@iconify/icons-mdi/alert-outline'; +import checkCircleOutline from '@iconify/icons-mdi/check-circle-outline'; +import { Icon } from '@iconify/react'; + +export interface ActivityItemIconProps { + severityName?: string; +} + +export default function ActivityItemIcon(props: ActivityItemIconProps) { + const { severityName } = props; + const stateIcon = stateIcons[severityName || 'info']; + + return ; +} + +const stateIcons: { + [key: string]: { + icon: object; + color: string; + }; +} = { + warning: { + icon: alertOutline, + color: '#ff5500', + }, + info: { + icon: alertCircleOutline, + color: '#00d3ff', + }, + error: { + icon: alertCircleOutline, + color: '#F44336', + }, + success: { + icon: checkCircleOutline, + color: '#22bb00', + }, +}; diff --git a/frontend/src/components/Activity/ActivityList.stories.tsx b/frontend/src/components/Activity/ActivityList.stories.tsx new file mode 100644 index 000000000..27090d852 --- /dev/null +++ b/frontend/src/components/Activity/ActivityList.stories.tsx @@ -0,0 +1,52 @@ +import { Meta, Story } from '@storybook/react/types-6-0'; +import { MemoryRouter } from 'react-router-dom'; +import ActivityList, { ActivityListProps } from './ActivityList'; + +export default { + title: 'activity/ActivityList', +} as Meta; + +const Template: Story = args => ( + + + +); + +export const Empty = Template.bind({}); +Empty.args = { + timestamp: 'Wed, 13 May 2020 14:56:03 GMT', +}; + +export const BetaList = Template.bind({}); + +BetaList.args = { + timestamp: 'Wed, 13 May 2020 14:56:03 GMT', + entries: [ + { + id: 1, + app_id: '', + group_id: '', + created_ts: '2020-05-13T20:26:03.837688+05:30', + class: 6, + severity: 2, + version: '0.0.0', + application_name: 'ABC', + group_name: null, + channel_name: 'beta', + instance_id: null, + }, + { + id: 2, + app_id: '', + group_id: '', + created_ts: '2020-05-13T20:25:52.589886+05:30', + class: 6, + severity: 2, + version: '0.0.0', + application_name: 'DEF', + group_name: null, + channel_name: 'beta', + instance_id: null, + }, + ], +}; diff --git a/frontend/src/js/components/Activity/List.tsx b/frontend/src/components/Activity/ActivityList.tsx similarity index 68% rename from frontend/src/js/components/Activity/List.tsx rename to frontend/src/components/Activity/ActivityList.tsx index 4a3318c30..8fab70518 100644 --- a/frontend/src/js/components/Activity/List.tsx +++ b/frontend/src/components/Activity/ActivityList.tsx @@ -3,8 +3,8 @@ import { makeStyles } from '@material-ui/core/styles'; import Typography from '@material-ui/core/Typography'; import React from 'react'; import { Activity } from '../../api/apiDataTypes'; -import { makeLocaleTime } from '../../utils/helpers'; -import Item from './Item'; +import { makeLocaleTime } from '../../i18n/dateTime'; +import ActivityItem from './ActivityItem'; const useStyles = makeStyles({ listTitle: { @@ -12,7 +12,12 @@ const useStyles = makeStyles({ }, }); -function List(props: { entries?: Activity[]; timestamp: string }) { +export interface ActivityListProps { + entries?: Activity[]; + timestamp: string; +} + +export default function ActivityList(props: ActivityListProps) { const classes = useStyles(); const entries = props.entries ? props.entries : []; @@ -25,12 +30,10 @@ function List(props: { entries?: Activity[]; timestamp: string }) { })} - {entries.map((entry: Activity, i: number) => ( - + {entries.map((entry: Activity) => ( + ))} ); } - -export default List; diff --git a/frontend/src/components/Activity/__snapshots__/ActivityContainer.stories.storyshot b/frontend/src/components/Activity/__snapshots__/ActivityContainer.stories.storyshot new file mode 100644 index 000000000..eaf085f1f --- /dev/null +++ b/frontend/src/components/Activity/__snapshots__/ActivityContainer.stories.storyshot @@ -0,0 +1,767 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots activity/ActivityContainer Empty 1`] = ` +
+
+
+
+

+ Activity +

+
+
+
+
+
+
+

+ No activity found for the last week. +
+
+ You will see here important events related to the rollout of your updates. Stay tuned! +

+
+
+
+
+`; + +exports[`Storyshots activity/ActivityContainer List 1`] = ` +
+
+
+
+

+ Activity +

+
+
+
+
+
+
+
+

+ Wednesday, May 13, 2020 +

+
    +
  • +
    +
    +
    +
    + + + +
    +
    +

    + ABC +

    +
    +
    +
    +
    +

    + 02:56 PM +

    +
    + +
    + Channel beta is now pointing to version 0.0.0 +
    +
    +
  • +
  • +
    +
    +
    +
    + + + +
    +
    +

    + DEF +

    +
    +
    +
    +
    +

    + 02:55 PM +

    +
    + +
    + Channel beta is now pointing to version 0.0.0 +
    +
    +
  • +
+
+
+
+
+
+

+ Rows per page: +

+
+
+ 5 +
+ + +
+

+ 1-2 of 2 +

+
+ + +
+
+
+
+
+
+
+
+`; + +exports[`Storyshots activity/ActivityContainer Multiple Days 1`] = ` +
+
+
+
+

+ Activity +

+
+
+
+
+
+
+
+

+ Wednesday, May 13, 2020 +

+
    +
  • +
    +
    +
    +
    + + + +
    +
    +

    + ABC +

    +
    +
    +
    +
    +

    + 02:56 PM +

    +
    + +
    + Channel beta is now pointing to version 0.0.0 +
    +
    +
  • +
  • +
    +
    +
    +
    + + + +
    +
    +

    + DEF +

    +
    +
    +
    +
    +

    + 02:55 PM +

    +
    + +
    + Channel beta is now pointing to version 0.0.0 +
    +
    +
  • +
+

+ Thursday, May 14, 2020 +

+
    +
  • +
    +
    +
    +
    + + + +
    +
    +

    + DEB +

    +
    +
    +
    +
    +

    + 02:56 PM +

    +
    + +
    + Channel beta is now pointing to version 0.0.1 +
    +
    +
  • +
  • +
    +
    +
    +
    + + + +
    +
    +

    + DOF +

    +
    +
    +
    +
    +

    + 02:55 PM +

    +
    + +
    + Channel beta is now pointing to version 0.0.1 +
    +
    +
  • +
  • +
    +
    +
    +
    + + + +
    +
    +

    + DAL +

    +
    +
    +
    +
    +

    + 02:56 PM +

    +
    + +
    + Channel alpha is now pointing to version 0.0.1 +
    +
    +
  • +
+
+
+
+
+
+

+ Rows per page: +

+
+
+ 5 +
+ + +
+

+ 1-5 of 6 +

+
+ + +
+
+
+
+
+
+
+
+`; diff --git a/frontend/src/components/Activity/__snapshots__/ActivityItem.stories.storyshot b/frontend/src/components/Activity/__snapshots__/ActivityItem.stories.storyshot new file mode 100644 index 000000000..18cb917fd --- /dev/null +++ b/frontend/src/components/Activity/__snapshots__/ActivityItem.stories.storyshot @@ -0,0 +1,153 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots activity/ActivityItem Activity Channel Package Updated 1`] = ` +
+
  • +
    +
    +
    +
    + + + +
    +
    +

    + some app +

    +
    +
    +
    +
    +

    + 02:56 PM +

    +
    + +
    + A description +
    +
    +
  • +
    +`; + +exports[`Storyshots activity/ActivityItem Warning 1`] = ` +
    +
  • +
    +
    +
    +
    + + + +
    +
    +

    + some app +

    +
    +
    +
    +
    +

    + 02:56 PM +

    +
    +
    +
    +

    + GROUP +

    +
    + +
    +
    + A description +
    +
    +
  • +
    +`; diff --git a/frontend/src/components/Activity/__snapshots__/ActivityItemIcon.stories.storyshot b/frontend/src/components/Activity/__snapshots__/ActivityItemIcon.stories.storyshot new file mode 100644 index 000000000..ec7ad90ec --- /dev/null +++ b/frontend/src/components/Activity/__snapshots__/ActivityItemIcon.stories.storyshot @@ -0,0 +1,106 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots activity/ActivityItemIcon Default 1`] = ` +
    + + + +
    +`; + +exports[`Storyshots activity/ActivityItemIcon Error 1`] = ` +
    + + + +
    +`; + +exports[`Storyshots activity/ActivityItemIcon Info 1`] = ` +
    + + + +
    +`; + +exports[`Storyshots activity/ActivityItemIcon Success 1`] = ` +
    + + + +
    +`; + +exports[`Storyshots activity/ActivityItemIcon Warning 1`] = ` +
    + + + +
    +`; diff --git a/frontend/src/components/Activity/__snapshots__/ActivityList.stories.storyshot b/frontend/src/components/Activity/__snapshots__/ActivityList.stories.storyshot new file mode 100644 index 000000000..e07f6c3cd --- /dev/null +++ b/frontend/src/components/Activity/__snapshots__/ActivityList.stories.storyshot @@ -0,0 +1,148 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots activity/ActivityList Beta List 1`] = ` +
    +

    + Wednesday, May 13, 2020 +

    +
      +
    • +
      +
      +
      +
      + + + +
      +
      +

      + ABC +

      +
      +
      +
      +
      +

      + 02:56 PM +

      +
      + +
      + Channel beta is now pointing to version 0.0.0 +
      +
      +
    • +
    • +
      +
      +
      +
      + + + +
      +
      +

      + DEF +

      +
      +
      +
      +
      +

      + 02:55 PM +

      +
      + +
      + Channel beta is now pointing to version 0.0.0 +
      +
      +
    • +
    +
    +`; + +exports[`Storyshots activity/ActivityList Empty 1`] = ` +
    +

    + Wednesday, May 13, 2020 +

    +
      +
    +`; diff --git a/frontend/src/js/components/Applications/EditDialog.tsx b/frontend/src/components/Applications/ApplicationEdit.tsx similarity index 93% rename from frontend/src/js/components/Applications/EditDialog.tsx rename to frontend/src/components/Applications/ApplicationEdit.tsx index c0965a810..d236e7c6c 100644 --- a/frontend/src/js/components/Applications/EditDialog.tsx +++ b/frontend/src/components/Applications/ApplicationEdit.tsx @@ -7,13 +7,19 @@ import DialogTitle from '@material-ui/core/DialogTitle'; import MenuItem from '@material-ui/core/MenuItem'; import { Field, Form, Formik } from 'formik'; import { TextField } from 'formik-material-ui'; -import React from 'react'; import { useTranslation } from 'react-i18next'; import * as Yup from 'yup'; import { Application } from '../../api/apiDataTypes'; import { applicationsStore } from '../../stores/Stores'; -function EditDialog(props: { create?: any; data: any; show: boolean; onHide: () => void }) { +export interface ApplicationEditProps { + create?: any; + data: any; + show: boolean; + onHide: () => void; +} + +export default function ApplicationEdit(props: ApplicationEditProps) { const isCreation = Boolean(props.create); const { t } = useTranslation(); @@ -34,9 +40,9 @@ function EditDialog(props: { create?: any; data: any; show: boolean; onHide: () if (values.appToClone === 'none') { values.appToClone = ''; } - appFunctionCall = applicationsStore.createApplication(data, values.appToClone); + appFunctionCall = applicationsStore().createApplication(data, values.appToClone); } else { - appFunctionCall = applicationsStore.updateApplication(props.data.id, data); + appFunctionCall = applicationsStore().updateApplication(props.data.id, data); } appFunctionCall @@ -171,5 +177,3 @@ function EditDialog(props: { create?: any; data: any; show: boolean; onHide: () ); } - -export default EditDialog; diff --git a/frontend/src/components/Applications/ApplicationItem.stories.tsx b/frontend/src/components/Applications/ApplicationItem.stories.tsx new file mode 100644 index 000000000..039f614d8 --- /dev/null +++ b/frontend/src/components/Applications/ApplicationItem.stories.tsx @@ -0,0 +1,98 @@ +import { Meta, Story } from '@storybook/react/types-6-0'; +import { MemoryRouter } from 'react-router-dom'; +import API, { APIContext } from '../../api/API'; +import ApplicationItem, { ApplicationItemProps } from './ApplicationItem'; + +export default { + title: 'applications/ApplicationItem', + argTypes: { + onUpdate: { action: 'onUpdate' }, + }, +} as Meta; + +const Template: Story = args => { + class APIMock extends API { + /* eslint-disable no-unused-vars */ + static getInstancesCount( + applicationID: string, + groupID: string, + duration: string + ): Promise { + return new Promise(resolve => resolve(20)); + } + } + + return ( + + + + + + ); +}; + +export const NoGroups = Template.bind({}); + +NoGroups.args = { + numberOfInstances: 1, + id: '123', + productId: 'xxx-xxx-yyy', + name: 'ABC', + description: 'App Item Description', + groups: [], +}; + +export const Application = Template.bind({}); + +Application.args = { + numberOfInstances: 1, + id: '123', + productId: 'xxx-xxx-yyy', + name: 'ABC', + description: 'App Item Description', + groups: [ + { + id: 'xxx-xxx-1', + name: 'First group', + description: '', + created_ts: '', + rollout_in_progress: false, + application_id: '', + channel_id: null, + policy_updates_enabled: false, + policy_safe_mode: false, + policy_office_hours: false, + policy_timezone: null, + policy_period_interval: '', + policy_max_updates_per_period: 0, + policy_update_timeout: '', + + channel: { + id: 'DEF', + name: 'main', + color: '#777777', + created_ts: '2018-10-16T21:07:56.819939+05:30', + application_id: '123', + package_id: 'XYZ', + package: { + id: 'PACK_ID', + type: 4, + version: '1.11.3', + url: 'https://github.com/kinvolk', + filename: '', + description: '', + size: '', + hash: '', + created_ts: '2019-07-18T20:10:39.163326+05:30', + channels_blacklist: null, + application_id: 'df1c8bbb-f525-49ee-8c94-3ca548b42059', + flatcar_action: null, + arch: 0, + extra_files: [], + }, + arch: 0, + }, + track: '', + }, + ], +}; diff --git a/frontend/src/js/components/Applications/Item.tsx b/frontend/src/components/Applications/ApplicationItem.tsx similarity index 56% rename from frontend/src/js/components/Applications/Item.tsx rename to frontend/src/components/Applications/ApplicationItem.tsx index 74c369ddd..ded6d36dc 100644 --- a/frontend/src/js/components/Applications/Item.tsx +++ b/frontend/src/components/Applications/ApplicationItem.tsx @@ -2,14 +2,13 @@ import { Box, Divider, Typography } from '@material-ui/core'; import Grid from '@material-ui/core/Grid'; import { makeStyles } from '@material-ui/core/styles'; import ScheduleIcon from '@material-ui/icons/Schedule'; -import React from 'react'; import { useTranslation } from 'react-i18next'; -import { Application } from '../../api/apiDataTypes'; +import { Group } from '../../api/apiDataTypes'; import { applicationsStore } from '../../stores/Stores'; -import { CardFeatureLabel, CardHeader, CardLabel } from '../Common/Card'; -import ListItem from '../Common/ListItem'; -import MoreMenu from '../Common/MoreMenu'; -import GroupsList from './ApplicationItemGroupsList'; +import { CardFeatureLabel, CardHeader, CardLabel } from '../common/Card/Card'; +import ListItem from '../common/ListItem'; +import MoreMenu from '../common/MoreMenu'; +import ApplicationItemGroupsList from './ApplicationItemGroupsList'; const useStyles = makeStyles({ root: { @@ -20,49 +19,47 @@ const useStyles = makeStyles({ }, }); -function Item(props: { - application: Application; - handleUpdateApplication: (appID: string) => void; -}) { +export interface ApplicationItemProps { + onUpdate: (appID: string) => void; + description?: string; + groups: Group[]; + numberOfInstances: number; + id: string; + productId: string; + name: string; +} + +export default function ApplicationItem(props: ApplicationItemProps) { const classes = useStyles(); const { t } = useTranslation(); - const description = props.application.description || t('applications|No description provided'); - const groups = props.application.groups || []; - const instances = props.application.instances?.count || t('applications|None'); - const appID = props.application ? props.application.id : ''; - const appProductID = props.application.product_id || ''; - - function updateApplication() { - props.handleUpdateApplication(props.application.id); - } - - function deleteApplication() { - const confirmationText = t('applications|Are you sure you want to delete this application?'); - if (window.confirm(confirmationText)) { - applicationsStore.deleteApplication(props.application.id); - } - } + const { description, groups, numberOfInstances, id, productId, name } = props; return ( props.onUpdate(id), }, { label: t('frequent|Delete'), - action: deleteApplication, + action: () => { + window.confirm( + t('applications|Are you sure you want to delete this application?') + ) + ? applicationsStore().deleteApplication(id) + : null; + }, }, ]} /> @@ -74,7 +71,9 @@ function Item(props: { {t('applications|INSTANCES')} - {instances} + + {numberOfInstances || t('applications|None')} + @@ -95,11 +94,7 @@ function Item(props: { {groups.length === 0 ? t('applications|None') : groups.length} - + @@ -108,5 +103,3 @@ function Item(props: { ); } - -export default Item; diff --git a/frontend/src/js/components/Applications/ApplicationItemChannelsList.tsx b/frontend/src/components/Applications/ApplicationItemChannelsList.tsx similarity index 92% rename from frontend/src/js/components/Applications/ApplicationItemChannelsList.tsx rename to frontend/src/components/Applications/ApplicationItemChannelsList.tsx index a8fb0d97c..9c627c42f 100644 --- a/frontend/src/js/components/Applications/ApplicationItemChannelsList.tsx +++ b/frontend/src/components/Applications/ApplicationItemChannelsList.tsx @@ -1,7 +1,7 @@ import Grid from '@material-ui/core/Grid'; import React from 'react'; import { Channel } from '../../api/apiDataTypes'; -import ChannelItem from '../Channels/Item'; +import ChannelItem from '../Channels/ChannelItem'; function ApplicationItemChannelsList(props: { channels?: Channel[] }) { const channels = props.channels || []; diff --git a/frontend/src/js/components/Applications/ApplicationItemGroupItem.tsx b/frontend/src/components/Applications/ApplicationItemGroupItem.tsx similarity index 93% rename from frontend/src/js/components/Applications/ApplicationItemGroupItem.tsx rename to frontend/src/components/Applications/ApplicationItemGroupItem.tsx index 193f3f99b..5fc9a9f15 100644 --- a/frontend/src/js/components/Applications/ApplicationItemGroupItem.tsx +++ b/frontend/src/components/Applications/ApplicationItemGroupItem.tsx @@ -3,11 +3,12 @@ import Link from '@material-ui/core/Link'; import { makeStyles } from '@material-ui/core/styles'; import LayersOutlinedIcon from '@material-ui/icons/LayersOutlined'; import React from 'react'; +import { useContext } from 'react'; import { useTranslation } from 'react-i18next'; import { Link as RouterLink } from 'react-router-dom'; -import API from '../../api/API'; +import { APIContext } from '../../api/API'; import { Group } from '../../api/apiDataTypes'; -import ChannelItem from '../Channels/Item'; +import ChannelItem from '../Channels/ChannelItem'; const useStyles = makeStyles({ groupLink: { @@ -24,6 +25,7 @@ function ApplicationItemGroupItem(props: { group: Group; appName: string }) { const { group } = props; const [totalInstances, setTotalInstances] = React.useState(-1); const { t } = useTranslation(); + const API = useContext(APIContext); React.useEffect(() => { // We use this function without any filter to get the total number of instances diff --git a/frontend/src/components/Applications/ApplicationItemGroupsList.tsx b/frontend/src/components/Applications/ApplicationItemGroupsList.tsx new file mode 100644 index 000000000..06dff54f8 --- /dev/null +++ b/frontend/src/components/Applications/ApplicationItemGroupsList.tsx @@ -0,0 +1,23 @@ +import { Box, Divider } from '@material-ui/core'; +import { Fragment } from 'react'; +import { Group } from '../../api/apiDataTypes'; +import ApplicationItemGroupItem from './ApplicationItemGroupItem'; + +export default function ApplicationItemGroupsList(props: { + groups: Group[]; + appID: string; + appName: string; +}) { + return ( + <> + {props.groups.map((group, i) => ( + + {i > 0 && } + + + + + ))} + + ); +} diff --git a/frontend/src/components/Applications/ApplicationList.stories.tsx b/frontend/src/components/Applications/ApplicationList.stories.tsx new file mode 100644 index 000000000..d94d20f14 --- /dev/null +++ b/frontend/src/components/Applications/ApplicationList.stories.tsx @@ -0,0 +1,168 @@ +import { Meta, Story } from '@storybook/react/types-6-0'; +import { MemoryRouter } from 'react-router-dom'; +import API, { APIContext } from '../../api/API'; +import { ApplicationListPure, ApplicationListPureProps } from './ApplicationList'; + +export default { + title: 'applications/ApplicationList', +} as Meta; + +const Template: Story = args => { + class APIMock extends API { + /* eslint-disable no-unused-vars */ + static getInstancesCount( + applicationID: string, + groupID: string, + duration: string + ): Promise { + return new Promise(resolve => resolve(20)); + } + } + + return ( + + + + + + ); +}; + +export const Loading = Template.bind({}); +Loading.args = { + applications: null, + loading: true, +}; + +export const Applications = Template.bind({}); + +Applications.args = { + applications: [ + { + id: 'FFFF-AAAA-CCCC-EEEE', + product_id: 'xxx-xxx-yyy', + name: 'ABC', + description: 'App Item Description', + created_ts: '2018-10-16T21:07:56.819939+05:30', + team_id: 'YYY-XXX-xxx', + channels: [], + packages: [], + instances: { count: 20 }, + groups: [ + { + id: 'xxx-xxx-1', + name: 'First group', + description: '', + created_ts: '', + rollout_in_progress: false, + application_id: '', + channel_id: null, + policy_updates_enabled: false, + policy_safe_mode: false, + policy_office_hours: false, + policy_timezone: null, + policy_period_interval: '', + policy_max_updates_per_period: 0, + policy_update_timeout: '', + + channel: { + id: 'DEF', + name: 'main', + color: '#777777', + created_ts: '2018-10-16T21:07:56.819939+05:30', + application_id: '123', + package_id: 'XYZ', + package: { + id: 'PACK_ID', + type: 4, + version: '1.11.3', + url: 'https://github.com/kinvolk', + filename: '', + description: '', + size: '', + hash: '', + created_ts: '2019-07-18T20:10:39.163326+05:30', + channels_blacklist: null, + application_id: 'df1c8bbb-f525-49ee-8c94-3ca548b42059', + flatcar_action: null, + arch: 0, + extra_files: [], + }, + arch: 0, + }, + track: '', + }, + ], + }, + { + id: 'BBBB-AAAA-CCCC-EEEE', + product_id: 'xxx-xxx-yyy', + name: 'ABC 2 the return', + description: 'App Item Description', + created_ts: '2021-10-17T21:07:56.819939+05:30', + team_id: 'YYY-XXX-xxx', + channels: [], + packages: [], + instances: { count: 20 }, + groups: [ + { + id: 'xxx-xxx-1', + name: 'First group', + description: '', + created_ts: '', + rollout_in_progress: false, + application_id: '', + channel_id: null, + policy_updates_enabled: false, + policy_safe_mode: false, + policy_office_hours: false, + policy_timezone: null, + policy_period_interval: '', + policy_max_updates_per_period: 0, + policy_update_timeout: '', + + channel: { + id: 'DEF', + name: 'main', + color: '#777777', + created_ts: '2018-10-16T21:07:56.819939+05:30', + application_id: '123', + package_id: 'XYZ', + package: { + id: 'PACK_ID', + type: 4, + version: '1.11.3', + url: 'https://github.com/kinvolk', + filename: '', + description: '', + size: '', + hash: '', + created_ts: '2019-07-18T20:10:39.163326+05:30', + channels_blacklist: null, + application_id: 'df1c8bbb-f525-49ee-8c94-3ca548b42059', + flatcar_action: null, + arch: 0, + extra_files: [], + }, + arch: 0, + }, + track: '', + }, + ], + }, + ], + loading: false, +}; + +export const EditOpen = Template.bind({}); +EditOpen.args = { + ...Applications.args, + editOpen: true, + editId: 'BBBB-AAAA-CCCC-EEEE', +}; + +export const SearchTerm = Template.bind({}); +SearchTerm.args = { + ...Applications.args, + defaultSearchTerm: 'the return', +}; diff --git a/frontend/src/components/Applications/ApplicationList.tsx b/frontend/src/components/Applications/ApplicationList.tsx new file mode 100644 index 000000000..b361f109f --- /dev/null +++ b/frontend/src/components/Applications/ApplicationList.tsx @@ -0,0 +1,140 @@ +import { List } from '@material-ui/core'; +import Paper from '@material-ui/core/Paper'; +import { makeStyles } from '@material-ui/core/styles'; +import React from 'react'; +import { Trans, useTranslation } from 'react-i18next'; +import _ from 'underscore'; +import { Application } from '../../api/apiDataTypes'; +import { applicationsStore } from '../../stores/Stores'; +import Empty from '../common/EmptyContent'; +import ListHeader from '../common/ListHeader'; +import Loader from '../common/Loader'; +import ModalButton from '../common/ModalButton'; +import ApplicationEdit from './ApplicationEdit'; +import ApplicationItem from './ApplicationItem'; + +const useStyles = makeStyles({ + root: { + '& > hr:first-child': { + display: 'none', + }, + }, +}); + +export interface ApplicationListProps {} + +export default function ApplicationList() { + const [applications, setApplications] = React.useState( + applicationsStore().getCachedApplications ? applicationsStore().getCachedApplications() : [] + ); + + React.useEffect(() => { + applicationsStore().addChangeListener(onChange); + return () => { + applicationsStore().removeChangeListener(onChange); + }; + }, []); + + React.useEffect(() => { + if (applicationsStore().getCachedApplications) { + setApplications(applicationsStore().getCachedApplications()); + } + }, [applicationsStore().getCachedApplications]); + + function onChange() { + setApplications(applicationsStore().getCachedApplications()); + } + + return ; +} + +export interface ApplicationListPureProps { + /** To show. */ + applications: null | Application[]; + /** If we are waiting for applications to load. */ + loading?: boolean; + /** If the edit screen is open for editId */ + editOpen?: boolean; + /** The id to show for editing. */ + editId?: string; + /** A default term to search. */ + defaultSearchTerm?: string; +} + +export function ApplicationListPure(props: ApplicationListPureProps) { + const classes = useStyles(); + const { t } = useTranslation(); + const [editOpen, setEditOpen] = React.useState(!!props.editOpen); + const [editId, setEditId] = React.useState(props.editId ? props.editId : null); + const [searchTerm] = React.useState(props.defaultSearchTerm); + + function closeUpdateAppModal() { + setEditOpen(false); + } + + function openUpdateAppModal(appID: string) { + setEditOpen(true); + setEditId(appID); + } + + let entries: React.ReactNode = ''; + const applications = props.applications + ? searchTerm + ? props.applications.filter(app => app.name.toLowerCase().includes(searchTerm)) + : props.applications + : null; + + if (props.loading || applications === null) { + entries = ; + } else { + if (_.isEmpty(applications)) { + if (searchTerm) { + entries = {t('applications|No results found.')}; + } else { + entries = ( + + + Oops, it looks like you have not created any application yet.. +
    +
    Now is a great time to create your first one, just click on the plus symbol + above. +
    +
    + ); + } + } else { + entries = _.map(applications, (application: Application) => { + return ( + + ); + }); + } + } + + const appToUpdate = applications && editId ? _.findWhere(applications, { id: editId }) : null; + return ( + <> + , + ]} + /> + + {entries} + {appToUpdate && ( + + )} + + + ); +} diff --git a/frontend/src/components/Applications/__snapshots__/ApplicationItem.stories.storyshot b/frontend/src/components/Applications/__snapshots__/ApplicationItem.stories.storyshot new file mode 100644 index 000000000..964ebe81f --- /dev/null +++ b/frontend/src/components/Applications/__snapshots__/ApplicationItem.stories.storyshot @@ -0,0 +1,487 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots applications/ApplicationItem Application 1`] = ` +
    +
  • +
    +
    +
    +
    +
    +

    + + ABC + +

    +
    +
    +
    +

    + xxx-xxx-yyy +

    +
    +
    + + App Item Description + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    + + INSTANCES + + +
    + 1 +
    +
    + +
    +
    + last 24 hours +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + Groups + +
    + + 1 + +
    +
    +
    + +
    +
    + +
    + -1 +
    + instances +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + main +
    +
    +
    +
    + 1.11.3 (ALL) +
    +
    +
    +
    + +
    +
    + 07/18/2019 +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
  • +
    +`; + +exports[`Storyshots applications/ApplicationItem No Groups 1`] = ` +
    +
  • +
    +
    +
    +
    +
    +

    + + ABC + +

    +
    +
    +
    +

    + xxx-xxx-yyy +

    +
    +
    + + App Item Description + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    + + INSTANCES + + +
    + 1 +
    +
    + +
    +
    + last 24 hours +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + Groups + +
    + + None + +
    +
    +
    +
    +
    +
    +
  • +
    +`; diff --git a/frontend/src/components/Applications/__snapshots__/ApplicationList.stories.storyshot b/frontend/src/components/Applications/__snapshots__/ApplicationList.stories.storyshot new file mode 100644 index 000000000..265b62307 --- /dev/null +++ b/frontend/src/components/Applications/__snapshots__/ApplicationList.stories.storyshot @@ -0,0 +1,1742 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots applications/ApplicationList Applications 1`] = ` +
    +
    +
    +
    +

    + Applications +

    +
    +
    +
    +
    + +
    +
    +
    +
    +
      +
    • +
      +
      +
      +
      +
      +

      + + ABC + +

      +
      +
      +
      +

      + xxx-xxx-yyy +

      +
      +
      + + App Item Description + +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      +
      +
      +
      + + INSTANCES + + +
      + 20 +
      +
      + +
      +
      + last 24 hours +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + + Groups + +
      + + 1 + +
      +
      +
      + +
      +
      + +
      + -1 +
      + instances +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + main +
      +
      +
      +
      + 1.11.3 (ALL) +
      +
      +
      +
      + +
      +
      + 07/18/2019 +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + xxx-xxx-yyy +

      +
      +
      + + App Item Description + +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      +
      +
      +
      + + INSTANCES + + +
      + 20 +
      +
      + +
      +
      + last 24 hours +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + + Groups + +
      + + 1 + +
      +
      +
      + +
      +
      + +
      + -1 +
      + instances +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + main +
      +
      +
      +
      + 1.11.3 (ALL) +
      +
      +
      +
      + +
      +
      + 07/18/2019 +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
    • +
    +
    +
    +`; + +exports[`Storyshots applications/ApplicationList Edit Open 1`] = ` +
    +
    +
    +
    +

    + Applications +

    +
    +
    +
    +
    + +
    +
    +
    +
    +
      +
    • +
      +
      +
      +
      +
      +

      + + ABC + +

      +
      +
      +
      +

      + xxx-xxx-yyy +

      +
      +
      + + App Item Description + +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      +
      +
      +
      + + INSTANCES + + +
      + 20 +
      +
      + +
      +
      + last 24 hours +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + + Groups + +
      + + 1 + +
      +
      +
      + +
      +
      + +
      + -1 +
      + instances +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + main +
      +
      +
      +
      + 1.11.3 (ALL) +
      +
      +
      +
      + +
      +
      + 07/18/2019 +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
    • +
    • +
      +
      +
      +
      + +
      +
      +

      + xxx-xxx-yyy +

      +
      +
      + + App Item Description + +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      +
      +
      +
      + + INSTANCES + + +
      + 20 +
      +
      + +
      +
      + last 24 hours +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + + Groups + +
      + + 1 + +
      +
      +
      + +
      +
      + +
      + -1 +
      + instances +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + main +
      +
      +
      +
      + 1.11.3 (ALL) +
      +
      +
      +
      + +
      +
      + 07/18/2019 +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
    • +
    +
    +
    +`; + +exports[`Storyshots applications/ApplicationList Loading 1`] = ` +
    +
    +
    +
    +

    + Applications +

    +
    +
    +
    +
    + +
    +
    +
    +
    +
      +
      +
      + + + +
      +
      +
    +
    +
    +`; + +exports[`Storyshots applications/ApplicationList Search Term 1`] = ` +
    +
    +
    +
    +

    + Applications +

    +
    +
    +
    +
    + +
    +
    +
    +
    +
      +
    • +
      +
      +
      +
      + +
      +
      +

      + xxx-xxx-yyy +

      +
      +
      + + App Item Description + +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      +
      +
      +
      + + INSTANCES + + +
      + 20 +
      +
      + +
      +
      + last 24 hours +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + + Groups + +
      + + 1 + +
      +
      +
      + +
      +
      + +
      + -1 +
      + instances +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + main +
      +
      +
      +
      + 1.11.3 (ALL) +
      +
      +
      +
      + +
      +
      + 07/18/2019 +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
    • +
    +
    +
    +`; diff --git a/frontend/src/components/Channels/ChannelAvatar.stories.tsx b/frontend/src/components/Channels/ChannelAvatar.stories.tsx new file mode 100644 index 000000000..7c2226b82 --- /dev/null +++ b/frontend/src/components/Channels/ChannelAvatar.stories.tsx @@ -0,0 +1,8 @@ +import { Meta } from '@storybook/react/types-6-0'; +import ChannelAvatar from './ChannelAvatar'; + +export default { + title: 'channels/ChannelAvatar', +} as Meta; + +export const White = () => ABC; diff --git a/frontend/src/js/components/Channels/ChannelAvatar.tsx b/frontend/src/components/Channels/ChannelAvatar.tsx similarity index 92% rename from frontend/src/js/components/Channels/ChannelAvatar.tsx rename to frontend/src/components/Channels/ChannelAvatar.tsx index a176970a6..837f62387 100644 --- a/frontend/src/js/components/Channels/ChannelAvatar.tsx +++ b/frontend/src/components/Channels/ChannelAvatar.tsx @@ -1,9 +1,8 @@ import { Theme } from '@material-ui/core'; import Avatar from '@material-ui/core/Avatar'; import makeStyles from '@material-ui/styles/makeStyles'; -import React from 'react'; -interface ChannelAvatarProps { +export interface ChannelAvatarProps { backgroundColor?: string; color?: string; size?: string | number; diff --git a/frontend/src/js/components/Channels/EditDialog.tsx b/frontend/src/components/Channels/ChannelEdit.tsx similarity index 86% rename from frontend/src/js/components/Channels/EditDialog.tsx rename to frontend/src/components/Channels/ChannelEdit.tsx index 84edb2e95..e360390a4 100644 --- a/frontend/src/js/components/Channels/EditDialog.tsx +++ b/frontend/src/components/Channels/ChannelEdit.tsx @@ -13,7 +13,6 @@ import MuiSelect from '@material-ui/core/Select'; import { makeStyles } from '@material-ui/core/styles'; import { Field, Form, Formik } from 'formik'; import { TextField } from 'formik-material-ui'; -import PropTypes from 'prop-types'; import React from 'react'; import { useTranslation } from 'react-i18next'; import * as Yup from 'yup'; @@ -21,9 +20,8 @@ import API from '../../api/API'; import { Channel, Package } from '../../api/apiDataTypes'; import { applicationsStore } from '../../stores/Stores'; import { ARCHES } from '../../utils/helpers'; -import AutoCompletePicker from '../Common/AutoCompletePicker'; -import { ColorPickerButton } from '../Common/ColorPicker'; -import ChannelAvatar from './ChannelAvatar'; +import AutoCompletePicker from '../common/AutoCompletePicker'; +import ColorPicker from '../common/ColorPicker'; const useStyles = makeStyles({ nameField: { @@ -33,7 +31,14 @@ const useStyles = makeStyles({ const PackagesPerPage = 15; -function EditDialog(props: { data: any; create?: boolean; show: boolean; onHide: () => void }) { +export interface ChannelEditProps { + data: any; + create?: boolean; + show: boolean; + onHide: () => void; +} + +export default function ChannelEdit(props: ChannelEditProps) { const classes = useStyles(); const { t } = useTranslation(); const defaultColor = ''; @@ -77,10 +82,10 @@ function EditDialog(props: { data: any; create?: boolean; show: boolean; onHide: let channelFunctionCall; if (isCreation) { - channelFunctionCall = applicationsStore.createChannel(data as Channel); + channelFunctionCall = applicationsStore().createChannel(data as Channel); } else { data['id'] = props.data.channel.id; - channelFunctionCall = applicationsStore.updateChannel(data as Channel); + channelFunctionCall = applicationsStore().updateChannel(data as Channel); } channelFunctionCall @@ -98,18 +103,6 @@ function EditDialog(props: { data: any; create?: boolean; show: boolean; onHide: }); } - function handleColorPicked(color: { hex: string }) { - setChannelColor(color.hex); - } - - function handleArchChange(event: React.ChangeEvent<{ value: any }>) { - setArch(event.target.value); - } - - function handleClose() { - props.onHide(); - } - function fetchPackages(term: string, page: number) { API.getPackages(props.data.applicationID, term || '', { page: (page || 0) + 1, @@ -178,13 +171,9 @@ function EditDialog(props: { data: any; create?: boolean; show: boolean; onHide: )} - - {values.name ? values.name[0] : ''} - + setChannelColor(color.hex)}> + {values.name ? values.name[0] : ''} + @@ -206,7 +195,10 @@ function EditDialog(props: { data: any; create?: boolean; show: boolean; onHide: Architecture - + ) => setArch(event.target.value)} + > {Object.keys(ARCHES).map((key: string) => { const archName = ARCHES[parseInt(key)]; return ( @@ -235,7 +227,7 @@ function EditDialog(props: { data: any; create?: boolean; show: boolean; onHide: .filter((packageItem: Package) => packageItem.version === packageVersion); setFieldValue('package', selectedPackage[0].id); }} - getSuggestions={packages.packages + suggestions={packages.packages .filter((packageItem: Package) => packageItem.arch === arch) .map((packageItem: Package) => { const date = new Date(packageItem.created_ts); @@ -257,7 +249,7 @@ function EditDialog(props: { data: any; create?: boolean; show: boolean; onHide: /> - +
    +
    + + +
    +
      +
    • + AMD64 +
    • +
    • +
      +
      +
      +
      + a +
      +
      +
      +
      +
      +
      + alpha +
      +
      +
      +
      + 2261.0.0 +
      +
      +
      +
      + +
      +
      + 09/13/2019 +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + +
      +
      +
    • +
    • +
      +
      +
      +
      + b +
      +
      +
      +
      +
      +
      + beta +
      +
      +
      +
      + 2247.2.0 +
      +
      +
      +
      + +
      +
      + 09/13/2019 +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + +
      +
      +
    • +
    • +
      +
      +
      +
      + e +
      +
      +
      +
      +
      +
      + edge +
      +
      +
      +
      + 2247.99.0 +
      +
      +
      +
      + +
      +
      + 09/05/2019 +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + +
      +
      +
    • +
    • +
      +
      +
      +
      + s +
      +
      +
      +
      +
      +
      + stable +
      +
      +
      +
      + 2191.5.0 +
      +
      +
      +
      + +
      +
      + 09/05/2019 +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + +
      +
      +
    • +
    +
      +
    • + ARM64 +
    • +
    • +
      +
      +
      +
      + a +
      +
      +
      +
      +
      +
      + alpha +
      +
      +
      +
      + No package +
      +
      +
      +
      +
      +
      +
      +
      + +
      +
      +
    • +
    • +
      +
      +
      +
      + b +
      +
      +
      +
      +
      +
      + beta +
      +
      +
      +
      + No package +
      +
      +
      +
      +
      +
      +
      +
      + +
      +
      +
    • +
    • +
      +
      +
      +
      + e +
      +
      +
      +
      +
      +
      + edge +
      +
      +
      +
      + No package +
      +
      +
      +
      +
      +
      +
      +
      + +
      +
      +
    • +
    • +
      +
      +
      +
      + s +
      +
      +
      +
      +
      +
      + stable +
      +
      +
      +
      + No package +
      +
      +
      +
      +
      +
      +
      +
      + +
      +
      +
    • +
    +
    + + +`; + +exports[`Storyshots channels/ChannelList Loading 1`] = ` +
    +
    +
    +
    +
    +

    + Channels +

    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +`; diff --git a/frontend/src/js/components/Footer.tsx b/frontend/src/components/Footer.tsx similarity index 100% rename from frontend/src/js/components/Footer.tsx rename to frontend/src/components/Footer.tsx diff --git a/frontend/src/components/Groups/GroupCharts/StatusCountTimeline.stories.tsx b/frontend/src/components/Groups/GroupCharts/StatusCountTimeline.stories.tsx new file mode 100644 index 000000000..1c6aff8f0 --- /dev/null +++ b/frontend/src/components/Groups/GroupCharts/StatusCountTimeline.stories.tsx @@ -0,0 +1,122 @@ +import { Meta, Story } from '@storybook/react/types-6-0'; +import { MemoryRouter } from 'react-router-dom'; +import GroupChartsStore from '../../../stores/GroupChartsStore'; +import { groupChartStoreContext } from '../../../stores/Stores'; +import StatusCountTimeline, { StatusCountTimelineProps } from './StatusCountTimeline'; + +export default { + title: 'groups/StatusCountTimeline', +} as Meta; + +const statusTimelineData = { + '2021-11-07T10:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-07T11:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-07T12:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-07T13:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-07T14:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-07T15:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-07T16:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-07T17:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-07T18:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-07T19:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-07T20:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-07T21:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-07T22:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-07T23:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-08T00:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-08T01:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-08T02:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-08T03:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-08T04:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-08T05:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-08T06:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-08T07:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-08T08:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, + '2021-11-08T09:35:28.823161+01:00': { + '1': { '2191.5.0': 177 }, + '2': { '2191.5.0': 221 }, + '3': { '2191.5.0': 12 }, + '6': { '2191.5.0': 193 }, + '7': { '2191.5.0': 215 }, + }, + '2021-11-08T10:35:28.823161+01:00': { '1': {}, '2': {}, '3': {}, '6': {}, '7': {} }, +}; + +const Template: Story = args => { + class GroupChartsStoreMock extends GroupChartsStore { + /* eslint-disable no-unused-vars */ + async getGroupStatusCountTimeline(appID: string, groupID: string, duration: string) { + return statusTimelineData; + } + } + + const ChartStoreContext = groupChartStoreContext(); + + return ( + + + + + + ); +}; + +export const Timeline = Template.bind({}); + +Timeline.args = { + group: { + id: '9a2deb70-37be-4026-853f-bfdd6b347bbe', + name: 'Stable (AMD64)', + description: 'For production clusters (AMD64)', + created_ts: '2015-09-19T07:09:34.269062+02:00', + rollout_in_progress: true, + application_id: 'e96281a6-d1af-4bde-9a0a-97b76e56dc57', + channel_id: 'e06064ad-4414-4904-9a6e-fd465593d1b2', + policy_updates_enabled: true, + policy_safe_mode: false, + policy_office_hours: false, + policy_timezone: 'Europe/Berlin', + policy_period_interval: '1 minutes', + policy_max_updates_per_period: 999999, + policy_update_timeout: '60 minutes', + channel: { + id: 'e06064ad-4414-4904-9a6e-fd465593d1b2', + name: 'stable', + color: '#14b9d6', + created_ts: '2015-09-19T07:09:34.261241+02:00', + application_id: 'e96281a6-d1af-4bde-9a0a-97b76e56dc57', + package_id: '84b4c599-9b6b-44a8-b13c-d4263fff0403', + package: { + id: '84b4c599-9b6b-44a8-b13c-d4263fff0403', + type: 1, + version: '2191.5.0', + url: 'https://update.release.flatcar-linux.net/amd64-usr/2191.5.0/', + filename: 'flatcar_production_update.gz', + description: 'Flatcar Container Linux 2191.5.0', + size: '465881871', + hash: 'r3nufcxgMTZaxYEqL+x2zIoeClk=', + created_ts: '2019-09-05T12:41:09.265687+02:00', + channels_blacklist: null, + application_id: 'e96281a6-d1af-4bde-9a0a-97b76e56dc57', + flatcar_action: { + id: '1f6e1bcf-4ebb-4fe6-8ca3-2cb6ad90d5dd', + event: 'postinstall', + chromeos_version: '', + sha256: 'LIkAKVZY2EJFiwTmltiJZLFLA5xT/FodbjVgqkyF/y8=', + needs_admin: false, + is_delta: false, + disable_payload_backoff: true, + metadata_signature_rsa: '', + metadata_size: '', + deadline: '', + created_ts: '2019-08-20T02:12:37.532281+02:00', + }, + arch: 1, + extra_files: [], + }, + arch: 1, + }, + track: 'stable', + }, + duration: { displayValue: '1 day', queryValue: '1d', disabled: false }, +}; diff --git a/frontend/src/components/Groups/GroupCharts/StatusCountTimeline.tsx b/frontend/src/components/Groups/GroupCharts/StatusCountTimeline.tsx new file mode 100644 index 000000000..94d463094 --- /dev/null +++ b/frontend/src/components/Groups/GroupCharts/StatusCountTimeline.tsx @@ -0,0 +1,251 @@ +import { IconifyIcon } from '@iconify/react'; +import { Theme } from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Chip from '@material-ui/core/Chip'; +import Grid from '@material-ui/core/Grid'; +import Typography from '@material-ui/core/Typography'; +import { useTheme } from '@material-ui/styles'; +import React from 'react'; +import _ from 'underscore'; +import { Group } from '../../../api/apiDataTypes'; +import { makeLocaleTime } from '../../../i18n/dateTime'; +import { groupChartStoreContext } from '../../../stores/Stores'; +import { getInstanceStatus } from '../../../utils/helpers'; +import Loader from '../../common/Loader/Loader'; +import SimpleTable from '../../common/SimpleTable/SimpleTable'; +import makeStatusDefs from '../../Instances/StatusDefs'; +import TimelineChart from './TimelineChart'; +import { Duration } from './TimelineChart'; + +export interface StatusCountTimelineProps { + duration: Duration; + group: Group | null; +} + +export default function StatusCountTimeline(props: StatusCountTimelineProps) { + const [selectedEntry, setSelectedEntry] = React.useState(-1); + const { duration } = props; + const [timelineChartData, setTimelineChartData] = React.useState<{ + data: { + index: number; + timestamp: string; + }[]; + keys: string[]; + colors: { + [key: string]: string; + }; + }>({ + data: [], + keys: [], + colors: {}, + }); + + const [timeline, setTimeline] = React.useState<{ + timeline: { + [key: string]: any; + }; + lastUpdate: Date | string; + }>({ + timeline: {}, + // A long time ago, to force the first update... + lastUpdate: new Date(2000, 1, 1), + }); + + const ChartStoreContext = groupChartStoreContext(); + const groupChartStore = React.useContext(ChartStoreContext); + + const theme = useTheme(); + const statusDefs: { + [key: string]: { + label: string; + color: string; + icon: IconifyIcon; + queryValue: string; + }; + } = makeStatusDefs(theme as Theme); + + function makeChartData(groupTimeline: { [key: string]: any }) { + const data = Object.keys(groupTimeline).map((timestamp, i) => { + const status = groupTimeline[timestamp]; + const statusCount: { + [key: string]: any; + } = {}; + Object.keys(status).forEach((st: string) => { + const values = status[st]; + const count = Object.values(values).reduce((a: any, b: any) => a + b, 0); + statusCount[st] = count; + }); + + return { + index: i, + timestamp: timestamp, + ...statusCount, + }; + }); + + const statuses = getStatusFromTimeline(groupTimeline); + const colors = makeStatusesColors(statuses); + + setTimelineChartData({ + data: data, + keys: statuses, + colors: colors, + }); + } + + function makeStatusesColors(statuses: { [key: string]: any }) { + const colors: { + [key: string]: string; + } = {}; + + Object.values(statuses).forEach(status => { + const statusInfo = getInstanceStatus(status, ''); + colors[status] = statusDefs[statusInfo.type].color; + }); + + return colors; + } + + function getStatusFromTimeline(timeline: { [key: number]: number }) { + if (Object.keys(timeline).length === 0) { + return []; + } + + return Object.keys(Object.values(timeline)[0]).filter(status => parseInt(status) !== 0); + } + + function getInstanceCount(selectedEntry: number) { + const status_breakdown: { + status: string; + version: string; + instances: number; + }[] = []; + const statusTimeline: { + [key: string]: any; + } = timeline.timeline; + + // Populate it from the selected time one. + if (!_.isEmpty(statusTimeline) && !_.isEmpty(timelineChartData.data)) { + const timelineIndex = selectedEntry >= 0 ? selectedEntry : timelineChartData.data.length - 1; + if (timelineIndex < 0) return []; + + const ts = timelineChartData.data[timelineIndex].timestamp; + // Create the version breakdown from the timeline + const entries = statusTimeline[ts] || []; + for (const status in entries) { + if (parseInt(status) === 0) { + continue; + } + + const versions = entries[status]; + + Object.keys(versions).forEach(version => { + const versionCount = versions[version]; + status_breakdown.push({ + status: status, + version: version, + instances: versionCount, + }); + }); + } + } + + status_breakdown.forEach((entry: { status: string; version: string; [key: string]: any }) => { + const statusInfo = getInstanceStatus(parseInt(entry.status), entry.version); + const statusTheme = statusDefs[statusInfo.type]; + + entry.color = statusTheme.color; + entry.status = statusTheme.label; + }); + + // Sort the entries per number of instances (higher first). + status_breakdown.sort((elem1, elem2) => { + return -(elem1.instances - elem2.instances); + }); + + return status_breakdown; + } + + function getSelectedTime() { + const data = timelineChartData.data; + if (selectedEntry < 0 || data.length === 0) { + return ''; + } + const timestamp = data[selectedEntry].timestamp; + return makeLocaleTime(timestamp); + } + + // Make the timeline data again when needed. + React.useEffect(() => { + async function getStatusTimeline(group: Group | null) { + if (group) { + setTimelineChartData({ data: [], keys: [], colors: {} }); + try { + const statusCountTimeline = await groupChartStore.getGroupStatusCountTimeline( + group.application_id, + group.id, + duration.queryValue + ); + setTimeline({ + timeline: statusCountTimeline, + lastUpdate: new Date().toUTCString(), + }); + + makeChartData(statusCountTimeline || []); + setSelectedEntry(-1); + } catch (error) { + console.error(error); + } + } + } + setSelectedEntry(-1); + getStatusTimeline(props.group); + }, [props.duration]); + + return ( + + + {timelineChartData.data.length > 0 ? ( + + ) : ( + + )} + + + + + {timelineChartData.data.length > 0 ? ( + selectedEntry !== -1 ? ( + + Showing for: +   + { + setSelectedEntry(-1); + }} + /> + + ) : ( + + Showing data for the last time point. +
    + Click the chart to choose a different time point. +
    + ) + ) : null} +
    +
    + + {timelineChartData.data.length > 0 && ( + + )} + +
    +
    + ); +} diff --git a/frontend/src/components/Groups/GroupCharts/TimelineChart.tsx b/frontend/src/components/Groups/GroupCharts/TimelineChart.tsx new file mode 100644 index 000000000..5beba4759 --- /dev/null +++ b/frontend/src/components/Groups/GroupCharts/TimelineChart.tsx @@ -0,0 +1,159 @@ +import Box from '@material-ui/core/Box'; +import Paper from '@material-ui/core/Paper'; +import Typography from '@material-ui/core/Typography'; +import { Area, AreaChart, AreaProps, CartesianGrid, Tooltip, XAxis, YAxis } from 'recharts'; +import { getMinuteDifference, makeLocaleTime } from '../../../i18n/dateTime'; + +export interface Duration { + displayValue: string; + queryValue: string; + disabled: boolean; +} + +function TimelineTooltip(props: { label?: string; data: any }) { + const { label, data } = props; + return ( +
    + + + {label && data[label] && makeLocaleTime(data[label].timestamp)} + + +
    + ); +} + +export interface TimelineChartProps { + width?: number; + height?: number; + interpolation?: AreaProps['type']; + data: any; + onSelect: (activeLabel: any) => void; + colors: any; + keys: string[]; +} + +export default function TimelineChart(props: TimelineChartProps) { + const { width = 500, height = 400, interpolation = 'monotone' } = props; + let ticks: { + [key: string]: string; + } = {}; + + function getTickValues() { + const DAY = 24 * 60; + let tickCount = 4; + let dateFormat: { + useDate?: boolean; + showTime?: boolean; + dateFormat?: Intl.DateTimeFormatOptions; + } = { useDate: false }; + const startTs = new Date(props.data[0].timestamp); + const endTs = new Date(props.data[props.data.length - 1].timestamp); + const lengthMinutes = getMinuteDifference(endTs.valueOf(), startTs.valueOf()); + // We remove 1 element since that's "0 hours" + const dimension = props.data.length - 1; + + // Reset the ticks for the chart + ticks = {}; + + if (lengthMinutes === 7 * DAY) { + tickCount = 7; + dateFormat = { dateFormat: { month: 'short', day: 'numeric' }, showTime: false }; + } + if (lengthMinutes === 60) { + for (let i = 0; i < 4; i++) { + const minuteValue = (lengthMinutes / 4) * i; + startTs.setMinutes(new Date(props.data[0].timestamp).getMinutes() + minuteValue); + ticks[i] = makeLocaleTime(startTs, { useDate: false }); + } + return ticks; + } + + if (lengthMinutes === 30 * DAY) { + for (let i = 0; i < props.data.length; i += 2) { + const tickDate = new Date(props.data[i].timestamp); + ticks[i] = makeLocaleTime(tickDate, { + showTime: false, + dateFormat: { month: 'short', day: 'numeric' }, + }); + } + return ticks; + } + // Set up a tick marking the 0 hours of the day contained in the range + const nextDay = new Date(startTs); + nextDay.setHours(24, 0, 0, 0); + const midnightDay = new Date(nextDay); + const nextDayMinuteDiff = getMinuteDifference(nextDay.valueOf(), startTs.valueOf()); + const midnightTick = (nextDayMinuteDiff * dimension) / lengthMinutes; + + // Set up the remaining ticks according to the desired amount, separated + // evenly. + const tickOffsetMinutes = lengthMinutes / tickCount; + + // Set the ticks around midnight. + for (const i of [-1, 1]) { + const tickDate = new Date(nextDay); + + while (true) { + tickDate.setMinutes(nextDay.getMinutes() + tickOffsetMinutes * i); + // Stop if this tick falls outside of the times being charted + + if (tickDate < startTs || tickDate > endTs) { + break; + } + + const tick = + (getMinuteDifference(tickDate.valueOf(), startTs.valueOf()) * dimension) / lengthMinutes; + // Show only the time. + ticks[tick] = makeLocaleTime(tickDate, dateFormat); + } + } + // The midnight tick just gets the date, not the hours (since they're zero) + ticks[midnightTick] = makeLocaleTime(midnightDay, { + dateFormat: { month: 'short', day: 'numeric' }, + showTime: false, + }); + return ticks; + } + + return ( + obj && props.onSelect(obj.activeLabel)} + > + + } /> + { + return ticks[index]; + }} + stroke={'#000'} + /> + + {props.keys.map((key: string, i: number) => ( + + ))} + + ); +} diff --git a/frontend/src/components/Groups/GroupCharts/VersionCountTimeline.stories.tsx b/frontend/src/components/Groups/GroupCharts/VersionCountTimeline.stories.tsx new file mode 100644 index 000000000..5266f5bde --- /dev/null +++ b/frontend/src/components/Groups/GroupCharts/VersionCountTimeline.stories.tsx @@ -0,0 +1,116 @@ +import { Meta, Story } from '@storybook/react/types-6-0'; +import { MemoryRouter } from 'react-router-dom'; +import GroupChartsStore from '../../../stores/GroupChartsStore'; +import { groupChartStoreContext } from '../../../stores/Stores'; +import VersionCountTimeline, { VersionCountTimelineProps } from './VersionCountTimeline'; + +export default { + title: 'groups/VersionCountTimeline', +} as Meta; + +const versionCountTimeline = { + '2021-11-07T10:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-07T11:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-07T12:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-07T13:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-07T14:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-07T15:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-07T16:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-07T17:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-07T18:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-07T19:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-07T20:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-07T21:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-07T22:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-07T23:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-08T00:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-08T01:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-08T02:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-08T03:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-08T04:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-08T05:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-08T06:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-08T07:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-08T08:35:28.827204+01:00': { '0.0.0': 0, '2191.5.0': 0 }, + '2021-11-08T09:35:28.827204+01:00': { '0.0.0': 61, '2191.5.0': 152 }, + '2021-11-08T10:35:28.827204+01:00': { '0.0.0': 61, '2191.5.0': 152 }, +}; + +const Template: Story = args => { + class GroupChartsStoreMock extends GroupChartsStore { + /* eslint-disable no-unused-vars */ + async getGroupVersionCountTimeline(appID: string, groupID: string, duration: string) { + return versionCountTimeline; + } + } + + const ChartStoreContext = groupChartStoreContext(); + + return ( + + + + + + ); +}; + +export const Timeline = Template.bind({}); + +Timeline.args = { + group: { + id: '9a2deb70-37be-4026-853f-bfdd6b347bbe', + name: 'Stable (AMD64)', + description: 'For production clusters (AMD64)', + created_ts: '2015-09-19T07:09:34.269062+02:00', + rollout_in_progress: true, + application_id: 'e96281a6-d1af-4bde-9a0a-97b76e56dc57', + channel_id: 'e06064ad-4414-4904-9a6e-fd465593d1b2', + policy_updates_enabled: true, + policy_safe_mode: false, + policy_office_hours: false, + policy_timezone: 'Europe/Berlin', + policy_period_interval: '1 minutes', + policy_max_updates_per_period: 999999, + policy_update_timeout: '60 minutes', + channel: { + id: 'e06064ad-4414-4904-9a6e-fd465593d1b2', + name: 'stable', + color: '#14b9d6', + created_ts: '2015-09-19T07:09:34.261241+02:00', + application_id: 'e96281a6-d1af-4bde-9a0a-97b76e56dc57', + package_id: '84b4c599-9b6b-44a8-b13c-d4263fff0403', + package: { + id: '84b4c599-9b6b-44a8-b13c-d4263fff0403', + type: 1, + version: '2191.5.0', + url: 'https://update.release.flatcar-linux.net/amd64-usr/2191.5.0/', + filename: 'flatcar_production_update.gz', + description: 'Flatcar Container Linux 2191.5.0', + size: '465881871', + hash: 'r3nufcxgMTZaxYEqL+x2zIoeClk=', + created_ts: '2019-09-05T12:41:09.265687+02:00', + channels_blacklist: null, + application_id: 'e96281a6-d1af-4bde-9a0a-97b76e56dc57', + flatcar_action: { + id: '1f6e1bcf-4ebb-4fe6-8ca3-2cb6ad90d5dd', + event: 'postinstall', + chromeos_version: '', + sha256: 'LIkAKVZY2EJFiwTmltiJZLFLA5xT/FodbjVgqkyF/y8=', + needs_admin: false, + is_delta: false, + disable_payload_backoff: true, + metadata_signature_rsa: '', + metadata_size: '', + deadline: '', + created_ts: '2019-08-20T02:12:37.532281+02:00', + }, + arch: 1, + extra_files: [], + }, + arch: 1, + }, + track: 'stable', + }, + duration: { displayValue: '1 day', queryValue: '1d', disabled: false }, +}; diff --git a/frontend/src/components/Groups/GroupCharts/VersionCountTimeline.tsx b/frontend/src/components/Groups/GroupCharts/VersionCountTimeline.tsx new file mode 100644 index 000000000..c18270044 --- /dev/null +++ b/frontend/src/components/Groups/GroupCharts/VersionCountTimeline.tsx @@ -0,0 +1,229 @@ +import { Theme } from '@material-ui/core'; +import Box from '@material-ui/core/Box'; +import Chip from '@material-ui/core/Chip'; +import Grid from '@material-ui/core/Grid'; +import Typography from '@material-ui/core/Typography'; +import { useTheme } from '@material-ui/styles'; +import React from 'react'; +import semver from 'semver'; +import { Group } from '../../../api/apiDataTypes'; +import { makeLocaleTime } from '../../../i18n/dateTime'; +import { groupChartStoreContext } from '../../../stores/Stores'; +import { cleanSemverVersion, makeColorsForVersions } from '../../../utils/helpers'; +import Loader from '../../common/Loader/Loader'; +import SimpleTable from '../../common/SimpleTable/SimpleTable'; +import TimelineChart from './TimelineChart'; +import { Duration } from './TimelineChart'; + +export interface VersionCountTimelineProps { + group: Group | null; + duration: Duration; +} + +export default function VersionCountTimeline(props: VersionCountTimelineProps) { + const [selectedEntry, setSelectedEntry] = React.useState(-1); + const { duration } = props; + const [timelineChartData, setTimelineChartData] = React.useState<{ + data: any[]; + keys: any[]; + colors: any; + }>({ + data: [], + keys: [], + colors: [], + }); + const [timeline, setTimeline] = React.useState({ + timeline: {}, + // A long time ago, to force the first update... + lastUpdate: new Date(2000, 1, 1).toUTCString(), + }); + + const theme = useTheme(); + + const ChartStoreContext = groupChartStoreContext(); + const groupChartStore = React.useContext(ChartStoreContext); + + function makeChartData(group: Group, groupTimeline: { [key: string]: any }) { + const data = Object.keys(groupTimeline).map((timestamp, i) => { + const versions = groupTimeline[timestamp]; + return { + index: i, + timestamp: timestamp, + ...versions, + }; + }); + + const versions = getVersionsFromTimeline(groupTimeline); + const versionColors: { + [key: string]: string; + } = makeColorsForVersions(theme as Theme, versions, group.channel); + + setTimelineChartData({ + data: data, + keys: versions, + colors: versionColors, + }); + } + + function getVersionsFromTimeline(timeline: { [key: string]: any }) { + if (Object.keys(timeline).length === 0) { + return []; + } + + const versions: string[] = []; + + Object.keys(Object.values(timeline)[0]).forEach(version => { + const cleanedVersion = cleanSemverVersion(version); + // Discard any invalid versions (empty strings, etc.) + if (semver.valid(cleanedVersion)) { + versions.push(cleanedVersion); + } + }); + + // Sort versions (earliest first) + versions.sort((version1, version2) => { + return semver.compare(version1, version2); + }); + + return versions; + } + + function getInstanceCount(selectedEntry: number) { + const version_breakdown = []; + let selectedEntryPoint = selectedEntry; + + // If there is no timeline or no specific time is selected, + // show the timeline for the last time point. + if (selectedEntry === -1) { + selectedEntryPoint = timelineChartData.data.length - 1; + } + + let total = 0; + + // If we're not using the default group version breakdown, + // let's populate it from the selected time one. + if (version_breakdown.length === 0 && selectedEntryPoint > -1) { + // Create the version breakdown from the timeline + const entries = timelineChartData.data[selectedEntryPoint] || []; + + for (const version of timelineChartData.keys) { + const versionCount = entries[version]; + + total += versionCount; + + version_breakdown.push({ + version: version, + instances: versionCount, + percentage: 0, + }); + } + } + + version_breakdown.forEach((entry: { [key: string]: any }) => { + entry.color = timelineChartData.colors[entry.version]; + + // Calculate the percentage if needed. + if (total > 0) { + entry.percentage = (entry.instances * 100.0) / total; + } + + entry.percentage = parseFloat(entry.percentage).toFixed(1); + }); + + // Sort the entries per number of instances (higher first). + version_breakdown.sort((elem1, elem2) => { + return -(elem1.instances - elem2.instances); + }); + + return version_breakdown; + } + + function getSelectedTime() { + const data = timelineChartData.data; + if (selectedEntry < 0 || data.length === 0) { + return ''; + } + const timestamp = data[selectedEntry] ? data[selectedEntry].timestamp : ''; + return makeLocaleTime(timestamp); + } + + // Make the timeline data again when needed. + React.useEffect(() => { + let canceled = false; + async function getVersionTimeline(group: Group | null) { + if (group) { + // Check if we should update the timeline or it's too early. + const lastUpdate = new Date(timeline.lastUpdate); + setTimelineChartData({ data: [], keys: [], colors: [] }); + try { + const versionCountTimeline = await groupChartStore.getGroupVersionCountTimeline( + group.application_id, + group.id, + duration.queryValue + ); + if (!canceled) { + setTimeline({ + timeline: versionCountTimeline, + lastUpdate: lastUpdate.toUTCString(), + }); + } + makeChartData(group, versionCountTimeline || []); + setSelectedEntry(-1); + } catch (error) { + console.error(error); + } + } + } + getVersionTimeline(props.group); + return () => { + canceled = true; + }; + }, [duration]); + + return ( + + + {timelineChartData.data.length > 0 ? ( + + ) : ( + + )} + + + + + {timelineChartData.data.length > 0 ? ( + selectedEntry !== -1 ? ( + + Showing for: +   + { + setSelectedEntry(-1); + }} + /> + + ) : ( + + Showing data for the last time point. +
    + Click the chart to choose a different time point. +
    + ) + ) : null} +
    +
    + + {timelineChartData.data.length > 0 && ( + + )} + +
    +
    + ); +} diff --git a/frontend/src/components/Groups/GroupCharts/__snapshots__/StatusCountTimeline.stories.storyshot b/frontend/src/components/Groups/GroupCharts/__snapshots__/StatusCountTimeline.stories.storyshot new file mode 100644 index 000000000..4ae5cda7e --- /dev/null +++ b/frontend/src/components/Groups/GroupCharts/__snapshots__/StatusCountTimeline.stories.storyshot @@ -0,0 +1,54 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots groups/StatusCountTimeline Timeline 1`] = ` +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +`; diff --git a/frontend/src/components/Groups/GroupCharts/__snapshots__/VersionCountTimeline.stories.storyshot b/frontend/src/components/Groups/GroupCharts/__snapshots__/VersionCountTimeline.stories.storyshot new file mode 100644 index 000000000..5ac9b1ae4 --- /dev/null +++ b/frontend/src/components/Groups/GroupCharts/__snapshots__/VersionCountTimeline.stories.storyshot @@ -0,0 +1,54 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots groups/VersionCountTimeline Timeline 1`] = ` +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +`; diff --git a/frontend/src/components/Groups/GroupEditDialog/GroupDetailsForm.stories.tsx b/frontend/src/components/Groups/GroupEditDialog/GroupDetailsForm.stories.tsx new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/frontend/src/components/Groups/GroupEditDialog/GroupDetailsForm.stories.tsx @@ -0,0 +1 @@ +export {}; diff --git a/frontend/src/js/components/Groups/EditDialog/GroupDetailsForm.tsx b/frontend/src/components/Groups/GroupEditDialog/GroupDetailsForm.tsx similarity index 95% rename from frontend/src/js/components/Groups/EditDialog/GroupDetailsForm.tsx rename to frontend/src/components/Groups/GroupEditDialog/GroupDetailsForm.tsx index c86e62800..8a4ad0a74 100644 --- a/frontend/src/js/components/Groups/EditDialog/GroupDetailsForm.tsx +++ b/frontend/src/components/Groups/GroupEditDialog/GroupDetailsForm.tsx @@ -5,11 +5,13 @@ import { useTranslation } from 'react-i18next'; import { Channel } from '../../../api/apiDataTypes'; import { ARCHES } from '../../../utils/helpers'; -export default function GroupDetailsForm(props: { +export interface GroupDetailsFormProps { channels: Channel[]; values: { [key: string]: string }; setFieldValue: (formField: string, value: any) => any; -}) { +} + +export default function GroupDetailsForm(props: GroupDetailsFormProps) { const { t } = useTranslation(); const { channels, values, setFieldValue } = props; diff --git a/frontend/src/components/Groups/GroupEditDialog/GroupEditDialog.stories.tsx b/frontend/src/components/Groups/GroupEditDialog/GroupEditDialog.stories.tsx new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/frontend/src/components/Groups/GroupEditDialog/GroupEditDialog.stories.tsx @@ -0,0 +1 @@ +export {}; diff --git a/frontend/src/js/components/Groups/EditDialog/index.tsx b/frontend/src/components/Groups/GroupEditDialog/GroupEditDialog.tsx similarity index 95% rename from frontend/src/js/components/Groups/EditDialog/index.tsx rename to frontend/src/components/Groups/GroupEditDialog/GroupEditDialog.tsx index a1eff9d2c..dc740042e 100644 --- a/frontend/src/js/components/Groups/EditDialog/index.tsx +++ b/frontend/src/components/Groups/GroupEditDialog/GroupEditDialog.tsx @@ -13,7 +13,7 @@ import { useTranslation } from 'react-i18next'; import * as Yup from 'yup'; import { Group } from '../../../api/apiDataTypes'; import { applicationsStore } from '../../../stores/Stores'; -import { DEFAULT_TIMEZONE } from '../../Common/TimezonePicker'; +import { DEFAULT_TIMEZONE } from '../../common/TimezonePicker'; import GroupDetailsForm from './GroupDetailsForm'; import GroupPolicyForm from './GroupPolicyForm'; @@ -27,14 +27,16 @@ const useStyles = makeStyles({ }, }); -function EditDialog(props: { +export interface GroupEditDialogProps { create?: boolean; data: { [key: string]: any; }; onHide: () => void; show: boolean; -}) { +} + +export default function GroupEditDialog(props: GroupEditDialogProps) { const isCreation = Boolean(props.create); const classes = useStyles(); const [groupEditActiveTab, setGroupEditActiveTab] = React.useState(0); @@ -67,10 +69,10 @@ function EditDialog(props: { let packageFunctionCall; data['application_id'] = props.data.appID; if (isCreation) { - packageFunctionCall = applicationsStore.createGroup(data as Group); + packageFunctionCall = applicationsStore().createGroup(data as Group); } else { data['id'] = props.data.group.id; - packageFunctionCall = applicationsStore.updateGroup(data as Group); + packageFunctionCall = applicationsStore().updateGroup(data as Group); } packageFunctionCall @@ -235,5 +237,3 @@ function EditDialog(props: { ); } - -export default EditDialog; diff --git a/frontend/src/components/Groups/GroupEditDialog/GroupPolicyForm.stories.tsx b/frontend/src/components/Groups/GroupEditDialog/GroupPolicyForm.stories.tsx new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/frontend/src/components/Groups/GroupEditDialog/GroupPolicyForm.stories.tsx @@ -0,0 +1 @@ +export {}; diff --git a/frontend/src/js/components/Groups/EditDialog/GroupPolicyForm.tsx b/frontend/src/components/Groups/GroupEditDialog/GroupPolicyForm.tsx similarity index 97% rename from frontend/src/js/components/Groups/EditDialog/GroupPolicyForm.tsx rename to frontend/src/components/Groups/GroupEditDialog/GroupPolicyForm.tsx index 0984ce994..ff70b204f 100644 --- a/frontend/src/js/components/Groups/EditDialog/GroupPolicyForm.tsx +++ b/frontend/src/components/Groups/GroupEditDialog/GroupPolicyForm.tsx @@ -14,12 +14,14 @@ import HelpOutlineIcon from '@material-ui/icons/HelpOutline'; import { Field } from 'formik'; import { TextField } from 'formik-material-ui'; import { useTranslation } from 'react-i18next'; -import TimezonePicker from '../../Common/TimezonePicker'; +import TimezonePicker from '../../common/TimezonePicker'; -export default function GroupPolicyForm(props: { +export interface GroupPolicyFormProps { values: { [key: string]: string }; setFieldValue: (formField: string, value: any) => any; -}) { +} + +export default function GroupPolicyForm(props: GroupPolicyFormProps) { const { t } = useTranslation(); const { values, setFieldValue } = props; diff --git a/frontend/src/components/Groups/GroupEditDialog/index.tsx b/frontend/src/components/Groups/GroupEditDialog/index.tsx new file mode 100644 index 000000000..55f1d1119 --- /dev/null +++ b/frontend/src/components/Groups/GroupEditDialog/index.tsx @@ -0,0 +1,2 @@ +export { default } from './GroupEditDialog'; +export * from './GroupEditDialog'; diff --git a/frontend/src/components/Groups/GroupItem.stories.tsx b/frontend/src/components/Groups/GroupItem.stories.tsx new file mode 100644 index 000000000..ca36ed7a5 --- /dev/null +++ b/frontend/src/components/Groups/GroupItem.stories.tsx @@ -0,0 +1,87 @@ +import { Meta, Story } from '@storybook/react/types-6-0'; +import { MemoryRouter } from 'react-router-dom'; +import { PureGroupItem, PureGroupItemProps } from './GroupItem'; + +export default { + title: 'groups/GroupItem', + argTypes: { + handleUpdateGroup: { action: 'handleUpdateGroup' }, + deleteGroup: { action: 'deleteGroup' }, + }, +} as Meta; + +const Template: Story = args => { + return ( + + + + ); +}; + +export const Group = Template.bind({}); + +Group.args = { + versionBreakdown: [], + totalInstances: 2, + group: { + id: '11a585f6-9418-4df0-8863-78b2fd3240f8', + name: 'Stable (ARM)', + description: 'For production clusters (ARM)', + created_ts: '2015-09-19T07:09:34.269062+02:00', + rollout_in_progress: false, + application_id: 'e96281a6-d1af-4bde-9a0a-97b76e56dc57', + channel_id: '5dfe7b12-c94a-470d-a2b6-2eae78c5c9f5', + policy_updates_enabled: true, + policy_safe_mode: false, + policy_office_hours: false, + policy_timezone: 'Europe/Berlin', + policy_period_interval: '1 minutes', + policy_max_updates_per_period: 999999, + policy_update_timeout: '60 minutes', + channel: { + id: '5dfe7b12-c94a-470d-a2b6-2eae78c5c9f5', + name: 'stable', + color: '#1458d6', + created_ts: '2015-09-19T07:09:34.261241+02:00', + application_id: 'e96281a6-d1af-4bde-9a0a-97b76e56dc57', + package_id: null, + package: null, + arch: 2, + }, + track: 'stable', + }, +}; + +export const Loading = Template.bind({}); + +Loading.args = { + versionBreakdown: null, + totalInstances: null, + group: { + id: '11a585f6-9418-4df0-8863-78b2fd3240f8', + name: 'Stable (ARM)', + description: 'For production clusters (ARM)', + created_ts: '2015-09-19T07:09:34.269062+02:00', + rollout_in_progress: false, + application_id: 'e96281a6-d1af-4bde-9a0a-97b76e56dc57', + channel_id: '5dfe7b12-c94a-470d-a2b6-2eae78c5c9f5', + policy_updates_enabled: true, + policy_safe_mode: false, + policy_office_hours: false, + policy_timezone: 'Europe/Berlin', + policy_period_interval: '1 minutes', + policy_max_updates_per_period: 999999, + policy_update_timeout: '60 minutes', + channel: { + id: '5dfe7b12-c94a-470d-a2b6-2eae78c5c9f5', + name: 'stable', + color: '#1458d6', + created_ts: '2015-09-19T07:09:34.261241+02:00', + application_id: 'e96281a6-d1af-4bde-9a0a-97b76e56dc57', + package_id: null, + package: null, + arch: 2, + }, + track: 'stable', + }, +}; diff --git a/frontend/src/js/components/Groups/Item.tsx b/frontend/src/components/Groups/GroupItem.tsx similarity index 64% rename from frontend/src/js/components/Groups/Item.tsx rename to frontend/src/components/Groups/GroupItem.tsx index 80998c87f..2e993ca77 100644 --- a/frontend/src/js/components/Groups/Item.tsx +++ b/frontend/src/components/Groups/GroupItem.tsx @@ -9,15 +9,15 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import _ from 'underscore'; import API from '../../api/API'; -import { Channel, Group } from '../../api/apiDataTypes'; +import { Group, VersionBreakdownEntry } from '../../api/apiDataTypes'; import { applicationsStore } from '../../stores/Stores'; import { useGroupVersionBreakdown } from '../../utils/helpers'; -import ChannelItem from '../Channels/Item'; -import { CardFeatureLabel, CardHeader, CardLabel } from '../Common/Card'; -import Empty from '../Common/EmptyContent'; -import ListItem from '../Common/ListItem'; -import MoreMenu from '../Common/MoreMenu'; -import VersionProgressBar from '../Common/VersionBreakdownBar'; +import ChannelItem from '../Channels/ChannelItem'; +import { CardFeatureLabel, CardHeader, CardLabel } from '../common/Card'; +import Empty from '../common/EmptyContent'; +import ListItem from '../common/ListItem'; +import MoreMenu from '../common/MoreMenu'; +import VersionProgressBar from '../common/VersionBreakdownBar'; const useStyles = makeStyles(theme => ({ root: { @@ -49,66 +49,90 @@ export function formatUpdateLimits(t: TFunction, group: Group) { }); } -function Item(props: { +export interface GroupItemProps { group: Group; - appName: string; - channels: Channel[]; handleUpdateGroup: (appID: string, groupID: string) => void; -}) { - const classes = useStyles(); - const { t } = useTranslation(); - const [totalInstances, setTotalInstances] = React.useState(-1); - - const version_breakdown = useGroupVersionBreakdown(props.group); - const description = props.group.description || t('groups|No description provided'); - const channel = props.group.channel || null; +} - const groupChannel = _.isEmpty(props.group.channel) ? ( - {t('groups|No channel provided')} - ) : ( - - ); - const groupPath = `/apps/${props.group.application_id}/groups/${props.group.id}`; +function GroupItem({ group, handleUpdateGroup }: GroupItemProps) { + const { t } = useTranslation(); + const [totalInstances, setTotalInstances] = React.useState(null); + const versionBreakdown = useGroupVersionBreakdown(group); + console.log('versionBreakdown', JSON.stringify(versionBreakdown)); - function deleteGroup() { + function deleteGroup(appID: string, groupID: string) { const confirmationText = t('groups|Are you sure you want to delete this group?'); if (window.confirm(confirmationText)) { - applicationsStore.deleteGroup(props.group.application_id, props.group.id); + applicationsStore().deleteGroup(appID, groupID); } } - function updateGroup() { - props.handleUpdateGroup(props.group.application_id, props.group.id); - } - React.useEffect(() => { - API.getInstancesCount(props.group.application_id, props.group.id, '1d') + API.getInstancesCount(group.application_id, group.id, '1d') .then(result => { setTotalInstances(result); }) .catch(err => console.error('Error getting total instances in Group/Item', err)); }, []); + return ( + + ); +} + +export interface PureGroupItemProps { + group: Group; + versionBreakdown: VersionBreakdownEntry[] | null; + totalInstances: number | null; + handleUpdateGroup: (appID: string, groupID: string) => void; + deleteGroup: (appID: string, groupID: string) => void; +} + +export function PureGroupItem({ + group, + versionBreakdown, + totalInstances, + handleUpdateGroup, + deleteGroup, +}: PureGroupItemProps) { + const classes = useStyles(); + const { t } = useTranslation(); + + const description = group.description || t('groups|No description provided'); + const channel = group.channel || null; + + const groupChannel = _.isEmpty(group.channel) ? ( + {t('groups|No channel provided')} + ) : ( + + ); + return ( handleUpdateGroup(group.application_id, group.id), }, { label: t('frequent|Delete'), - action: deleteGroup, + action: () => deleteGroup(group.application_id, group.id), }, ]} /> @@ -120,7 +144,15 @@ function Item(props: { {t('groups|Instances')} - {totalInstances > 0 ? totalInstances : t('frequent|None')} + {totalInstances !== null ? ( + totalInstances > 0 ? ( + totalInstances + ) : ( + t('frequent|None') + ) + ) : ( + {t('frequent|Loading...')} + )} @@ -145,7 +177,7 @@ function Item(props: { - {props.group.policy_updates_enabled ? ( + {group.policy_updates_enabled ? ( <> {t('frequent|Enabled')} @@ -167,7 +199,7 @@ function Item(props: { {t('groups|Rollout Policy')} - {formatUpdateLimits(t, props.group)} + {formatUpdateLimits(t, group)} @@ -175,8 +207,10 @@ function Item(props: { {t('groups|Version breakdown')} - {version_breakdown?.length > 0 ? ( - + {versionBreakdown === null ? ( + {t('frequent|Loading...')} + ) : versionBreakdown?.length > 0 ? ( + ) : ( {t('groups|No instances available.')} )} @@ -189,4 +223,4 @@ function Item(props: { ); } -export default Item; +export default GroupItem; diff --git a/frontend/src/components/Groups/GroupItemExtended.stories.tsx b/frontend/src/components/Groups/GroupItemExtended.stories.tsx new file mode 100644 index 000000000..cb0ff5c3b --- /dev/null +++ b/frontend/src/components/Groups/GroupItemExtended.stories.tsx @@ -0,0 +1 @@ +export {}; diff --git a/frontend/src/js/components/Groups/ItemExtended.tsx b/frontend/src/components/Groups/GroupItemExtended.tsx similarity index 94% rename from frontend/src/js/components/Groups/ItemExtended.tsx rename to frontend/src/components/Groups/GroupItemExtended.tsx index 6fb2aee5b..6ddcf841b 100644 --- a/frontend/src/js/components/Groups/ItemExtended.tsx +++ b/frontend/src/components/Groups/GroupItemExtended.tsx @@ -13,13 +13,14 @@ import API from '../../api/API'; import { Application, Group } from '../../api/apiDataTypes'; import { applicationsStore } from '../../stores/Stores'; import { defaultTimeInterval, timeIntervalsDefault } from '../../utils/helpers'; -import ChannelItem from '../Channels/Item'; -import { CardFeatureLabel, CardHeader, CardLabel } from '../Common/Card'; -import MoreMenu from '../Common/MoreMenu'; -import TimeIntervalLinks from '../Common/TimeIntervalLinks'; +import ChannelItem from '../Channels/ChannelItem'; +import { CardFeatureLabel, CardHeader, CardLabel } from '../common/Card'; +import MoreMenu from '../common/MoreMenu'; +import TimeIntervalLinks from '../common/TimeIntervalLinks'; import InstanceStatusArea from '../Instances/Charts'; -import { StatusCountTimeline, VersionCountTimeline } from './Charts'; -import { formatUpdateLimits } from './Item'; +import StatusCountTimeline from './GroupCharts/StatusCountTimeline'; +import VersionCountTimeline from './GroupCharts/VersionCountTimeline'; +import { formatUpdateLimits } from './GroupItem'; const useStyles = makeStyles(theme => ({ link: { @@ -56,10 +57,10 @@ function ItemExtended(props: { const { t } = useTranslation(); function onChange() { - const app = applicationsStore.getCachedApplication(props.appID); + const app = applicationsStore().getCachedApplication(props.appID); if (!app) { - applicationsStore.getApplication(props.appID); + applicationsStore().getApplication(props.appID); return; } @@ -86,11 +87,11 @@ function ItemExtended(props: { } React.useEffect(() => { - applicationsStore.addChangeListener(onChange); + applicationsStore().addChangeListener(onChange); onChange(); return function cleanup() { - applicationsStore.removeChangeListener(onChange); + applicationsStore().removeChangeListener(onChange); }; }, []); diff --git a/frontend/src/js/components/Groups/List.tsx b/frontend/src/components/Groups/GroupList.tsx similarity index 73% rename from frontend/src/js/components/Groups/List.tsx rename to frontend/src/components/Groups/GroupList.tsx index 701a51501..641b802c2 100644 --- a/frontend/src/js/components/Groups/List.tsx +++ b/frontend/src/components/Groups/GroupList.tsx @@ -1,29 +1,34 @@ -import { withStyles } from '@material-ui/core'; import MuiList from '@material-ui/core/List'; import Paper from '@material-ui/core/Paper'; +import { makeStyles } from '@material-ui/core/styles'; import React from 'react'; import { Trans } from 'react-i18next'; import _ from 'underscore'; import { Channel, Group } from '../../api/apiDataTypes'; import { applicationsStore } from '../../stores/Stores'; -import Empty from '../Common/EmptyContent'; -import ListHeader from '../Common/ListHeader'; -import Loader from '../Common/Loader'; -import ModalButton from '../Common/ModalButton'; -import EditDialog from './EditDialog'; -import Item from './Item'; +import Empty from '../common/EmptyContent'; +import ListHeader from '../common/ListHeader'; +import Loader from '../common/Loader/Loader'; +import ModalButton from '../common/ModalButton'; +import GroupEditDialog from './GroupEditDialog'; +import GroupItem from './GroupItem'; -const styles = () => ({ +const useStyles = makeStyles(() => ({ root: { '& > hr:first-child': { display: 'none', }, }, -}); +})); -function List(props: { appID: string; classes: Record<'root', string> }) { +export interface GroupListProps { + appID: string; +} + +function GroupList({ appID }: GroupListProps) { + const classes = useStyles(); const [application, setApplication] = React.useState( - applicationsStore.getCachedApplication(props.appID) + applicationsStore().getCachedApplication(appID) ); const [updateGroupModalVisible, setUpdateGroupModalVisible] = React.useState(false); const [updateGroupIDModal, setUpdateGroupIDModal] = React.useState(null); @@ -38,23 +43,21 @@ function List(props: { appID: string; classes: Record<'root', string> }) { } React.useEffect(() => { - applicationsStore.addChangeListener(onChange); + applicationsStore().addChangeListener(onChange); return () => { - applicationsStore.removeChangeListener(onChange); + applicationsStore().removeChangeListener(onChange); }; }, []); function onChange() { - setApplication(applicationsStore.getCachedApplication(props.appID)); + setApplication(applicationsStore().getCachedApplication(appID)); } let channels: Channel[] = []; let groups: Group[] = []; - let name = ''; let entries: React.ReactNode = ''; if (application) { - name = application.name; groups = application.groups ? application.groups : []; channels = application.channels ? application.channels : []; @@ -73,11 +76,9 @@ function List(props: { appID: string; classes: Record<'root', string> }) { } else { entries = _.map(groups, group => { return ( - ); @@ -91,7 +92,6 @@ function List(props: { appID: string; classes: Record<'root', string> }) { !_.isEmpty(groups) && updateGroupIDModal ? _.findWhere(groups, { id: updateGroupIDModal }) : null; - const { classes } = props; return ( <> @@ -103,7 +103,7 @@ function List(props: { appID: string; classes: Record<'root', string> }) { modalToOpen="AddGroupModal" data={{ channels: channels, - appID: props.appID, + appID: appID, }} />, ]} @@ -111,8 +111,8 @@ function List(props: { appID: string; classes: Record<'root', string> }) { {entries} {groupToUpdate && ( - @@ -122,4 +122,4 @@ function List(props: { appID: string; classes: Record<'root', string> }) { ); } -export default withStyles(styles)(List); +export default GroupList; diff --git a/frontend/src/components/Groups/__snapshots__/GroupItem.stories.storyshot b/frontend/src/components/Groups/__snapshots__/GroupItem.stories.storyshot new file mode 100644 index 000000000..8e85cd5ec --- /dev/null +++ b/frontend/src/components/Groups/__snapshots__/GroupItem.stories.storyshot @@ -0,0 +1,614 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots groups/GroupItem Group 1`] = ` +
    +
  • +
    +
    +
    +
    + +
    +
    +

    + stable +

    +
    +
    + + For production clusters (ARM) + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + Instances + +
    + + 2 + +
    + +
    +

    + last 24 hours +

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + Channel + + +
    +
    +
    +
    + s +
    +
    +
    +
    +
    +
    + stable +
    +
    +
    +
    + No package (ARM64) +
    +
    +
    +
    +
    +
    +
    +
    + + Updates + +
    + +
    +
    + Enabled +
    +
    + +
    +
    +
    +
    +
    +
    + + Rollout Policy + +
    + + Unlimited number of parallel updates + +
    +
    +
    +
    + + Version breakdown + +
    +
    +
    +

    + No instances available. +

    +
    +
    +
    +
    +
    +
    +
  • +
    +`; + +exports[`Storyshots groups/GroupItem Loading 1`] = ` +
    +
  • +
    +
    +
    +
    + +
    +
    +

    + stable +

    +
    +
    + + For production clusters (ARM) + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + Instances + +
    + +
    +

    + Loading... +

    +
    +
    +
    + +
    +

    + last 24 hours +

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + Channel + + +
    +
    +
    +
    + s +
    +
    +
    +
    +
    +
    + stable +
    +
    +
    +
    + No package (ARM64) +
    +
    +
    +
    +
    +
    +
    +
    + + Updates + +
    + +
    +
    + Enabled +
    +
    + +
    +
    +
    +
    +
    +
    + + Rollout Policy + +
    + + Unlimited number of parallel updates + +
    +
    +
    +
    + + Version breakdown + +
    +
    +
    +

    + Loading... +

    +
    +
    +
    +
    +
    +
    +
  • +
    +`; diff --git a/frontend/src/js/components/Header.tsx b/frontend/src/components/Header.tsx similarity index 92% rename from frontend/src/js/components/Header.tsx rename to frontend/src/components/Header.tsx index 56f557b7e..ae1eac096 100644 --- a/frontend/src/js/components/Header.tsx +++ b/frontend/src/components/Header.tsx @@ -3,13 +3,7 @@ import { Box, Button } from '@material-ui/core'; import AppBar from '@material-ui/core/AppBar'; import IconButton from '@material-ui/core/IconButton'; import Menu, { MenuProps } from '@material-ui/core/Menu'; -import { - createMuiTheme, - makeStyles, - Theme, - ThemeProvider, - useTheme, -} from '@material-ui/core/styles'; +import { makeStyles, ThemeProvider } from '@material-ui/core/styles'; import Toolbar from '@material-ui/core/Toolbar'; import Typography from '@material-ui/core/Typography'; import AccountCircle from '@material-ui/icons/AccountCircle'; @@ -19,6 +13,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import _ from 'underscore'; import nebraskaLogo from '../icons/nebraska-logo.json'; +import themes from '../lib/themes'; import { UserState } from '../stores/redux/features/user'; import { useSelector } from '../stores/redux/hooks'; @@ -47,19 +42,6 @@ const useStyles = makeStyles(theme => ({ }, })); -function prepareDarkTheme(theme: Theme) { - return createMuiTheme({ - ...theme, - palette: { - type: 'dark', - primary: { - contrastText: '#fff', - main: '#000', - }, - }, - }); -} - interface NebraskaConfig { title?: string; logo?: string; @@ -158,7 +140,6 @@ function Appbar(props: AppbarProps) { export default function Header() { const { config, user } = useSelector(state => ({ config: state.config, user: state.user })); - const theme = useTheme(); const projectLogo = _.isEmpty(nebraskaLogo) ? null : nebraskaLogo; const [menuAnchorEl, setMenuAnchorEl] = React.useState(null); @@ -180,10 +161,11 @@ export default function Header() { } as AppbarProps; const appBar = ; // cachedConfig.appBarColor is for backward compatibility (the name used for the setting before). + // @todo: Use themes@getThemeName to get the name. return config && (config.header_style === 'dark' || (config.header_style === undefined && config.appBarColor === 'dark')) ? ( - {appBar} + {appBar} ) : ( appBar ); diff --git a/frontend/src/js/components/Instances/Charts.tsx b/frontend/src/components/Instances/Charts.tsx similarity index 98% rename from frontend/src/js/components/Instances/Charts.tsx rename to frontend/src/components/Instances/Charts.tsx index dc23e7795..91e78292d 100644 --- a/frontend/src/js/components/Instances/Charts.tsx +++ b/frontend/src/components/Instances/Charts.tsx @@ -6,9 +6,9 @@ import { makeStyles, useTheme } from '@material-ui/styles'; import React from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { Cell, Label, Pie, PieChart } from 'recharts'; -import Empty from '../Common/EmptyContent'; -import LightTooltip from '../Common/LightTooltip'; -import Loader from '../Common/Loader'; +import Empty from '../common/EmptyContent'; +import LightTooltip from '../common/LightTooltip'; +import Loader from '../common/Loader'; import { InstanceCountLabel } from './Common'; import makeStatusDefs from './StatusDefs'; diff --git a/frontend/src/js/components/Instances/Common.tsx b/frontend/src/components/Instances/Common.tsx similarity index 100% rename from frontend/src/js/components/Instances/Common.tsx rename to frontend/src/components/Instances/Common.tsx diff --git a/frontend/src/js/components/Instances/Details.tsx b/frontend/src/components/Instances/Details.tsx similarity index 97% rename from frontend/src/js/components/Instances/Details.tsx rename to frontend/src/components/Instances/Details.tsx index ce056b8b8..3520f8aeb 100644 --- a/frontend/src/js/components/Instances/Details.tsx +++ b/frontend/src/components/Instances/Details.tsx @@ -29,19 +29,19 @@ import { Link as RouterLink } from 'react-router-dom'; import * as Yup from 'yup'; import API from '../../api/API'; import { Application, Group, Instance, InstanceStatusHistory } from '../../api/apiDataTypes'; +import { makeLocaleTime } from '../../i18n/dateTime'; import { ERROR_STATUS_CODE, getErrorAndFlags, getInstanceStatus, - makeLocaleTime, prepareErrorMessage, } from '../../utils/helpers'; -import ChannelItem from '../Channels/Item'; -import { CardFeatureLabel, CardLabel } from '../Common/Card'; -import Empty from '../Common/EmptyContent'; -import ListHeader from '../Common/ListHeader'; -import Loader from '../Common/Loader'; -import MoreMenu from '../Common/MoreMenu'; +import ChannelItem from '../Channels/ChannelItem'; +import { CardFeatureLabel, CardLabel } from '../common/Card'; +import Empty from '../common/EmptyContent'; +import ListHeader from '../common/ListHeader'; +import Loader from '../common/Loader/Loader'; +import MoreMenu from '../common/MoreMenu/MoreMenu'; import makeStatusDefs from './StatusDefs'; const useDetailsStyles = makeStyles((theme: Theme) => ({ diff --git a/frontend/src/js/components/Instances/Item.tsx b/frontend/src/components/Instances/Item.tsx similarity index 97% rename from frontend/src/js/components/Instances/Item.tsx rename to frontend/src/components/Instances/Item.tsx index f9c70a558..770ddfc61 100644 --- a/frontend/src/js/components/Instances/Item.tsx +++ b/frontend/src/components/Instances/Item.tsx @@ -13,7 +13,8 @@ import semver from 'semver'; import _ from 'underscore'; import API from '../../api/API'; import { Instance } from '../../api/apiDataTypes'; -import { cleanSemverVersion, makeLocaleTime } from '../../utils/helpers'; +import { makeLocaleTime } from '../../i18n/dateTime'; +import { cleanSemverVersion } from '../../utils/helpers'; import StatusHistoryContainer from './StatusHistoryContainer'; const TableLabel = function (props: PropsWithChildren<{ bgColor?: string; textColor?: string }>) { diff --git a/frontend/src/js/components/Instances/List.tsx b/frontend/src/components/Instances/List.tsx similarity index 98% rename from frontend/src/js/components/Instances/List.tsx rename to frontend/src/components/Instances/List.tsx index bbea7a6d7..ac9c5777b 100644 --- a/frontend/src/js/components/Instances/List.tsx +++ b/frontend/src/components/Instances/List.tsx @@ -29,12 +29,12 @@ import { SearchFilterClassifiers, useGroupVersionBreakdown, } from '../../utils/helpers'; -import Empty from '../Common/EmptyContent'; -import LightTooltip from '../Common/LightTooltip'; -import ListHeader from '../Common/ListHeader'; -import SearchInput from '../Common/ListSearch'; -import Loader from '../Common/Loader'; -import TimeIntervalLinks from '../Common/TimeIntervalLinks'; +import Empty from '../common/EmptyContent'; +import LightTooltip from '../common/LightTooltip'; +import ListHeader from '../common/ListHeader'; +import SearchInput from '../common/ListSearch'; +import Loader from '../common/Loader'; +import TimeIntervalLinks from '../common/TimeIntervalLinks'; import { InstanceCountLabel } from './Common'; import makeStatusDefs from './StatusDefs'; import Table from './Table'; diff --git a/frontend/src/js/components/Instances/StatusDefs.ts b/frontend/src/components/Instances/StatusDefs.ts similarity index 100% rename from frontend/src/js/components/Instances/StatusDefs.ts rename to frontend/src/components/Instances/StatusDefs.ts diff --git a/frontend/src/js/components/Instances/StatusHistoryContainer.tsx b/frontend/src/components/Instances/StatusHistoryContainer.tsx similarity index 95% rename from frontend/src/js/components/Instances/StatusHistoryContainer.tsx rename to frontend/src/components/Instances/StatusHistoryContainer.tsx index 4c70c2117..a176f6870 100644 --- a/frontend/src/js/components/Instances/StatusHistoryContainer.tsx +++ b/frontend/src/components/Instances/StatusHistoryContainer.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import _ from 'underscore'; import { InstanceStatusHistory } from '../../api/apiDataTypes'; -import Empty from '../Common/EmptyContent'; +import Empty from '../common/EmptyContent'; import StatusHistoryList from './StatusHistoryList'; const useStyles = makeStyles({ diff --git a/frontend/src/js/components/Instances/StatusHistoryItem.tsx b/frontend/src/components/Instances/StatusHistoryItem.tsx similarity index 97% rename from frontend/src/js/components/Instances/StatusHistoryItem.tsx rename to frontend/src/components/Instances/StatusHistoryItem.tsx index c1d73cab0..98be2e0ef 100644 --- a/frontend/src/js/components/Instances/StatusHistoryItem.tsx +++ b/frontend/src/components/Instances/StatusHistoryItem.tsx @@ -3,11 +3,11 @@ import TableCell from '@material-ui/core/TableCell'; import TableRow from '@material-ui/core/TableRow'; import React from 'react'; import { InstanceStatusHistory } from '../../api/apiDataTypes'; +import { makeLocaleTime } from '../../i18n/dateTime'; import { ERROR_STATUS_CODE, getErrorAndFlags, getInstanceStatus, - makeLocaleTime, prepareErrorMessage, } from '../../utils/helpers'; diff --git a/frontend/src/js/components/Instances/StatusHistoryList.tsx b/frontend/src/components/Instances/StatusHistoryList.tsx similarity index 100% rename from frontend/src/js/components/Instances/StatusHistoryList.tsx rename to frontend/src/components/Instances/StatusHistoryList.tsx diff --git a/frontend/src/js/components/Instances/Table.tsx b/frontend/src/components/Instances/Table.tsx similarity index 100% rename from frontend/src/js/components/Instances/Table.tsx rename to frontend/src/components/Instances/Table.tsx diff --git a/frontend/src/js/components/Main..tsx b/frontend/src/components/Main.tsx similarity index 60% rename from frontend/src/js/components/Main..tsx rename to frontend/src/components/Main.tsx index 1df7f3258..14ff2a10b 100644 --- a/frontend/src/js/components/Main..tsx +++ b/frontend/src/components/Main.tsx @@ -1,71 +1,23 @@ -import green from '@material-ui/core/colors/green'; import Container from '@material-ui/core/Container'; import CssBaseline from '@material-ui/core/CssBaseline'; import Link from '@material-ui/core/Link'; -import { createMuiTheme } from '@material-ui/core/styles'; import { makeStyles } from '@material-ui/core/styles'; import React from 'react'; import { Route, Switch } from 'react-router-dom'; import API from '../api/API'; import ThemeProviderNexti18n from '../i18n/ThemeProviderNexti18n'; +import themes, { getThemeName, usePrefersColorScheme } from '../lib/themes'; import { setConfig } from '../stores/redux/features/config'; import { useDispatch } from '../stores/redux/hooks'; import { useAuthRedirect } from '../utils/auth'; import Footer from './Footer'; import Header from './Header'; -import ApplicationLayout from './Layouts/ApplicationLayout'; -import GroupLayout from './Layouts/GroupLayout'; -import InstanceLayout from './Layouts/InstanceLayout'; -import InstanceListLayout from './Layouts/InstanceListLayout'; -import MainLayout from './Layouts/MainLayout'; -import PageNotFoundLayout from './Layouts/PageNotFoundLayout'; -declare module '@material-ui/core/styles/createPalette' { - interface Palette { - titleColor: '#000000'; - lightSilverShade: '#F0F0F0'; - greyShadeColor: '#474747'; - sapphireColor: '#061751'; - } -} - -const nebraskaTheme = createMuiTheme({ - palette: { - primary: { - contrastText: '#fff', - main: process.env.REACT_APP_PRIMARY_COLOR ? process.env.REACT_APP_PRIMARY_COLOR : '#2C98F0', - }, - success: { - main: green['500'], - ...green, - }, - }, - typography: { - fontFamily: 'Overpass, sans-serif', - h1: { - fontSize: '1.875rem', - fontWeight: 900, - }, - h2: { - fontSize: '1.875rem', - fontWeight: 900, - }, - h3: { - fontSize: '1.875rem', - fontWeight: 900, - }, - h4: { - fontSize: '1.875rem', - fontWeight: 900, - }, - subtitle1: { - fontSize: '0.875rem', - color: 'rgba(0,0,0,0.6)', - }, - }, - shape: { - borderRadius: 0, - }, -}); +import ApplicationLayout from './layouts/ApplicationLayout'; +import GroupLayout from './layouts/GroupLayout'; +import InstanceLayout from './layouts/InstanceLayout'; +import InstanceListLayout from './layouts/InstanceListLayout'; +import MainLayout from './layouts/MainLayout'; +import PageNotFoundLayout from './layouts/PageNotFoundLayout'; const useStyle = makeStyles(() => ({ // importing visuallyHidden has typing issues at time of writing. @@ -86,6 +38,13 @@ const useStyle = makeStyles(() => ({ export default function Main() { const dispatch = useDispatch(); const classes = useStyle(); + // let themeName = useTypedSelector(state => state.ui.theme.name); + let themeName = 'light'; + usePrefersColorScheme(); + + if (!themeName) { + themeName = getThemeName(); + } React.useEffect(() => { API.getConfig().then(config => { @@ -97,7 +56,7 @@ export default function Main() { useAuthRedirect(); return ( - + Skip to main content diff --git a/frontend/src/js/components/Packages/EditDialog.tsx b/frontend/src/components/Packages/EditDialog.tsx similarity index 97% rename from frontend/src/js/components/Packages/EditDialog.tsx rename to frontend/src/components/Packages/EditDialog.tsx index e72598dfc..e023be4b7 100644 --- a/frontend/src/js/components/Packages/EditDialog.tsx +++ b/frontend/src/components/Packages/EditDialog.tsx @@ -23,7 +23,7 @@ import { Channel, Package } from '../../api/apiDataTypes'; import { applicationsStore } from '../../stores/Stores'; import { ARCHES } from '../../utils/helpers'; import { REGEX_SEMVER } from '../../utils/regex'; -import Tabs from '../Common/Tabs'; +import Tabs from '../common/Tabs'; import FileList from './FileList'; const useStyles = makeStyles({ @@ -105,9 +105,9 @@ function EditDialog(props: EditDialogProps) { let pkgFunc: Promise; if (isCreation) { - pkgFunc = applicationsStore.createPackage(data); + pkgFunc = applicationsStore().createPackage(data); } else { - pkgFunc = applicationsStore.updatePackage({ ...data, id: props.data.package.id }); + pkgFunc = applicationsStore().updatePackage({ ...data, id: props.data.package.id }); } pkgFunc @@ -277,10 +277,10 @@ function EditDialog(props: EditDialogProps) { .map((packageItem: Channel) => { const label = packageItem.name; const isDisabled = - !isCreation && - packageItem.package && - props.data.package.version === packageItem.package.version; - + (!isCreation && + packageItem.package && + props.data.package.version === packageItem.package.version) || + false; return ( (null); const [packageToUpdate, setPackageToUpdate] = React.useState(null); @@ -27,29 +27,31 @@ function List(props: { appID: string }) { const { t } = useTranslation(); function onChange() { - setApplication(applicationsStore.getCachedApplication(props.appID)); + setApplication(applicationsStore().getCachedApplication(props.appID)); } React.useEffect(() => { - applicationsStore.addChangeListener(onChange); - API.getPackages(props.appID) - .then(result => { - if (_.isNull(result.packages)) { - setPackages([]); - return; - } - setPackages(result.packages); - }) - .catch(err => { - console.error('Error getting the packages in the Packages/List: ', err); - }); + applicationsStore().addChangeListener(onChange); + if (!packages) { + API.getPackages(props.appID) + .then(result => { + if (_.isNull(result.packages)) { + setPackages([]); + return; + } + setPackages(result.packages); + }) + .catch(err => { + console.error('Error getting the packages in the Packages/List: ', err); + }); + } if (application === null) { - applicationsStore.getApplication(props.appID); + applicationsStore().getApplication(props.appID); } return function cleanup() { - applicationsStore.removeChangeListener(onChange); + applicationsStore().removeChangeListener(onChange); }; }, [props.appID, application]); diff --git a/frontend/src/components/common/AutoCompletePicker/AutoCompletePicker.stories.tsx b/frontend/src/components/common/AutoCompletePicker/AutoCompletePicker.stories.tsx new file mode 100644 index 000000000..c5a463028 --- /dev/null +++ b/frontend/src/components/common/AutoCompletePicker/AutoCompletePicker.stories.tsx @@ -0,0 +1,36 @@ +import { Meta, Story } from '@storybook/react/types-6-0'; +import AutoCompletePicker, { AutoCompletePickerProps } from './AutoCompletePicker'; + +export default { + title: 'AutoCompletePicker', + argTypes: { + onSelect: { action: 'onSelect' }, + onValueChanged: { action: 'onValueChanged' }, + }, +} as Meta; + +const AutoCompletePickerTemplate: Story = args => ( + +); + +export const Closed = AutoCompletePickerTemplate.bind({}); +Closed.args = { + defaultValue: '2261.0.0', + suggestions: [ + { primary: '2261.0.0', secondary: 'created: 09/13/2019' }, + { primary: '2247.99.0', secondary: 'created: 09/05/2019' }, + { primary: '2247.2.0', secondary: 'created: 09/13/2019' }, + { primary: '2191.5.0', secondary: 'created: 09/05/2019' }, + ], + label: 'Package', + placeholder: 'Pick a package', + dialogTitle: 'Choose a package', + pickerPlaceholder: 'Start typing to search a package', + initialOpen: false, +}; + +export const Open = AutoCompletePickerTemplate.bind({}); +Open.args = { + ...Closed.args, + initialOpen: true, +}; diff --git a/frontend/src/js/components/Common/AutoCompletePicker.tsx b/frontend/src/components/common/AutoCompletePicker/AutoCompletePicker.tsx similarity index 78% rename from frontend/src/js/components/Common/AutoCompletePicker.tsx rename to frontend/src/components/common/AutoCompletePicker/AutoCompletePicker.tsx index df3223ad4..8c5be589e 100644 --- a/frontend/src/js/components/Common/AutoCompletePicker.tsx +++ b/frontend/src/components/common/AutoCompletePicker/AutoCompletePicker.tsx @@ -61,7 +61,6 @@ interface RenderSuggestionProps { itemProps: object; selectedItem: string; suggestion: { - label: string; primary: string; secondary: string; }; @@ -80,24 +79,27 @@ function renderSuggestion(suggestionProps: RenderSuggestionProps) { ); } -function getSuggestions( +/** + * Filters suggestions to those which match value. + * @param value to search for. + * @param selectedItem if the value is already selected, return unfiltered suggestions. + * @param suggestions to search through. + * @returns filtered suggestions that match value. + */ +function filterSuggestions( value: string | null, selectedItem: string, suggestions: RenderSuggestionProps['suggestion'][] ) { - if (!value) { + if (!value || value === selectedItem) { return suggestions; } const inputValue = value.toLowerCase(); - if (value === selectedItem) return suggestions; - - return inputValue.length === 0 - ? suggestions - : suggestions.filter(suggestion => { - return suggestion.primary.toLowerCase().includes(inputValue); - }); + return suggestions.filter(suggestion => { + return suggestion.primary.toLowerCase().includes(inputValue); + }); } const useStyles = makeStyles({ @@ -155,45 +157,39 @@ function LazyList(props: LazyListProps) { ); } -interface AutoCompletePickerProps { + +export interface AutoCompletePickerProps { + /** The default value. Use when the component is not controlled. */ defaultValue: string; - getSuggestions: RenderSuggestionProps['suggestion'][]; + /** Suggestions that can be picked. */ + suggestions: RenderSuggestionProps['suggestion'][]; + /** Callback fired when the value is selected. */ onSelect: (selectedValue: string) => void; + /** The label content. */ label: string; + /** The short hint displayed in the input before the user enters a value. */ placeholder: string; + /** Title shown when the picker is being displayed. */ dialogTitle: string; + /** A separate placeholder for the picker. */ pickerPlaceholder: string; onValueChanged: (value?: string | null) => void; + /** */ onBottomScrolled?: () => void; + /** Should the color picker be displayed initially? */ + initialOpen?: boolean; } export default function AutoCompletePicker(props: AutoCompletePickerProps) { - const [showPicker, setShowPicker] = React.useState(false); + const [showPicker, setShowPicker] = React.useState(props.initialOpen); const [selectedValue, setSelectedValue] = React.useState(props.defaultValue); const [currentValue, setCurrentValue] = React.useState(props.defaultValue); - const suggestions = props.getSuggestions; const { onBottomScrolled } = props; const { t } = useTranslation(); - const classes = useStyles(); - function onInputActivate() { - setShowPicker(true); - } - - function handleClose() { - setShowPicker(false); - // It's important to send this value as a way to tell that no value is - // selected any longer. - props.onValueChanged(null); - } - - function handleSelect() { - setShowPicker(false); - setCurrentValue(selectedValue); - props.onSelect(selectedValue); - } function onInputChange(event: React.ChangeEvent) { + setSelectedValue(event.target.value); props.onValueChanged(event.target.value); } @@ -215,7 +211,9 @@ export default function AutoCompletePicker(props: AutoCompletePickerProps) { {props.label} { + setShowPicker(true); + }} inputProps={{ className: classes.pickerButtonInput, }} @@ -224,7 +222,7 @@ export default function AutoCompletePicker(props: AutoCompletePickerProps) { readOnly /> - + {props.dialogTitle} @@ -236,8 +234,6 @@ export default function AutoCompletePicker(props: AutoCompletePickerProps) { inputValue, selectedItem, }) => { - setSelectedValue(selectedItem); - const { onBlur, onFocus, ...inputProps } = getInputProps(); return ( @@ -255,7 +251,7 @@ export default function AutoCompletePicker(props: AutoCompletePickerProps) { onKeyDown: handleEscape, })} - - diff --git a/frontend/src/components/common/AutoCompletePicker/__snapshots__/AutoCompletePicker.stories.storyshot b/frontend/src/components/common/AutoCompletePicker/__snapshots__/AutoCompletePicker.stories.storyshot new file mode 100644 index 000000000..fe966859c --- /dev/null +++ b/frontend/src/components/common/AutoCompletePicker/__snapshots__/AutoCompletePicker.stories.storyshot @@ -0,0 +1,63 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots AutoCompletePicker Closed 1`] = ` +
    +
    +
    + +
    + +
    +
    +
    +
    +`; + +exports[`Storyshots AutoCompletePicker Open 1`] = ` +
    +
    +
    + +
    + +
    +
    +
    +
    +`; diff --git a/frontend/src/components/common/AutoCompletePicker/index.tsx b/frontend/src/components/common/AutoCompletePicker/index.tsx new file mode 100644 index 000000000..ba353fa06 --- /dev/null +++ b/frontend/src/components/common/AutoCompletePicker/index.tsx @@ -0,0 +1,2 @@ +export * from './AutoCompletePicker'; +export { default } from './AutoCompletePicker'; diff --git a/frontend/src/components/common/Card/Card.stories.tsx b/frontend/src/components/common/Card/Card.stories.tsx new file mode 100644 index 000000000..f846576d0 --- /dev/null +++ b/frontend/src/components/common/Card/Card.stories.tsx @@ -0,0 +1,61 @@ +import { Meta, Story } from '@storybook/react/types-6-0'; +import React from 'react'; +import { MemoryRouter } from 'react-router-dom'; +import { + CardDescriptionLabel, + CardFeatureLabel, + CardHeader, + CardHeaderProps, + CardLabel, +} from './Card'; + +export default { + title: 'Card', +} as Meta; + +export const FeatureLabel = () => Feature Label; +export const DescriptionLabel = () => ( + Description Label +); +export const Label = () => Label; +export const LabelWithStyles = () => Label; + +const CardHeaderTemplate: Story = args => ( + + + +); +export const Header = CardHeaderTemplate.bind({}); +Header.args = { + cardDescription: 'Card Header description', + cardMainLinkPath: '/apps/123', + cardMainLinkLabel: 'Flatcar', + children: 'CardHeader children', + cardTrack: 'a cardTrack', +}; + +export const HeaderWithDescription = CardHeaderTemplate.bind({}); +HeaderWithDescription.args = { + cardDescription: 'Card Header description', +}; +export const HeaderWithLink = CardHeaderTemplate.bind({}); +HeaderWithLink.args = { + cardDescription: 'Card Header With Link description', + cardMainLinkPath: '/apps/123', + cardMainLinkLabel: 'Flatcar', +}; +export const HeaderWithChildren = CardHeaderTemplate.bind({}); +HeaderWithChildren.args = { + cardDescription: 'Card Header With Children description', + children: 'CardHeader children', +}; +export const HeaderWithCardTrack = CardHeaderTemplate.bind({}); +HeaderWithCardTrack.args = { + cardDescription: 'Card Header With cardTrack description', + cardTrack: 'a cardTrack', +}; +export const HeaderWithCardId = CardHeaderTemplate.bind({}); +HeaderWithCardId.args = { + cardDescription: 'Card Header With cardId description', + cardId: 'a cardId', +}; diff --git a/frontend/src/js/components/Common/Card.tsx b/frontend/src/components/common/Card/Card.tsx similarity index 87% rename from frontend/src/js/components/Common/Card.tsx rename to frontend/src/components/common/Card/Card.tsx index 373df7349..2436f77b6 100644 --- a/frontend/src/js/components/Common/Card.tsx +++ b/frontend/src/components/common/Card/Card.tsx @@ -44,7 +44,11 @@ const useStyles = makeStyles(theme => ({ }), })); -export function CardFeatureLabel(props: { children: React.ReactNode }) { +export interface CardFeatureLabelProps { + children: React.ReactNode; +} + +export function CardFeatureLabel(props: CardFeatureLabelProps) { const classes = useStyles(); return ( @@ -53,7 +57,11 @@ export function CardFeatureLabel(props: { children: React.ReactNode }) { ); } -export function CardDescriptionLabel(props: { children: React.ReactNode }) { +export interface CardDescriptionLabelProps { + children: React.ReactNode; +} + +export function CardDescriptionLabel(props: CardDescriptionLabelProps) { const classes = useStyles(); return ( @@ -64,7 +72,12 @@ export function CardDescriptionLabel(props: { children: React.ReactNode }) { ); } -export function CardLabel(props: { children: React.ReactNode; labelStyle?: object }) { +export interface CardLabelProps { + children: React.ReactNode; + labelStyle?: object; +} + +export function CardLabel(props: CardLabelProps) { const { labelStyle = {} } = props; const classes = useStyles(labelStyle); return ( @@ -74,7 +87,7 @@ export function CardLabel(props: { children: React.ReactNode; labelStyle?: objec ); } -interface CardHeaderProps { +export interface CardHeaderProps { cardMainLinkPath?: string | { pathname: string }; cardMainLinkLabel?: string; cardTrack?: string; diff --git a/frontend/src/components/common/Card/__snapshots__/Card.stories.storyshot b/frontend/src/components/common/Card/__snapshots__/Card.stories.storyshot new file mode 100644 index 000000000..42c295e26 --- /dev/null +++ b/frontend/src/components/common/Card/__snapshots__/Card.stories.storyshot @@ -0,0 +1,359 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Card Description Label 1`] = ` +
    +
    + + Description Label + +
    +
    +`; + +exports[`Storyshots Card Feature Label 1`] = ` +
    + + Feature Label + +
    +`; + +exports[`Storyshots Card Header 1`] = ` +
    +
    +
    + +
    +
    +

    + a cardTrack +

    +
    +
    + + Card Header description + +
    +
    +
    +
    + CardHeader children +
    +
    +
    +
    +`; + +exports[`Storyshots Card Header With Card Id 1`] = ` +
    +
    +
    +
    +

    +

    +
    +
    +

    + a cardId +

    +
    +
    + + Card Header With cardId description + +
    +
    +
    +
    +
    +
    +`; + +exports[`Storyshots Card Header With Card Track 1`] = ` +
    +
    +
    +
    +

    +

    +
    +
    +

    + a cardTrack +

    +
    +
    + + Card Header With cardTrack description + +
    +
    +
    +
    +
    +
    +`; + +exports[`Storyshots Card Header With Children 1`] = ` +
    +
    +
    +
    +

    +

    +
    +
    +

    +

    +
    + + Card Header With Children description + +
    +
    +
    +
    + CardHeader children +
    +
    +
    +
    +`; + +exports[`Storyshots Card Header With Description 1`] = ` +
    +
    +
    +
    +

    +

    +
    +
    +

    +

    +
    + + Card Header description + +
    +
    +
    +
    +
    +
    +`; + +exports[`Storyshots Card Header With Link 1`] = ` +
    +
    +
    + +
    +
    +

    +

    +
    + + Card Header With Link description + +
    +
    +
    +
    +
    +
    +`; + +exports[`Storyshots Card Label 1`] = ` +
    + + Label + +
    +`; + +exports[`Storyshots Card Label With Styles 1`] = ` +
    + + Label + +
    +`; diff --git a/frontend/src/components/common/Card/index.tsx b/frontend/src/components/common/Card/index.tsx new file mode 100644 index 000000000..ca0b06047 --- /dev/null +++ b/frontend/src/components/common/Card/index.tsx @@ -0,0 +1 @@ +export * from './Card'; diff --git a/frontend/src/components/common/ColorPicker/ColorPicker.stories.tsx b/frontend/src/components/common/ColorPicker/ColorPicker.stories.tsx new file mode 100644 index 000000000..cf3273410 --- /dev/null +++ b/frontend/src/components/common/ColorPicker/ColorPicker.stories.tsx @@ -0,0 +1,24 @@ +import { Meta, Story } from '@storybook/react/types-6-0'; +import ChannelAvatar from '../../Channels/ChannelAvatar'; +import ColorPicker, { ColorPickerProps } from './ColorPicker'; + +export default { + title: 'ColorPickerButton', + argTypes: { + onColorPicked: { action: 'onColorPicked' }, + }, +} as Meta; + +const ColorPickerButtonTemplate: Story = args => ; +export const Closed = ColorPickerButtonTemplate.bind({}); +Closed.args = { + color: '#EB144C', + children: Beta, + initialOpen: false, +}; + +export const Open = ColorPickerButtonTemplate.bind({}); +Open.args = { + ...Closed.args, + initialOpen: true, +}; diff --git a/frontend/src/js/components/Common/ColorPicker.tsx b/frontend/src/components/common/ColorPicker/ColorPicker.tsx similarity index 78% rename from frontend/src/js/components/Common/ColorPicker.tsx rename to frontend/src/components/common/ColorPicker/ColorPicker.tsx index d778d719c..d81d8e356 100644 --- a/frontend/src/js/components/Common/ColorPicker.tsx +++ b/frontend/src/components/common/ColorPicker/ColorPicker.tsx @@ -3,7 +3,7 @@ import Popover from '@material-ui/core/Popover'; import { makeStyles } from '@material-ui/styles'; import React from 'react'; import { TwitterPicker } from 'react-color'; -import ChannelAvatar from '../Channels/ChannelAvatar'; +import ChannelAvatar from '../../Channels/ChannelAvatar'; // @todo: This needs to become a FormControl so we can display it in a similar // style as the other form controls. @@ -14,22 +14,22 @@ const useStyles = makeStyles({ }, }); -interface ColorPickerButtonProps { +export interface ColorPickerProps { + /** Text color, applied to the children and used in the popover. */ color: string; + /** When a color is chosen. */ onColorPicked: (color: { hex: string }) => void; - componentColorProp: string; + /** Should the color picker be displayed initially? */ + initialOpen?: boolean; children: React.ReactElement; } -export function ColorPickerButton(props: ColorPickerButtonProps) { +export default function ColorPicker(props: ColorPickerProps) { const classes = useStyles(); const [channelColor, setChannelColor] = React.useState(props.color); - const [displayColorPicker, setDisplayColorPicker] = React.useState(false); + const [displayColorPicker, setDisplayColorPicker] = React.useState(props.initialOpen); const [anchorEl, setAnchorEl] = React.useState(null); - const { onColorPicked, componentColorProp } = props; - - const componentProps: { [key: string]: string } = {}; - componentProps[componentColorProp] = channelColor; + const { onColorPicked } = props; function handleColorChange(color: { hex: string }) { setChannelColor(color.hex); @@ -54,12 +54,12 @@ export function ColorPickerButton(props: ColorPickerButtonProps) { data-testid="icon-button" > {props.children ? ( - React.cloneElement(props.children as React.ReactElement, componentProps) + {props.children} ) : ( )} - {displayColorPicker && ( + {displayColorPicker && anchorEl && ( +
    + +
    +
    +`; + +exports[`Storyshots ColorPickerButton Open 1`] = ` +
    +
    + +
    +
    +`; diff --git a/frontend/src/components/common/ColorPicker/index.tsx b/frontend/src/components/common/ColorPicker/index.tsx new file mode 100644 index 000000000..f388c0843 --- /dev/null +++ b/frontend/src/components/common/ColorPicker/index.tsx @@ -0,0 +1,2 @@ +export { default } from './ColorPicker'; +export * from './ColorPicker'; diff --git a/frontend/src/js/components/Common/ConfirmationContent.tsx b/frontend/src/components/common/ConfirmationContent/ConfirmationContent.tsx similarity index 74% rename from frontend/src/js/components/Common/ConfirmationContent.tsx rename to frontend/src/components/common/ConfirmationContent/ConfirmationContent.tsx index cca7706e5..8325f303a 100644 --- a/frontend/src/js/components/Common/ConfirmationContent.tsx +++ b/frontend/src/components/common/ConfirmationContent/ConfirmationContent.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; -import { applicationsStore } from '../../stores/Stores'; +import { applicationsStore } from '../../../stores/Stores'; function ConfirmationContent(props: { data: { @@ -15,13 +15,13 @@ function ConfirmationContent(props: { function processClick() { if (props.data.type === 'application') { - applicationsStore.deleteApplication(props.data.appID); + applicationsStore().deleteApplication(props.data.appID); } else if (props.data.type === 'group' && props.data.groupID !== undefined) { - applicationsStore.deleteGroup(props.data.appID, props.data.groupID); + applicationsStore().deleteGroup(props.data.appID, props.data.groupID); } else if (props.data.type === 'channel' && props.data.channelID !== undefined) { - applicationsStore.deleteChannel(props.data.appID, props.data.channelID); + applicationsStore().deleteChannel(props.data.appID, props.data.channelID); } else if (props.data.type === 'package' && props.data.packageID !== undefined) { - applicationsStore.deletePackage(props.data.appID, props.data.packageID); + applicationsStore().deletePackage(props.data.appID, props.data.packageID); } } diff --git a/frontend/src/components/common/ConfirmationContent/index.tsx b/frontend/src/components/common/ConfirmationContent/index.tsx new file mode 100644 index 000000000..0be08926e --- /dev/null +++ b/frontend/src/components/common/ConfirmationContent/index.tsx @@ -0,0 +1,2 @@ +export { default } from './ConfirmationContent'; +export * from './ConfirmationContent'; diff --git a/frontend/src/js/components/Common/EmptyContent.tsx b/frontend/src/components/common/EmptyContent/EmptyContent.tsx similarity index 100% rename from frontend/src/js/components/Common/EmptyContent.tsx rename to frontend/src/components/common/EmptyContent/EmptyContent.tsx diff --git a/frontend/src/components/common/EmptyContent/index.tsx b/frontend/src/components/common/EmptyContent/index.tsx new file mode 100644 index 000000000..6a20e1f1a --- /dev/null +++ b/frontend/src/components/common/EmptyContent/index.tsx @@ -0,0 +1,2 @@ +export { default } from './EmptyContent'; +export * from './EmptyContent'; diff --git a/frontend/src/js/components/Common/Label.tsx b/frontend/src/components/common/Label/Label.tsx similarity index 100% rename from frontend/src/js/components/Common/Label.tsx rename to frontend/src/components/common/Label/Label.tsx diff --git a/frontend/src/components/common/Label/index.tsx b/frontend/src/components/common/Label/index.tsx new file mode 100644 index 000000000..24b3e7ec5 --- /dev/null +++ b/frontend/src/components/common/Label/index.tsx @@ -0,0 +1,2 @@ +export { default } from './Label'; +export * from './Label'; diff --git a/frontend/src/js/components/Common/LightTooltip.tsx b/frontend/src/components/common/LightTooltip/LightTooltip.tsx similarity index 100% rename from frontend/src/js/components/Common/LightTooltip.tsx rename to frontend/src/components/common/LightTooltip/LightTooltip.tsx diff --git a/frontend/src/components/common/LightTooltip/index.tsx b/frontend/src/components/common/LightTooltip/index.tsx new file mode 100644 index 000000000..ada31e7e6 --- /dev/null +++ b/frontend/src/components/common/LightTooltip/index.tsx @@ -0,0 +1,2 @@ +export { default } from './LightTooltip'; +export * from './LightTooltip'; diff --git a/frontend/src/js/components/Common/ListHeader.tsx b/frontend/src/components/common/ListHeader/ListHeader.tsx similarity index 100% rename from frontend/src/js/components/Common/ListHeader.tsx rename to frontend/src/components/common/ListHeader/ListHeader.tsx diff --git a/frontend/src/components/common/ListHeader/index.tsx b/frontend/src/components/common/ListHeader/index.tsx new file mode 100644 index 000000000..e9182af68 --- /dev/null +++ b/frontend/src/components/common/ListHeader/index.tsx @@ -0,0 +1,2 @@ +export { default } from './ListHeader'; +export * from './ListHeader'; diff --git a/frontend/src/js/components/Common/ListItem.tsx b/frontend/src/components/common/ListItem/ListItem.tsx similarity index 100% rename from frontend/src/js/components/Common/ListItem.tsx rename to frontend/src/components/common/ListItem/ListItem.tsx diff --git a/frontend/src/components/common/ListItem/index.tsx b/frontend/src/components/common/ListItem/index.tsx new file mode 100644 index 000000000..d0ef0af7f --- /dev/null +++ b/frontend/src/components/common/ListItem/index.tsx @@ -0,0 +1,2 @@ +export { default } from './ListItem'; +export * from './ListItem'; diff --git a/frontend/src/js/components/Common/ListSearch.tsx b/frontend/src/components/common/ListSearch/ListSearch.tsx similarity index 100% rename from frontend/src/js/components/Common/ListSearch.tsx rename to frontend/src/components/common/ListSearch/ListSearch.tsx diff --git a/frontend/src/components/common/ListSearch/index.tsx b/frontend/src/components/common/ListSearch/index.tsx new file mode 100644 index 000000000..900297a52 --- /dev/null +++ b/frontend/src/components/common/ListSearch/index.tsx @@ -0,0 +1,2 @@ +export { default } from './ListSearch'; +export * from './ListSearch'; diff --git a/frontend/src/js/components/Common/Loader.tsx b/frontend/src/components/common/Loader/Loader.tsx similarity index 100% rename from frontend/src/js/components/Common/Loader.tsx rename to frontend/src/components/common/Loader/Loader.tsx diff --git a/frontend/src/components/common/Loader/index.tsx b/frontend/src/components/common/Loader/index.tsx new file mode 100644 index 000000000..61e090820 --- /dev/null +++ b/frontend/src/components/common/Loader/index.tsx @@ -0,0 +1,2 @@ +export { default } from './Loader'; +export * from './Loader'; diff --git a/frontend/src/js/components/Common/ModalButton.tsx b/frontend/src/components/common/ModalButton/ModalButton.tsx similarity index 83% rename from frontend/src/js/components/Common/ModalButton.tsx rename to frontend/src/components/common/ModalButton/ModalButton.tsx index 9fd187f32..f70d88f2d 100644 --- a/frontend/src/js/components/Common/ModalButton.tsx +++ b/frontend/src/components/common/ModalButton/ModalButton.tsx @@ -3,12 +3,12 @@ import AddIcon from '@material-ui/icons/Add'; import PropTypes from 'prop-types'; import React from 'react'; import { useTranslation } from 'react-i18next'; -import ApplicationEditDialog from '../Applications/EditDialog'; -import ChannelEditDialog from '../Channels/EditDialog'; -import GroupEditDialog from '../Groups/EditDialog'; +import ApplicationEdit from '../../Applications/ApplicationEdit'; +import ChannelEdit from '../../Channels/ChannelEdit'; +import GroupEditDialog from '../../Groups/GroupEditDialog/GroupEditDialog'; import PackageEditDialog, { EditDialogProps as PackageEditDialogProps, -} from '../Packages/EditDialog'; +} from '../../Packages/EditDialog'; const useStyles = makeStyles(theme => ({ root: { @@ -39,13 +39,13 @@ function ModalButton(props: { data: object; modalToOpen: string; icon?: string } let modal = null; switch (props.modalToOpen) { case 'AddApplicationModal': - modal = ; + modal = ; break; case 'AddGroupModal': modal = ; break; case 'AddChannelModal': - modal = ; + modal = ; break; case 'AddPackageModal': modal = ; diff --git a/frontend/src/components/common/ModalButton/index.tsx b/frontend/src/components/common/ModalButton/index.tsx new file mode 100644 index 000000000..28366a230 --- /dev/null +++ b/frontend/src/components/common/ModalButton/index.tsx @@ -0,0 +1,2 @@ +export { default } from './ModalButton'; +export * from './ModalButton'; diff --git a/frontend/src/js/components/Common/MoreMenu.tsx b/frontend/src/components/common/MoreMenu/MoreMenu.tsx similarity index 100% rename from frontend/src/js/components/Common/MoreMenu.tsx rename to frontend/src/components/common/MoreMenu/MoreMenu.tsx diff --git a/frontend/src/components/common/MoreMenu/index.tsx b/frontend/src/components/common/MoreMenu/index.tsx new file mode 100644 index 000000000..9976c0f6e --- /dev/null +++ b/frontend/src/components/common/MoreMenu/index.tsx @@ -0,0 +1,2 @@ +export { default } from './MoreMenu'; +export * from './MoreMenu'; diff --git a/frontend/src/js/components/Common/PageTitle.tsx b/frontend/src/components/common/PageTitle/PageTitle.tsx similarity index 100% rename from frontend/src/js/components/Common/PageTitle.tsx rename to frontend/src/components/common/PageTitle/PageTitle.tsx diff --git a/frontend/src/components/common/PageTitle/index.tsx b/frontend/src/components/common/PageTitle/index.tsx new file mode 100644 index 000000000..110b283e9 --- /dev/null +++ b/frontend/src/components/common/PageTitle/index.tsx @@ -0,0 +1,2 @@ +export { default } from './PageTitle'; +export * from './PageTitle'; diff --git a/frontend/src/js/components/Common/SectionHeader.tsx b/frontend/src/components/common/SectionHeader/SectionHeader.tsx similarity index 97% rename from frontend/src/js/components/Common/SectionHeader.tsx rename to frontend/src/components/common/SectionHeader/SectionHeader.tsx index 0c9ec4e1d..519114bc9 100644 --- a/frontend/src/js/components/Common/SectionHeader.tsx +++ b/frontend/src/components/common/SectionHeader/SectionHeader.tsx @@ -8,7 +8,7 @@ import NavigateNextIcon from '@material-ui/icons/NavigateNext'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { Link as RouterLink } from 'react-router-dom'; -import PageTitle from './PageTitle'; +import PageTitle from '../PageTitle/PageTitle'; const useStyles = makeStyles(theme => ({ sectionContainer: { diff --git a/frontend/src/components/common/SectionHeader/index.tsx b/frontend/src/components/common/SectionHeader/index.tsx new file mode 100644 index 000000000..3bfdb5502 --- /dev/null +++ b/frontend/src/components/common/SectionHeader/index.tsx @@ -0,0 +1,2 @@ +export { default } from './SectionHeader'; +export * from './SectionHeader'; diff --git a/frontend/src/js/components/Common/SectionPaper.tsx b/frontend/src/components/common/SectionPaper/SectionPaper.tsx similarity index 100% rename from frontend/src/js/components/Common/SectionPaper.tsx rename to frontend/src/components/common/SectionPaper/SectionPaper.tsx diff --git a/frontend/src/components/common/SectionPaper/index.tsx b/frontend/src/components/common/SectionPaper/index.tsx new file mode 100644 index 000000000..87d601cf1 --- /dev/null +++ b/frontend/src/components/common/SectionPaper/index.tsx @@ -0,0 +1,2 @@ +export { default } from './SectionPaper'; +export * from './SectionPaper'; diff --git a/frontend/src/js/components/Common/SimpleTable.tsx b/frontend/src/components/common/SimpleTable/SimpleTable.tsx similarity index 98% rename from frontend/src/js/components/Common/SimpleTable.tsx rename to frontend/src/components/common/SimpleTable/SimpleTable.tsx index a2071322e..a3be8c818 100644 --- a/frontend/src/js/components/Common/SimpleTable.tsx +++ b/frontend/src/components/common/SimpleTable/SimpleTable.tsx @@ -8,7 +8,7 @@ import TablePagination from '@material-ui/core/TablePagination'; import TableRow from '@material-ui/core/TableRow'; import React from 'react'; import { useTranslation } from 'react-i18next'; -import Empty from './EmptyContent'; +import Empty from '../EmptyContent/EmptyContent'; interface SimpleTableProps { columns: { diff --git a/frontend/src/components/common/SimpleTable/index.tsx b/frontend/src/components/common/SimpleTable/index.tsx new file mode 100644 index 000000000..265e8d824 --- /dev/null +++ b/frontend/src/components/common/SimpleTable/index.tsx @@ -0,0 +1,2 @@ +export { default } from './SimpleTable'; +export * from './SimpleTable'; diff --git a/frontend/src/js/components/Common/Tabs.tsx b/frontend/src/components/common/Tabs/Tabs.tsx similarity index 100% rename from frontend/src/js/components/Common/Tabs.tsx rename to frontend/src/components/common/Tabs/Tabs.tsx diff --git a/frontend/src/components/common/Tabs/index.tsx b/frontend/src/components/common/Tabs/index.tsx new file mode 100644 index 000000000..cd2e770d2 --- /dev/null +++ b/frontend/src/components/common/Tabs/index.tsx @@ -0,0 +1,2 @@ +export { default } from './Tabs'; +export * from './Tabs'; diff --git a/frontend/src/js/components/Common/TimeIntervalLinks.tsx b/frontend/src/components/common/TimeIntervalLinks/TimeIntervalLinks.tsx similarity index 95% rename from frontend/src/js/components/Common/TimeIntervalLinks.tsx rename to frontend/src/components/common/TimeIntervalLinks/TimeIntervalLinks.tsx index b8d5e0307..c741365ca 100644 --- a/frontend/src/js/components/Common/TimeIntervalLinks.tsx +++ b/frontend/src/components/common/TimeIntervalLinks/TimeIntervalLinks.tsx @@ -1,7 +1,7 @@ import { Box, Grid, Link, makeStyles, Typography } from '@material-ui/core'; import React from 'react'; -import API from '../../api/API'; -import { timeIntervalsDefault } from '../../utils/helpers'; +import API from '../../../api/API'; +import { timeIntervalsDefault } from '../../../utils/helpers'; const useStyles = makeStyles(() => ({ title: { diff --git a/frontend/src/components/common/TimeIntervalLinks/index.tsx b/frontend/src/components/common/TimeIntervalLinks/index.tsx new file mode 100644 index 000000000..3b42a6206 --- /dev/null +++ b/frontend/src/components/common/TimeIntervalLinks/index.tsx @@ -0,0 +1,2 @@ +export { default } from './TimeIntervalLinks'; +export * from './TimeIntervalLinks'; diff --git a/frontend/src/js/components/Common/TimezonePicker.tsx b/frontend/src/components/common/TimezonePicker/TimezonePicker.tsx similarity index 100% rename from frontend/src/js/components/Common/TimezonePicker.tsx rename to frontend/src/components/common/TimezonePicker/TimezonePicker.tsx diff --git a/frontend/src/components/common/TimezonePicker/index.tsx b/frontend/src/components/common/TimezonePicker/index.tsx new file mode 100644 index 000000000..82ac74cfd --- /dev/null +++ b/frontend/src/components/common/TimezonePicker/index.tsx @@ -0,0 +1,2 @@ +export { default } from './TimezonePicker'; +export * from './TimezonePicker'; diff --git a/frontend/src/js/components/Common/VersionBreakdownBar.tsx b/frontend/src/components/common/VersionBreakdownBar/VersionBreakdownBar.tsx similarity index 98% rename from frontend/src/js/components/Common/VersionBreakdownBar.tsx rename to frontend/src/components/common/VersionBreakdownBar/VersionBreakdownBar.tsx index 14d71930c..5fc2df332 100644 --- a/frontend/src/js/components/Common/VersionBreakdownBar.tsx +++ b/frontend/src/components/common/VersionBreakdownBar/VersionBreakdownBar.tsx @@ -8,8 +8,8 @@ import { useTheme } from '@material-ui/styles'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { Bar, BarChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts'; -import { Channel } from '../../api/apiDataTypes'; -import { cleanSemverVersion, makeColorsForVersions } from '../../utils/helpers'; +import { Channel } from '../../../api/apiDataTypes'; +import { cleanSemverVersion, makeColorsForVersions } from '../../../utils/helpers'; const useStyles = makeStyles({ noBorder: { diff --git a/frontend/src/components/common/VersionBreakdownBar/index.tsx b/frontend/src/components/common/VersionBreakdownBar/index.tsx new file mode 100644 index 000000000..6c9adee78 --- /dev/null +++ b/frontend/src/components/common/VersionBreakdownBar/index.tsx @@ -0,0 +1,2 @@ +export { default } from './VersionBreakdownBar'; +export * from './VersionBreakdownBar'; diff --git a/frontend/src/js/components/Layouts/ApplicationLayout.tsx b/frontend/src/components/layouts/ApplicationLayout/ApplicationLayout.tsx similarity index 71% rename from frontend/src/js/components/Layouts/ApplicationLayout.tsx rename to frontend/src/components/layouts/ApplicationLayout/ApplicationLayout.tsx index bc32301ba..f7d2bb3a9 100644 --- a/frontend/src/js/components/Layouts/ApplicationLayout.tsx +++ b/frontend/src/components/layouts/ApplicationLayout/ApplicationLayout.tsx @@ -3,16 +3,16 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { useParams } from 'react-router-dom'; import _ from 'underscore'; -import { applicationsStore } from '../../stores/Stores'; -import ChannelsList from '../Channels/List'; -import SectionHeader from '../Common/SectionHeader'; -import GroupsList from '../Groups/List'; -import PackagesList from '../Packages/List'; +import { applicationsStore } from '../../../stores/Stores'; +import ChannelList from '../../Channels/ChannelList'; +import SectionHeader from '../../common/SectionHeader/SectionHeader'; +import GroupList from '../../Groups/GroupList'; +import PackagesList from '../../Packages/List'; function ApplicationLayout() { const { appID } = useParams<{ appID: string }>(); const [applications, setApplications] = React.useState( - applicationsStore.getCachedApplications() || [] + applicationsStore().getCachedApplications() || [] ); const { t } = useTranslation(); @@ -21,9 +21,9 @@ function ApplicationLayout() { } React.useEffect(() => { - applicationsStore.addChangeListener(onChange); + applicationsStore().addChangeListener(onChange); return () => { - applicationsStore.removeChangeListener(onChange); + applicationsStore().removeChangeListener(onChange); }; }); @@ -47,12 +47,12 @@ function ApplicationLayout() { /> - + - + diff --git a/frontend/src/components/layouts/ApplicationLayout/index.tsx b/frontend/src/components/layouts/ApplicationLayout/index.tsx new file mode 100644 index 000000000..2dda4f867 --- /dev/null +++ b/frontend/src/components/layouts/ApplicationLayout/index.tsx @@ -0,0 +1,2 @@ +export * from './ApplicationLayout'; +export { default } from './ApplicationLayout'; diff --git a/frontend/src/js/components/Layouts/GroupLayout.tsx b/frontend/src/components/layouts/GroupLayout/GroupLayout.tsx similarity index 70% rename from frontend/src/js/components/Layouts/GroupLayout.tsx rename to frontend/src/components/layouts/GroupLayout/GroupLayout.tsx index 0dada9588..b9ecc488f 100644 --- a/frontend/src/js/components/Layouts/GroupLayout.tsx +++ b/frontend/src/components/layouts/GroupLayout/GroupLayout.tsx @@ -2,30 +2,30 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { useParams } from 'react-router-dom'; import _ from 'underscore'; -import { Channel, Group } from '../../api/apiDataTypes'; -import { applicationsStore } from '../../stores/Stores'; -import SectionHeader from '../Common/SectionHeader'; -import EditDialog from '../Groups/EditDialog'; -import GroupExtended from '../Groups/ItemExtended'; +import { Channel, Group } from '../../../api/apiDataTypes'; +import { applicationsStore } from '../../../stores/Stores'; +import SectionHeader from '../../common/SectionHeader'; +import GroupEditDialog from '../../Groups/GroupEditDialog/GroupEditDialog'; +import GroupItemExtended from '../../Groups/GroupItemExtended'; function GroupLayout() { const { appID, groupID } = useParams<{ appID: string; groupID: string }>(); const [applications, setApplications] = React.useState( - applicationsStore.getCachedApplications() || [] + applicationsStore().getCachedApplications() || [] ); const [updateGroupModalVisible, setUpdateGroupModalVisible] = React.useState(false); const { t } = useTranslation(); React.useEffect(() => { - applicationsStore.getApplication(appID); - applicationsStore.addChangeListener(onChange); + applicationsStore().getApplication(appID); + applicationsStore().addChangeListener(onChange); return () => { - applicationsStore.removeChangeListener(onChange); + applicationsStore().removeChangeListener(onChange); }; }, []); function onChange() { - setApplications(applicationsStore.getCachedApplications() || []); + setApplications(applicationsStore().getCachedApplications() || []); } function openUpdateGroupModal() { @@ -70,8 +70,8 @@ function GroupLayout() { }, ]} /> - - + (); const [application, setApplication] = React.useState( - applicationsStore.getCachedApplication(appID) + applicationsStore().getCachedApplication(appID) ); const [group, setGroup] = React.useState(getGroupFromApplication(application || null)); const [instance, setInstance] = React.useState(null); @@ -30,7 +30,7 @@ export default function InstanceLayout() { ); setInstance(instance); }); - const apps = applicationsStore.getCachedApplications() || []; + const apps = applicationsStore().getCachedApplications() || []; const app = apps.find(({ id }) => id === appID) || null; if (app !== application) { setApplication(app); @@ -47,12 +47,12 @@ export default function InstanceLayout() { } React.useEffect(() => { - applicationsStore.addChangeListener(onChange); + applicationsStore().addChangeListener(onChange); - applicationsStore.getApplication(appID); + applicationsStore().getApplication(appID); return function cleanup() { - applicationsStore.removeChangeListener(onChange); + applicationsStore().removeChangeListener(onChange); }; }, []); diff --git a/frontend/src/components/layouts/InstanceLayout/index.tsx b/frontend/src/components/layouts/InstanceLayout/index.tsx new file mode 100644 index 000000000..7a01b6686 --- /dev/null +++ b/frontend/src/components/layouts/InstanceLayout/index.tsx @@ -0,0 +1,2 @@ +export * from './InstanceLayout'; +export { default } from './InstanceLayout'; diff --git a/frontend/src/js/components/Layouts/InstanceListLayout.tsx b/frontend/src/components/layouts/InstanceListLayout/InstanceListLayout.tsx similarity index 72% rename from frontend/src/js/components/Layouts/InstanceListLayout.tsx rename to frontend/src/components/layouts/InstanceListLayout/InstanceListLayout.tsx index 4d5a2e3e4..e8d53c889 100644 --- a/frontend/src/js/components/Layouts/InstanceListLayout.tsx +++ b/frontend/src/components/layouts/InstanceListLayout/InstanceListLayout.tsx @@ -1,22 +1,22 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { useParams } from 'react-router-dom'; -import { Application, Group } from '../../api/apiDataTypes'; -import { applicationsStore } from '../../stores/Stores'; -import Loader from '../Common/Loader'; -import SectionHeader from '../Common/SectionHeader'; -import List from '../Instances/List'; +import { Application, Group } from '../../../api/apiDataTypes'; +import { applicationsStore } from '../../../stores/Stores'; +import Loader from '../../common/Loader'; +import SectionHeader from '../../common/SectionHeader'; +import List from '../../Instances/List'; -export default function InstanceLayout() { +export default function InstanceListLayout() { const { appID, groupID } = useParams<{ appID: string; groupID: string }>(); const [application, setApplication] = React.useState( - applicationsStore.getCachedApplication(appID) + applicationsStore().getCachedApplication(appID) ); const [group, setGroup] = React.useState(getGroupFromApplication(application)); const { t } = useTranslation(); function onChange() { - const apps = applicationsStore.getCachedApplications() || []; + const apps = applicationsStore().getCachedApplications() || []; const app = apps.find(({ id }) => id === appID) || null; if (app !== application) { setApplication(app); @@ -33,11 +33,11 @@ export default function InstanceLayout() { } React.useEffect(() => { - applicationsStore.addChangeListener(onChange); - applicationsStore.getApplication(appID); + applicationsStore().addChangeListener(onChange); + applicationsStore().getApplication(appID); return function cleanup() { - applicationsStore.removeChangeListener(onChange); + applicationsStore().removeChangeListener(onChange); }; }, []); diff --git a/frontend/src/components/layouts/InstanceListLayout/index.tsx b/frontend/src/components/layouts/InstanceListLayout/index.tsx new file mode 100644 index 000000000..3966657aa --- /dev/null +++ b/frontend/src/components/layouts/InstanceListLayout/index.tsx @@ -0,0 +1,2 @@ +export * from './InstanceListLayout'; +export { default } from './InstanceListLayout'; diff --git a/frontend/src/js/components/Layouts/MainLayout.tsx b/frontend/src/components/layouts/MainLayout/MainLayout.tsx similarity index 68% rename from frontend/src/js/components/Layouts/MainLayout.tsx rename to frontend/src/components/layouts/MainLayout/MainLayout.tsx index 45f13834b..3f69401a9 100644 --- a/frontend/src/js/components/Layouts/MainLayout.tsx +++ b/frontend/src/components/layouts/MainLayout/MainLayout.tsx @@ -1,13 +1,13 @@ import Grid from '@material-ui/core/Grid'; import React from 'react'; -import ActivityContainer from '../Activity/Container'; -import ApplicationsList from '../Applications/List'; +import ActivityContainer from '../../Activity/ActivityContainer'; +import ApplicationList from '../../Applications/ApplicationList'; function MainLayout() { return ( - + diff --git a/frontend/src/components/layouts/MainLayout/index.tsx b/frontend/src/components/layouts/MainLayout/index.tsx new file mode 100644 index 000000000..ab27677ef --- /dev/null +++ b/frontend/src/components/layouts/MainLayout/index.tsx @@ -0,0 +1,2 @@ +export * from './MainLayout'; +export { default } from './MainLayout'; diff --git a/frontend/src/img/404.svg b/frontend/src/components/layouts/PageNotFoundLayout/404.svg similarity index 100% rename from frontend/src/img/404.svg rename to frontend/src/components/layouts/PageNotFoundLayout/404.svg diff --git a/frontend/src/js/components/Layouts/PageNotFoundLayout.tsx b/frontend/src/components/layouts/PageNotFoundLayout/PageNotFoundLayout.tsx similarity index 93% rename from frontend/src/js/components/Layouts/PageNotFoundLayout.tsx rename to frontend/src/components/layouts/PageNotFoundLayout/PageNotFoundLayout.tsx index e46405ae5..d2bc5a85a 100644 --- a/frontend/src/js/components/Layouts/PageNotFoundLayout.tsx +++ b/frontend/src/components/layouts/PageNotFoundLayout/PageNotFoundLayout.tsx @@ -1,7 +1,7 @@ import { Grid, Typography } from '@material-ui/core'; import { Trans, useTranslation } from 'react-i18next'; import { Link } from 'react-router-dom'; -import pageNotFoundGraphic from '../../../img/404.svg'; +import pageNotFoundGraphic from './404.svg'; export default function PageNotFoundLayout() { const { t } = useTranslation('404'); diff --git a/frontend/src/components/layouts/PageNotFoundLayout/index.tsx b/frontend/src/components/layouts/PageNotFoundLayout/index.tsx new file mode 100644 index 000000000..6dcd1cb86 --- /dev/null +++ b/frontend/src/components/layouts/PageNotFoundLayout/index.tsx @@ -0,0 +1,2 @@ +export * from './PageNotFoundLayout'; +export { default } from './PageNotFoundLayout'; diff --git a/frontend/src/js/i18n/LocaleSelect/LocaleSelect.tsx b/frontend/src/i18n/LocaleSelect/LocaleSelect.tsx similarity index 100% rename from frontend/src/js/i18n/LocaleSelect/LocaleSelect.tsx rename to frontend/src/i18n/LocaleSelect/LocaleSelect.tsx diff --git a/frontend/src/js/i18n/README.md b/frontend/src/i18n/README.md similarity index 100% rename from frontend/src/js/i18n/README.md rename to frontend/src/i18n/README.md diff --git a/frontend/src/js/i18n/ThemeProviderNexti18n.tsx b/frontend/src/i18n/ThemeProviderNexti18n.tsx similarity index 100% rename from frontend/src/js/i18n/ThemeProviderNexti18n.tsx rename to frontend/src/i18n/ThemeProviderNexti18n.tsx diff --git a/frontend/src/js/i18n/config.ts b/frontend/src/i18n/config.ts similarity index 100% rename from frontend/src/js/i18n/config.ts rename to frontend/src/i18n/config.ts diff --git a/frontend/src/i18n/dateTime.ts b/frontend/src/i18n/dateTime.ts new file mode 100644 index 000000000..3002a8902 --- /dev/null +++ b/frontend/src/i18n/dateTime.ts @@ -0,0 +1,51 @@ +type DateParam = string | number | Date; + +export function toLocaleString( + date: DateParam, + locales?: string | string[], + options?: Intl.DateTimeFormatOptions +) { + // Locales and timezones can be different, so we set a default when under test. + if (process.env.TEST_TZ) { + const newOptions = options ? options : {}; + return new Date(date).toLocaleString('en-US', { ...newOptions, timeZone: 'UTC' }); + } else { + return new Date(date).toLocaleString(locales, options); + } +} + +export function toLocaleDateString( + date: DateParam, + locales?: string | string[], + options?: Intl.DateTimeFormatOptions +) { + if (process.env.TEST_TZ) { + // Locales and timezones can be different, so we set a default when under test. + const newOptions = options ? options : {}; + return new Date(date).toLocaleDateString('en-US', { ...newOptions, timeZone: 'UTC' }); + } else { + return new Date(date).toLocaleDateString(locales, options); + } +} + +export function getMinuteDifference(date1: number, date2: number) { + return (date1 - date2) / 1000 / 60; +} + +export function makeLocaleTime( + timestamp: string | Date | number, + opts: { useDate?: boolean; showTime?: boolean; dateFormat?: Intl.DateTimeFormatOptions } = {} +) { + const { useDate = true, showTime = true, dateFormat = {} } = opts; + const date = new Date(timestamp); + const formattedDate = toLocaleDateString(date, undefined, dateFormat); + const timeFormat = toLocaleString(date, undefined, { hour: '2-digit', minute: '2-digit' }); + + if (useDate && showTime) { + return `${formattedDate} ${timeFormat}`; + } + if (useDate) { + return formattedDate; + } + return timeFormat; +} diff --git a/frontend/src/js/i18n/i18next-parser.config.js b/frontend/src/i18n/i18next-parser.config.js similarity index 100% rename from frontend/src/js/i18n/i18next-parser.config.js rename to frontend/src/i18n/i18next-parser.config.js diff --git a/frontend/src/js/i18n/locales/en/404.json b/frontend/src/i18n/locales/en/404.json similarity index 100% rename from frontend/src/js/i18n/locales/en/404.json rename to frontend/src/i18n/locales/en/404.json diff --git a/frontend/src/js/i18n/locales/en/frequent.json b/frontend/src/i18n/locales/en/frequent.json similarity index 100% rename from frontend/src/js/i18n/locales/en/frequent.json rename to frontend/src/i18n/locales/en/frequent.json diff --git a/frontend/src/js/i18n/locales/en/glossary.json b/frontend/src/i18n/locales/en/glossary.json similarity index 100% rename from frontend/src/js/i18n/locales/en/glossary.json rename to frontend/src/i18n/locales/en/glossary.json diff --git a/frontend/src/icons/flatcar-logo.json b/frontend/src/icons/flatcar-logo.json new file mode 100644 index 000000000..8f1d6ff69 --- /dev/null +++ b/frontend/src/icons/flatcar-logo.json @@ -0,0 +1,5 @@ +{ + "body": "", + "width": 19.844, + "height": 19.844 +} diff --git a/frontend/src/icons/nebraska-logo.json b/frontend/src/icons/nebraska-logo.json new file mode 100644 index 000000000..d425d052e --- /dev/null +++ b/frontend/src/icons/nebraska-logo.json @@ -0,0 +1,5 @@ +{ + "body": "", + "width": 768, + "height": 180 +} diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 45f523235..bf71c07c5 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,7 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter } from 'react-router-dom'; -import AppRoutes from './js/App'; +import AppRoutes from './App'; if (process.env.NODE_ENV !== 'production') { const axe = require('@axe-core/react'); diff --git a/frontend/src/js/__tests__/Activity/Container.spec.js b/frontend/src/js/__tests__/Activity/Container.spec.js deleted file mode 100644 index dc094dd03..000000000 --- a/frontend/src/js/__tests__/Activity/Container.spec.js +++ /dev/null @@ -1,47 +0,0 @@ -import { render } from '@testing-library/react'; -import React from 'react'; -import { BrowserRouter } from 'react-router-dom'; -import Container from '../../components/Activity/Container'; -import { activityStore } from '../../stores/Stores'; - -describe('Activity Container', () => { - it('should render fetched activities correctly', () => { - activityStore.activity = [ - { - created_ts: '2020-05-13T20:26:03.837688+05:30', - class: 6, - severity: 2, - version: '0.0.0', - application_name: 'ABC', - group_name: null, - channel_name: 'beta', - instance_id: null, - }, - { - created_ts: '2020-05-13T20:25:52.589886+05:30', - class: 6, - severity: 2, - version: '0.0.0', - application_name: 'DBZ', - group_name: null, - channel_name: 'beta', - instance_id: null, - }, - ]; - - const { getByText } = render( - - - - ); - expect(getByText('ABC')).toBeInTheDocument(); - expect(getByText('DBZ')).toBeInTheDocument(); - activityStore.activity = null; - }); - it('should render no activity found message when there is no activity fetched', () => { - activityStore.activity = []; - const { getAllByTestId } = render(); - expect(getAllByTestId('empty')).toBeTruthy(); - activityStore.activity = null; - }); -}); diff --git a/frontend/src/js/__tests__/Activity/Item.spec.js b/frontend/src/js/__tests__/Activity/Item.spec.js deleted file mode 100644 index 92e8f7fba..000000000 --- a/frontend/src/js/__tests__/Activity/Item.spec.js +++ /dev/null @@ -1,27 +0,0 @@ -import { render } from '@testing-library/react'; -import React from 'react'; -import { BrowserRouter } from 'react-router-dom'; -import Item from '../../components/Activity/Item'; - -describe('Activity Item', () => { - it('should render acitivity item correctly', () => { - const minProps = { - entry: { - application_name: 'ABC', - channel_name: 'beta', - class: 6, - created_ts: '2020-05-13T20:26:03.837688+05:30', - group_name: 'DEF', - instance_id: null, - severity: 2, - version: '0.0.0', - }, - }; - const { getByText } = render( - - - - ); - expect(getByText(minProps.entry.application_name)).toBeInTheDocument(); - }); -}); diff --git a/frontend/src/js/__tests__/Activity/List.spec.js b/frontend/src/js/__tests__/Activity/List.spec.js deleted file mode 100644 index 55482aaff..000000000 --- a/frontend/src/js/__tests__/Activity/List.spec.js +++ /dev/null @@ -1,48 +0,0 @@ -import { render } from '@testing-library/react'; -import React from 'react'; -import { BrowserRouter } from 'react-router-dom'; -import List from '../../components/Activity/List'; -import { makeLocaleTime } from '../../utils/helpers'; - -describe('Activity List', () => { - it('should render correct entries and timestamp for Activity list', () => { - const minProps = { - timestamp: 'Wed, 13 May 2020 14:56:03 GMT', - entries: [ - { - application_name: 'ABC', - channel_name: 'beta', - class: 6, - created_ts: '2020-05-13T20:26:03.837688+05:30', - group_name: null, - instance_id: null, - severity: 2, - version: '0.0.0', - }, - { - application_name: 'DEF', - channel_name: 'beta', - class: 6, - created_ts: '2020-05-13T20:25:52.589886+05:30', - group_name: null, - instance_id: null, - severity: 2, - version: '0.0.0', - }, - ], - }; - const time = makeLocaleTime(minProps.timestamp, { - showTime: false, - dateFormat: { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' }, - }); - const { getByText } = render( - - - - ); - expect(getByText(time)).toBeInTheDocument(); - minProps.entries.forEach(entry => { - expect(getByText(entry.application_name)).toBeInTheDocument(); - }); - }); -}); diff --git a/frontend/src/js/__tests__/Applications/ApplicationItemChannelList.spec.js b/frontend/src/js/__tests__/Applications/ApplicationItemChannelList.spec.js deleted file mode 100644 index 5498e9df7..000000000 --- a/frontend/src/js/__tests__/Applications/ApplicationItemChannelList.spec.js +++ /dev/null @@ -1,42 +0,0 @@ -import { render } from '@testing-library/react'; -import React from 'react'; -import ApplicationItemChannelsList from '../../components/Applications/ApplicationItemChannelsList'; - -describe('Application Channel List ', () => { - it('should render no application channel for empty channels', () => { - const { container } = render(); - expect(container.firstChild).toBeEmpty(); - }); - it('should render channel item if there are channels', () => { - const channels = [ - { - id: 'ABC', - name: 'main', - color: '#777777', - created_ts: '2018-10-16T21:07:56.819939+05:30', - application_id: 'DEF', - package_id: 'XYZ', - package: { - id: 'PACK_ID', - type: 4, - version: '1.11.3', - url: 'https://github.com/kinvolk', - filename: '', - description: '', - size: '', - hash: '', - created_ts: '2019-07-18T20:10:39.163326+05:30', - channels_blacklist: null, - application_id: 'df1c8bbb-f525-49ee-8c94-3ca548b42059', - flatcar_action: null, - arch: 0, - }, - arch: 0, - }, - ]; - const { getByText } = render(); - expect(getByText(channels[0].name[0])).toBeInTheDocument(); - expect(getByText(channels[0].name)).toBeInTheDocument(); - expect(getByText(`${channels[0].package.version} (ALL)`)).toBeInTheDocument(); - }); -}); diff --git a/frontend/src/js/__tests__/Applications/ApplicationItemGroupItem.spec.js b/frontend/src/js/__tests__/Applications/ApplicationItemGroupItem.spec.js deleted file mode 100644 index d9c6c9271..000000000 --- a/frontend/src/js/__tests__/Applications/ApplicationItemGroupItem.spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import { MuiThemeProvider } from '@material-ui/core/styles'; -import { render, screen } from '@testing-library/react'; -import jest from 'jest-mock'; -import React from 'react'; -import { BrowserRouter } from 'react-router-dom'; -import API from '../../api/API'; -import ApplicationItemGroupItem from '../../components/Applications/ApplicationItemGroupItem'; -import { theme } from '../../TestHelpers/theme'; - -function mockResolver() { - return Promise.resolve(1); -} -const mockAjax = jest.fn(() => mockResolver); -describe('Application Item Group Item', () => { - const minProps = { - group: { - name: 'ABC', - application_id: '123', - id: '1', - channel: { - name: 'main', - }, - }, - appName: 'FlatCar', - }; - beforeEach(() => { - API.getInstancesCount = mockAjax(); - }); - it('should render correct link and correct total instances', async () => { - render( - - - - - - ); - - expect(screen.getByText(`${minProps.group.name}`)).toBeInTheDocument(); - expect(screen.getByText(minProps.group.channel.name)).toBeInTheDocument(); - expect( - screen.getByRole('link', { - href: `/apps/${minProps.group.application_id}/groups/${minProps.group.id}`, - }) - ).toBeInTheDocument(); - }); - afterEach(() => { - mockAjax.mockClear(); - }); -}); diff --git a/frontend/src/js/__tests__/Applications/EditDialog.spec.js b/frontend/src/js/__tests__/Applications/EditDialog.spec.js deleted file mode 100644 index 7eada1de1..000000000 --- a/frontend/src/js/__tests__/Applications/EditDialog.spec.js +++ /dev/null @@ -1,16 +0,0 @@ -import '../../i18n/config.ts'; -import { render } from '@testing-library/react'; -import React from 'react'; -import EditDialog from '../../components/Applications/EditDialog'; - -describe('Application Edit Dialog', () => { - it('should render Update button', () => { - const { getByText } = render(); - expect(getByText('Update')).toBeInTheDocument(); - expect(getByText('Update Application')).toBeInTheDocument(); - }); - it('should render Add button', () => { - const { getByText } = render(); - expect(getByText('Add')).toBeInTheDocument(); - }); -}); diff --git a/frontend/src/js/__tests__/Applications/Item.spec.js b/frontend/src/js/__tests__/Applications/Item.spec.js deleted file mode 100644 index 9a0a0d8ed..000000000 --- a/frontend/src/js/__tests__/Applications/Item.spec.js +++ /dev/null @@ -1,68 +0,0 @@ -import '../../i18n/config.ts'; -import { render } from '@testing-library/react'; -import React from 'react'; -import { BrowserRouter } from 'react-router-dom'; -import Item from '../../components/Applications/Item'; - -describe('Application Item', () => { - it('should render item correctly for no data', () => { - const { asFragment } = render( - - {}} - /> - - ); - expect(asFragment()).toMatchSnapshot(); - }); - it('should render item correctly for data', () => { - const minProps = { - instances: { - count: '1', - }, - id: '123', - name: 'ABC', - group: { - channel: { - id: 'DEF', - name: 'main', - color: '#777777', - created_ts: '2018-10-16T21:07:56.819939+05:30', - application_id: '123', - package_id: 'XYZ', - package: { - id: 'PACK_ID', - type: 4, - version: '1.11.3', - url: 'https://github.com/kinvolk', - filename: '', - description: '', - size: '', - hash: '', - created_ts: '2019-07-18T20:10:39.163326+05:30', - channels_blacklist: null, - application_id: 'df1c8bbb-f525-49ee-8c94-3ca548b42059', - flatcar_action: null, - arch: 0, - }, - arch: 0, - }, - }, - description: 'App Item Description', - }; - const { getByText } = render( - - {}} /> - - ); - expect(getByText(minProps.description)).toBeInTheDocument(); - expect(getByText(minProps.instances.count)).toBeInTheDocument(); - expect(getByText(minProps.name)).toBeInTheDocument(); - expect(getByText(minProps.id)).toBeInTheDocument(); - }); -}); diff --git a/frontend/src/js/__tests__/Applications/List.spec.js b/frontend/src/js/__tests__/Applications/List.spec.js deleted file mode 100644 index d0ee24d73..000000000 --- a/frontend/src/js/__tests__/Applications/List.spec.js +++ /dev/null @@ -1,58 +0,0 @@ -import '../../i18n/config.ts'; -import { render } from '@testing-library/react'; -import React from 'react'; -import { BrowserRouter } from 'react-router-dom'; -import List from '../../components/Applications/List'; -import { applicationsStore } from '../../stores/Stores'; - -describe('Application List', () => { - const minProps = { - applications: [ - { - id: '123', - name: 'ABC', - channels: [ - { - id: 'DEF', - name: 'main', - color: '#777777', - created_ts: '2018-10-16T21:07:56.819939+05:30', - application_id: '123', - package_id: 'XYZ', - package: { - id: 'PACK_ID', - type: 4, - version: '1.11.3', - url: 'https://github.com/kinvolk', - filename: '', - description: '', - size: '', - hash: '', - created_ts: '2019-07-18T20:10:39.163326+05:30', - channels_blacklist: null, - application_id: 'df1c8bbb-f525-49ee-8c94-3ca548b42059', - flatcar_action: null, - arch: 0, - }, - arch: 0, - }, - ], - description: 'App Item Description', - instances: { - count: '1', - }, - }, - ], - }; - it('should render list correctly with data', () => { - const getCachedApplications = applicationsStore.getCachedApplications(); - applicationsStore.getCachedApplications = () => minProps.applications; - const { asFragment } = render( - - - - ); - expect(asFragment()).toMatchSnapshot(); - applicationsStore.getCachedApplications = getCachedApplications; - }); -}); diff --git a/frontend/src/js/__tests__/Applications/__snapshots__/Item.spec.js.snap b/frontend/src/js/__tests__/Applications/__snapshots__/Item.spec.js.snap deleted file mode 100644 index b4b189aa1..000000000 --- a/frontend/src/js/__tests__/Applications/__snapshots__/Item.spec.js.snap +++ /dev/null @@ -1,185 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Application Item should render item correctly for no data 1`] = ` - -
  • -
    -
    -
    -
    -
    -

    - - ABC - -

    -
    -
    -
    -

    - 123 -

    -
    -
    - - No description provided - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    - - INSTANCES - - -
    - None -
    -
    - -
    -
    - last 24 hours -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - - Groups - -
    - - None - -
    -
    -
    -
    -
    -
    -
  • -
    -`; diff --git a/frontend/src/js/__tests__/Applications/__snapshots__/List.spec.js.snap b/frontend/src/js/__tests__/Applications/__snapshots__/List.spec.js.snap deleted file mode 100644 index f58d67f68..000000000 --- a/frontend/src/js/__tests__/Applications/__snapshots__/List.spec.js.snap +++ /dev/null @@ -1,241 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Application List should render list correctly with data 1`] = ` - -
    -
    -
    -

    - Applications -

    -
    -
    -
    -
    - -
    -
    -
    -
    -
      -
    • -
      -
      -
      -
      -
      -

      - - ABC - -

      -
      -
      -
      -

      - 123 -

      -
      -
      - - App Item Description - -
      -
      -
      -
      -
      - -
      -
      -
      -
      -
      -
      -
      -
      -
      - - INSTANCES - - -
      - 1 -
      -
      - -
      -
      - last 24 hours -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      -
      - - Groups - -
      - - None - -
      -
      -
      -
      -
      -
      -
    • -
    -
    -
    -`; diff --git a/frontend/src/js/__tests__/Channels/ChannelAvatar.spec.js b/frontend/src/js/__tests__/Channels/ChannelAvatar.spec.js deleted file mode 100644 index f53804b00..000000000 --- a/frontend/src/js/__tests__/Channels/ChannelAvatar.spec.js +++ /dev/null @@ -1,10 +0,0 @@ -import { render } from '@testing-library/react'; -import React from 'react'; -import ChannelAvatar from '../../components/Channels/ChannelAvatar'; - -describe('Channel Avatar', () => { - it('should render avatar with correct color', () => { - const { asFragment } = render(ABC); - expect(asFragment()).toMatchSnapshot(); - }); -}); diff --git a/frontend/src/js/__tests__/Channels/Item.react.spec.js b/frontend/src/js/__tests__/Channels/Item.react.spec.js deleted file mode 100644 index 6b40b5bfe..000000000 --- a/frontend/src/js/__tests__/Channels/Item.react.spec.js +++ /dev/null @@ -1,45 +0,0 @@ -import '../../i18n/config.ts'; -import { fireEvent, render } from '@testing-library/react'; -import React from 'react'; -import Item from '../../components/Channels/Item'; - -describe('Channel Item', () => { - const minProps = { - channel: { - id: 'ABC', - name: 'main', - color: '#777777', - created_ts: '2018-10-16T21:07:56.819939+05:30', - application_id: 'DEF', - package_id: 'XYZ', - package: { - id: 'PACK_ID', - type: 4, - version: '1.11.3', - url: 'https://github.com/kinvolk', - filename: '', - description: '', - size: '', - hash: '', - created_ts: '2019-07-18T20:10:39.163326+05:30', - channels_blacklist: null, - application_id: 'df1c8bbb-f525-49ee-8c94-3ca548b42059', - flatcar_action: null, - arch: 0, - }, - arch: 0, - }, - handleUpdateChannel: jest.fn(() => {}), - }; - it('should show confirmation box on delete click', () => { - const { getByText } = render(); - window.confirm = jest.fn(() => true); - fireEvent.click(getByText('Delete')); - expect(window.confirm).toBeCalled(); - }); - it('should call edit handler on edit click', () => { - const { getByText } = render(); - fireEvent.click(getByText('Edit')); - expect(minProps.handleUpdateChannel).toBeCalled(); - }); -}); diff --git a/frontend/src/js/__tests__/Channels/List.react.spec.js b/frontend/src/js/__tests__/Channels/List.react.spec.js deleted file mode 100644 index 0326872cc..000000000 --- a/frontend/src/js/__tests__/Channels/List.react.spec.js +++ /dev/null @@ -1,39 +0,0 @@ -import { render } from '@testing-library/react'; -import React from 'react'; -import List from '../../components/Channels/List'; - -describe('Channel List', () => { - const minProps = { - appID: '123', - channels: [ - { - id: 'ABC', - name: 'main', - color: '#777777', - created_ts: '2018-10-16T21:07:56.819939+05:30', - application_id: 'DEF', - package_id: 'XYZ', - package: { - id: 'PACK_ID', - type: 4, - version: '1.11.3', - url: 'https://github.com/kinvolk', - filename: '', - description: '', - size: '', - hash: '', - created_ts: '2019-07-18T20:10:39.163326+05:30', - channels_blacklist: null, - application_id: 'df1c8bbb-f525-49ee-8c94-3ca548b42059', - flatcar_action: null, - arch: 0, - }, - arch: 0, - }, - ], - }; - it('should render channel list correctly with data', () => { - const { asFragment } = render(); - expect(asFragment).toMatchSnapshot(); - }); -}); diff --git a/frontend/src/js/__tests__/Channels/__snapshots__/ChannelAvatar.spec.js.snap b/frontend/src/js/__tests__/Channels/__snapshots__/ChannelAvatar.spec.js.snap deleted file mode 100644 index 5ea25e147..000000000 --- a/frontend/src/js/__tests__/Channels/__snapshots__/ChannelAvatar.spec.js.snap +++ /dev/null @@ -1,11 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Channel Avatar should render avatar with correct color 1`] = ` - -
    - ABC -
    -
    -`; diff --git a/frontend/src/js/__tests__/Channels/__snapshots__/List.react.spec.js.snap b/frontend/src/js/__tests__/Channels/__snapshots__/List.react.spec.js.snap deleted file mode 100644 index 0bd260468..000000000 --- a/frontend/src/js/__tests__/Channels/__snapshots__/List.react.spec.js.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Channel List should render channel list correctly with data 1`] = `[Function]`; diff --git a/frontend/src/js/__tests__/Common/Card.spec.js b/frontend/src/js/__tests__/Common/Card.spec.js deleted file mode 100644 index cdcf4bd37..000000000 --- a/frontend/src/js/__tests__/Common/Card.spec.js +++ /dev/null @@ -1,48 +0,0 @@ -import { render } from '@testing-library/react'; -import React from 'react'; -import { BrowserRouter } from 'react-router-dom'; -import { - CardDescriptionLabel, - CardFeatureLabel, - CardHeader, - CardLabel, -} from '../../components/Common/Card'; - -describe('Card', () => { - const minProps = { - children: 'Children Content', - cardMainLinkPath: '/apps/123', - cardMainLinkLabel: 'Flatcar', - }; - it('should render correct card feature label', () => { - const { getByText } = render(); - expect(getByText(minProps.children)).toBeInTheDocument(); - }); - it('should render correct card description label', () => { - const { getByText } = render(); - expect(getByText(minProps.children)).toBeInTheDocument(); - }); - it('should render correct card label', () => { - const { getByText } = render(); - expect(getByText(minProps.children)).toBeInTheDocument(); - }); - it('should render card header with correct links', () => { - const { container } = render( - - - - ); - expect(container.querySelector('a').getAttribute('href')).toBe(minProps.cardMainLinkPath); - }); - it('should render correct card label', () => { - const { getByText } = render(); - expect(getByText(minProps.cardMainLinkLabel)).toBeInTheDocument(); - }); - it('should render correct card childrens', () => { - const { getByText } = render({minProps.children}); - expect(getByText(minProps.children)).toBeInTheDocument(); - }); -}); diff --git a/frontend/src/js/__tests__/Common/ColorPicker.spec.js b/frontend/src/js/__tests__/Common/ColorPicker.spec.js deleted file mode 100644 index 3a1209f15..000000000 --- a/frontend/src/js/__tests__/Common/ColorPicker.spec.js +++ /dev/null @@ -1,15 +0,0 @@ -import { fireEvent, render } from '@testing-library/react'; -import React from 'react'; -import { ColorPickerButton } from '../../components/Common/ColorPicker'; - -describe('Color Picker', () => { - const minProps = { - children: 'Click Me', - color: '#fff', - }; - it('should render popover on Icon Click', () => { - const { getByTestId } = render(); - fireEvent.click(getByTestId('icon-button')); - expect(getByTestId('popover')).toBeTruthy(); - }); -}); diff --git a/frontend/src/js/components/Activity/Item.tsx b/frontend/src/js/components/Activity/Item.tsx deleted file mode 100644 index 1bb9332be..000000000 --- a/frontend/src/js/components/Activity/Item.tsx +++ /dev/null @@ -1,154 +0,0 @@ -import alertCircleOutline from '@iconify/icons-mdi/alert-circle-outline'; -import alertOutline from '@iconify/icons-mdi/alert-outline'; -import checkCircleOutline from '@iconify/icons-mdi/check-circle-outline'; -import { Icon } from '@iconify/react'; -import { Box, makeStyles } from '@material-ui/core'; -import Grid from '@material-ui/core/Grid'; -import Link from '@material-ui/core/Link'; -import ListItem from '@material-ui/core/ListItem'; -import Typography from '@material-ui/core/Typography'; -import React from 'react'; -import { useTranslation } from 'react-i18next'; -import { Link as RouterLink } from 'react-router-dom'; -import { Activity } from '../../api/apiDataTypes'; -import { activityStore } from '../../stores/Stores'; - -function ActivityItemIcon(props: { icon: object; color?: string | undefined }) { - const { icon, color } = props; - return ; -} - -const stateIcons: { - [key: string]: { - icon: any; - color: string; - }; -} = { - warning: { - icon: alertOutline, - color: '#ff5500', - }, - info: { - icon: alertCircleOutline, - color: '#00d3ff', - }, - error: { - icon: alertCircleOutline, - color: '#F44336', - }, - success: { - icon: checkCircleOutline, - color: '#22bb00', - }, -}; - -const useStyles = makeStyles({ - groupLink: { - color: '#1b5c91', - }, -}); - -function Item(props: { entry: Activity }) { - const [entryClass, setEntryClass] = React.useState<{ [key: string]: any }>({}); - const [entrySeverity, setEntrySeverity] = React.useState<{ - className?: string; - [key: string]: any; - }>({}); - const classes = useStyles(); - const { t } = useTranslation(); - - function fetchEntryClassFromStore() { - const entryClass = activityStore.getActivityEntryClass(props.entry.class, props.entry); - setEntryClass(entryClass); - } - - function fetchEntrySeverityFromStore() { - const entrySeverity = activityStore.getActivityEntrySeverity(props.entry.severity); - setEntrySeverity(entrySeverity); - } - - React.useEffect(() => { - fetchEntryClassFromStore(); - fetchEntrySeverityFromStore(); - }, []); - - const time = new Date(props.entry.created_ts).toLocaleString('default', { - hour: '2-digit', - minute: '2-digit', - }); - let subtitle = ''; - let name: React.ReactNode = ''; - - if (entryClass.type !== 'activityChannelPackageUpdated') { - const { app_id, group_id } = props.entry; - const groupPath = `apps/${app_id}/groups/${group_id}`; - subtitle = t('activity|GROUP'); - name = ( - - {entryClass.groupName} - - ); - } - - const stateIcon = stateIcons[entrySeverity.className || 'info']; - - return ( - - - - - - - - - - {entryClass.appName} - - - - - - - - {time} - - - {subtitle && ( - - - - {subtitle} - - - {name} - - )} - {entryClass.description} - - - ); -} - -export default Item; diff --git a/frontend/src/js/components/Applications/ApplicationItemGroupsList.tsx b/frontend/src/js/components/Applications/ApplicationItemGroupsList.tsx deleted file mode 100644 index d76826464..000000000 --- a/frontend/src/js/components/Applications/ApplicationItemGroupsList.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Box, Divider } from '@material-ui/core'; -import React from 'react'; -import { Group } from '../../api/apiDataTypes'; -import Item from './ApplicationItemGroupItem'; - -function ApplicationItemGroupsList(props: { groups: Group[]; appID: string; appName: string }) { - return ( - <> - {props.groups.map((group, i) => ( - - {i > 0 && } - - - - - ))} - - ); -} - -export default ApplicationItemGroupsList; diff --git a/frontend/src/js/components/Applications/List.tsx b/frontend/src/js/components/Applications/List.tsx deleted file mode 100644 index 2350f9a47..000000000 --- a/frontend/src/js/components/Applications/List.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import { List as MuiList, withStyles } from '@material-ui/core'; -import Paper from '@material-ui/core/Paper'; -import React from 'react'; -import { Trans, useTranslation } from 'react-i18next'; -import _ from 'underscore'; -import { Application } from '../../api/apiDataTypes'; -import { applicationsStore } from '../../stores/Stores'; -import Empty from '../Common/EmptyContent'; -import ListHeader from '../Common/ListHeader'; -import Loader from '../Common/Loader'; -import ModalButton from '../Common/ModalButton'; -import EditDialog from './EditDialog'; -import Item from './Item'; - -const styles = () => ({ - root: { - '& > hr:first-child': { - display: 'none', - }, - }, -}); - -function List(props: { classes: Record<'root', string> }) { - const [applications, setApplications] = React.useState( - applicationsStore.getCachedApplications ? applicationsStore.getCachedApplications() : [] - ); - const [searchTerm] = React.useState(''); - const [updateAppModalVisible, setUpdateModalVisible] = React.useState(false); - const [updateAppIDModal, setUpdateAppIDModal] = React.useState(null); - const { t } = useTranslation(); - - function closeUpdateAppModal() { - setUpdateModalVisible(false); - } - - function openUpdateAppModal(appID: string) { - setUpdateModalVisible(true); - setUpdateAppIDModal(appID); - } - - React.useEffect(() => { - applicationsStore.addChangeListener(onChange); - return () => { - applicationsStore.removeChangeListener(onChange); - }; - }, []); - - React.useEffect(() => { - if (applicationsStore.getCachedApplications) { - setApplications(applicationsStore.getCachedApplications()); - } - }, [applicationsStore.getCachedApplications]); - - function onChange() { - setApplications(applicationsStore.getCachedApplications()); - } - - let entries: React.ReactNode = ''; - const { classes } = props; - - if (searchTerm) { - if (applications) { - setApplications(applications.filter(app => app.name.toLowerCase().includes(searchTerm))); - } - } - - if (_.isNull(applications)) { - entries = ; - } else { - if (_.isEmpty(applications)) { - if (searchTerm) { - entries = {t('applications|No results found.')}; - } else { - entries = ( - - - Oops, it looks like you have not created any application yet.. -
    -
    Now is a great time to create your first one, just click on the plus symbol - above. -
    -
    - ); - } - } else { - entries = _.map(applications, (application: Application) => { - return ( - - ); - }); - } - } - - const appToUpdate = - applications && updateAppIDModal ? _.findWhere(applications, { id: updateAppIDModal }) : null; - return ( - <> - , - ]} - /> - - {entries} - {appToUpdate && ( - - )} - - - ); -} - -export default withStyles(styles)(List); diff --git a/frontend/src/js/components/Groups/Charts.tsx b/frontend/src/js/components/Groups/Charts.tsx deleted file mode 100644 index 9384a0105..000000000 --- a/frontend/src/js/components/Groups/Charts.tsx +++ /dev/null @@ -1,610 +0,0 @@ -import { IconifyIcon } from '@iconify/react'; -import { Theme } from '@material-ui/core'; -import Box from '@material-ui/core/Box'; -import Chip from '@material-ui/core/Chip'; -import Grid from '@material-ui/core/Grid'; -import Paper from '@material-ui/core/Paper'; -import Typography from '@material-ui/core/Typography'; -import { useTheme } from '@material-ui/styles'; -import React from 'react'; -import { Area, AreaChart, AreaProps, CartesianGrid, Tooltip, XAxis, YAxis } from 'recharts'; -import semver from 'semver'; -import _ from 'underscore'; -import { Group } from '../../api/apiDataTypes'; -import { groupChartStore } from '../../stores/Stores'; -import { - cleanSemverVersion, - getInstanceStatus, - getMinuteDifference, - makeColorsForVersions, - makeLocaleTime, -} from '../../utils/helpers'; -import Loader from '../Common/Loader'; -import SimpleTable from '../Common/SimpleTable'; -import makeStatusDefs from '../Instances/StatusDefs'; - -function TimelineTooltip(props: { label?: string; data: any }) { - const { label, data } = props; - return ( -
    - - - {label && data[label] && makeLocaleTime(data[label].timestamp)} - - -
    - ); -} - -function TimelineChart(props: { - width?: number; - height?: number; - interpolation?: AreaProps['type']; - data: any; - onSelect: (activeLabel: any) => void; - colors: any; - keys: string[]; -}) { - const { width = 500, height = 400, interpolation = 'monotone' } = props; - let ticks: { - [key: string]: string; - } = {}; - - function getTickValues() { - const DAY = 24 * 60; - let tickCount = 4; - let dateFormat: { - useDate?: boolean; - showTime?: boolean; - dateFormat?: Intl.DateTimeFormatOptions; - } = { useDate: false }; - const startTs = new Date(props.data[0].timestamp); - const endTs = new Date(props.data[props.data.length - 1].timestamp); - const lengthMinutes = getMinuteDifference(endTs.valueOf(), startTs.valueOf()); - // We remove 1 element since that's "0 hours" - const dimension = props.data.length - 1; - - // Reset the ticks for the chart - ticks = {}; - - if (lengthMinutes === 7 * DAY) { - tickCount = 7; - dateFormat = { dateFormat: { month: 'short', day: 'numeric' }, showTime: false }; - } - if (lengthMinutes === 60) { - for (let i = 0; i < 4; i++) { - const minuteValue = (lengthMinutes / 4) * i; - startTs.setMinutes(new Date(props.data[0].timestamp).getMinutes() + minuteValue); - ticks[i] = makeLocaleTime(startTs, { useDate: false }); - } - return ticks; - } - - if (lengthMinutes === 30 * DAY) { - for (let i = 0; i < props.data.length; i += 2) { - const tickDate = new Date(props.data[i].timestamp); - ticks[i] = makeLocaleTime(tickDate, { - showTime: false, - dateFormat: { month: 'short', day: 'numeric' }, - }); - } - return ticks; - } - // Set up a tick marking the 0 hours of the day contained in the range - const nextDay = new Date(startTs); - nextDay.setHours(24, 0, 0, 0); - const midnightDay = new Date(nextDay); - const nextDayMinuteDiff = getMinuteDifference(nextDay.valueOf(), startTs.valueOf()); - const midnightTick = (nextDayMinuteDiff * dimension) / lengthMinutes; - - // Set up the remaining ticks according to the desired amount, separated - // evenly. - const tickOffsetMinutes = lengthMinutes / tickCount; - - // Set the ticks around midnight. - for (const i of [-1, 1]) { - const tickDate = new Date(nextDay); - - while (true) { - tickDate.setMinutes(nextDay.getMinutes() + tickOffsetMinutes * i); - // Stop if this tick falls outside of the times being charted - - if (tickDate < startTs || tickDate > endTs) { - break; - } - - const tick = - (getMinuteDifference(tickDate.valueOf(), startTs.valueOf()) * dimension) / lengthMinutes; - // Show only the time. - ticks[tick] = makeLocaleTime(tickDate, dateFormat); - } - } - // The midnight tick just gets the date, not the hours (since they're zero) - ticks[midnightTick] = makeLocaleTime(midnightDay, { - dateFormat: { month: 'short', day: 'numeric' }, - showTime: false, - }); - return ticks; - } - - return ( - obj && props.onSelect(obj.activeLabel)} - > - - } /> - { - return ticks[index]; - }} - stroke={'#000'} - /> - - {props.keys.map((key: string, i: number) => ( - - ))} - - ); -} - -export function VersionCountTimeline(props: { - group: Group | null; - duration: { - [key: string]: any; - }; -}) { - const [selectedEntry, setSelectedEntry] = React.useState(-1); - const { duration } = props; - const [timelineChartData, setTimelineChartData] = React.useState<{ - data: any[]; - keys: any[]; - colors: any; - }>({ - data: [], - keys: [], - colors: [], - }); - const [timeline, setTimeline] = React.useState({ - timeline: {}, - // A long time ago, to force the first update... - lastUpdate: new Date(2000, 1, 1).toUTCString(), - }); - - const theme = useTheme(); - - function makeChartData(group: Group, groupTimeline: { [key: string]: any }) { - const data = Object.keys(groupTimeline).map((timestamp, i) => { - const versions = groupTimeline[timestamp]; - return { - index: i, - timestamp: timestamp, - ...versions, - }; - }); - - const versions = getVersionsFromTimeline(groupTimeline); - const versionColors: { - [key: string]: string; - } = makeColorsForVersions(theme as Theme, versions, group.channel); - - setTimelineChartData({ - data: data, - keys: versions, - colors: versionColors, - }); - } - - function getVersionsFromTimeline(timeline: { [key: string]: any }) { - if (Object.keys(timeline).length === 0) { - return []; - } - - const versions: string[] = []; - - Object.keys(Object.values(timeline)[0]).forEach(version => { - const cleanedVersion = cleanSemverVersion(version); - // Discard any invalid versions (empty strings, etc.) - if (semver.valid(cleanedVersion)) { - versions.push(cleanedVersion); - } - }); - - // Sort versions (earliest first) - versions.sort((version1, version2) => { - return semver.compare(version1, version2); - }); - - return versions; - } - - function getInstanceCount(selectedEntry: number) { - const version_breakdown = []; - let selectedEntryPoint = selectedEntry; - - // If there is no timeline or no specific time is selected, - // show the timeline for the last time point. - if (selectedEntry === -1) { - selectedEntryPoint = timelineChartData.data.length - 1; - } - - let total = 0; - - // If we're not using the default group version breakdown, - // let's populate it from the selected time one. - if (version_breakdown.length === 0 && selectedEntryPoint > -1) { - // Create the version breakdown from the timeline - const entries = timelineChartData.data[selectedEntryPoint] || []; - - for (const version of timelineChartData.keys) { - const versionCount = entries[version]; - - total += versionCount; - - version_breakdown.push({ - version: version, - instances: versionCount, - percentage: 0, - }); - } - } - - version_breakdown.forEach((entry: { [key: string]: any }) => { - entry.color = timelineChartData.colors[entry.version]; - - // Calculate the percentage if needed. - if (total > 0) { - entry.percentage = (entry.instances * 100.0) / total; - } - - entry.percentage = parseFloat(entry.percentage).toFixed(1); - }); - - // Sort the entries per number of instances (higher first). - version_breakdown.sort((elem1, elem2) => { - return -(elem1.instances - elem2.instances); - }); - - return version_breakdown; - } - - function getSelectedTime() { - const data = timelineChartData.data; - if (selectedEntry < 0 || data.length === 0) { - return ''; - } - const timestamp = data[selectedEntry] ? data[selectedEntry].timestamp : ''; - return makeLocaleTime(timestamp); - } - - // Make the timeline data again when needed. - React.useEffect(() => { - let canceled = false; - async function getVersionTimeline(group: Group | null) { - if (group) { - // Check if we should update the timeline or it's too early. - const lastUpdate = new Date(timeline.lastUpdate); - setTimelineChartData({ data: [], keys: [], colors: [] }); - try { - const versionCountTimeline = await groupChartStore.getGroupVersionCountTimeline( - group.application_id, - group.id, - duration.queryValue - ); - if (!canceled) { - setTimeline({ - timeline: versionCountTimeline, - lastUpdate: lastUpdate.toUTCString(), - }); - } - makeChartData(group, versionCountTimeline || []); - setSelectedEntry(-1); - } catch (error) { - console.error(error); - } - } - } - getVersionTimeline(props.group); - return () => { - canceled = true; - }; - }, [duration]); - - return ( - - - {timelineChartData.data.length > 0 ? ( - - ) : ( - - )} - - - - - {timelineChartData.data.length > 0 ? ( - selectedEntry !== -1 ? ( - - Showing for: -   - { - setSelectedEntry(-1); - }} - /> - - ) : ( - - Showing data for the last time point. -
    - Click the chart to choose a different time point. -
    - ) - ) : null} -
    -
    - - {timelineChartData.data.length > 0 && ( - - )} - -
    -
    - ); -} - -export function StatusCountTimeline(props: { - duration: { - [key: string]: any; - }; - group: Group | null; -}) { - const [selectedEntry, setSelectedEntry] = React.useState(-1); - const { duration } = props; - const [timelineChartData, setTimelineChartData] = React.useState<{ - data: { - index: number; - timestamp: string; - }[]; - keys: string[]; - colors: { - [key: string]: any; - }; - }>({ - data: [], - keys: [], - colors: [], - }); - - const [timeline, setTimeline] = React.useState<{ - timeline: { - [key: string]: any; - }; - lastUpdate: Date | string; - }>({ - timeline: {}, - // A long time ago, to force the first update... - lastUpdate: new Date(2000, 1, 1), - }); - - const theme = useTheme(); - const statusDefs: { - [key: string]: { - label: string; - color: any; - icon: IconifyIcon; - queryValue: string; - }; - } = makeStatusDefs(theme as Theme); - - function makeChartData(groupTimeline: { [key: string]: any }) { - const data = Object.keys(groupTimeline).map((timestamp, i) => { - const status = groupTimeline[timestamp]; - const statusCount: { - [key: string]: any; - } = {}; - Object.keys(status).forEach((st: string) => { - const values = status[st]; - const count = Object.values(values).reduce((a: any, b: any) => a + b, 0); - statusCount[st] = count; - }); - - return { - index: i, - timestamp: timestamp, - ...statusCount, - }; - }); - - const statuses = getStatusFromTimeline(groupTimeline); - const colors = makeStatusesColors(statuses); - - setTimelineChartData({ - data: data, - keys: statuses, - colors: colors, - }); - } - - function makeStatusesColors(statuses: { [key: string]: any }) { - const colors: { - [key: string]: any; - } = {}; - - Object.values(statuses).forEach(status => { - const statusInfo = getInstanceStatus(status, ''); - colors[status] = statusDefs[statusInfo.type].color; - }); - - return colors; - } - - function getStatusFromTimeline(timeline: { [key: number]: number }) { - if (Object.keys(timeline).length === 0) { - return []; - } - - return Object.keys(Object.values(timeline)[0]).filter(status => parseInt(status) !== 0); - } - - function getInstanceCount(selectedEntry: number) { - const status_breakdown: { - status: string; - version: string; - instances: number; - }[] = []; - const statusTimeline: { - [key: string]: any; - } = timeline.timeline; - - // Populate it from the selected time one. - if (!_.isEmpty(statusTimeline) && !_.isEmpty(timelineChartData.data)) { - const timelineIndex = selectedEntry >= 0 ? selectedEntry : timelineChartData.data.length - 1; - if (timelineIndex < 0) return []; - - const ts = timelineChartData.data[timelineIndex].timestamp; - // Create the version breakdown from the timeline - const entries = statusTimeline[ts] || []; - for (const status in entries) { - if (parseInt(status) === 0) { - continue; - } - - const versions = entries[status]; - - Object.keys(versions).forEach(version => { - const versionCount = versions[version]; - status_breakdown.push({ - status: status, - version: version, - instances: versionCount, - }); - }); - } - } - - status_breakdown.forEach((entry: { status: string; version: string; [key: string]: any }) => { - const statusInfo = getInstanceStatus(parseInt(entry.status), entry.version); - const statusTheme = statusDefs[statusInfo.type]; - - entry.color = statusTheme.color; - entry.status = statusTheme.label; - }); - - // Sort the entries per number of instances (higher first). - status_breakdown.sort((elem1, elem2) => { - return -(elem1.instances - elem2.instances); - }); - - return status_breakdown; - } - - function getSelectedTime() { - const data = timelineChartData.data; - if (selectedEntry < 0 || data.length === 0) { - return ''; - } - const timestamp = data[selectedEntry].timestamp; - return makeLocaleTime(timestamp); - } - - // Make the timeline data again when needed. - React.useEffect(() => { - async function getStatusTimeline(group: Group | null) { - if (group) { - setTimelineChartData({ data: [], keys: [], colors: [] }); - try { - const statusCountTimeline = await groupChartStore.getGroupStatusCountTimeline( - group.application_id, - group.id, - duration.queryValue - ); - setTimeline({ - timeline: statusCountTimeline, - lastUpdate: new Date().toUTCString(), - }); - - makeChartData(statusCountTimeline || []); - setSelectedEntry(-1); - } catch (error) { - console.error(error); - } - } - } - setSelectedEntry(-1); - getStatusTimeline(props.group); - }, [props.duration]); - - return ( - - - {timelineChartData.data.length > 0 ? ( - - ) : ( - - )} - - - - - {timelineChartData.data.length > 0 ? ( - selectedEntry !== -1 ? ( - - Showing for: -   - { - setSelectedEntry(-1); - }} - /> - - ) : ( - - Showing data for the last time point. -
    - Click the chart to choose a different time point. -
    - ) - ) : null} -
    -
    - - {timelineChartData.data.length > 0 && ( - - )} - -
    -
    - ); -} diff --git a/frontend/src/js/stores/Stores.ts b/frontend/src/js/stores/Stores.ts deleted file mode 100644 index f7e6991bb..000000000 --- a/frontend/src/js/stores/Stores.ts +++ /dev/null @@ -1,7 +0,0 @@ -import ActivityStore from './ActivityStore'; -import ApplicationsStore from './ApplicationsStore'; -import GroupChartsStore from './GroupChartsStore'; - -export const applicationsStore = new ApplicationsStore(); -export const activityStore = new ActivityStore(); -export const groupChartStore = new GroupChartsStore(); diff --git a/frontend/src/lib/themes.ts b/frontend/src/lib/themes.ts new file mode 100644 index 000000000..9b1e81bed --- /dev/null +++ b/frontend/src/lib/themes.ts @@ -0,0 +1,123 @@ +import green from '@material-ui/core/colors/green'; +import { createMuiTheme, Theme } from '@material-ui/core/styles'; +import React from 'react'; + +const DISABLE_BROWSER_THEME_PREF = true; + +declare module '@material-ui/core/styles/createPalette' { + interface Palette { + titleColor: '#000000'; + lightSilverShade: '#F0F0F0'; + greyShadeColor: '#474747'; + sapphireColor: '#061751'; + } +} + +const lightTheme = createMuiTheme({ + palette: { + primary: { + contrastText: '#fff', + main: process.env.REACT_APP_PRIMARY_COLOR ? process.env.REACT_APP_PRIMARY_COLOR : '#2C98F0', + }, + success: { + main: green['500'], + ...green, + }, + }, + typography: { + fontFamily: 'Overpass, sans-serif', + h1: { + fontSize: '1.875rem', + fontWeight: 900, + }, + h2: { + fontSize: '1.875rem', + fontWeight: 900, + }, + h3: { + fontSize: '1.875rem', + fontWeight: 900, + }, + h4: { + fontSize: '1.875rem', + fontWeight: 900, + }, + subtitle1: { + fontSize: '0.875rem', + color: 'rgba(0,0,0,0.6)', + }, + }, + shape: { + borderRadius: 0, + }, +}); + +const darkTheme = createMuiTheme({ + ...lightTheme, + palette: { + type: 'dark', + primary: { + contrastText: '#fff', + main: '#000', + }, + }, +}); + +export interface ThemesConf { + [themeName: string]: Theme; +} + +const themesConf: ThemesConf = { + light: lightTheme, + dark: darkTheme, +}; + +export default themesConf; + +export function usePrefersColorScheme() { + if (DISABLE_BROWSER_THEME_PREF || typeof window.matchMedia !== 'function') { + return 'light'; + } + + const mql = window.matchMedia('(prefers-color-scheme: dark)'); + const [value, setValue] = React.useState(mql.matches); + + React.useEffect(() => { + const handler = (x: MediaQueryListEvent | MediaQueryList) => setValue(x.matches); + mql.addListener(handler); + return () => mql.removeListener(handler); + }, []); + + return value; +} + +/** + * Hook gets theme based on user preference, and also OS/Browser preference. + * @returns 'light' | 'dark' theme name + */ +export function getThemeName(): string { + if (DISABLE_BROWSER_THEME_PREF || typeof window.matchMedia !== 'function') { + return 'light'; + } + const themePreference: string = localStorage.nebraskaThemePreference; + const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + const prefersLight = window.matchMedia('(prefers-color-scheme: light)').matches; + + let themeName = 'light'; + if (themePreference) { + // A selected theme preference takes precedence. + themeName = themePreference; + } else { + if (prefersLight) { + themeName = 'light'; + } else if (prefersDark) { + themeName = 'dark'; + } + } + + return themeName; +} + +export function setTheme(themeName: string) { + localStorage.nebraskaThemePreference = themeName; +} diff --git a/frontend/src/setupTests.ts b/frontend/src/setupTests.ts index 74b1a275a..eec163ba9 100644 --- a/frontend/src/setupTests.ts +++ b/frontend/src/setupTests.ts @@ -3,3 +3,11 @@ // expect(element).toHaveTextContent(/react/i) // learn more: https://github.com/testing-library/jest-dom import '@testing-library/jest-dom/extend-expect'; + +// Material UI doesn't have a stable ID generator. +// Every render a different ID is made and snapshot tests are broken. +// mui v5 +// jest.mock('@material-ui/utils/useId', () => jest.fn().mockReturnValue('mui-test-id')) + +// mui v4 +jest.mock('@material-ui/core/utils/unstable_useId', () => jest.fn().mockReturnValue('mui-test-id')); diff --git a/frontend/src/js/stores/ActivityStore.tsx b/frontend/src/stores/ActivityStore.tsx similarity index 74% rename from frontend/src/js/stores/ActivityStore.tsx rename to frontend/src/stores/ActivityStore.tsx index 033fc3b3c..41eff46f7 100644 --- a/frontend/src/js/stores/ActivityStore.tsx +++ b/frontend/src/stores/ActivityStore.tsx @@ -4,18 +4,48 @@ import { Link as RouterLink } from 'react-router-dom'; import _ from 'underscore'; import API from '../api/API'; import { Activity } from '../api/apiDataTypes'; +import { toLocaleDateString } from '../i18n/dateTime'; import Store from './BaseStore'; +interface ActivityEntryClass { + type: string; + appName: string; + groupName: string | null; + channelName: string | null; + description: string | React.ReactElement; +} +interface ActivityEntrySeverity { + type: string; + className: string; + icon: string; +} + class ActivityStore extends Store { - activity: { [key: string]: Activity[] } | null | never[]; - constructor() { + activity: { [key: string]: Activity[] } | null; + interval: null | number; + constructor(noRefresh?: boolean) { super(); this.activity = null; - this.getActivity(); - setInterval(() => { + if (noRefresh) { + this.interval = null; + } else { this.getActivity(); - }, 60 * 1000); + this.interval = window.setInterval(() => { + this.getActivity(); + }, 60 * 1000); + } + } + + stopRefreshing() { + if (this.interval) { + window.clearInterval(this.interval); + } + this.interval = null; + } + + setActivity(entries: Activity[] | null) { + this.activity = entries === null ? null : this.sortActivityByDate(entries); } getCachedActivity() { @@ -25,14 +55,12 @@ class ActivityStore extends Store { getActivity() { API.getActivity() .then(response => { - this.activity = _.isNull(response.activities) - ? [] - : this.sortActivityByDate(response.activities); + this.setActivity(response.totalCount === 0 ? [] : response.activities); this.emitChange(); }) .catch(error => { if (error.status === 404) { - this.activity = []; + this.setActivity(null); this.emitChange(); } }); @@ -44,8 +72,7 @@ class ActivityStore extends Store { } = {}; entries.forEach(entry => { - const createdDate = new Date(entry.created_ts); - const date = createdDate.toLocaleDateString('default', { + const date = toLocaleDateString(entry.created_ts, undefined, { day: 'numeric', weekday: 'short', month: 'short', @@ -61,17 +88,11 @@ class ActivityStore extends Store { return sortedEntries; } - getActivityEntryClass(classID: number, entry: Activity) { + makeActivityEntryClass(classID: number, entry: Activity): ActivityEntryClass { const instancePath = `/apps/${entry.app_id}/groups/${entry.group_id}/instances/${entry.instance_id}?period=1d`; - const classType: { - [key: string]: { - type: string; - appName: string; - groupName: string | null; - channelName: string | null; - description: string | React.ReactElement; - }; + const classTypes: { + [key: string]: ActivityEntryClass; } = { 1: { type: 'activityPackageNotFound', @@ -130,17 +151,13 @@ class ActivityStore extends Store { }, }; - const classDetails = classID ? classType[classID] : classType[1]; + const classDetails = classID ? classTypes[classID] : classTypes[1]; return classDetails; } - getActivityEntrySeverity(severityID: number) { + makeActivityEntrySeverity(severityID: number) { const severityType: { - [key: string]: { - type: string; - className: string; - icon: string; - }; + [key: string]: ActivityEntrySeverity; } = { 1: { type: 'activitySuccess', diff --git a/frontend/src/js/stores/ApplicationsStore.ts b/frontend/src/stores/ApplicationsStore.ts similarity index 97% rename from frontend/src/js/stores/ApplicationsStore.ts rename to frontend/src/stores/ApplicationsStore.ts index c6ebaf949..64b594967 100644 --- a/frontend/src/js/stores/ApplicationsStore.ts +++ b/frontend/src/stores/ApplicationsStore.ts @@ -7,14 +7,20 @@ import store from './redux/store'; class ApplicationsStore extends Store { applications: Application[]; - constructor() { + interval: null | number; + constructor(noRefresh?: boolean) { super(); this.applications = []; - this.getApplications(); - setInterval(() => { + if (noRefresh) { + this.interval = null; + } else { this.getApplications(); - }, 60 * 1000); + + this.interval = window.setInterval(() => { + this.getApplications(); + }, 60 * 1000); + } } // Applications diff --git a/frontend/src/js/stores/BaseStore.ts b/frontend/src/stores/BaseStore.ts similarity index 100% rename from frontend/src/js/stores/BaseStore.ts rename to frontend/src/stores/BaseStore.ts diff --git a/frontend/src/js/stores/GroupChartsStore.ts b/frontend/src/stores/GroupChartsStore.ts similarity index 94% rename from frontend/src/js/stores/GroupChartsStore.ts rename to frontend/src/stores/GroupChartsStore.ts index 1c9e1f4f7..064ee80d7 100644 --- a/frontend/src/js/stores/GroupChartsStore.ts +++ b/frontend/src/stores/GroupChartsStore.ts @@ -25,7 +25,7 @@ export default class GroupChartsStore { versionCountTimeline = this.getVersionChartData(groupID, duration); if (!versionCountTimeline) { try { - versionCountTimeline = await applicationsStore.getGroupVersionCountTimeline( + versionCountTimeline = await applicationsStore().getGroupVersionCountTimeline( appID, groupID, duration @@ -70,7 +70,7 @@ export default class GroupChartsStore { statusCountTimeline = this.getStatusChartData(groupID, duration); if (!statusCountTimeline) { try { - statusCountTimeline = await applicationsStore.getGroupStatusCountTimeline( + statusCountTimeline = await applicationsStore().getGroupStatusCountTimeline( appID, groupID, duration diff --git a/frontend/src/stores/Stores.ts b/frontend/src/stores/Stores.ts new file mode 100644 index 000000000..d6ad0b8f4 --- /dev/null +++ b/frontend/src/stores/Stores.ts @@ -0,0 +1,53 @@ +import { Context, createContext } from 'react'; +import ActivityStore from './ActivityStore'; +import ApplicationsStore from './ApplicationsStore'; +import GroupChartsStore from './GroupChartsStore'; + +interface Stores { + applicationsStore: ApplicationsStore; + activityStore: ActivityStore; + groupChartStore: GroupChartsStore; + + applicationsStoreContext: Context; + activityStoreContext: Context; + groupChartStoreContext: Context; +} +let stores: Stores | undefined; + +export function getStores(noRefresh?: boolean): Stores { + if (stores === undefined) { + const applicationsStore = new ApplicationsStore(noRefresh); + const activityStore = new ActivityStore(noRefresh); + const groupChartStore = new GroupChartsStore(); + + const applicationsStoreContext = createContext(applicationsStore); + const activityStoreContext = createContext(activityStore); + const groupChartStoreContext = createContext(groupChartStore); + + stores = { + applicationsStore, + activityStore, + groupChartStore, + applicationsStoreContext, + activityStoreContext, + groupChartStoreContext, + }; + } + return stores; +} + +export function applicationsStore(noRefresh?: boolean) { + return getStores(noRefresh).applicationsStore; +} + +export function activityStore(noRefresh?: boolean) { + return getStores(noRefresh).activityStore; +} + +export function groupChartStore(noRefresh?: boolean) { + return getStores(noRefresh).groupChartStore; +} + +export function groupChartStoreContext() { + return getStores().groupChartStoreContext; +} diff --git a/frontend/src/js/stores/redux/features/config/index.ts b/frontend/src/stores/redux/features/config/index.ts similarity index 100% rename from frontend/src/js/stores/redux/features/config/index.ts rename to frontend/src/stores/redux/features/config/index.ts diff --git a/frontend/src/js/stores/redux/features/user/index.ts b/frontend/src/stores/redux/features/user/index.ts similarity index 100% rename from frontend/src/js/stores/redux/features/user/index.ts rename to frontend/src/stores/redux/features/user/index.ts diff --git a/frontend/src/js/stores/redux/hooks.ts b/frontend/src/stores/redux/hooks.ts similarity index 100% rename from frontend/src/js/stores/redux/hooks.ts rename to frontend/src/stores/redux/hooks.ts diff --git a/frontend/src/js/stores/redux/store.ts b/frontend/src/stores/redux/store.ts similarity index 100% rename from frontend/src/js/stores/redux/store.ts rename to frontend/src/stores/redux/store.ts diff --git a/frontend/src/storybook.test.js b/frontend/src/storybook.test.js new file mode 100644 index 000000000..e2b9d2422 --- /dev/null +++ b/frontend/src/storybook.test.js @@ -0,0 +1,25 @@ +import initStoryshots, { Stories2SnapsConverter } from '@storybook/addon-storyshots'; +import * as rtl from '@testing-library/react'; +import React from 'react'; + +initStoryshots({ + test: ({ story: { storyFn: Story }, context }) => { + const converter = new Stories2SnapsConverter(); + const snapshotFilename = converter.getSnapshotFileName(context); + const rendered = rtl.render( +
    + +
    + ); + expect(rendered).toMatchSpecificSnapshot(snapshotFilename); + }, + snapshotSerializers: [ + { + print: (val, serialize) => { + const root = val.container.firstChild; + return serialize(root); + }, + test: val => val.hasOwnProperty('container'), + }, + ], +}); diff --git a/frontend/src/js/utils/auth.ts b/frontend/src/utils/auth.ts similarity index 100% rename from frontend/src/js/utils/auth.ts rename to frontend/src/utils/auth.ts diff --git a/frontend/src/js/utils/helpers.ts b/frontend/src/utils/helpers.ts similarity index 93% rename from frontend/src/js/utils/helpers.ts rename to frontend/src/utils/helpers.ts index 39d599ed6..9bd135ec8 100644 --- a/frontend/src/js/utils/helpers.ts +++ b/frontend/src/utils/helpers.ts @@ -91,28 +91,6 @@ export function cleanSemverVersion(version: string) { return shortVersion; } -export function getMinuteDifference(date1: number, date2: number) { - return (date1 - date2) / 1000 / 60; -} - -export function makeLocaleTime( - timestamp: string | Date | number, - opts: { useDate?: boolean; showTime?: boolean; dateFormat?: Intl.DateTimeFormatOptions } = {} -) { - const { useDate = true, showTime = true, dateFormat = {} } = opts; - const date = new Date(timestamp); - const formattedDate = date.toLocaleDateString('default', dateFormat); - const timeFormat = date.toLocaleString('default', { hour: '2-digit', minute: '2-digit' }); - - if (useDate && showTime) { - return `${formattedDate} ${timeFormat}`; - } - if (useDate) { - return formattedDate; - } - return timeFormat; -} - export function makeColorsForVersions( theme: Theme, versions: string[], @@ -265,6 +243,7 @@ export function useGroupVersionBreakdown(group: Group) { API.getGroupVersionBreakdown(group.application_id, group.id) .then(versions => { + console.log('versionBreakdown versions', versions); setVersionBreakdown(versions); }) .catch(err => { diff --git a/frontend/src/js/utils/regex.ts b/frontend/src/utils/regex.ts similarity index 100% rename from frontend/src/js/utils/regex.ts rename to frontend/src/utils/regex.ts