From 79903ff9f5d89c35bf8c097161cf533ae75b69d1 Mon Sep 17 00:00:00 2001 From: Logan Allen Date: Mon, 7 Oct 2019 11:16:47 -0700 Subject: [PATCH] chat: changed wire format and quitting subscription properly on ban --- pkg/arvo/app/chat-hook.hoon | 228 +++++++++--------- pkg/arvo/app/chat-store.hoon | 78 +++--- pkg/arvo/app/chat-view.hoon | 17 +- pkg/arvo/app/chat/js/index.js | 2 +- pkg/arvo/app/group-hook.hoon | 80 +++--- pkg/arvo/app/group-store.hoon | 11 +- pkg/arvo/app/permission-group-hook.hoon | 10 +- pkg/arvo/app/permission-store.hoon | 10 +- pkg/arvo/lib/chat-json.hoon | 11 +- pkg/arvo/sur/chat-hook.hoon | 8 +- pkg/arvo/sur/chat-store.hoon | 5 +- pkg/arvo/sur/chat-view.hoon | 8 +- pkg/interface/chat/src/js/components/chat.js | 14 +- pkg/interface/chat/src/js/components/join.js | 4 +- .../src/js/components/lib/sidebar-item.js | 2 +- .../chat/src/js/components/member.js | 23 +- pkg/interface/chat/src/js/components/new.js | 2 +- pkg/interface/chat/src/js/components/root.js | 21 +- .../chat/src/js/components/settings.js | 9 +- .../chat/src/js/components/sidebar.js | 2 +- .../chat/src/js/reducers/chat-update.js | 3 +- 21 files changed, 257 insertions(+), 291 deletions(-) diff --git a/pkg/arvo/app/chat-hook.hoon b/pkg/arvo/app/chat-hook.hoon index b4810ef97..76c68d6dd 100644 --- a/pkg/arvo/app/chat-hook.hoon +++ b/pkg/arvo/app/chat-hook.hoon @@ -39,13 +39,15 @@ |= old=(unit state) ^- (quip move _this) ?~ old - [~ this] + :_ this + [ost.bol %peer /permissions [our.bol %permission-store] /updates]~ [~ this(+<+ u.old)] :: ++ poke-noun |= a=* ^- (quip move _this) ~& synced + ~& boned [~ this] :: ++ poke-json @@ -58,25 +60,25 @@ ^- (quip move _this) ?> ?=(%message -.act) :: local + :_ this ?: (team:title our.bol src.bol) ?. (~(has by synced) path.act) - [~ this] + ~ =/ ship (~(got by synced) path.act) =/ appl ?:(=(ship our.bol) %chat-store %chat-hook) - :_ this [ost.bol %poke / [ship appl] [%chat-action act]]~ :: foreign =/ ship (~(get by synced) path.act) ?~ ship - [~ this] - :_ this + ~ ?. =(u.ship our.bol) ~ :: scry permissions to check if write is permitted ?. (permitted-scry [(scot %p src.bol) %chat (weld path.act /write)]) ~ - =. author.envelope.act src.bol - =. when.envelope.act now.bol + =: author.envelope.act src.bol + when.envelope.act now.bol + == [ost.bol %poke / [our.bol %chat-store] [%chat-action act]]~ :: ++ poke-chat-hook-action @@ -86,24 +88,22 @@ %add-owned ?> (team:title our.bol src.bol) =/ chat-path [%mailbox path.act] - =/ chat-wire [(scot %p our.bol) chat-path] ?: (~(has by synced) path.act) [~ this] =. synced (~(put by synced) path.act our.bol) - :_ (track-bone chat-wire) + :_ (track-bone chat-path) %+ weld - [ost.bol %peer chat-wire [our.bol %chat-store] chat-path]~ + [ost.bol %peer chat-path [our.bol %chat-store] chat-path]~ (create-permission [%chat path.act] security.act) :: %add-synced ?> (team:title our.bol src.bol) - =/ chat-path [%mailbox path.act] - =/ chat-wire [(scot %p ship.act) chat-path] - ?: (~(has by synced) path.act) + =/ chat-path [%mailbox (scot %p ship.act) path.act] + ?: (~(has by synced) [(scot %p ship.act) path.act]) [~ this] - =. synced (~(put by synced) path.act ship.act) - :_ (track-bone chat-wire) - [ost.bol %peer chat-wire [ship.act %chat-hook] chat-path]~ + =. synced (~(put by synced) [(scot %p ship.act) path.act] ship.act) + :_ (track-bone chat-path) + [ost.bol %peer chat-path [ship.act %chat-hook] chat-path]~ :: %remove =/ ship (~(get by synced) path.act) @@ -111,14 +111,12 @@ [~ this] ?: &(=(u.ship our.bol) (team:title our.bol src.bol)) :: delete one of our.bol own paths - =/ chat-wire [(scot %p our.bol) %mailbox path.act] - :_ - %_ this - synced (~(del by synced) path.act) - boned (~(del by boned) chat-wire) - == + :_ %_ this + synced (~(del by synced) path.act) + boned (~(del by boned) [%mailbox path.act]) + == %- zing - :~ (pull-wire chat-wire path.act) + :~ (pull-wire [%mailbox path.act]) (delete-permission [%chat path.act]) ^- (list move) %+ turn (prey:pubsub:userlib [%mailbox path.act] bol) @@ -126,32 +124,63 @@ ^- move [bone %quit ~] == - ?: |(=(u.ship src.bol) (team:title our.bol src.bol)) - :: delete a foreign ship's path - =/ chat-wire [(scot %p u.ship) %mailbox path.act] - :_ - %_ this - synced (~(del by synced) path.act) - boned (~(del by boned) chat-wire) - == - (pull-wire chat-wire path.act) - :: don't allow - [~ this] - :: + ?. |(=(u.ship src.bol) (team:title our.bol src.bol)) + :: if neither ship = source or source = us, do nothing + [~ this] + :: delete a foreign ship's path + :- (pull-wire [%mailbox path.act]) + %_ this + synced (~(del by synced) path.act) + boned (~(del by boned) [%mailbox path.act]) + == == :: ++ peer-mailbox |= pax=path ^- (quip move _this) - ?~ pax !! - ?. (~(has by synced) pax) !! + ?> ?=([* ^] pax) + ?> (~(has by synced) pax) :: scry permissions to check if read is permitted - ?. (permitted-scry [(scot %p src.bol) %chat (weld pax /read)]) - !! - =/ box=(unit mailbox) (chat-scry pax) + ?> (permitted-scry [(scot %p src.bol) %chat (weld pax /read)]) + =/ box (chat-scry pax) ?~ box !! :_ this - [ost.bol %diff [%chat-update [%create pax owner.config.u.box]]]~ + [ost.bol %diff %chat-update [%create (slav %p i.pax) pax]]~ +:: +++ diff-permission-update + |= [wir=wire diff=permission-update] + ^- (quip move _this) + :_ this + ?- -.diff + %create ~ + %delete ~ + %add (handle-permissions [%add path.diff who.diff]) + %remove (handle-permissions [%remove path.diff who.diff]) + == +:: +++ handle-permissions + |= [kind=?(%add %remove) pax=path who=(set ship)] + ^- (list move) + ?> ?=([* *] pax) + ?. =(%chat i.pax) ~ + :: check path to see if this is a %read permission + ?. =(%read (snag (dec (lent pax)) `(list @t)`pax)) + ~ + =/ sup + %- ~(gas by *(map [ship path] bone)) + %+ turn ~(tap by sup.bol) + |=([=bone anchor=[ship path]] [anchor bone]) + %- zing + %+ turn ~(tap in who) + |= check-ship=ship + ?: (permitted-scry [(scot %p check-ship) pax]) + :: if ship is permitted to be subscribed, do nothing + ~ + :: if ship is not permitted, quit their subscription + =/ mail-path + (oust [(dec (lent t.pax)) (lent t.pax)] `(list @t)`t.pax) + =/ bne (~(get by sup) [check-ship [%mailbox mail-path]]) + ?~(bne ~ [u.bne %quit ~]~) :: ++ diff-chat-update |= [wir=wire diff=chat-update] @@ -164,25 +193,16 @@ |= diff=chat-update ^- (quip move _this) ?- -.diff - %keys - [~ this] - :: - %config - [~ this] - :: - %create - [~ this] - :: - %read - [~ this] - :: + %keys [~ this] + %config [~ this] + %create [~ this] + %read [~ this] %delete ?. (~(has by synced) path.diff) [~ this] - =/ chat-wire [(scot %p our.bol) %mailbox path.diff] :_ this(synced (~(del by synced) path.diff)) :- (chat-poke diff) - [ost.bol %pull chat-wire [our.bol %chat-store] ~]~ + [ost.bol %pull [%mailbox path.diff] [our.bol %chat-store] ~]~ :: %message :_ this @@ -190,86 +210,66 @@ |= [=bone *] ^- move [bone %diff [%chat-update diff]] - :: == :: ++ handle-foreign |= diff=chat-update ^- (quip move _this) ?- -.diff - %keys - [~ this] - :: - %config - [~ this] - :: - %read - [~ this] - :: + %keys [~ this] + %config [~ this] + %read [~ this] %create - :: send a create poke to local chat - ?~ path.diff - [~ this] - =/ shp (~(get by synced) path.diff) - ?~ shp - [~ this] - ?. (team:title u.shp src.bol) - [~ this] :_ this - :~ (chat-poke diff) - == + ?> ?=([* ^] path.diff) + =/ shp (~(get by synced) path.diff) + ?~ shp ~ + ?. =(src.bol u.shp) ~ + [(chat-poke [%create ship.diff t.path.diff])]~ :: %delete - :: send a delete poke to local chat - ?~ path.diff - [~ this] + ?> ?=([* ^] path.diff) =/ shp (~(get by synced) path.diff) ?~ shp [~ this] - ?. (team:title u.shp src.bol) + ?. =(u.shp src.bol) [~ this] - =/ chat-wire [(scot %p src.bol) %mailbox path.diff] :_ this(synced (~(del by synced) path.diff)) :- (chat-poke diff) - [ost.bol %pull chat-wire [src.bol %chat-hook] ~]~ + [ost.bol %pull [%mailbox path.diff] [src.bol %chat-hook] ~]~ :: %message - ?~ path.diff - [~ this] - =/ sync (~(get by synced) path.diff) - ?~ sync - [~ this] - ?. =(src.bol u.sync) - [~ this] :_ this - :~ (chat-poke diff) - == - :: + ?> ?=([* ^] path.diff) + =/ shp (~(get by synced) path.diff) + ?~ shp ~ + ?. =(src.bol u.shp) ~ + [(chat-poke diff)]~ == :: ++ quit |= wir=wire ^- (quip move _this) - =^ =ship wir - ?> ?=([* ^] wir) - [(slav %p i.wir) t.t.wir] - ?. (~(has by synced) wir) + ~& chat-hook-quit+wir + ?: =(wir /permissions) + :_ this + [ost.bol %peer /permissions [our.bol %permission-store] /updates]~ + ?> ?=([* ^] wir) + ?. (~(has by synced) t.wir) :: no-op [~ this] - =/ chat-path [%mailbox wir] - =/ chat-wire [(scot %p ship) chat-path] - :_ (track-bone chat-wire) - [ost.bol %peer chat-wire [ship %chat-hook] chat-path]~ + ~& %chat-hook-resubscribe + :_ (track-bone wir) + [ost.bol %peer wir [(slav %p i.t.wir) %chat-hook] wir]~ :: ++ reap |= [wir=wire saw=(unit tang)] ^- (quip move _this) ?~ saw [~ this] - =^ =ship wir - ?> ?=([* ^] wir) - [(slav %p i.wir) t.t.wir] - [~ this(synced (~(del by synced) wir))] + ?> ?=(^ wir) + ~& %chat-hook-reap + [((slog u.saw) ~) this(synced (~(del by synced) t.wir))] :: ++ chat-poke |= act=chat-action @@ -306,7 +306,6 @@ :~ (permission-poke (sec-to-perm read-perm %white)) (permission-poke (sec-to-perm write-perm %black)) == - :: == :: ++ delete-permission @@ -326,7 +325,7 @@ ++ chat-scry |= pax=path ^- (unit mailbox) - =. pax ;:(weld /=chat-store/(scot %da now.bol)/mailbox pax /noun) + =. pax ;:(weld /=chat-store/(scot %da now.bol)/mailbox pax /noun) .^((unit mailbox) %gx pax) :: ++ permitted-scry @@ -343,19 +342,18 @@ this(boned (~(put by boned) wir [ost.bol]~)) :: ++ pull-wire - |= [wir=wire pax=path] + |= pax=path ^- (list move) - =/ bnd (~(get by boned) wir) - ?~ bnd - ~ - =/ shp (~(get by synced) pax) - ?~ shp - ~ + ?> ?=([* ^] pax) + =/ bnd (~(get by boned) pax) + ?~ bnd ~ + =/ shp (~(get by synced) t.pax) + ?~ shp ~ %+ turn u.bnd - |= ost=bone + |= =bone ^- move ?: =(u.shp our.bol) - [ost %pull wir [our.bol %chat-store] ~] - [ost %pull wir [u.shp %chat-hook] ~] + [bone %pull pax [our.bol %chat-store] ~] + [bone %pull pax [u.shp %chat-hook] ~] :: -- diff --git a/pkg/arvo/app/chat-store.hoon b/pkg/arvo/app/chat-store.hoon index bb3f5f5ca..064616e8d 100644 --- a/pkg/arvo/app/chat-store.hoon +++ b/pkg/arvo/app/chat-store.hoon @@ -31,9 +31,7 @@ ++ prep |= old=(unit state) ^- (quip move _this) - ?~ old - [~ this] - [~ this(+<+ u.old)] + [~ ?~(old this this(+<+ u.old))] :: ++ peek-x-all |= pax=path @@ -54,28 +52,23 @@ ++ peek-x-mailbox |= pax=path ^- (unit (unit [%noun (unit mailbox)])) - ?~ pax - ~ + ?~ pax ~ =/ mailbox=(unit mailbox) (~(get by inbox) pax) [~ ~ %noun mailbox] :: ++ peek-x-config |= pax=path ^- (unit (unit [%noun config])) - ?~ pax - ~ + ?~ pax ~ =/ mailbox (~(get by inbox) pax) - ?~ mailbox - ~ + ?~ mailbox ~ :^ ~ ~ %noun config.u.mailbox :: ++ peek-x-envelopes |= pax=path ^- (unit (unit [%noun (list envelope)])) - ?+ pax - ~ - :: + ?+ pax ~ [@ @ *] =/ mail-path t.t.pax =/ mailbox (~(get by inbox) mail-path) @@ -143,10 +136,18 @@ |= pax=path ^- (quip move _this) ?> (team:title our.bol src.bol) - =/ box=(unit mailbox) (~(get by inbox) pax) - ?~ box !! - :_ this - [ost.bol %diff %chat-update [%create pax owner.config.u.box]]~ + ?> (~(has by inbox) pax) + =^ =ship pax + ?> ?=([* ^] pax) + [(slav %p i.pax) t.pax] + :_ this + [ost.bol %diff %chat-update [%create ship pax]]~ +:: +++ poke-noun + |= a=* + ^- (quip move _this) + ~& inbox + [~ this] :: ++ poke-json |= jon=json @@ -159,31 +160,21 @@ ^- (quip move _this) ?> (team:title our.bol src.bol) ?- -.action - %create - (handle-create action) - :: - %delete - (handle-delete action) - :: - %message - (handle-message action) - :: - %read - (handle-read action) - :: + %create (handle-create action) + %delete (handle-delete action) + %message (handle-message action) + %read (handle-read action) == :: ++ handle-create |= act=chat-action ^- (quip move _this) ?> ?=(%create -.act) - ?: (~(has by inbox) path.act) + =/ pax [(scot %p ship.act) path.act] + ?: (~(has by inbox) pax) [~ this] - =/ mailbox *mailbox - =. owner.config.mailbox owner.act - =. inbox (~(put by inbox) path.act mailbox) - :_ this(inbox inbox) - (send-diff path.act act) + :- (send-diff pax act) + this(inbox (~(put by inbox) pax *mailbox)) :: ++ handle-delete |= act=chat-action @@ -192,9 +183,8 @@ =/ mailbox=(unit mailbox) (~(get by inbox) path.act) ?~ mailbox [~ this] - =. inbox (~(del by inbox) path.act) - :_ this(inbox inbox) - (send-diff path.act act) + :- (send-diff path.act act) + this(inbox (~(del by inbox) path.act)) :: ++ handle-message |= act=chat-action @@ -203,10 +193,11 @@ =/ mailbox=(unit mailbox) (~(get by inbox) path.act) ?~ mailbox [~ this] - =. length.config.u.mailbox +(length.config.u.mailbox) - =. number.envelope.act length.config.u.mailbox - =. envelopes.u.mailbox (snoc envelopes.u.mailbox envelope.act) - =. inbox (~(put by inbox) path.act u.mailbox) + =: length.config.u.mailbox +(length.config.u.mailbox) + number.envelope.act length.config.u.mailbox + envelopes.u.mailbox (snoc envelopes.u.mailbox envelope.act) + inbox (~(put by inbox) path.act u.mailbox) + == :_ this(inbox inbox) (send-diff path.act act) :: @@ -217,8 +208,9 @@ =/ mailbox=(unit mailbox) (~(get by inbox) path.act) ?~ mailbox [~ this] - =. read.config.u.mailbox length.config.u.mailbox - =. inbox (~(put by inbox) path.act u.mailbox) + =: read.config.u.mailbox length.config.u.mailbox + inbox (~(put by inbox) path.act u.mailbox) + == :_ this(inbox inbox) (send-diff path.act act) :: diff --git a/pkg/arvo/app/chat-view.hoon b/pkg/arvo/app/chat-view.hoon index fe0ba1be7..cbd58f7e4 100644 --- a/pkg/arvo/app/chat-view.hoon +++ b/pkg/arvo/app/chat-view.hoon @@ -151,18 +151,19 @@ ?- -.act %create :: TODO: add invites - =/ group-read=path [%chat (weld path.act /read)] - =/ group-write=path [%chat (weld path.act /write)] + =/ pax [(scot %p our.bol) path.act] + =/ group-read=path [%chat (weld pax /read)] + =/ group-write=path [%chat (weld pax /write)] :_ this %+ weld - :~ (chat-poke [%create path.act our.bol]) + :~ (chat-poke [%create our.bol path.act]) (group-poke [%bundle group-read]) (group-poke [%bundle group-write]) (group-poke [%add read.act group-read]) (group-poke [%add write.act group-write]) - (chat-hook-poke [%add-owned path.act security.act]) + (chat-hook-poke [%add-owned pax security.act]) == - (create-security [%chat path.act] security.act) + (create-security [%chat pax] security.act) :: %delete =/ group-read [%chat (weld path.act /read)] @@ -179,7 +180,7 @@ ++ peer-initial |= pax=path ^- (quip move _this) - ?. =(src.bol our.bol) !! + ?> (team:title our.bol src.bol) :: create inbox with 100 messages max per mailbox and send that along :: then quit the subscription :_ this @@ -190,14 +191,14 @@ ++ peer-updates |= pax=path ^- (quip move _this) - ?. =(src.bol our.bol) !! + ?> (team:title our.bol src.bol) :: send along all subsequent updates [~ this] :: ++ peer-configs |= pax=path ^- (quip move _this) - ?. =(src.bol our.bol) !! + ?> (team:title our.bol src.bol) :_ this [ost.bol %diff %json *json]~ :: diff --git a/pkg/arvo/app/chat/js/index.js b/pkg/arvo/app/chat/js/index.js index 735bbef95..4cc580dc0 100644 --- a/pkg/arvo/app/chat/js/index.js +++ b/pkg/arvo/app/chat/js/index.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(require("buffer")):"function"==typeof define&&define.amd?define("index",["buffer"],t):t((e=e||self).buffer)}(this,function(e){"use strict";e=e&&e.hasOwnProperty("default")?e.default:e;var t="undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{},n=t.performance||{},r=(n.now||n.mozNow||n.msNow||n.oNow||n.webkitNow,"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{});function i(){throw new Error("Dynamic requires are not currently supported by rollup-plugin-commonjs")}function a(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function l(e,t){return e(t={exports:{}},t.exports),t.exports}var o=Object.getOwnPropertySymbols,u=Object.prototype.hasOwnProperty,s=Object.prototype.propertyIsEnumerable;var c=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach(function(e){r[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,r,i=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),a=1;a2?n-2:0),i=2;i1?t-1:0),r=1;r2?n-2:0),i=2;i8)throw new Error("warningWithoutStack() currently supports at most 8 arguments.");if(!e){if("undefined"!=typeof console){var a=r.map(function(e){return""+e});a.unshift("Warning: "+t),Function.prototype.apply.call(console.error,console,a)}try{var l=0,o="Warning: "+t.replace(/%s/g,function(){return r[l++]});throw new Error(o)}catch(e){}}},T={};function P(e,t){var n=e.constructor,r=n&&(n.displayName||n.name)||"ReactClass",i=r+"."+t;T[i]||(S(!1,"Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.",t,r),T[i]=!0)}var N={isMounted:function(e){return!1},enqueueForceUpdate:function(e,t,n){P(e,"forceUpdate")},enqueueReplaceState:function(e,t,n,r){P(e,"replaceState")},enqueueSetState:function(e,t,n,r){P(e,"setState")}},R={};function L(e,t,n){this.props=e,this.context=t,this.refs=R,this.updater=n||N}Object.freeze(R),L.prototype.isReactComponent={},L.prototype.setState=function(e,t){!function(){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw M(Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables."))}(),this.updater.enqueueSetState(this,e,t,"setState")},L.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};var O={isMounted:["isMounted","Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks."],replaceState:["replaceState","Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236)."]},D=function(e,t){Object.defineProperty(L.prototype,e,{get:function(){E(!1,"%s(...) is deprecated in plain JavaScript React classes. %s",t[0],t[1])}})};for(var A in O)O.hasOwnProperty(A)&&D(A,O[A]);function I(){}function U(e,t,n){this.props=e,this.context=t,this.refs=R,this.updater=n||N}I.prototype=L.prototype;var j=U.prototype=new I;j.constructor=U,t(j,L.prototype),j.isPureReactComponent=!0;var z={current:null},H={suspense:null},F={current:null},Z=/^(.*)[\\\/]/,V=1;function W(e){if(null==e)return null;if("number"==typeof e.tag&&S(!1,"Received an unexpected object in getComponentName(). This is likely a bug in React. Please file an issue."),"function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case l:return"Fragment";case a:return"Portal";case u:return"Profiler";case o:return"StrictMode";case p:return"Suspense";case m:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case f:return"Context.Consumer";case s:return"Context.Provider";case h:return r=e,i=e.render,c="ForwardRef",d=i.displayName||i.name||"",r.displayName||(""!==d?c+"("+d+")":c);case v:return W(e.type);case b:var t=(n=e)._status===V?n._result:null;if(t)return W(t)}var n,r,i,c,d;return null}var q={},Y=null;function B(e){Y=e}q.getCurrentStack=null,q.getStackAddendum=function(){var e="";if(Y){var t=W(Y.type),n=Y._owner;e+=function(e,t,n){var r="";if(t){var i=t.fileName,a=i.replace(Z,"");if(/^index\./.test(a)){var l=i.match(Z);if(l){var o=l[1];o&&(a=o.replace(Z,"")+"/"+a)}}r=" (at "+a+":"+t.lineNumber+")"}else n&&(r=" (created by "+n+")");return"\n in "+(e||"Unknown")+r}(t,Y._source,n&&W(n.type))}var r=q.getCurrentStack;return r&&(e+=r()||""),e};var $={ReactCurrentDispatcher:z,ReactCurrentBatchConfig:H,ReactCurrentOwner:F,IsSomeRendererActing:{current:!1},assign:t};t($,{ReactDebugCurrentFrame:q,ReactComponentTreeHook:{}});var Q,G,K=function(e,t){if(!e){for(var n=$.ReactDebugCurrentFrame.getStackAddendum(),r=arguments.length,i=new Array(r>2?r-2:0),a=2;a1){for(var c=Array(s),f=0;f.")}return t}(t);if(!xe[n]){xe[n]=!0;var r="";e&&e._owner&&e._owner!==F.current&&(r=" It was passed a child from "+W(e._owner.type)+"."),B(e),K(!1,'Each child in a list should have a unique "key" prop.%s%s See https://fb.me/react-warning-keys for more information.',n,r),B(null)}}}function Me(e,t){if("object"==typeof e)if(Array.isArray(e))for(var n=0;n",u=" Did you accidentally export a JSX literal instead of a component?"):s=typeof e,K(!1,"React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s",s,u)}var f=re.apply(this,arguments);if(null==f)return f;if(o)for(var d=2;d is not supported and will be removed in a future major release. Did you mean to render instead?")),n.Provider},set:function(e){n.Provider=e}},_currentValue:{get:function(){return n._currentValue},set:function(e){n._currentValue=e}},_currentValue2:{get:function(){return n._currentValue2},set:function(e){n._currentValue2=e}},_threadCount:{get:function(){return n._threadCount},set:function(e){n._threadCount=e}},Consumer:{get:function(){return r||(r=!0,K(!1,"Rendering is not supported and will be removed in a future major release. Did you mean to render instead?")),n.Consumer}}}),n.Consumer=a,n._currentRenderer=null,n._currentRenderer2=null,n},forwardRef:function(e){return null!=e&&e.$$typeof===v?S(!1,"forwardRef requires a render function but received a `memo` component. Instead of forwardRef(memo(...)), use memo(forwardRef(...))."):"function"!=typeof e?S(!1,"forwardRef requires a render function but was given %s.",null===e?"null":typeof e):0!==e.length&&2!==e.length&&S(!1,"forwardRef render functions accept exactly two parameters: props and ref. %s",1===e.length?"Did you forget to use the ref parameter?":"Any additional parameter will be undefined."),null!=e&&(null!=e.defaultProps||null!=e.propTypes)&&S(!1,"forwardRef render functions do not support propTypes or defaultProps. Did you accidentally pass a React component?"),{$$typeof:h,render:e}},lazy:function(e){var t,n,r={$$typeof:b,_ctor:e,_status:-1,_result:null};return Object.defineProperties(r,{defaultProps:{configurable:!0,get:function(){return t},set:function(e){K(!1,"React.lazy(...): It is not supported to assign `defaultProps` to a lazy component import. Either specify them where the component is defined, or create a wrapping component around it."),t=e,Object.defineProperty(r,"defaultProps",{enumerable:!0})}},propTypes:{configurable:!0,get:function(){return n},set:function(e){K(!1,"React.lazy(...): It is not supported to assign `propTypes` to a lazy component import. Either specify them where the component is defined, or create a wrapping component around it."),n=e,Object.defineProperty(r,"propTypes",{enumerable:!0})}}}),r},memo:function(e,t){return ke(e)||S(!1,"memo: The first argument must be a component. Instead received: %s",null===e?"null":typeof e),{$$typeof:v,type:e,compare:void 0===t?null:t}},useCallback:function(e,t){return we().useCallback(e,t)},useContext:function(e,t){var n=we();if(void 0!==t&&K(!1,"useContext() second argument is reserved for future use in React. Passing it is not supported. You passed: %s.%s",t,"number"==typeof t&&Array.isArray(arguments[2])?"\n\nDid you call array.map(useContext)? Calling Hooks inside a loop is not supported. Learn more at https://fb.me/rules-of-hooks":""),void 0!==e._context){var r=e._context;r.Consumer===e?K(!1,"Calling useContext(Context.Consumer) is not supported, may cause bugs, and will be removed in a future major release. Did you mean to call useContext(Context) instead?"):r.Provider===e&&K(!1,"Calling useContext(Context.Provider) is not supported. Did you mean to call useContext(Context) instead?")}return n.useContext(e,t)},useEffect:function(e,t){return we().useEffect(e,t)},useImperativeHandle:function(e,t,n){return we().useImperativeHandle(e,t,n)},useDebugValue:function(e,t){return we().useDebugValue(e,t)},useLayoutEffect:function(e,t){return we().useLayoutEffect(e,t)},useMemo:function(e,t){return we().useMemo(e,t)},useReducer:function(e,t,n){return we().useReducer(e,t,n)},useRef:function(e){return we().useRef(e)},useState:function(e){return we().useState(e)},Fragment:l,Profiler:u,StrictMode:o,Suspense:p,unstable_SuspenseList:m,createElement:Se,cloneElement:function(e,n,r){for(var i=function(e,n,r){var i;!function(){if(null==e)throw M(Error("React.cloneElement(...): The argument must be a React element, but you passed "+e+"."))}();var a,l=t({},e.props),o=e.key,u=e.ref,s=e._self,c=e._source,f=e._owner;if(null!=n)for(i in ee(n)&&(u=n.ref,f=F.current),te(n)&&(o=""+n.key),e.type&&e.type.defaultProps&&(a=e.type.defaultProps),n)X.call(n,i)&&!J.hasOwnProperty(i)&&(void 0===n[i]&&void 0!==a?l[i]=a[i]:l[i]=n[i]);var d=arguments.length-2;if(1===d)l.children=r;else if(d>1){for(var h=Array(d),p=0;p=_},l=function(){},t.unstable_forceFrameRate=function(e){0>e||125T(l,n))void 0!==u&&0>T(u,l)?(e[r]=u,e[o]=n,r=o):(e[r]=l,e[a]=n,r=a);else{if(!(void 0!==u&&0>T(u,n)))break e;e[r]=u,e[o]=n,r=o}}}return t}return null}function T(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var P=[],N=[],R=1,L=null,O=3,D=!1,A=!1,I=!1;function U(e){for(var t=E(N);null!==t;){if(null===t.callback)S(N);else{if(!(t.startTime<=e))break;S(N),t.sortIndex=t.expirationTime,M(P,t)}t=E(N)}}function j(e){if(I=!1,U(e),!A)if(null!==E(P))A=!0,n(z);else{var t=E(N);null!==t&&r(j,t.startTime-e)}}function z(e,n){A=!1,I&&(I=!1,i()),D=!0;var l=O;try{for(U(n),L=E(P);null!==L&&(!(L.expirationTime>n)||e&&!a());){var o=L.callback;if(null!==o){L.callback=null,O=L.priorityLevel;var u=o(L.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?L.callback=u:L===E(P)&&S(P),U(n)}else S(P);L=E(P)}if(null!==L)var s=!0;else{var c=E(N);null!==c&&r(j,c.startTime-n),s=!1}return s}finally{L=null,O=l,D=!1}}function H(e){switch(e){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var F=l;t.unstable_ImmediatePriority=1,t.unstable_UserBlockingPriority=2,t.unstable_NormalPriority=3,t.unstable_IdlePriority=5,t.unstable_LowPriority=4,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=O;O=e;try{return t()}finally{O=n}},t.unstable_next=function(e){switch(O){case 1:case 2:case 3:var t=3;break;default:t=O}var n=O;O=t;try{return e()}finally{O=n}},t.unstable_scheduleCallback=function(e,a,l){var o=t.unstable_now();if("object"==typeof l&&null!==l){var u=l.delay;u="number"==typeof u&&0o?(e.sortIndex=u,M(N,e),null===E(P)&&e===E(N)&&(I?i():I=!0,r(j,u-o))):(e.sortIndex=l,M(P,e),A||D||(A=!0,n(z))),e},t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_wrapCallback=function(e){var t=O;return function(){var n=O;O=t;try{return e.apply(this,arguments)}finally{O=n}}},t.unstable_getCurrentPriorityLevel=function(){return O},t.unstable_shouldYield=function(){var e=t.unstable_now();U(e);var n=E(P);return n!==L&&null!==L&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime=x},a=function(){},t.unstable_forceFrameRate=function(e){e<0||e>125?console.error("forceFrameRate takes a positive int between 0 and 125, forcing framerates higher than 125 fps is not unsupported"):_=e>0?Math.floor(1e3/e):33.33};var C=new MessageChannel,M=C.port2;C.port1.onmessage=function(){if(null!==k){var e=t.unstable_now();x=e+_;try{k(!0,e)?M.postMessage(null):(g=!1,k=null)}catch(e){throw M.postMessage(null),e}}else g=!1},e=function(e){k=e,g||(g=!0,M.postMessage(null))},n=function(e,n){w=p(function(){e(t.unstable_now())},n)},r=function(){m(w),w=-1}}function E(e,t){var n=e.length;e.push(t),function(e,t,n){var r=n;for(;;){var i=Math.floor((r-1)/2),a=e[i];if(!(void 0!==a&&P(a,t)>0))return;e[i]=t,e[r]=a,r=i}}(e,t,n)}function S(e){var t=e[0];return void 0===t?null:t}function T(e){var t=e[0];if(void 0!==t){var n=e.pop();return n!==t&&(e[0]=n,function(e,t,n){var r=n,i=e.length;for(;rY){if((Y*=2)>q)return console.error("Scheduler Profiling: Event log exceeded maximum size. Don't forget to call `stopLoggingProfilingEvents()`."),void ae();var n=new Int32Array(4*Y);n.set($),B=n.buffer,$=n}$.set(e,t)}}function ae(){var e=B;return Y=0,B=null,$=null,Q=0,e}function le(e,t){z[V]++,null!==$&&ie([G,t,e.id,e.priorityLevel])}function oe(e,t){z[H]=N,z[F]=0,z[V]--,null!==$&&ie([K,t,e.id])}function ue(e,t){z[H]=N,z[F]=0,z[Z]=0,null!==$&&ie([te,t,e.id,I])}var se=-1,ce=250,fe=5e3,de=1e4,he=1073741823,pe=[],me=[],ve=1,be=null,ye=O,ge=!1,ke=!1,we=!1;function _e(e){for(var t=S(me);null!==t;){if(null===t.callback)T(me);else{if(!(t.startTime<=e))return;T(me),t.sortIndex=t.expirationTime,E(pe,t),le(t,e),t.isQueued=!0}t=S(me)}}function xe(t){if(we=!1,_e(t),!ke)if(null!==S(pe))ke=!0,e(Ce);else{var r=S(me);null!==r&&n(xe,r.startTime-t)}}function Ce(e,n){var i;i=n,null!==$&&ie([re,i,U]),ke=!1,we&&(we=!1,r()),ge=!0;var a=ye;try{if(!o)return Me(e,n);try{return Me(e,n)}catch(e){if(null!==be){var l=t.unstable_now();!function(e,t){z[H]=N,z[F]=0,z[V]--,null!==$&&ie([X,t,e.id])}(be,l),be.isQueued=!1}throw e}}finally{be=null,ye=a,ge=!1,function(e){U++,null!==$&&ie([ne,e,U])}(t.unstable_now())}}function Me(e,r){var a,o,u=r;for(_e(u),be=S(pe);null!==be&&!l&&(!(be.expirationTime>u)||e&&!i());){var s=be.callback;if(null!==s){be.callback=null,ye=be.priorityLevel;var c=be.expirationTime<=u;a=be,o=u,I++,z[H]=a.priorityLevel,z[F]=a.id,z[Z]=I,null!==$&&ie([ee,o,a.id,I]);var f=s(c);u=t.unstable_now(),"function"==typeof f?(be.callback=f,ue(be,u)):(oe(be,u),be.isQueued=!1,be===S(pe)&&T(pe)),_e(u)}else T(pe);be=S(pe)}if(null!==be)return!0;var d=S(me);return null!==d&&n(xe,d.startTime-u),!1}function Ee(e){switch(e){case R:return se;case L:return ce;case A:return he;case D:return de;case O:default:return fe}}var Se=a,Te={startLoggingProfilingEvents:function(){Y=W,B=new ArrayBuffer(4*Y),$=new Int32Array(B),Q=0},stopLoggingProfilingEvents:ae,sharedProfilingBuffer:j};t.unstable_ImmediatePriority=R,t.unstable_UserBlockingPriority=L,t.unstable_NormalPriority=O,t.unstable_IdlePriority=A,t.unstable_LowPriority=D,t.unstable_runWithPriority=function(e,t){switch(e){case R:case L:case O:case D:case A:break;default:e=O}var n=ye;ye=e;try{return t()}finally{ye=n}},t.unstable_next=function(e){var t;switch(ye){case R:case L:case O:t=O;break;default:t=ye}var n=ye;ye=t;try{return e()}finally{ye=n}},t.unstable_scheduleCallback=function(i,a,l){var o,u,s=t.unstable_now();if("object"==typeof l&&null!==l){var c=l.delay;o="number"==typeof c&&c>0?s+c:s,u="number"==typeof l.timeout?l.timeout:Ee(i)}else u=Ee(i),o=s;var f=o+u,d={id:ve++,callback:a,priorityLevel:i,startTime:o,expirationTime:f,sortIndex:-1,isQueued:!1};return o>s?(d.sortIndex=o,E(me,d),null===S(pe)&&d===S(me)&&(we?r():we=!0,n(xe,o-s))):(d.sortIndex=f,E(pe,d),le(d,s),d.isQueued=!0,ke||ge||(ke=!0,e(Ce))),d},t.unstable_cancelCallback=function(e){e.isQueued&&(function(e,t){z[V]--,null!==$&&ie([J,t,e.id])}(e,t.unstable_now()),e.isQueued=!1),e.callback=null},t.unstable_wrapCallback=function(e){var t=ye;return function(){var n=ye;ye=t;try{return e.apply(this,arguments)}finally{ye=n}}},t.unstable_getCurrentPriorityLevel=function(){return ye},t.unstable_shouldYield=function(){var e=t.unstable_now();_e(e);var n=S(pe);return n!==be&&null!==be&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime