im-browser.js 797 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  3. typeof define === 'function' && define.amd ? define('leancloud-realtime', ['exports'], factory) :
  4. (global = global || self, factory(global.AV = global.AV || {}));
  5. }(this, (function (exports) { 'use strict';
  6. var define = undefined;
  7. var require = require || function(id) {throw new Error('Unexpected required ' + id)};
  8. var process = (typeof window !== 'undefined' && window.process) || {};
  9. process.env = process.env || {};
  10. var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
  11. function unwrapExports (x) {
  12. return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
  13. }
  14. function createCommonjsModule(fn, basedir, module) {
  15. return module = {
  16. path: basedir,
  17. exports: {},
  18. require: function (path, base) {
  19. return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
  20. }
  21. }, fn(module, module.exports), module.exports;
  22. }
  23. function getCjsExportFromNamespace (n) {
  24. return n && n['default'] || n;
  25. }
  26. function commonjsRequire () {
  27. throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
  28. }
  29. var componentEmitter = createCommonjsModule(function (module) {
  30. /**
  31. * Expose `Emitter`.
  32. */
  33. {
  34. module.exports = Emitter;
  35. }
  36. /**
  37. * Initialize a new `Emitter`.
  38. *
  39. * @api public
  40. */
  41. function Emitter(obj) {
  42. if (obj) return mixin(obj);
  43. }
  44. /**
  45. * Mixin the emitter properties.
  46. *
  47. * @param {Object} obj
  48. * @return {Object}
  49. * @api private
  50. */
  51. function mixin(obj) {
  52. for (var key in Emitter.prototype) {
  53. obj[key] = Emitter.prototype[key];
  54. }
  55. return obj;
  56. }
  57. /**
  58. * Listen on the given `event` with `fn`.
  59. *
  60. * @param {String} event
  61. * @param {Function} fn
  62. * @return {Emitter}
  63. * @api public
  64. */
  65. Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) {
  66. this._callbacks = this._callbacks || {};
  67. (this._callbacks['$' + event] = this._callbacks['$' + event] || []).push(fn);
  68. return this;
  69. };
  70. /**
  71. * Adds an `event` listener that will be invoked a single
  72. * time then automatically removed.
  73. *
  74. * @param {String} event
  75. * @param {Function} fn
  76. * @return {Emitter}
  77. * @api public
  78. */
  79. Emitter.prototype.once = function (event, fn) {
  80. function on() {
  81. this.off(event, on);
  82. fn.apply(this, arguments);
  83. }
  84. on.fn = fn;
  85. this.on(event, on);
  86. return this;
  87. };
  88. /**
  89. * Remove the given callback for `event` or all
  90. * registered callbacks.
  91. *
  92. * @param {String} event
  93. * @param {Function} fn
  94. * @return {Emitter}
  95. * @api public
  96. */
  97. Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) {
  98. this._callbacks = this._callbacks || {}; // all
  99. if (0 == arguments.length) {
  100. this._callbacks = {};
  101. return this;
  102. } // specific event
  103. var callbacks = this._callbacks['$' + event];
  104. if (!callbacks) return this; // remove all handlers
  105. if (1 == arguments.length) {
  106. delete this._callbacks['$' + event];
  107. return this;
  108. } // remove specific handler
  109. var cb;
  110. for (var i = 0; i < callbacks.length; i++) {
  111. cb = callbacks[i];
  112. if (cb === fn || cb.fn === fn) {
  113. callbacks.splice(i, 1);
  114. break;
  115. }
  116. } // Remove event specific arrays for event types that no
  117. // one is subscribed for to avoid memory leak.
  118. if (callbacks.length === 0) {
  119. delete this._callbacks['$' + event];
  120. }
  121. return this;
  122. };
  123. /**
  124. * Emit `event` with the given args.
  125. *
  126. * @param {String} event
  127. * @param {Mixed} ...
  128. * @return {Emitter}
  129. */
  130. Emitter.prototype.emit = function (event) {
  131. this._callbacks = this._callbacks || {};
  132. var args = new Array(arguments.length - 1),
  133. callbacks = this._callbacks['$' + event];
  134. for (var i = 1; i < arguments.length; i++) {
  135. args[i - 1] = arguments[i];
  136. }
  137. if (callbacks) {
  138. callbacks = callbacks.slice(0);
  139. for (var i = 0, len = callbacks.length; i < len; ++i) {
  140. callbacks[i].apply(this, args);
  141. }
  142. }
  143. return this;
  144. };
  145. /**
  146. * Return array of callbacks for `event`.
  147. *
  148. * @param {String} event
  149. * @return {Array}
  150. * @api public
  151. */
  152. Emitter.prototype.listeners = function (event) {
  153. this._callbacks = this._callbacks || {};
  154. return this._callbacks['$' + event] || [];
  155. };
  156. /**
  157. * Check if this emitter has `event` handlers.
  158. *
  159. * @param {String} event
  160. * @return {Boolean}
  161. * @api public
  162. */
  163. Emitter.prototype.hasListeners = function (event) {
  164. return !!this.listeners(event).length;
  165. };
  166. });
  167. var fastSafeStringify = stringify;
  168. stringify.default = stringify;
  169. stringify.stable = deterministicStringify;
  170. stringify.stableStringify = deterministicStringify;
  171. var arr = [];
  172. var replacerStack = [];
  173. // Regular stringify
  174. function stringify (obj, replacer, spacer) {
  175. decirc(obj, '', [], undefined);
  176. var res;
  177. if (replacerStack.length === 0) {
  178. res = JSON.stringify(obj, replacer, spacer);
  179. } else {
  180. res = JSON.stringify(obj, replaceGetterValues(replacer), spacer);
  181. }
  182. while (arr.length !== 0) {
  183. var part = arr.pop();
  184. if (part.length === 4) {
  185. Object.defineProperty(part[0], part[1], part[3]);
  186. } else {
  187. part[0][part[1]] = part[2];
  188. }
  189. }
  190. return res
  191. }
  192. function decirc (val, k, stack, parent) {
  193. var i;
  194. if (typeof val === 'object' && val !== null) {
  195. for (i = 0; i < stack.length; i++) {
  196. if (stack[i] === val) {
  197. var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k);
  198. if (propertyDescriptor.get !== undefined) {
  199. if (propertyDescriptor.configurable) {
  200. Object.defineProperty(parent, k, { value: '[Circular]' });
  201. arr.push([parent, k, val, propertyDescriptor]);
  202. } else {
  203. replacerStack.push([val, k]);
  204. }
  205. } else {
  206. parent[k] = '[Circular]';
  207. arr.push([parent, k, val]);
  208. }
  209. return
  210. }
  211. }
  212. stack.push(val);
  213. // Optimize for Arrays. Big arrays could kill the performance otherwise!
  214. if (Array.isArray(val)) {
  215. for (i = 0; i < val.length; i++) {
  216. decirc(val[i], i, stack, val);
  217. }
  218. } else {
  219. var keys = Object.keys(val);
  220. for (i = 0; i < keys.length; i++) {
  221. var key = keys[i];
  222. decirc(val[key], key, stack, val);
  223. }
  224. }
  225. stack.pop();
  226. }
  227. }
  228. // Stable-stringify
  229. function compareFunction (a, b) {
  230. if (a < b) {
  231. return -1
  232. }
  233. if (a > b) {
  234. return 1
  235. }
  236. return 0
  237. }
  238. function deterministicStringify (obj, replacer, spacer) {
  239. var tmp = deterministicDecirc(obj, '', [], undefined) || obj;
  240. var res;
  241. if (replacerStack.length === 0) {
  242. res = JSON.stringify(tmp, replacer, spacer);
  243. } else {
  244. res = JSON.stringify(tmp, replaceGetterValues(replacer), spacer);
  245. }
  246. while (arr.length !== 0) {
  247. var part = arr.pop();
  248. if (part.length === 4) {
  249. Object.defineProperty(part[0], part[1], part[3]);
  250. } else {
  251. part[0][part[1]] = part[2];
  252. }
  253. }
  254. return res
  255. }
  256. function deterministicDecirc (val, k, stack, parent) {
  257. var i;
  258. if (typeof val === 'object' && val !== null) {
  259. for (i = 0; i < stack.length; i++) {
  260. if (stack[i] === val) {
  261. var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k);
  262. if (propertyDescriptor.get !== undefined) {
  263. if (propertyDescriptor.configurable) {
  264. Object.defineProperty(parent, k, { value: '[Circular]' });
  265. arr.push([parent, k, val, propertyDescriptor]);
  266. } else {
  267. replacerStack.push([val, k]);
  268. }
  269. } else {
  270. parent[k] = '[Circular]';
  271. arr.push([parent, k, val]);
  272. }
  273. return
  274. }
  275. }
  276. if (typeof val.toJSON === 'function') {
  277. return
  278. }
  279. stack.push(val);
  280. // Optimize for Arrays. Big arrays could kill the performance otherwise!
  281. if (Array.isArray(val)) {
  282. for (i = 0; i < val.length; i++) {
  283. deterministicDecirc(val[i], i, stack, val);
  284. }
  285. } else {
  286. // Create a temporary object in the required way
  287. var tmp = {};
  288. var keys = Object.keys(val).sort(compareFunction);
  289. for (i = 0; i < keys.length; i++) {
  290. var key = keys[i];
  291. deterministicDecirc(val[key], key, stack, val);
  292. tmp[key] = val[key];
  293. }
  294. if (parent !== undefined) {
  295. arr.push([parent, k, val]);
  296. parent[k] = tmp;
  297. } else {
  298. return tmp
  299. }
  300. }
  301. stack.pop();
  302. }
  303. }
  304. // wraps replacer function to handle values we couldn't replace
  305. // and mark them as [Circular]
  306. function replaceGetterValues (replacer) {
  307. replacer = replacer !== undefined ? replacer : function (k, v) { return v };
  308. return function (key, val) {
  309. if (replacerStack.length > 0) {
  310. for (var i = 0; i < replacerStack.length; i++) {
  311. var part = replacerStack[i];
  312. if (part[1] === key && part[0] === val) {
  313. val = '[Circular]';
  314. replacerStack.splice(i, 1);
  315. break
  316. }
  317. }
  318. }
  319. return replacer.call(this, key, val)
  320. }
  321. }
  322. function _typeof(obj) {
  323. if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
  324. _typeof = function _typeof(obj) {
  325. return typeof obj;
  326. };
  327. } else {
  328. _typeof = function _typeof(obj) {
  329. return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  330. };
  331. }
  332. return _typeof(obj);
  333. }
  334. /**
  335. * Check if `obj` is an object.
  336. *
  337. * @param {Object} obj
  338. * @return {Boolean}
  339. * @api private
  340. */
  341. function isObject(obj) {
  342. return obj !== null && _typeof(obj) === 'object';
  343. }
  344. var isObject_1 = isObject;
  345. function _typeof$1(obj) {
  346. if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
  347. _typeof$1 = function _typeof(obj) {
  348. return typeof obj;
  349. };
  350. } else {
  351. _typeof$1 = function _typeof(obj) {
  352. return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  353. };
  354. }
  355. return _typeof$1(obj);
  356. }
  357. /**
  358. * Module of mixed-in functions shared between node and client code
  359. */
  360. /**
  361. * Expose `RequestBase`.
  362. */
  363. var requestBase = RequestBase;
  364. /**
  365. * Initialize a new `RequestBase`.
  366. *
  367. * @api public
  368. */
  369. function RequestBase(obj) {
  370. if (obj) return mixin(obj);
  371. }
  372. /**
  373. * Mixin the prototype properties.
  374. *
  375. * @param {Object} obj
  376. * @return {Object}
  377. * @api private
  378. */
  379. function mixin(obj) {
  380. for (var key in RequestBase.prototype) {
  381. if (Object.prototype.hasOwnProperty.call(RequestBase.prototype, key)) obj[key] = RequestBase.prototype[key];
  382. }
  383. return obj;
  384. }
  385. /**
  386. * Clear previous timeout.
  387. *
  388. * @return {Request} for chaining
  389. * @api public
  390. */
  391. RequestBase.prototype.clearTimeout = function () {
  392. clearTimeout(this._timer);
  393. clearTimeout(this._responseTimeoutTimer);
  394. clearTimeout(this._uploadTimeoutTimer);
  395. delete this._timer;
  396. delete this._responseTimeoutTimer;
  397. delete this._uploadTimeoutTimer;
  398. return this;
  399. };
  400. /**
  401. * Override default response body parser
  402. *
  403. * This function will be called to convert incoming data into request.body
  404. *
  405. * @param {Function}
  406. * @api public
  407. */
  408. RequestBase.prototype.parse = function (fn) {
  409. this._parser = fn;
  410. return this;
  411. };
  412. /**
  413. * Set format of binary response body.
  414. * In browser valid formats are 'blob' and 'arraybuffer',
  415. * which return Blob and ArrayBuffer, respectively.
  416. *
  417. * In Node all values result in Buffer.
  418. *
  419. * Examples:
  420. *
  421. * req.get('/')
  422. * .responseType('blob')
  423. * .end(callback);
  424. *
  425. * @param {String} val
  426. * @return {Request} for chaining
  427. * @api public
  428. */
  429. RequestBase.prototype.responseType = function (val) {
  430. this._responseType = val;
  431. return this;
  432. };
  433. /**
  434. * Override default request body serializer
  435. *
  436. * This function will be called to convert data set via .send or .attach into payload to send
  437. *
  438. * @param {Function}
  439. * @api public
  440. */
  441. RequestBase.prototype.serialize = function (fn) {
  442. this._serializer = fn;
  443. return this;
  444. };
  445. /**
  446. * Set timeouts.
  447. *
  448. * - response timeout is time between sending request and receiving the first byte of the response. Includes DNS and connection time.
  449. * - deadline is the time from start of the request to receiving response body in full. If the deadline is too short large files may not load at all on slow connections.
  450. * - upload is the time since last bit of data was sent or received. This timeout works only if deadline timeout is off
  451. *
  452. * Value of 0 or false means no timeout.
  453. *
  454. * @param {Number|Object} ms or {response, deadline}
  455. * @return {Request} for chaining
  456. * @api public
  457. */
  458. RequestBase.prototype.timeout = function (options) {
  459. if (!options || _typeof$1(options) !== 'object') {
  460. this._timeout = options;
  461. this._responseTimeout = 0;
  462. this._uploadTimeout = 0;
  463. return this;
  464. }
  465. for (var option in options) {
  466. if (Object.prototype.hasOwnProperty.call(options, option)) {
  467. switch (option) {
  468. case 'deadline':
  469. this._timeout = options.deadline;
  470. break;
  471. case 'response':
  472. this._responseTimeout = options.response;
  473. break;
  474. case 'upload':
  475. this._uploadTimeout = options.upload;
  476. break;
  477. default:
  478. console.warn('Unknown timeout option', option);
  479. }
  480. }
  481. }
  482. return this;
  483. };
  484. /**
  485. * Set number of retry attempts on error.
  486. *
  487. * Failed requests will be retried 'count' times if timeout or err.code >= 500.
  488. *
  489. * @param {Number} count
  490. * @param {Function} [fn]
  491. * @return {Request} for chaining
  492. * @api public
  493. */
  494. RequestBase.prototype.retry = function (count, fn) {
  495. // Default to 1 if no count passed or true
  496. if (arguments.length === 0 || count === true) count = 1;
  497. if (count <= 0) count = 0;
  498. this._maxRetries = count;
  499. this._retries = 0;
  500. this._retryCallback = fn;
  501. return this;
  502. };
  503. var ERROR_CODES = ['ECONNRESET', 'ETIMEDOUT', 'EADDRINFO', 'ESOCKETTIMEDOUT'];
  504. /**
  505. * Determine if a request should be retried.
  506. * (Borrowed from segmentio/superagent-retry)
  507. *
  508. * @param {Error} err an error
  509. * @param {Response} [res] response
  510. * @returns {Boolean} if segment should be retried
  511. */
  512. RequestBase.prototype._shouldRetry = function (err, res) {
  513. if (!this._maxRetries || this._retries++ >= this._maxRetries) {
  514. return false;
  515. }
  516. if (this._retryCallback) {
  517. try {
  518. var override = this._retryCallback(err, res);
  519. if (override === true) return true;
  520. if (override === false) return false; // undefined falls back to defaults
  521. } catch (err_) {
  522. console.error(err_);
  523. }
  524. }
  525. if (res && res.status && res.status >= 500 && res.status !== 501) return true;
  526. if (err) {
  527. if (err.code && ERROR_CODES.includes(err.code)) return true; // Superagent timeout
  528. if (err.timeout && err.code === 'ECONNABORTED') return true;
  529. if (err.crossDomain) return true;
  530. }
  531. return false;
  532. };
  533. /**
  534. * Retry request
  535. *
  536. * @return {Request} for chaining
  537. * @api private
  538. */
  539. RequestBase.prototype._retry = function () {
  540. this.clearTimeout(); // node
  541. if (this.req) {
  542. this.req = null;
  543. this.req = this.request();
  544. }
  545. this._aborted = false;
  546. this.timedout = false;
  547. this.timedoutError = null;
  548. return this._end();
  549. };
  550. /**
  551. * Promise support
  552. *
  553. * @param {Function} resolve
  554. * @param {Function} [reject]
  555. * @return {Request}
  556. */
  557. RequestBase.prototype.then = function (resolve, reject) {
  558. var _this = this;
  559. if (!this._fullfilledPromise) {
  560. var self = this;
  561. if (this._endCalled) {
  562. console.warn('Warning: superagent request was sent twice, because both .end() and .then() were called. Never call .end() if you use promises');
  563. }
  564. this._fullfilledPromise = new Promise(function (resolve, reject) {
  565. self.on('abort', function () {
  566. if (_this.timedout && _this.timedoutError) {
  567. reject(_this.timedoutError);
  568. return;
  569. }
  570. var err = new Error('Aborted');
  571. err.code = 'ABORTED';
  572. err.status = _this.status;
  573. err.method = _this.method;
  574. err.url = _this.url;
  575. reject(err);
  576. });
  577. self.end(function (err, res) {
  578. if (err) reject(err);else resolve(res);
  579. });
  580. });
  581. }
  582. return this._fullfilledPromise.then(resolve, reject);
  583. };
  584. RequestBase.prototype.catch = function (cb) {
  585. return this.then(undefined, cb);
  586. };
  587. /**
  588. * Allow for extension
  589. */
  590. RequestBase.prototype.use = function (fn) {
  591. fn(this);
  592. return this;
  593. };
  594. RequestBase.prototype.ok = function (cb) {
  595. if (typeof cb !== 'function') throw new Error('Callback required');
  596. this._okCallback = cb;
  597. return this;
  598. };
  599. RequestBase.prototype._isResponseOK = function (res) {
  600. if (!res) {
  601. return false;
  602. }
  603. if (this._okCallback) {
  604. return this._okCallback(res);
  605. }
  606. return res.status >= 200 && res.status < 300;
  607. };
  608. /**
  609. * Get request header `field`.
  610. * Case-insensitive.
  611. *
  612. * @param {String} field
  613. * @return {String}
  614. * @api public
  615. */
  616. RequestBase.prototype.get = function (field) {
  617. return this._header[field.toLowerCase()];
  618. };
  619. /**
  620. * Get case-insensitive header `field` value.
  621. * This is a deprecated internal API. Use `.get(field)` instead.
  622. *
  623. * (getHeader is no longer used internally by the superagent code base)
  624. *
  625. * @param {String} field
  626. * @return {String}
  627. * @api private
  628. * @deprecated
  629. */
  630. RequestBase.prototype.getHeader = RequestBase.prototype.get;
  631. /**
  632. * Set header `field` to `val`, or multiple fields with one object.
  633. * Case-insensitive.
  634. *
  635. * Examples:
  636. *
  637. * req.get('/')
  638. * .set('Accept', 'application/json')
  639. * .set('X-API-Key', 'foobar')
  640. * .end(callback);
  641. *
  642. * req.get('/')
  643. * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
  644. * .end(callback);
  645. *
  646. * @param {String|Object} field
  647. * @param {String} val
  648. * @return {Request} for chaining
  649. * @api public
  650. */
  651. RequestBase.prototype.set = function (field, val) {
  652. if (isObject_1(field)) {
  653. for (var key in field) {
  654. if (Object.prototype.hasOwnProperty.call(field, key)) this.set(key, field[key]);
  655. }
  656. return this;
  657. }
  658. this._header[field.toLowerCase()] = val;
  659. this.header[field] = val;
  660. return this;
  661. };
  662. /**
  663. * Remove header `field`.
  664. * Case-insensitive.
  665. *
  666. * Example:
  667. *
  668. * req.get('/')
  669. * .unset('User-Agent')
  670. * .end(callback);
  671. *
  672. * @param {String} field field name
  673. */
  674. RequestBase.prototype.unset = function (field) {
  675. delete this._header[field.toLowerCase()];
  676. delete this.header[field];
  677. return this;
  678. };
  679. /**
  680. * Write the field `name` and `val`, or multiple fields with one object
  681. * for "multipart/form-data" request bodies.
  682. *
  683. * ``` js
  684. * request.post('/upload')
  685. * .field('foo', 'bar')
  686. * .end(callback);
  687. *
  688. * request.post('/upload')
  689. * .field({ foo: 'bar', baz: 'qux' })
  690. * .end(callback);
  691. * ```
  692. *
  693. * @param {String|Object} name name of field
  694. * @param {String|Blob|File|Buffer|fs.ReadStream} val value of field
  695. * @return {Request} for chaining
  696. * @api public
  697. */
  698. RequestBase.prototype.field = function (name, val) {
  699. // name should be either a string or an object.
  700. if (name === null || undefined === name) {
  701. throw new Error('.field(name, val) name can not be empty');
  702. }
  703. if (this._data) {
  704. throw new Error(".field() can't be used if .send() is used. Please use only .send() or only .field() & .attach()");
  705. }
  706. if (isObject_1(name)) {
  707. for (var key in name) {
  708. if (Object.prototype.hasOwnProperty.call(name, key)) this.field(key, name[key]);
  709. }
  710. return this;
  711. }
  712. if (Array.isArray(val)) {
  713. for (var i in val) {
  714. if (Object.prototype.hasOwnProperty.call(val, i)) this.field(name, val[i]);
  715. }
  716. return this;
  717. } // val should be defined now
  718. if (val === null || undefined === val) {
  719. throw new Error('.field(name, val) val can not be empty');
  720. }
  721. if (typeof val === 'boolean') {
  722. val = String(val);
  723. }
  724. this._getFormData().append(name, val);
  725. return this;
  726. };
  727. /**
  728. * Abort the request, and clear potential timeout.
  729. *
  730. * @return {Request} request
  731. * @api public
  732. */
  733. RequestBase.prototype.abort = function () {
  734. if (this._aborted) {
  735. return this;
  736. }
  737. this._aborted = true;
  738. if (this.xhr) this.xhr.abort(); // browser
  739. if (this.req) this.req.abort(); // node
  740. this.clearTimeout();
  741. this.emit('abort');
  742. return this;
  743. };
  744. RequestBase.prototype._auth = function (user, pass, options, base64Encoder) {
  745. switch (options.type) {
  746. case 'basic':
  747. this.set('Authorization', "Basic ".concat(base64Encoder("".concat(user, ":").concat(pass))));
  748. break;
  749. case 'auto':
  750. this.username = user;
  751. this.password = pass;
  752. break;
  753. case 'bearer':
  754. // usage would be .auth(accessToken, { type: 'bearer' })
  755. this.set('Authorization', "Bearer ".concat(user));
  756. break;
  757. }
  758. return this;
  759. };
  760. /**
  761. * Enable transmission of cookies with x-domain requests.
  762. *
  763. * Note that for this to work the origin must not be
  764. * using "Access-Control-Allow-Origin" with a wildcard,
  765. * and also must set "Access-Control-Allow-Credentials"
  766. * to "true".
  767. *
  768. * @api public
  769. */
  770. RequestBase.prototype.withCredentials = function (on) {
  771. // This is browser-only functionality. Node side is no-op.
  772. if (on === undefined) on = true;
  773. this._withCredentials = on;
  774. return this;
  775. };
  776. /**
  777. * Set the max redirects to `n`. Does nothing in browser XHR implementation.
  778. *
  779. * @param {Number} n
  780. * @return {Request} for chaining
  781. * @api public
  782. */
  783. RequestBase.prototype.redirects = function (n) {
  784. this._maxRedirects = n;
  785. return this;
  786. };
  787. /**
  788. * Maximum size of buffered response body, in bytes. Counts uncompressed size.
  789. * Default 200MB.
  790. *
  791. * @param {Number} n number of bytes
  792. * @return {Request} for chaining
  793. */
  794. RequestBase.prototype.maxResponseSize = function (n) {
  795. if (typeof n !== 'number') {
  796. throw new TypeError('Invalid argument');
  797. }
  798. this._maxResponseSize = n;
  799. return this;
  800. };
  801. /**
  802. * Convert to a plain javascript object (not JSON string) of scalar properties.
  803. * Note as this method is designed to return a useful non-this value,
  804. * it cannot be chained.
  805. *
  806. * @return {Object} describing method, url, and data of this request
  807. * @api public
  808. */
  809. RequestBase.prototype.toJSON = function () {
  810. return {
  811. method: this.method,
  812. url: this.url,
  813. data: this._data,
  814. headers: this._header
  815. };
  816. };
  817. /**
  818. * Send `data` as the request body, defaulting the `.type()` to "json" when
  819. * an object is given.
  820. *
  821. * Examples:
  822. *
  823. * // manual json
  824. * request.post('/user')
  825. * .type('json')
  826. * .send('{"name":"tj"}')
  827. * .end(callback)
  828. *
  829. * // auto json
  830. * request.post('/user')
  831. * .send({ name: 'tj' })
  832. * .end(callback)
  833. *
  834. * // manual x-www-form-urlencoded
  835. * request.post('/user')
  836. * .type('form')
  837. * .send('name=tj')
  838. * .end(callback)
  839. *
  840. * // auto x-www-form-urlencoded
  841. * request.post('/user')
  842. * .type('form')
  843. * .send({ name: 'tj' })
  844. * .end(callback)
  845. *
  846. * // defaults to x-www-form-urlencoded
  847. * request.post('/user')
  848. * .send('name=tobi')
  849. * .send('species=ferret')
  850. * .end(callback)
  851. *
  852. * @param {String|Object} data
  853. * @return {Request} for chaining
  854. * @api public
  855. */
  856. // eslint-disable-next-line complexity
  857. RequestBase.prototype.send = function (data) {
  858. var isObj = isObject_1(data);
  859. var type = this._header['content-type'];
  860. if (this._formData) {
  861. throw new Error(".send() can't be used if .attach() or .field() is used. Please use only .send() or only .field() & .attach()");
  862. }
  863. if (isObj && !this._data) {
  864. if (Array.isArray(data)) {
  865. this._data = [];
  866. } else if (!this._isHost(data)) {
  867. this._data = {};
  868. }
  869. } else if (data && this._data && this._isHost(this._data)) {
  870. throw new Error("Can't merge these send calls");
  871. } // merge
  872. if (isObj && isObject_1(this._data)) {
  873. for (var key in data) {
  874. if (Object.prototype.hasOwnProperty.call(data, key)) this._data[key] = data[key];
  875. }
  876. } else if (typeof data === 'string') {
  877. // default to x-www-form-urlencoded
  878. if (!type) this.type('form');
  879. type = this._header['content-type'];
  880. if (type === 'application/x-www-form-urlencoded') {
  881. this._data = this._data ? "".concat(this._data, "&").concat(data) : data;
  882. } else {
  883. this._data = (this._data || '') + data;
  884. }
  885. } else {
  886. this._data = data;
  887. }
  888. if (!isObj || this._isHost(data)) {
  889. return this;
  890. } // default to json
  891. if (!type) this.type('json');
  892. return this;
  893. };
  894. /**
  895. * Sort `querystring` by the sort function
  896. *
  897. *
  898. * Examples:
  899. *
  900. * // default order
  901. * request.get('/user')
  902. * .query('name=Nick')
  903. * .query('search=Manny')
  904. * .sortQuery()
  905. * .end(callback)
  906. *
  907. * // customized sort function
  908. * request.get('/user')
  909. * .query('name=Nick')
  910. * .query('search=Manny')
  911. * .sortQuery(function(a, b){
  912. * return a.length - b.length;
  913. * })
  914. * .end(callback)
  915. *
  916. *
  917. * @param {Function} sort
  918. * @return {Request} for chaining
  919. * @api public
  920. */
  921. RequestBase.prototype.sortQuery = function (sort) {
  922. // _sort default to true but otherwise can be a function or boolean
  923. this._sort = typeof sort === 'undefined' ? true : sort;
  924. return this;
  925. };
  926. /**
  927. * Compose querystring to append to req.url
  928. *
  929. * @api private
  930. */
  931. RequestBase.prototype._finalizeQueryString = function () {
  932. var query = this._query.join('&');
  933. if (query) {
  934. this.url += (this.url.includes('?') ? '&' : '?') + query;
  935. }
  936. this._query.length = 0; // Makes the call idempotent
  937. if (this._sort) {
  938. var index = this.url.indexOf('?');
  939. if (index >= 0) {
  940. var queryArr = this.url.slice(index + 1).split('&');
  941. if (typeof this._sort === 'function') {
  942. queryArr.sort(this._sort);
  943. } else {
  944. queryArr.sort();
  945. }
  946. this.url = this.url.slice(0, index) + '?' + queryArr.join('&');
  947. }
  948. }
  949. }; // For backwards compat only
  950. RequestBase.prototype._appendQueryString = function () {
  951. console.warn('Unsupported');
  952. };
  953. /**
  954. * Invoke callback with timeout error.
  955. *
  956. * @api private
  957. */
  958. RequestBase.prototype._timeoutError = function (reason, timeout, errno) {
  959. if (this._aborted) {
  960. return;
  961. }
  962. var err = new Error("".concat(reason + timeout, "ms exceeded"));
  963. err.timeout = timeout;
  964. err.code = 'ECONNABORTED';
  965. err.errno = errno;
  966. this.timedout = true;
  967. this.timedoutError = err;
  968. this.abort();
  969. this.callback(err);
  970. };
  971. RequestBase.prototype._setTimeouts = function () {
  972. var self = this; // deadline
  973. if (this._timeout && !this._timer) {
  974. this._timer = setTimeout(function () {
  975. self._timeoutError('Timeout of ', self._timeout, 'ETIME');
  976. }, this._timeout);
  977. } // response timeout
  978. if (this._responseTimeout && !this._responseTimeoutTimer) {
  979. this._responseTimeoutTimer = setTimeout(function () {
  980. self._timeoutError('Response timeout of ', self._responseTimeout, 'ETIMEDOUT');
  981. }, this._responseTimeout);
  982. }
  983. };
  984. /**
  985. * Return the mime type for the given `str`.
  986. *
  987. * @param {String} str
  988. * @return {String}
  989. * @api private
  990. */
  991. var type = function (str) {
  992. return str.split(/ *; */).shift();
  993. };
  994. /**
  995. * Return header field parameters.
  996. *
  997. * @param {String} str
  998. * @return {Object}
  999. * @api private
  1000. */
  1001. var params = function (str) {
  1002. return str.split(/ *; */).reduce(function (obj, str) {
  1003. var parts = str.split(/ *= */);
  1004. var key = parts.shift();
  1005. var val = parts.shift();
  1006. if (key && val) obj[key] = val;
  1007. return obj;
  1008. }, {});
  1009. };
  1010. /**
  1011. * Parse Link header fields.
  1012. *
  1013. * @param {String} str
  1014. * @return {Object}
  1015. * @api private
  1016. */
  1017. var parseLinks = function (str) {
  1018. return str.split(/ *, */).reduce(function (obj, str) {
  1019. var parts = str.split(/ *; */);
  1020. var url = parts[0].slice(1, -1);
  1021. var rel = parts[1].split(/ *= */)[1].slice(1, -1);
  1022. obj[rel] = url;
  1023. return obj;
  1024. }, {});
  1025. };
  1026. /**
  1027. * Strip content related fields from `header`.
  1028. *
  1029. * @param {Object} header
  1030. * @return {Object} header
  1031. * @api private
  1032. */
  1033. var cleanHeader = function (header, changesOrigin) {
  1034. delete header['content-type'];
  1035. delete header['content-length'];
  1036. delete header['transfer-encoding'];
  1037. delete header.host; // secuirty
  1038. if (changesOrigin) {
  1039. delete header.authorization;
  1040. delete header.cookie;
  1041. }
  1042. return header;
  1043. };
  1044. var utils = {
  1045. type: type,
  1046. params: params,
  1047. parseLinks: parseLinks,
  1048. cleanHeader: cleanHeader
  1049. };
  1050. /**
  1051. * Module dependencies.
  1052. */
  1053. /**
  1054. * Expose `ResponseBase`.
  1055. */
  1056. var responseBase = ResponseBase;
  1057. /**
  1058. * Initialize a new `ResponseBase`.
  1059. *
  1060. * @api public
  1061. */
  1062. function ResponseBase(obj) {
  1063. if (obj) return mixin$1(obj);
  1064. }
  1065. /**
  1066. * Mixin the prototype properties.
  1067. *
  1068. * @param {Object} obj
  1069. * @return {Object}
  1070. * @api private
  1071. */
  1072. function mixin$1(obj) {
  1073. for (var key in ResponseBase.prototype) {
  1074. if (Object.prototype.hasOwnProperty.call(ResponseBase.prototype, key)) obj[key] = ResponseBase.prototype[key];
  1075. }
  1076. return obj;
  1077. }
  1078. /**
  1079. * Get case-insensitive `field` value.
  1080. *
  1081. * @param {String} field
  1082. * @return {String}
  1083. * @api public
  1084. */
  1085. ResponseBase.prototype.get = function (field) {
  1086. return this.header[field.toLowerCase()];
  1087. };
  1088. /**
  1089. * Set header related properties:
  1090. *
  1091. * - `.type` the content type without params
  1092. *
  1093. * A response of "Content-Type: text/plain; charset=utf-8"
  1094. * will provide you with a `.type` of "text/plain".
  1095. *
  1096. * @param {Object} header
  1097. * @api private
  1098. */
  1099. ResponseBase.prototype._setHeaderProperties = function (header) {
  1100. // TODO: moar!
  1101. // TODO: make this a util
  1102. // content-type
  1103. var ct = header['content-type'] || '';
  1104. this.type = utils.type(ct); // params
  1105. var params = utils.params(ct);
  1106. for (var key in params) {
  1107. if (Object.prototype.hasOwnProperty.call(params, key)) this[key] = params[key];
  1108. }
  1109. this.links = {}; // links
  1110. try {
  1111. if (header.link) {
  1112. this.links = utils.parseLinks(header.link);
  1113. }
  1114. } catch (_unused) {// ignore
  1115. }
  1116. };
  1117. /**
  1118. * Set flags such as `.ok` based on `status`.
  1119. *
  1120. * For example a 2xx response will give you a `.ok` of __true__
  1121. * whereas 5xx will be __false__ and `.error` will be __true__. The
  1122. * `.clientError` and `.serverError` are also available to be more
  1123. * specific, and `.statusType` is the class of error ranging from 1..5
  1124. * sometimes useful for mapping respond colors etc.
  1125. *
  1126. * "sugar" properties are also defined for common cases. Currently providing:
  1127. *
  1128. * - .noContent
  1129. * - .badRequest
  1130. * - .unauthorized
  1131. * - .notAcceptable
  1132. * - .notFound
  1133. *
  1134. * @param {Number} status
  1135. * @api private
  1136. */
  1137. ResponseBase.prototype._setStatusProperties = function (status) {
  1138. var type = status / 100 | 0; // status / class
  1139. this.statusCode = status;
  1140. this.status = this.statusCode;
  1141. this.statusType = type; // basics
  1142. this.info = type === 1;
  1143. this.ok = type === 2;
  1144. this.redirect = type === 3;
  1145. this.clientError = type === 4;
  1146. this.serverError = type === 5;
  1147. this.error = type === 4 || type === 5 ? this.toError() : false; // sugar
  1148. this.created = status === 201;
  1149. this.accepted = status === 202;
  1150. this.noContent = status === 204;
  1151. this.badRequest = status === 400;
  1152. this.unauthorized = status === 401;
  1153. this.notAcceptable = status === 406;
  1154. this.forbidden = status === 403;
  1155. this.notFound = status === 404;
  1156. this.unprocessableEntity = status === 422;
  1157. };
  1158. function _toConsumableArray(arr) {
  1159. return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
  1160. }
  1161. function _nonIterableSpread() {
  1162. throw new TypeError("Invalid attempt to spread non-iterable instance");
  1163. }
  1164. function _iterableToArray(iter) {
  1165. if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
  1166. }
  1167. function _arrayWithoutHoles(arr) {
  1168. if (Array.isArray(arr)) {
  1169. for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
  1170. arr2[i] = arr[i];
  1171. }
  1172. return arr2;
  1173. }
  1174. }
  1175. function Agent() {
  1176. this._defaults = [];
  1177. }
  1178. ['use', 'on', 'once', 'set', 'query', 'type', 'accept', 'auth', 'withCredentials', 'sortQuery', 'retry', 'ok', 'redirects', 'timeout', 'buffer', 'serialize', 'parse', 'ca', 'key', 'pfx', 'cert', 'disableTLSCerts'].forEach(function (fn) {
  1179. // Default setting for all requests from this agent
  1180. Agent.prototype[fn] = function () {
  1181. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  1182. args[_key] = arguments[_key];
  1183. }
  1184. this._defaults.push({
  1185. fn: fn,
  1186. args: args
  1187. });
  1188. return this;
  1189. };
  1190. });
  1191. Agent.prototype._setDefaults = function (req) {
  1192. this._defaults.forEach(function (def) {
  1193. req[def.fn].apply(req, _toConsumableArray(def.args));
  1194. });
  1195. };
  1196. var agentBase = Agent;
  1197. var client = createCommonjsModule(function (module, exports) {
  1198. function _typeof(obj) {
  1199. if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
  1200. _typeof = function _typeof(obj) {
  1201. return typeof obj;
  1202. };
  1203. } else {
  1204. _typeof = function _typeof(obj) {
  1205. return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  1206. };
  1207. }
  1208. return _typeof(obj);
  1209. }
  1210. /**
  1211. * Root reference for iframes.
  1212. */
  1213. var root;
  1214. if (typeof window !== 'undefined') {
  1215. // Browser window
  1216. root = window;
  1217. } else if (typeof self === 'undefined') {
  1218. // Other environments
  1219. console.warn('Using browser-only version of superagent in non-browser environment');
  1220. root = void 0;
  1221. } else {
  1222. // Web Worker
  1223. root = self;
  1224. }
  1225. /**
  1226. * Noop.
  1227. */
  1228. function noop() {}
  1229. /**
  1230. * Expose `request`.
  1231. */
  1232. module.exports = function (method, url) {
  1233. // callback
  1234. if (typeof url === 'function') {
  1235. return new exports.Request('GET', method).end(url);
  1236. } // url first
  1237. if (arguments.length === 1) {
  1238. return new exports.Request('GET', method);
  1239. }
  1240. return new exports.Request(method, url);
  1241. };
  1242. exports = module.exports;
  1243. var request = exports;
  1244. exports.Request = Request;
  1245. /**
  1246. * Determine XHR.
  1247. */
  1248. request.getXHR = function () {
  1249. if (root.XMLHttpRequest && (!root.location || root.location.protocol !== 'file:' || !root.ActiveXObject)) {
  1250. return new XMLHttpRequest();
  1251. }
  1252. try {
  1253. return new ActiveXObject('Microsoft.XMLHTTP');
  1254. } catch (_unused) {}
  1255. try {
  1256. return new ActiveXObject('Msxml2.XMLHTTP.6.0');
  1257. } catch (_unused2) {}
  1258. try {
  1259. return new ActiveXObject('Msxml2.XMLHTTP.3.0');
  1260. } catch (_unused3) {}
  1261. try {
  1262. return new ActiveXObject('Msxml2.XMLHTTP');
  1263. } catch (_unused4) {}
  1264. throw new Error('Browser-only version of superagent could not find XHR');
  1265. };
  1266. /**
  1267. * Removes leading and trailing whitespace, added to support IE.
  1268. *
  1269. * @param {String} s
  1270. * @return {String}
  1271. * @api private
  1272. */
  1273. var trim = ''.trim ? function (s) {
  1274. return s.trim();
  1275. } : function (s) {
  1276. return s.replace(/(^\s*|\s*$)/g, '');
  1277. };
  1278. /**
  1279. * Serialize the given `obj`.
  1280. *
  1281. * @param {Object} obj
  1282. * @return {String}
  1283. * @api private
  1284. */
  1285. function serialize(obj) {
  1286. if (!isObject_1(obj)) return obj;
  1287. var pairs = [];
  1288. for (var key in obj) {
  1289. if (Object.prototype.hasOwnProperty.call(obj, key)) pushEncodedKeyValuePair(pairs, key, obj[key]);
  1290. }
  1291. return pairs.join('&');
  1292. }
  1293. /**
  1294. * Helps 'serialize' with serializing arrays.
  1295. * Mutates the pairs array.
  1296. *
  1297. * @param {Array} pairs
  1298. * @param {String} key
  1299. * @param {Mixed} val
  1300. */
  1301. function pushEncodedKeyValuePair(pairs, key, val) {
  1302. if (val === undefined) return;
  1303. if (val === null) {
  1304. pairs.push(encodeURI(key));
  1305. return;
  1306. }
  1307. if (Array.isArray(val)) {
  1308. val.forEach(function (v) {
  1309. pushEncodedKeyValuePair(pairs, key, v);
  1310. });
  1311. } else if (isObject_1(val)) {
  1312. for (var subkey in val) {
  1313. if (Object.prototype.hasOwnProperty.call(val, subkey)) pushEncodedKeyValuePair(pairs, "".concat(key, "[").concat(subkey, "]"), val[subkey]);
  1314. }
  1315. } else {
  1316. pairs.push(encodeURI(key) + '=' + encodeURIComponent(val));
  1317. }
  1318. }
  1319. /**
  1320. * Expose serialization method.
  1321. */
  1322. request.serializeObject = serialize;
  1323. /**
  1324. * Parse the given x-www-form-urlencoded `str`.
  1325. *
  1326. * @param {String} str
  1327. * @return {Object}
  1328. * @api private
  1329. */
  1330. function parseString(str) {
  1331. var obj = {};
  1332. var pairs = str.split('&');
  1333. var pair;
  1334. var pos;
  1335. for (var i = 0, len = pairs.length; i < len; ++i) {
  1336. pair = pairs[i];
  1337. pos = pair.indexOf('=');
  1338. if (pos === -1) {
  1339. obj[decodeURIComponent(pair)] = '';
  1340. } else {
  1341. obj[decodeURIComponent(pair.slice(0, pos))] = decodeURIComponent(pair.slice(pos + 1));
  1342. }
  1343. }
  1344. return obj;
  1345. }
  1346. /**
  1347. * Expose parser.
  1348. */
  1349. request.parseString = parseString;
  1350. /**
  1351. * Default MIME type map.
  1352. *
  1353. * superagent.types.xml = 'application/xml';
  1354. *
  1355. */
  1356. request.types = {
  1357. html: 'text/html',
  1358. json: 'application/json',
  1359. xml: 'text/xml',
  1360. urlencoded: 'application/x-www-form-urlencoded',
  1361. form: 'application/x-www-form-urlencoded',
  1362. 'form-data': 'application/x-www-form-urlencoded'
  1363. };
  1364. /**
  1365. * Default serialization map.
  1366. *
  1367. * superagent.serialize['application/xml'] = function(obj){
  1368. * return 'generated xml here';
  1369. * };
  1370. *
  1371. */
  1372. request.serialize = {
  1373. 'application/x-www-form-urlencoded': serialize,
  1374. 'application/json': fastSafeStringify
  1375. };
  1376. /**
  1377. * Default parsers.
  1378. *
  1379. * superagent.parse['application/xml'] = function(str){
  1380. * return { object parsed from str };
  1381. * };
  1382. *
  1383. */
  1384. request.parse = {
  1385. 'application/x-www-form-urlencoded': parseString,
  1386. 'application/json': JSON.parse
  1387. };
  1388. /**
  1389. * Parse the given header `str` into
  1390. * an object containing the mapped fields.
  1391. *
  1392. * @param {String} str
  1393. * @return {Object}
  1394. * @api private
  1395. */
  1396. function parseHeader(str) {
  1397. var lines = str.split(/\r?\n/);
  1398. var fields = {};
  1399. var index;
  1400. var line;
  1401. var field;
  1402. var val;
  1403. for (var i = 0, len = lines.length; i < len; ++i) {
  1404. line = lines[i];
  1405. index = line.indexOf(':');
  1406. if (index === -1) {
  1407. // could be empty line, just skip it
  1408. continue;
  1409. }
  1410. field = line.slice(0, index).toLowerCase();
  1411. val = trim(line.slice(index + 1));
  1412. fields[field] = val;
  1413. }
  1414. return fields;
  1415. }
  1416. /**
  1417. * Check if `mime` is json or has +json structured syntax suffix.
  1418. *
  1419. * @param {String} mime
  1420. * @return {Boolean}
  1421. * @api private
  1422. */
  1423. function isJSON(mime) {
  1424. // should match /json or +json
  1425. // but not /json-seq
  1426. return /[/+]json($|[^-\w])/.test(mime);
  1427. }
  1428. /**
  1429. * Initialize a new `Response` with the given `xhr`.
  1430. *
  1431. * - set flags (.ok, .error, etc)
  1432. * - parse header
  1433. *
  1434. * Examples:
  1435. *
  1436. * Aliasing `superagent` as `request` is nice:
  1437. *
  1438. * request = superagent;
  1439. *
  1440. * We can use the promise-like API, or pass callbacks:
  1441. *
  1442. * request.get('/').end(function(res){});
  1443. * request.get('/', function(res){});
  1444. *
  1445. * Sending data can be chained:
  1446. *
  1447. * request
  1448. * .post('/user')
  1449. * .send({ name: 'tj' })
  1450. * .end(function(res){});
  1451. *
  1452. * Or passed to `.send()`:
  1453. *
  1454. * request
  1455. * .post('/user')
  1456. * .send({ name: 'tj' }, function(res){});
  1457. *
  1458. * Or passed to `.post()`:
  1459. *
  1460. * request
  1461. * .post('/user', { name: 'tj' })
  1462. * .end(function(res){});
  1463. *
  1464. * Or further reduced to a single call for simple cases:
  1465. *
  1466. * request
  1467. * .post('/user', { name: 'tj' }, function(res){});
  1468. *
  1469. * @param {XMLHTTPRequest} xhr
  1470. * @param {Object} options
  1471. * @api private
  1472. */
  1473. function Response(req) {
  1474. this.req = req;
  1475. this.xhr = this.req.xhr; // responseText is accessible only if responseType is '' or 'text' and on older browsers
  1476. this.text = this.req.method !== 'HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text') || typeof this.xhr.responseType === 'undefined' ? this.xhr.responseText : null;
  1477. this.statusText = this.req.xhr.statusText;
  1478. var status = this.xhr.status; // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
  1479. if (status === 1223) {
  1480. status = 204;
  1481. }
  1482. this._setStatusProperties(status);
  1483. this.headers = parseHeader(this.xhr.getAllResponseHeaders());
  1484. this.header = this.headers; // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
  1485. // getResponseHeader still works. so we get content-type even if getting
  1486. // other headers fails.
  1487. this.header['content-type'] = this.xhr.getResponseHeader('content-type');
  1488. this._setHeaderProperties(this.header);
  1489. if (this.text === null && req._responseType) {
  1490. this.body = this.xhr.response;
  1491. } else {
  1492. this.body = this.req.method === 'HEAD' ? null : this._parseBody(this.text ? this.text : this.xhr.response);
  1493. }
  1494. } // eslint-disable-next-line new-cap
  1495. responseBase(Response.prototype);
  1496. /**
  1497. * Parse the given body `str`.
  1498. *
  1499. * Used for auto-parsing of bodies. Parsers
  1500. * are defined on the `superagent.parse` object.
  1501. *
  1502. * @param {String} str
  1503. * @return {Mixed}
  1504. * @api private
  1505. */
  1506. Response.prototype._parseBody = function (str) {
  1507. var parse = request.parse[this.type];
  1508. if (this.req._parser) {
  1509. return this.req._parser(this, str);
  1510. }
  1511. if (!parse && isJSON(this.type)) {
  1512. parse = request.parse['application/json'];
  1513. }
  1514. return parse && str && (str.length > 0 || str instanceof Object) ? parse(str) : null;
  1515. };
  1516. /**
  1517. * Return an `Error` representative of this response.
  1518. *
  1519. * @return {Error}
  1520. * @api public
  1521. */
  1522. Response.prototype.toError = function () {
  1523. var req = this.req;
  1524. var method = req.method;
  1525. var url = req.url;
  1526. var msg = "cannot ".concat(method, " ").concat(url, " (").concat(this.status, ")");
  1527. var err = new Error(msg);
  1528. err.status = this.status;
  1529. err.method = method;
  1530. err.url = url;
  1531. return err;
  1532. };
  1533. /**
  1534. * Expose `Response`.
  1535. */
  1536. request.Response = Response;
  1537. /**
  1538. * Initialize a new `Request` with the given `method` and `url`.
  1539. *
  1540. * @param {String} method
  1541. * @param {String} url
  1542. * @api public
  1543. */
  1544. function Request(method, url) {
  1545. var self = this;
  1546. this._query = this._query || [];
  1547. this.method = method;
  1548. this.url = url;
  1549. this.header = {}; // preserves header name case
  1550. this._header = {}; // coerces header names to lowercase
  1551. this.on('end', function () {
  1552. var err = null;
  1553. var res = null;
  1554. try {
  1555. res = new Response(self);
  1556. } catch (err_) {
  1557. err = new Error('Parser is unable to parse the response');
  1558. err.parse = true;
  1559. err.original = err_; // issue #675: return the raw response if the response parsing fails
  1560. if (self.xhr) {
  1561. // ie9 doesn't have 'response' property
  1562. err.rawResponse = typeof self.xhr.responseType === 'undefined' ? self.xhr.responseText : self.xhr.response; // issue #876: return the http status code if the response parsing fails
  1563. err.status = self.xhr.status ? self.xhr.status : null;
  1564. err.statusCode = err.status; // backwards-compat only
  1565. } else {
  1566. err.rawResponse = null;
  1567. err.status = null;
  1568. }
  1569. return self.callback(err);
  1570. }
  1571. self.emit('response', res);
  1572. var new_err;
  1573. try {
  1574. if (!self._isResponseOK(res)) {
  1575. new_err = new Error(res.statusText || res.text || 'Unsuccessful HTTP response');
  1576. }
  1577. } catch (err_) {
  1578. new_err = err_; // ok() callback can throw
  1579. } // #1000 don't catch errors from the callback to avoid double calling it
  1580. if (new_err) {
  1581. new_err.original = err;
  1582. new_err.response = res;
  1583. new_err.status = res.status;
  1584. self.callback(new_err, res);
  1585. } else {
  1586. self.callback(null, res);
  1587. }
  1588. });
  1589. }
  1590. /**
  1591. * Mixin `Emitter` and `RequestBase`.
  1592. */
  1593. // eslint-disable-next-line new-cap
  1594. componentEmitter(Request.prototype); // eslint-disable-next-line new-cap
  1595. requestBase(Request.prototype);
  1596. /**
  1597. * Set Content-Type to `type`, mapping values from `request.types`.
  1598. *
  1599. * Examples:
  1600. *
  1601. * superagent.types.xml = 'application/xml';
  1602. *
  1603. * request.post('/')
  1604. * .type('xml')
  1605. * .send(xmlstring)
  1606. * .end(callback);
  1607. *
  1608. * request.post('/')
  1609. * .type('application/xml')
  1610. * .send(xmlstring)
  1611. * .end(callback);
  1612. *
  1613. * @param {String} type
  1614. * @return {Request} for chaining
  1615. * @api public
  1616. */
  1617. Request.prototype.type = function (type) {
  1618. this.set('Content-Type', request.types[type] || type);
  1619. return this;
  1620. };
  1621. /**
  1622. * Set Accept to `type`, mapping values from `request.types`.
  1623. *
  1624. * Examples:
  1625. *
  1626. * superagent.types.json = 'application/json';
  1627. *
  1628. * request.get('/agent')
  1629. * .accept('json')
  1630. * .end(callback);
  1631. *
  1632. * request.get('/agent')
  1633. * .accept('application/json')
  1634. * .end(callback);
  1635. *
  1636. * @param {String} accept
  1637. * @return {Request} for chaining
  1638. * @api public
  1639. */
  1640. Request.prototype.accept = function (type) {
  1641. this.set('Accept', request.types[type] || type);
  1642. return this;
  1643. };
  1644. /**
  1645. * Set Authorization field value with `user` and `pass`.
  1646. *
  1647. * @param {String} user
  1648. * @param {String} [pass] optional in case of using 'bearer' as type
  1649. * @param {Object} options with 'type' property 'auto', 'basic' or 'bearer' (default 'basic')
  1650. * @return {Request} for chaining
  1651. * @api public
  1652. */
  1653. Request.prototype.auth = function (user, pass, options) {
  1654. if (arguments.length === 1) pass = '';
  1655. if (_typeof(pass) === 'object' && pass !== null) {
  1656. // pass is optional and can be replaced with options
  1657. options = pass;
  1658. pass = '';
  1659. }
  1660. if (!options) {
  1661. options = {
  1662. type: typeof btoa === 'function' ? 'basic' : 'auto'
  1663. };
  1664. }
  1665. var encoder = function encoder(string) {
  1666. if (typeof btoa === 'function') {
  1667. return btoa(string);
  1668. }
  1669. throw new Error('Cannot use basic auth, btoa is not a function');
  1670. };
  1671. return this._auth(user, pass, options, encoder);
  1672. };
  1673. /**
  1674. * Add query-string `val`.
  1675. *
  1676. * Examples:
  1677. *
  1678. * request.get('/shoes')
  1679. * .query('size=10')
  1680. * .query({ color: 'blue' })
  1681. *
  1682. * @param {Object|String} val
  1683. * @return {Request} for chaining
  1684. * @api public
  1685. */
  1686. Request.prototype.query = function (val) {
  1687. if (typeof val !== 'string') val = serialize(val);
  1688. if (val) this._query.push(val);
  1689. return this;
  1690. };
  1691. /**
  1692. * Queue the given `file` as an attachment to the specified `field`,
  1693. * with optional `options` (or filename).
  1694. *
  1695. * ``` js
  1696. * request.post('/upload')
  1697. * .attach('content', new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"}))
  1698. * .end(callback);
  1699. * ```
  1700. *
  1701. * @param {String} field
  1702. * @param {Blob|File} file
  1703. * @param {String|Object} options
  1704. * @return {Request} for chaining
  1705. * @api public
  1706. */
  1707. Request.prototype.attach = function (field, file, options) {
  1708. if (file) {
  1709. if (this._data) {
  1710. throw new Error("superagent can't mix .send() and .attach()");
  1711. }
  1712. this._getFormData().append(field, file, options || file.name);
  1713. }
  1714. return this;
  1715. };
  1716. Request.prototype._getFormData = function () {
  1717. if (!this._formData) {
  1718. this._formData = new root.FormData();
  1719. }
  1720. return this._formData;
  1721. };
  1722. /**
  1723. * Invoke the callback with `err` and `res`
  1724. * and handle arity check.
  1725. *
  1726. * @param {Error} err
  1727. * @param {Response} res
  1728. * @api private
  1729. */
  1730. Request.prototype.callback = function (err, res) {
  1731. if (this._shouldRetry(err, res)) {
  1732. return this._retry();
  1733. }
  1734. var fn = this._callback;
  1735. this.clearTimeout();
  1736. if (err) {
  1737. if (this._maxRetries) err.retries = this._retries - 1;
  1738. this.emit('error', err);
  1739. }
  1740. fn(err, res);
  1741. };
  1742. /**
  1743. * Invoke callback with x-domain error.
  1744. *
  1745. * @api private
  1746. */
  1747. Request.prototype.crossDomainError = function () {
  1748. var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.');
  1749. err.crossDomain = true;
  1750. err.status = this.status;
  1751. err.method = this.method;
  1752. err.url = this.url;
  1753. this.callback(err);
  1754. }; // This only warns, because the request is still likely to work
  1755. Request.prototype.agent = function () {
  1756. console.warn('This is not supported in browser version of superagent');
  1757. return this;
  1758. };
  1759. Request.prototype.ca = Request.prototype.agent;
  1760. Request.prototype.buffer = Request.prototype.ca; // This throws, because it can't send/receive data as expected
  1761. Request.prototype.write = function () {
  1762. throw new Error('Streaming is not supported in browser version of superagent');
  1763. };
  1764. Request.prototype.pipe = Request.prototype.write;
  1765. /**
  1766. * Check if `obj` is a host object,
  1767. * we don't want to serialize these :)
  1768. *
  1769. * @param {Object} obj host object
  1770. * @return {Boolean} is a host object
  1771. * @api private
  1772. */
  1773. Request.prototype._isHost = function (obj) {
  1774. // Native objects stringify to [object File], [object Blob], [object FormData], etc.
  1775. return obj && _typeof(obj) === 'object' && !Array.isArray(obj) && Object.prototype.toString.call(obj) !== '[object Object]';
  1776. };
  1777. /**
  1778. * Initiate request, invoking callback `fn(res)`
  1779. * with an instanceof `Response`.
  1780. *
  1781. * @param {Function} fn
  1782. * @return {Request} for chaining
  1783. * @api public
  1784. */
  1785. Request.prototype.end = function (fn) {
  1786. if (this._endCalled) {
  1787. console.warn('Warning: .end() was called twice. This is not supported in superagent');
  1788. }
  1789. this._endCalled = true; // store callback
  1790. this._callback = fn || noop; // querystring
  1791. this._finalizeQueryString();
  1792. this._end();
  1793. };
  1794. Request.prototype._setUploadTimeout = function () {
  1795. var self = this; // upload timeout it's wokrs only if deadline timeout is off
  1796. if (this._uploadTimeout && !this._uploadTimeoutTimer) {
  1797. this._uploadTimeoutTimer = setTimeout(function () {
  1798. self._timeoutError('Upload timeout of ', self._uploadTimeout, 'ETIMEDOUT');
  1799. }, this._uploadTimeout);
  1800. }
  1801. }; // eslint-disable-next-line complexity
  1802. Request.prototype._end = function () {
  1803. if (this._aborted) return this.callback(new Error('The request has been aborted even before .end() was called'));
  1804. var self = this;
  1805. this.xhr = request.getXHR();
  1806. var xhr = this.xhr;
  1807. var data = this._formData || this._data;
  1808. this._setTimeouts(); // state change
  1809. xhr.onreadystatechange = function () {
  1810. var readyState = xhr.readyState;
  1811. if (readyState >= 2 && self._responseTimeoutTimer) {
  1812. clearTimeout(self._responseTimeoutTimer);
  1813. }
  1814. if (readyState !== 4) {
  1815. return;
  1816. } // In IE9, reads to any property (e.g. status) off of an aborted XHR will
  1817. // result in the error "Could not complete the operation due to error c00c023f"
  1818. var status;
  1819. try {
  1820. status = xhr.status;
  1821. } catch (_unused5) {
  1822. status = 0;
  1823. }
  1824. if (!status) {
  1825. if (self.timedout || self._aborted) return;
  1826. return self.crossDomainError();
  1827. }
  1828. self.emit('end');
  1829. }; // progress
  1830. var handleProgress = function handleProgress(direction, e) {
  1831. if (e.total > 0) {
  1832. e.percent = e.loaded / e.total * 100;
  1833. if (e.percent === 100) {
  1834. clearTimeout(self._uploadTimeoutTimer);
  1835. }
  1836. }
  1837. e.direction = direction;
  1838. self.emit('progress', e);
  1839. };
  1840. if (this.hasListeners('progress')) {
  1841. try {
  1842. xhr.addEventListener('progress', handleProgress.bind(null, 'download'));
  1843. if (xhr.upload) {
  1844. xhr.upload.addEventListener('progress', handleProgress.bind(null, 'upload'));
  1845. }
  1846. } catch (_unused6) {// Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
  1847. // Reported here:
  1848. // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
  1849. }
  1850. }
  1851. if (xhr.upload) {
  1852. this._setUploadTimeout();
  1853. } // initiate request
  1854. try {
  1855. if (this.username && this.password) {
  1856. xhr.open(this.method, this.url, true, this.username, this.password);
  1857. } else {
  1858. xhr.open(this.method, this.url, true);
  1859. }
  1860. } catch (err) {
  1861. // see #1149
  1862. return this.callback(err);
  1863. } // CORS
  1864. if (this._withCredentials) xhr.withCredentials = true; // body
  1865. if (!this._formData && this.method !== 'GET' && this.method !== 'HEAD' && typeof data !== 'string' && !this._isHost(data)) {
  1866. // serialize stuff
  1867. var contentType = this._header['content-type'];
  1868. var _serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : ''];
  1869. if (!_serialize && isJSON(contentType)) {
  1870. _serialize = request.serialize['application/json'];
  1871. }
  1872. if (_serialize) data = _serialize(data);
  1873. } // set header fields
  1874. for (var field in this.header) {
  1875. if (this.header[field] === null) continue;
  1876. if (Object.prototype.hasOwnProperty.call(this.header, field)) xhr.setRequestHeader(field, this.header[field]);
  1877. }
  1878. if (this._responseType) {
  1879. xhr.responseType = this._responseType;
  1880. } // send stuff
  1881. this.emit('request', this); // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing)
  1882. // We need null here if data is undefined
  1883. xhr.send(typeof data === 'undefined' ? null : data);
  1884. };
  1885. request.agent = function () {
  1886. return new agentBase();
  1887. };
  1888. ['GET', 'POST', 'OPTIONS', 'PATCH', 'PUT', 'DELETE'].forEach(function (method) {
  1889. agentBase.prototype[method.toLowerCase()] = function (url, fn) {
  1890. var req = new request.Request(method, url);
  1891. this._setDefaults(req);
  1892. if (fn) {
  1893. req.end(fn);
  1894. }
  1895. return req;
  1896. };
  1897. });
  1898. agentBase.prototype.del = agentBase.prototype.delete;
  1899. /**
  1900. * GET `url` with optional callback `fn(res)`.
  1901. *
  1902. * @param {String} url
  1903. * @param {Mixed|Function} [data] or fn
  1904. * @param {Function} [fn]
  1905. * @return {Request}
  1906. * @api public
  1907. */
  1908. request.get = function (url, data, fn) {
  1909. var req = request('GET', url);
  1910. if (typeof data === 'function') {
  1911. fn = data;
  1912. data = null;
  1913. }
  1914. if (data) req.query(data);
  1915. if (fn) req.end(fn);
  1916. return req;
  1917. };
  1918. /**
  1919. * HEAD `url` with optional callback `fn(res)`.
  1920. *
  1921. * @param {String} url
  1922. * @param {Mixed|Function} [data] or fn
  1923. * @param {Function} [fn]
  1924. * @return {Request}
  1925. * @api public
  1926. */
  1927. request.head = function (url, data, fn) {
  1928. var req = request('HEAD', url);
  1929. if (typeof data === 'function') {
  1930. fn = data;
  1931. data = null;
  1932. }
  1933. if (data) req.query(data);
  1934. if (fn) req.end(fn);
  1935. return req;
  1936. };
  1937. /**
  1938. * OPTIONS query to `url` with optional callback `fn(res)`.
  1939. *
  1940. * @param {String} url
  1941. * @param {Mixed|Function} [data] or fn
  1942. * @param {Function} [fn]
  1943. * @return {Request}
  1944. * @api public
  1945. */
  1946. request.options = function (url, data, fn) {
  1947. var req = request('OPTIONS', url);
  1948. if (typeof data === 'function') {
  1949. fn = data;
  1950. data = null;
  1951. }
  1952. if (data) req.send(data);
  1953. if (fn) req.end(fn);
  1954. return req;
  1955. };
  1956. /**
  1957. * DELETE `url` with optional `data` and callback `fn(res)`.
  1958. *
  1959. * @param {String} url
  1960. * @param {Mixed} [data]
  1961. * @param {Function} [fn]
  1962. * @return {Request}
  1963. * @api public
  1964. */
  1965. function del(url, data, fn) {
  1966. var req = request('DELETE', url);
  1967. if (typeof data === 'function') {
  1968. fn = data;
  1969. data = null;
  1970. }
  1971. if (data) req.send(data);
  1972. if (fn) req.end(fn);
  1973. return req;
  1974. }
  1975. request.del = del;
  1976. request.delete = del;
  1977. /**
  1978. * PATCH `url` with optional `data` and callback `fn(res)`.
  1979. *
  1980. * @param {String} url
  1981. * @param {Mixed} [data]
  1982. * @param {Function} [fn]
  1983. * @return {Request}
  1984. * @api public
  1985. */
  1986. request.patch = function (url, data, fn) {
  1987. var req = request('PATCH', url);
  1988. if (typeof data === 'function') {
  1989. fn = data;
  1990. data = null;
  1991. }
  1992. if (data) req.send(data);
  1993. if (fn) req.end(fn);
  1994. return req;
  1995. };
  1996. /**
  1997. * POST `url` with optional `data` and callback `fn(res)`.
  1998. *
  1999. * @param {String} url
  2000. * @param {Mixed} [data]
  2001. * @param {Function} [fn]
  2002. * @return {Request}
  2003. * @api public
  2004. */
  2005. request.post = function (url, data, fn) {
  2006. var req = request('POST', url);
  2007. if (typeof data === 'function') {
  2008. fn = data;
  2009. data = null;
  2010. }
  2011. if (data) req.send(data);
  2012. if (fn) req.end(fn);
  2013. return req;
  2014. };
  2015. /**
  2016. * PUT `url` with optional `data` and callback `fn(res)`.
  2017. *
  2018. * @param {String} url
  2019. * @param {Mixed|Function} [data] or fn
  2020. * @param {Function} [fn]
  2021. * @return {Request}
  2022. * @api public
  2023. */
  2024. request.put = function (url, data, fn) {
  2025. var req = request('PUT', url);
  2026. if (typeof data === 'function') {
  2027. fn = data;
  2028. data = null;
  2029. }
  2030. if (data) req.send(data);
  2031. if (fn) req.end(fn);
  2032. return req;
  2033. };
  2034. });
  2035. var client_1 = client.Request;
  2036. var lib = createCommonjsModule(function (module, exports) {
  2037. Object.defineProperty(exports, "__esModule", { value: true });
  2038. exports.request = function (url, options) {
  2039. if (options === void 0) { options = {}; }
  2040. var _a = options.method, method = _a === void 0 ? "GET" : _a, data = options.data, headers = options.headers, onprogress = options.onprogress;
  2041. var req = client(method, url);
  2042. if (headers) {
  2043. req.set(headers);
  2044. }
  2045. if (onprogress) {
  2046. req.on("progress", onprogress);
  2047. }
  2048. return req
  2049. .send(data)
  2050. .catch(function (error) {
  2051. if (error.response) {
  2052. return error.response;
  2053. }
  2054. throw error;
  2055. })
  2056. .then(function (_a) {
  2057. var status = _a.status, ok = _a.ok, header = _a.header, body = _a.body;
  2058. return ({
  2059. status: status,
  2060. ok: ok,
  2061. headers: header,
  2062. data: body
  2063. });
  2064. });
  2065. };
  2066. exports.upload = function (url, file, options) {
  2067. if (options === void 0) { options = {}; }
  2068. var data = options.data, headers = options.headers, onprogress = options.onprogress;
  2069. var req = client("POST", url).attach(file.field, file.data, file.name);
  2070. if (data) {
  2071. req.field(data);
  2072. }
  2073. if (headers) {
  2074. req.set(headers);
  2075. }
  2076. if (onprogress) {
  2077. req.on("progress", onprogress);
  2078. }
  2079. return req
  2080. .catch(function (error) {
  2081. if (error.response) {
  2082. return error.response;
  2083. }
  2084. throw error;
  2085. })
  2086. .then(function (_a) {
  2087. var status = _a.status, ok = _a.ok, header = _a.header, body = _a.body;
  2088. return ({
  2089. status: status,
  2090. ok: ok,
  2091. headers: header,
  2092. data: body
  2093. });
  2094. });
  2095. };
  2096. });
  2097. unwrapExports(lib);
  2098. var lib_1 = lib.request;
  2099. var lib_2 = lib.upload;
  2100. var lib$1 = createCommonjsModule(function (module, exports) {
  2101. Object.defineProperty(exports, "__esModule", {
  2102. value: true
  2103. });
  2104. exports.request = lib.request;
  2105. exports.upload = lib.upload;
  2106. exports.storage = window.localStorage;
  2107. exports.WebSocket = window.WebSocket;
  2108. exports.platformInfo = {
  2109. name: "Browser"
  2110. };
  2111. });
  2112. unwrapExports(lib$1);
  2113. var lib_1$1 = lib$1.request;
  2114. var lib_2$1 = lib$1.upload;
  2115. var lib_3 = lib$1.storage;
  2116. var lib_4 = lib$1.WebSocket;
  2117. var lib_5 = lib$1.platformInfo;
  2118. var long_1 = createCommonjsModule(function (module) {
  2119. /*
  2120. Copyright 2013 Daniel Wirtz <dcode@dcode.io>
  2121. Copyright 2009 The Closure Library Authors. All Rights Reserved.
  2122. Licensed under the Apache License, Version 2.0 (the "License");
  2123. you may not use this file except in compliance with the License.
  2124. You may obtain a copy of the License at
  2125. http://www.apache.org/licenses/LICENSE-2.0
  2126. Unless required by applicable law or agreed to in writing, software
  2127. distributed under the License is distributed on an "AS-IS" BASIS,
  2128. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  2129. See the License for the specific language governing permissions and
  2130. limitations under the License.
  2131. */
  2132. /**
  2133. * @license long.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
  2134. * Released under the Apache License, Version 2.0
  2135. * see: https://github.com/dcodeIO/long.js for details
  2136. */
  2137. (function(global, factory) {
  2138. /* AMD */ if (typeof commonjsRequire === 'function' && 'object' === "object" && module && module["exports"])
  2139. module["exports"] = factory();
  2140. /* Global */ else
  2141. (global["dcodeIO"] = global["dcodeIO"] || {})["Long"] = factory();
  2142. })(commonjsGlobal, function() {
  2143. /**
  2144. * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers.
  2145. * See the from* functions below for more convenient ways of constructing Longs.
  2146. * @exports Long
  2147. * @class A Long class for representing a 64 bit two's-complement integer value.
  2148. * @param {number} low The low (signed) 32 bits of the long
  2149. * @param {number} high The high (signed) 32 bits of the long
  2150. * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
  2151. * @constructor
  2152. */
  2153. function Long(low, high, unsigned) {
  2154. /**
  2155. * The low 32 bits as a signed value.
  2156. * @type {number}
  2157. */
  2158. this.low = low | 0;
  2159. /**
  2160. * The high 32 bits as a signed value.
  2161. * @type {number}
  2162. */
  2163. this.high = high | 0;
  2164. /**
  2165. * Whether unsigned or not.
  2166. * @type {boolean}
  2167. */
  2168. this.unsigned = !!unsigned;
  2169. }
  2170. // The internal representation of a long is the two given signed, 32-bit values.
  2171. // We use 32-bit pieces because these are the size of integers on which
  2172. // Javascript performs bit-operations. For operations like addition and
  2173. // multiplication, we split each number into 16 bit pieces, which can easily be
  2174. // multiplied within Javascript's floating-point representation without overflow
  2175. // or change in sign.
  2176. //
  2177. // In the algorithms below, we frequently reduce the negative case to the
  2178. // positive case by negating the input(s) and then post-processing the result.
  2179. // Note that we must ALWAYS check specially whether those values are MIN_VALUE
  2180. // (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
  2181. // a positive number, it overflows back into a negative). Not handling this
  2182. // case would often result in infinite recursion.
  2183. //
  2184. // Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from*
  2185. // methods on which they depend.
  2186. /**
  2187. * An indicator used to reliably determine if an object is a Long or not.
  2188. * @type {boolean}
  2189. * @const
  2190. * @private
  2191. */
  2192. Long.prototype.__isLong__;
  2193. Object.defineProperty(Long.prototype, "__isLong__", {
  2194. value: true,
  2195. enumerable: false,
  2196. configurable: false
  2197. });
  2198. /**
  2199. * @function
  2200. * @param {*} obj Object
  2201. * @returns {boolean}
  2202. * @inner
  2203. */
  2204. function isLong(obj) {
  2205. return (obj && obj["__isLong__"]) === true;
  2206. }
  2207. /**
  2208. * Tests if the specified object is a Long.
  2209. * @function
  2210. * @param {*} obj Object
  2211. * @returns {boolean}
  2212. */
  2213. Long.isLong = isLong;
  2214. /**
  2215. * A cache of the Long representations of small integer values.
  2216. * @type {!Object}
  2217. * @inner
  2218. */
  2219. var INT_CACHE = {};
  2220. /**
  2221. * A cache of the Long representations of small unsigned integer values.
  2222. * @type {!Object}
  2223. * @inner
  2224. */
  2225. var UINT_CACHE = {};
  2226. /**
  2227. * @param {number} value
  2228. * @param {boolean=} unsigned
  2229. * @returns {!Long}
  2230. * @inner
  2231. */
  2232. function fromInt(value, unsigned) {
  2233. var obj, cachedObj, cache;
  2234. if (unsigned) {
  2235. value >>>= 0;
  2236. if (cache = (0 <= value && value < 256)) {
  2237. cachedObj = UINT_CACHE[value];
  2238. if (cachedObj)
  2239. return cachedObj;
  2240. }
  2241. obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true);
  2242. if (cache)
  2243. UINT_CACHE[value] = obj;
  2244. return obj;
  2245. } else {
  2246. value |= 0;
  2247. if (cache = (-128 <= value && value < 128)) {
  2248. cachedObj = INT_CACHE[value];
  2249. if (cachedObj)
  2250. return cachedObj;
  2251. }
  2252. obj = fromBits(value, value < 0 ? -1 : 0, false);
  2253. if (cache)
  2254. INT_CACHE[value] = obj;
  2255. return obj;
  2256. }
  2257. }
  2258. /**
  2259. * Returns a Long representing the given 32 bit integer value.
  2260. * @function
  2261. * @param {number} value The 32 bit integer in question
  2262. * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
  2263. * @returns {!Long} The corresponding Long value
  2264. */
  2265. Long.fromInt = fromInt;
  2266. /**
  2267. * @param {number} value
  2268. * @param {boolean=} unsigned
  2269. * @returns {!Long}
  2270. * @inner
  2271. */
  2272. function fromNumber(value, unsigned) {
  2273. if (isNaN(value) || !isFinite(value))
  2274. return unsigned ? UZERO : ZERO;
  2275. if (unsigned) {
  2276. if (value < 0)
  2277. return UZERO;
  2278. if (value >= TWO_PWR_64_DBL)
  2279. return MAX_UNSIGNED_VALUE;
  2280. } else {
  2281. if (value <= -TWO_PWR_63_DBL)
  2282. return MIN_VALUE;
  2283. if (value + 1 >= TWO_PWR_63_DBL)
  2284. return MAX_VALUE;
  2285. }
  2286. if (value < 0)
  2287. return fromNumber(-value, unsigned).neg();
  2288. return fromBits((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned);
  2289. }
  2290. /**
  2291. * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.
  2292. * @function
  2293. * @param {number} value The number in question
  2294. * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
  2295. * @returns {!Long} The corresponding Long value
  2296. */
  2297. Long.fromNumber = fromNumber;
  2298. /**
  2299. * @param {number} lowBits
  2300. * @param {number} highBits
  2301. * @param {boolean=} unsigned
  2302. * @returns {!Long}
  2303. * @inner
  2304. */
  2305. function fromBits(lowBits, highBits, unsigned) {
  2306. return new Long(lowBits, highBits, unsigned);
  2307. }
  2308. /**
  2309. * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is
  2310. * assumed to use 32 bits.
  2311. * @function
  2312. * @param {number} lowBits The low 32 bits
  2313. * @param {number} highBits The high 32 bits
  2314. * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
  2315. * @returns {!Long} The corresponding Long value
  2316. */
  2317. Long.fromBits = fromBits;
  2318. /**
  2319. * @function
  2320. * @param {number} base
  2321. * @param {number} exponent
  2322. * @returns {number}
  2323. * @inner
  2324. */
  2325. var pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4)
  2326. /**
  2327. * @param {string} str
  2328. * @param {(boolean|number)=} unsigned
  2329. * @param {number=} radix
  2330. * @returns {!Long}
  2331. * @inner
  2332. */
  2333. function fromString(str, unsigned, radix) {
  2334. if (str.length === 0)
  2335. throw Error('empty string');
  2336. if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity")
  2337. return ZERO;
  2338. if (typeof unsigned === 'number') {
  2339. // For goog.math.long compatibility
  2340. radix = unsigned,
  2341. unsigned = false;
  2342. } else {
  2343. unsigned = !! unsigned;
  2344. }
  2345. radix = radix || 10;
  2346. if (radix < 2 || 36 < radix)
  2347. throw RangeError('radix');
  2348. var p;
  2349. if ((p = str.indexOf('-')) > 0)
  2350. throw Error('interior hyphen');
  2351. else if (p === 0) {
  2352. return fromString(str.substring(1), unsigned, radix).neg();
  2353. }
  2354. // Do several (8) digits each time through the loop, so as to
  2355. // minimize the calls to the very expensive emulated div.
  2356. var radixToPower = fromNumber(pow_dbl(radix, 8));
  2357. var result = ZERO;
  2358. for (var i = 0; i < str.length; i += 8) {
  2359. var size = Math.min(8, str.length - i),
  2360. value = parseInt(str.substring(i, i + size), radix);
  2361. if (size < 8) {
  2362. var power = fromNumber(pow_dbl(radix, size));
  2363. result = result.mul(power).add(fromNumber(value));
  2364. } else {
  2365. result = result.mul(radixToPower);
  2366. result = result.add(fromNumber(value));
  2367. }
  2368. }
  2369. result.unsigned = unsigned;
  2370. return result;
  2371. }
  2372. /**
  2373. * Returns a Long representation of the given string, written using the specified radix.
  2374. * @function
  2375. * @param {string} str The textual representation of the Long
  2376. * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed
  2377. * @param {number=} radix The radix in which the text is written (2-36), defaults to 10
  2378. * @returns {!Long} The corresponding Long value
  2379. */
  2380. Long.fromString = fromString;
  2381. /**
  2382. * @function
  2383. * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val
  2384. * @returns {!Long}
  2385. * @inner
  2386. */
  2387. function fromValue(val) {
  2388. if (val /* is compatible */ instanceof Long)
  2389. return val;
  2390. if (typeof val === 'number')
  2391. return fromNumber(val);
  2392. if (typeof val === 'string')
  2393. return fromString(val);
  2394. // Throws for non-objects, converts non-instanceof Long:
  2395. return fromBits(val.low, val.high, val.unsigned);
  2396. }
  2397. /**
  2398. * Converts the specified value to a Long.
  2399. * @function
  2400. * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value
  2401. * @returns {!Long}
  2402. */
  2403. Long.fromValue = fromValue;
  2404. // NOTE: the compiler should inline these constant values below and then remove these variables, so there should be
  2405. // no runtime penalty for these.
  2406. /**
  2407. * @type {number}
  2408. * @const
  2409. * @inner
  2410. */
  2411. var TWO_PWR_16_DBL = 1 << 16;
  2412. /**
  2413. * @type {number}
  2414. * @const
  2415. * @inner
  2416. */
  2417. var TWO_PWR_24_DBL = 1 << 24;
  2418. /**
  2419. * @type {number}
  2420. * @const
  2421. * @inner
  2422. */
  2423. var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;
  2424. /**
  2425. * @type {number}
  2426. * @const
  2427. * @inner
  2428. */
  2429. var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;
  2430. /**
  2431. * @type {number}
  2432. * @const
  2433. * @inner
  2434. */
  2435. var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;
  2436. /**
  2437. * @type {!Long}
  2438. * @const
  2439. * @inner
  2440. */
  2441. var TWO_PWR_24 = fromInt(TWO_PWR_24_DBL);
  2442. /**
  2443. * @type {!Long}
  2444. * @inner
  2445. */
  2446. var ZERO = fromInt(0);
  2447. /**
  2448. * Signed zero.
  2449. * @type {!Long}
  2450. */
  2451. Long.ZERO = ZERO;
  2452. /**
  2453. * @type {!Long}
  2454. * @inner
  2455. */
  2456. var UZERO = fromInt(0, true);
  2457. /**
  2458. * Unsigned zero.
  2459. * @type {!Long}
  2460. */
  2461. Long.UZERO = UZERO;
  2462. /**
  2463. * @type {!Long}
  2464. * @inner
  2465. */
  2466. var ONE = fromInt(1);
  2467. /**
  2468. * Signed one.
  2469. * @type {!Long}
  2470. */
  2471. Long.ONE = ONE;
  2472. /**
  2473. * @type {!Long}
  2474. * @inner
  2475. */
  2476. var UONE = fromInt(1, true);
  2477. /**
  2478. * Unsigned one.
  2479. * @type {!Long}
  2480. */
  2481. Long.UONE = UONE;
  2482. /**
  2483. * @type {!Long}
  2484. * @inner
  2485. */
  2486. var NEG_ONE = fromInt(-1);
  2487. /**
  2488. * Signed negative one.
  2489. * @type {!Long}
  2490. */
  2491. Long.NEG_ONE = NEG_ONE;
  2492. /**
  2493. * @type {!Long}
  2494. * @inner
  2495. */
  2496. var MAX_VALUE = fromBits(0xFFFFFFFF|0, 0x7FFFFFFF|0, false);
  2497. /**
  2498. * Maximum signed value.
  2499. * @type {!Long}
  2500. */
  2501. Long.MAX_VALUE = MAX_VALUE;
  2502. /**
  2503. * @type {!Long}
  2504. * @inner
  2505. */
  2506. var MAX_UNSIGNED_VALUE = fromBits(0xFFFFFFFF|0, 0xFFFFFFFF|0, true);
  2507. /**
  2508. * Maximum unsigned value.
  2509. * @type {!Long}
  2510. */
  2511. Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE;
  2512. /**
  2513. * @type {!Long}
  2514. * @inner
  2515. */
  2516. var MIN_VALUE = fromBits(0, 0x80000000|0, false);
  2517. /**
  2518. * Minimum signed value.
  2519. * @type {!Long}
  2520. */
  2521. Long.MIN_VALUE = MIN_VALUE;
  2522. /**
  2523. * @alias Long.prototype
  2524. * @inner
  2525. */
  2526. var LongPrototype = Long.prototype;
  2527. /**
  2528. * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.
  2529. * @returns {number}
  2530. */
  2531. LongPrototype.toInt = function toInt() {
  2532. return this.unsigned ? this.low >>> 0 : this.low;
  2533. };
  2534. /**
  2535. * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).
  2536. * @returns {number}
  2537. */
  2538. LongPrototype.toNumber = function toNumber() {
  2539. if (this.unsigned)
  2540. return ((this.high >>> 0) * TWO_PWR_32_DBL) + (this.low >>> 0);
  2541. return this.high * TWO_PWR_32_DBL + (this.low >>> 0);
  2542. };
  2543. /**
  2544. * Converts the Long to a string written in the specified radix.
  2545. * @param {number=} radix Radix (2-36), defaults to 10
  2546. * @returns {string}
  2547. * @override
  2548. * @throws {RangeError} If `radix` is out of range
  2549. */
  2550. LongPrototype.toString = function toString(radix) {
  2551. radix = radix || 10;
  2552. if (radix < 2 || 36 < radix)
  2553. throw RangeError('radix');
  2554. if (this.isZero())
  2555. return '0';
  2556. if (this.isNegative()) { // Unsigned Longs are never negative
  2557. if (this.eq(MIN_VALUE)) {
  2558. // We need to change the Long value before it can be negated, so we remove
  2559. // the bottom-most digit in this base and then recurse to do the rest.
  2560. var radixLong = fromNumber(radix),
  2561. div = this.div(radixLong),
  2562. rem1 = div.mul(radixLong).sub(this);
  2563. return div.toString(radix) + rem1.toInt().toString(radix);
  2564. } else
  2565. return '-' + this.neg().toString(radix);
  2566. }
  2567. // Do several (6) digits each time through the loop, so as to
  2568. // minimize the calls to the very expensive emulated div.
  2569. var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned),
  2570. rem = this;
  2571. var result = '';
  2572. while (true) {
  2573. var remDiv = rem.div(radixToPower),
  2574. intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0,
  2575. digits = intval.toString(radix);
  2576. rem = remDiv;
  2577. if (rem.isZero())
  2578. return digits + result;
  2579. else {
  2580. while (digits.length < 6)
  2581. digits = '0' + digits;
  2582. result = '' + digits + result;
  2583. }
  2584. }
  2585. };
  2586. /**
  2587. * Gets the high 32 bits as a signed integer.
  2588. * @returns {number} Signed high bits
  2589. */
  2590. LongPrototype.getHighBits = function getHighBits() {
  2591. return this.high;
  2592. };
  2593. /**
  2594. * Gets the high 32 bits as an unsigned integer.
  2595. * @returns {number} Unsigned high bits
  2596. */
  2597. LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() {
  2598. return this.high >>> 0;
  2599. };
  2600. /**
  2601. * Gets the low 32 bits as a signed integer.
  2602. * @returns {number} Signed low bits
  2603. */
  2604. LongPrototype.getLowBits = function getLowBits() {
  2605. return this.low;
  2606. };
  2607. /**
  2608. * Gets the low 32 bits as an unsigned integer.
  2609. * @returns {number} Unsigned low bits
  2610. */
  2611. LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() {
  2612. return this.low >>> 0;
  2613. };
  2614. /**
  2615. * Gets the number of bits needed to represent the absolute value of this Long.
  2616. * @returns {number}
  2617. */
  2618. LongPrototype.getNumBitsAbs = function getNumBitsAbs() {
  2619. if (this.isNegative()) // Unsigned Longs are never negative
  2620. return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs();
  2621. var val = this.high != 0 ? this.high : this.low;
  2622. for (var bit = 31; bit > 0; bit--)
  2623. if ((val & (1 << bit)) != 0)
  2624. break;
  2625. return this.high != 0 ? bit + 33 : bit + 1;
  2626. };
  2627. /**
  2628. * Tests if this Long's value equals zero.
  2629. * @returns {boolean}
  2630. */
  2631. LongPrototype.isZero = function isZero() {
  2632. return this.high === 0 && this.low === 0;
  2633. };
  2634. /**
  2635. * Tests if this Long's value is negative.
  2636. * @returns {boolean}
  2637. */
  2638. LongPrototype.isNegative = function isNegative() {
  2639. return !this.unsigned && this.high < 0;
  2640. };
  2641. /**
  2642. * Tests if this Long's value is positive.
  2643. * @returns {boolean}
  2644. */
  2645. LongPrototype.isPositive = function isPositive() {
  2646. return this.unsigned || this.high >= 0;
  2647. };
  2648. /**
  2649. * Tests if this Long's value is odd.
  2650. * @returns {boolean}
  2651. */
  2652. LongPrototype.isOdd = function isOdd() {
  2653. return (this.low & 1) === 1;
  2654. };
  2655. /**
  2656. * Tests if this Long's value is even.
  2657. * @returns {boolean}
  2658. */
  2659. LongPrototype.isEven = function isEven() {
  2660. return (this.low & 1) === 0;
  2661. };
  2662. /**
  2663. * Tests if this Long's value equals the specified's.
  2664. * @param {!Long|number|string} other Other value
  2665. * @returns {boolean}
  2666. */
  2667. LongPrototype.equals = function equals(other) {
  2668. if (!isLong(other))
  2669. other = fromValue(other);
  2670. if (this.unsigned !== other.unsigned && (this.high >>> 31) === 1 && (other.high >>> 31) === 1)
  2671. return false;
  2672. return this.high === other.high && this.low === other.low;
  2673. };
  2674. /**
  2675. * Tests if this Long's value equals the specified's. This is an alias of {@link Long#equals}.
  2676. * @function
  2677. * @param {!Long|number|string} other Other value
  2678. * @returns {boolean}
  2679. */
  2680. LongPrototype.eq = LongPrototype.equals;
  2681. /**
  2682. * Tests if this Long's value differs from the specified's.
  2683. * @param {!Long|number|string} other Other value
  2684. * @returns {boolean}
  2685. */
  2686. LongPrototype.notEquals = function notEquals(other) {
  2687. return !this.eq(/* validates */ other);
  2688. };
  2689. /**
  2690. * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}.
  2691. * @function
  2692. * @param {!Long|number|string} other Other value
  2693. * @returns {boolean}
  2694. */
  2695. LongPrototype.neq = LongPrototype.notEquals;
  2696. /**
  2697. * Tests if this Long's value is less than the specified's.
  2698. * @param {!Long|number|string} other Other value
  2699. * @returns {boolean}
  2700. */
  2701. LongPrototype.lessThan = function lessThan(other) {
  2702. return this.comp(/* validates */ other) < 0;
  2703. };
  2704. /**
  2705. * Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}.
  2706. * @function
  2707. * @param {!Long|number|string} other Other value
  2708. * @returns {boolean}
  2709. */
  2710. LongPrototype.lt = LongPrototype.lessThan;
  2711. /**
  2712. * Tests if this Long's value is less than or equal the specified's.
  2713. * @param {!Long|number|string} other Other value
  2714. * @returns {boolean}
  2715. */
  2716. LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) {
  2717. return this.comp(/* validates */ other) <= 0;
  2718. };
  2719. /**
  2720. * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.
  2721. * @function
  2722. * @param {!Long|number|string} other Other value
  2723. * @returns {boolean}
  2724. */
  2725. LongPrototype.lte = LongPrototype.lessThanOrEqual;
  2726. /**
  2727. * Tests if this Long's value is greater than the specified's.
  2728. * @param {!Long|number|string} other Other value
  2729. * @returns {boolean}
  2730. */
  2731. LongPrototype.greaterThan = function greaterThan(other) {
  2732. return this.comp(/* validates */ other) > 0;
  2733. };
  2734. /**
  2735. * Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}.
  2736. * @function
  2737. * @param {!Long|number|string} other Other value
  2738. * @returns {boolean}
  2739. */
  2740. LongPrototype.gt = LongPrototype.greaterThan;
  2741. /**
  2742. * Tests if this Long's value is greater than or equal the specified's.
  2743. * @param {!Long|number|string} other Other value
  2744. * @returns {boolean}
  2745. */
  2746. LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) {
  2747. return this.comp(/* validates */ other) >= 0;
  2748. };
  2749. /**
  2750. * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.
  2751. * @function
  2752. * @param {!Long|number|string} other Other value
  2753. * @returns {boolean}
  2754. */
  2755. LongPrototype.gte = LongPrototype.greaterThanOrEqual;
  2756. /**
  2757. * Compares this Long's value with the specified's.
  2758. * @param {!Long|number|string} other Other value
  2759. * @returns {number} 0 if they are the same, 1 if the this is greater and -1
  2760. * if the given one is greater
  2761. */
  2762. LongPrototype.compare = function compare(other) {
  2763. if (!isLong(other))
  2764. other = fromValue(other);
  2765. if (this.eq(other))
  2766. return 0;
  2767. var thisNeg = this.isNegative(),
  2768. otherNeg = other.isNegative();
  2769. if (thisNeg && !otherNeg)
  2770. return -1;
  2771. if (!thisNeg && otherNeg)
  2772. return 1;
  2773. // At this point the sign bits are the same
  2774. if (!this.unsigned)
  2775. return this.sub(other).isNegative() ? -1 : 1;
  2776. // Both are positive if at least one is unsigned
  2777. return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1;
  2778. };
  2779. /**
  2780. * Compares this Long's value with the specified's. This is an alias of {@link Long#compare}.
  2781. * @function
  2782. * @param {!Long|number|string} other Other value
  2783. * @returns {number} 0 if they are the same, 1 if the this is greater and -1
  2784. * if the given one is greater
  2785. */
  2786. LongPrototype.comp = LongPrototype.compare;
  2787. /**
  2788. * Negates this Long's value.
  2789. * @returns {!Long} Negated Long
  2790. */
  2791. LongPrototype.negate = function negate() {
  2792. if (!this.unsigned && this.eq(MIN_VALUE))
  2793. return MIN_VALUE;
  2794. return this.not().add(ONE);
  2795. };
  2796. /**
  2797. * Negates this Long's value. This is an alias of {@link Long#negate}.
  2798. * @function
  2799. * @returns {!Long} Negated Long
  2800. */
  2801. LongPrototype.neg = LongPrototype.negate;
  2802. /**
  2803. * Returns the sum of this and the specified Long.
  2804. * @param {!Long|number|string} addend Addend
  2805. * @returns {!Long} Sum
  2806. */
  2807. LongPrototype.add = function add(addend) {
  2808. if (!isLong(addend))
  2809. addend = fromValue(addend);
  2810. // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
  2811. var a48 = this.high >>> 16;
  2812. var a32 = this.high & 0xFFFF;
  2813. var a16 = this.low >>> 16;
  2814. var a00 = this.low & 0xFFFF;
  2815. var b48 = addend.high >>> 16;
  2816. var b32 = addend.high & 0xFFFF;
  2817. var b16 = addend.low >>> 16;
  2818. var b00 = addend.low & 0xFFFF;
  2819. var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
  2820. c00 += a00 + b00;
  2821. c16 += c00 >>> 16;
  2822. c00 &= 0xFFFF;
  2823. c16 += a16 + b16;
  2824. c32 += c16 >>> 16;
  2825. c16 &= 0xFFFF;
  2826. c32 += a32 + b32;
  2827. c48 += c32 >>> 16;
  2828. c32 &= 0xFFFF;
  2829. c48 += a48 + b48;
  2830. c48 &= 0xFFFF;
  2831. return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
  2832. };
  2833. /**
  2834. * Returns the difference of this and the specified Long.
  2835. * @param {!Long|number|string} subtrahend Subtrahend
  2836. * @returns {!Long} Difference
  2837. */
  2838. LongPrototype.subtract = function subtract(subtrahend) {
  2839. if (!isLong(subtrahend))
  2840. subtrahend = fromValue(subtrahend);
  2841. return this.add(subtrahend.neg());
  2842. };
  2843. /**
  2844. * Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}.
  2845. * @function
  2846. * @param {!Long|number|string} subtrahend Subtrahend
  2847. * @returns {!Long} Difference
  2848. */
  2849. LongPrototype.sub = LongPrototype.subtract;
  2850. /**
  2851. * Returns the product of this and the specified Long.
  2852. * @param {!Long|number|string} multiplier Multiplier
  2853. * @returns {!Long} Product
  2854. */
  2855. LongPrototype.multiply = function multiply(multiplier) {
  2856. if (this.isZero())
  2857. return ZERO;
  2858. if (!isLong(multiplier))
  2859. multiplier = fromValue(multiplier);
  2860. if (multiplier.isZero())
  2861. return ZERO;
  2862. if (this.eq(MIN_VALUE))
  2863. return multiplier.isOdd() ? MIN_VALUE : ZERO;
  2864. if (multiplier.eq(MIN_VALUE))
  2865. return this.isOdd() ? MIN_VALUE : ZERO;
  2866. if (this.isNegative()) {
  2867. if (multiplier.isNegative())
  2868. return this.neg().mul(multiplier.neg());
  2869. else
  2870. return this.neg().mul(multiplier).neg();
  2871. } else if (multiplier.isNegative())
  2872. return this.mul(multiplier.neg()).neg();
  2873. // If both longs are small, use float multiplication
  2874. if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24))
  2875. return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned);
  2876. // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
  2877. // We can skip products that would overflow.
  2878. var a48 = this.high >>> 16;
  2879. var a32 = this.high & 0xFFFF;
  2880. var a16 = this.low >>> 16;
  2881. var a00 = this.low & 0xFFFF;
  2882. var b48 = multiplier.high >>> 16;
  2883. var b32 = multiplier.high & 0xFFFF;
  2884. var b16 = multiplier.low >>> 16;
  2885. var b00 = multiplier.low & 0xFFFF;
  2886. var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
  2887. c00 += a00 * b00;
  2888. c16 += c00 >>> 16;
  2889. c00 &= 0xFFFF;
  2890. c16 += a16 * b00;
  2891. c32 += c16 >>> 16;
  2892. c16 &= 0xFFFF;
  2893. c16 += a00 * b16;
  2894. c32 += c16 >>> 16;
  2895. c16 &= 0xFFFF;
  2896. c32 += a32 * b00;
  2897. c48 += c32 >>> 16;
  2898. c32 &= 0xFFFF;
  2899. c32 += a16 * b16;
  2900. c48 += c32 >>> 16;
  2901. c32 &= 0xFFFF;
  2902. c32 += a00 * b32;
  2903. c48 += c32 >>> 16;
  2904. c32 &= 0xFFFF;
  2905. c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
  2906. c48 &= 0xFFFF;
  2907. return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
  2908. };
  2909. /**
  2910. * Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}.
  2911. * @function
  2912. * @param {!Long|number|string} multiplier Multiplier
  2913. * @returns {!Long} Product
  2914. */
  2915. LongPrototype.mul = LongPrototype.multiply;
  2916. /**
  2917. * Returns this Long divided by the specified. The result is signed if this Long is signed or
  2918. * unsigned if this Long is unsigned.
  2919. * @param {!Long|number|string} divisor Divisor
  2920. * @returns {!Long} Quotient
  2921. */
  2922. LongPrototype.divide = function divide(divisor) {
  2923. if (!isLong(divisor))
  2924. divisor = fromValue(divisor);
  2925. if (divisor.isZero())
  2926. throw Error('division by zero');
  2927. if (this.isZero())
  2928. return this.unsigned ? UZERO : ZERO;
  2929. var approx, rem, res;
  2930. if (!this.unsigned) {
  2931. // This section is only relevant for signed longs and is derived from the
  2932. // closure library as a whole.
  2933. if (this.eq(MIN_VALUE)) {
  2934. if (divisor.eq(ONE) || divisor.eq(NEG_ONE))
  2935. return MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE
  2936. else if (divisor.eq(MIN_VALUE))
  2937. return ONE;
  2938. else {
  2939. // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
  2940. var halfThis = this.shr(1);
  2941. approx = halfThis.div(divisor).shl(1);
  2942. if (approx.eq(ZERO)) {
  2943. return divisor.isNegative() ? ONE : NEG_ONE;
  2944. } else {
  2945. rem = this.sub(divisor.mul(approx));
  2946. res = approx.add(rem.div(divisor));
  2947. return res;
  2948. }
  2949. }
  2950. } else if (divisor.eq(MIN_VALUE))
  2951. return this.unsigned ? UZERO : ZERO;
  2952. if (this.isNegative()) {
  2953. if (divisor.isNegative())
  2954. return this.neg().div(divisor.neg());
  2955. return this.neg().div(divisor).neg();
  2956. } else if (divisor.isNegative())
  2957. return this.div(divisor.neg()).neg();
  2958. res = ZERO;
  2959. } else {
  2960. // The algorithm below has not been made for unsigned longs. It's therefore
  2961. // required to take special care of the MSB prior to running it.
  2962. if (!divisor.unsigned)
  2963. divisor = divisor.toUnsigned();
  2964. if (divisor.gt(this))
  2965. return UZERO;
  2966. if (divisor.gt(this.shru(1))) // 15 >>> 1 = 7 ; with divisor = 8 ; true
  2967. return UONE;
  2968. res = UZERO;
  2969. }
  2970. // Repeat the following until the remainder is less than other: find a
  2971. // floating-point that approximates remainder / other *from below*, add this
  2972. // into the result, and subtract it from the remainder. It is critical that
  2973. // the approximate value is less than or equal to the real value so that the
  2974. // remainder never becomes negative.
  2975. rem = this;
  2976. while (rem.gte(divisor)) {
  2977. // Approximate the result of division. This may be a little greater or
  2978. // smaller than the actual value.
  2979. approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber()));
  2980. // We will tweak the approximate result by changing it in the 48-th digit or
  2981. // the smallest non-fractional digit, whichever is larger.
  2982. var log2 = Math.ceil(Math.log(approx) / Math.LN2),
  2983. delta = (log2 <= 48) ? 1 : pow_dbl(2, log2 - 48),
  2984. // Decrease the approximation until it is smaller than the remainder. Note
  2985. // that if it is too large, the product overflows and is negative.
  2986. approxRes = fromNumber(approx),
  2987. approxRem = approxRes.mul(divisor);
  2988. while (approxRem.isNegative() || approxRem.gt(rem)) {
  2989. approx -= delta;
  2990. approxRes = fromNumber(approx, this.unsigned);
  2991. approxRem = approxRes.mul(divisor);
  2992. }
  2993. // We know the answer can't be zero... and actually, zero would cause
  2994. // infinite recursion since we would make no progress.
  2995. if (approxRes.isZero())
  2996. approxRes = ONE;
  2997. res = res.add(approxRes);
  2998. rem = rem.sub(approxRem);
  2999. }
  3000. return res;
  3001. };
  3002. /**
  3003. * Returns this Long divided by the specified. This is an alias of {@link Long#divide}.
  3004. * @function
  3005. * @param {!Long|number|string} divisor Divisor
  3006. * @returns {!Long} Quotient
  3007. */
  3008. LongPrototype.div = LongPrototype.divide;
  3009. /**
  3010. * Returns this Long modulo the specified.
  3011. * @param {!Long|number|string} divisor Divisor
  3012. * @returns {!Long} Remainder
  3013. */
  3014. LongPrototype.modulo = function modulo(divisor) {
  3015. if (!isLong(divisor))
  3016. divisor = fromValue(divisor);
  3017. return this.sub(this.div(divisor).mul(divisor));
  3018. };
  3019. /**
  3020. * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.
  3021. * @function
  3022. * @param {!Long|number|string} divisor Divisor
  3023. * @returns {!Long} Remainder
  3024. */
  3025. LongPrototype.mod = LongPrototype.modulo;
  3026. /**
  3027. * Returns the bitwise NOT of this Long.
  3028. * @returns {!Long}
  3029. */
  3030. LongPrototype.not = function not() {
  3031. return fromBits(~this.low, ~this.high, this.unsigned);
  3032. };
  3033. /**
  3034. * Returns the bitwise AND of this Long and the specified.
  3035. * @param {!Long|number|string} other Other Long
  3036. * @returns {!Long}
  3037. */
  3038. LongPrototype.and = function and(other) {
  3039. if (!isLong(other))
  3040. other = fromValue(other);
  3041. return fromBits(this.low & other.low, this.high & other.high, this.unsigned);
  3042. };
  3043. /**
  3044. * Returns the bitwise OR of this Long and the specified.
  3045. * @param {!Long|number|string} other Other Long
  3046. * @returns {!Long}
  3047. */
  3048. LongPrototype.or = function or(other) {
  3049. if (!isLong(other))
  3050. other = fromValue(other);
  3051. return fromBits(this.low | other.low, this.high | other.high, this.unsigned);
  3052. };
  3053. /**
  3054. * Returns the bitwise XOR of this Long and the given one.
  3055. * @param {!Long|number|string} other Other Long
  3056. * @returns {!Long}
  3057. */
  3058. LongPrototype.xor = function xor(other) {
  3059. if (!isLong(other))
  3060. other = fromValue(other);
  3061. return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned);
  3062. };
  3063. /**
  3064. * Returns this Long with bits shifted to the left by the given amount.
  3065. * @param {number|!Long} numBits Number of bits
  3066. * @returns {!Long} Shifted Long
  3067. */
  3068. LongPrototype.shiftLeft = function shiftLeft(numBits) {
  3069. if (isLong(numBits))
  3070. numBits = numBits.toInt();
  3071. if ((numBits &= 63) === 0)
  3072. return this;
  3073. else if (numBits < 32)
  3074. return fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned);
  3075. else
  3076. return fromBits(0, this.low << (numBits - 32), this.unsigned);
  3077. };
  3078. /**
  3079. * Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}.
  3080. * @function
  3081. * @param {number|!Long} numBits Number of bits
  3082. * @returns {!Long} Shifted Long
  3083. */
  3084. LongPrototype.shl = LongPrototype.shiftLeft;
  3085. /**
  3086. * Returns this Long with bits arithmetically shifted to the right by the given amount.
  3087. * @param {number|!Long} numBits Number of bits
  3088. * @returns {!Long} Shifted Long
  3089. */
  3090. LongPrototype.shiftRight = function shiftRight(numBits) {
  3091. if (isLong(numBits))
  3092. numBits = numBits.toInt();
  3093. if ((numBits &= 63) === 0)
  3094. return this;
  3095. else if (numBits < 32)
  3096. return fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned);
  3097. else
  3098. return fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned);
  3099. };
  3100. /**
  3101. * Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}.
  3102. * @function
  3103. * @param {number|!Long} numBits Number of bits
  3104. * @returns {!Long} Shifted Long
  3105. */
  3106. LongPrototype.shr = LongPrototype.shiftRight;
  3107. /**
  3108. * Returns this Long with bits logically shifted to the right by the given amount.
  3109. * @param {number|!Long} numBits Number of bits
  3110. * @returns {!Long} Shifted Long
  3111. */
  3112. LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) {
  3113. if (isLong(numBits))
  3114. numBits = numBits.toInt();
  3115. numBits &= 63;
  3116. if (numBits === 0)
  3117. return this;
  3118. else {
  3119. var high = this.high;
  3120. if (numBits < 32) {
  3121. var low = this.low;
  3122. return fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned);
  3123. } else if (numBits === 32)
  3124. return fromBits(high, 0, this.unsigned);
  3125. else
  3126. return fromBits(high >>> (numBits - 32), 0, this.unsigned);
  3127. }
  3128. };
  3129. /**
  3130. * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.
  3131. * @function
  3132. * @param {number|!Long} numBits Number of bits
  3133. * @returns {!Long} Shifted Long
  3134. */
  3135. LongPrototype.shru = LongPrototype.shiftRightUnsigned;
  3136. /**
  3137. * Converts this Long to signed.
  3138. * @returns {!Long} Signed long
  3139. */
  3140. LongPrototype.toSigned = function toSigned() {
  3141. if (!this.unsigned)
  3142. return this;
  3143. return fromBits(this.low, this.high, false);
  3144. };
  3145. /**
  3146. * Converts this Long to unsigned.
  3147. * @returns {!Long} Unsigned long
  3148. */
  3149. LongPrototype.toUnsigned = function toUnsigned() {
  3150. if (this.unsigned)
  3151. return this;
  3152. return fromBits(this.low, this.high, true);
  3153. };
  3154. /**
  3155. * Converts this Long to its byte representation.
  3156. * @param {boolean=} le Whether little or big endian, defaults to big endian
  3157. * @returns {!Array.<number>} Byte representation
  3158. */
  3159. LongPrototype.toBytes = function(le) {
  3160. return le ? this.toBytesLE() : this.toBytesBE();
  3161. };
  3162. /**
  3163. * Converts this Long to its little endian byte representation.
  3164. * @returns {!Array.<number>} Little endian byte representation
  3165. */
  3166. LongPrototype.toBytesLE = function() {
  3167. var hi = this.high,
  3168. lo = this.low;
  3169. return [
  3170. lo & 0xff,
  3171. (lo >>> 8) & 0xff,
  3172. (lo >>> 16) & 0xff,
  3173. (lo >>> 24) & 0xff,
  3174. hi & 0xff,
  3175. (hi >>> 8) & 0xff,
  3176. (hi >>> 16) & 0xff,
  3177. (hi >>> 24) & 0xff
  3178. ];
  3179. };
  3180. /**
  3181. * Converts this Long to its big endian byte representation.
  3182. * @returns {!Array.<number>} Big endian byte representation
  3183. */
  3184. LongPrototype.toBytesBE = function() {
  3185. var hi = this.high,
  3186. lo = this.low;
  3187. return [
  3188. (hi >>> 24) & 0xff,
  3189. (hi >>> 16) & 0xff,
  3190. (hi >>> 8) & 0xff,
  3191. hi & 0xff,
  3192. (lo >>> 24) & 0xff,
  3193. (lo >>> 16) & 0xff,
  3194. (lo >>> 8) & 0xff,
  3195. lo & 0xff
  3196. ];
  3197. };
  3198. return Long;
  3199. });
  3200. });
  3201. var bytebuffer = createCommonjsModule(function (module) {
  3202. /*
  3203. Copyright 2013-2014 Daniel Wirtz <dcode@dcode.io>
  3204. Licensed under the Apache License, Version 2.0 (the "License");
  3205. you may not use this file except in compliance with the License.
  3206. You may obtain a copy of the License at
  3207. http://www.apache.org/licenses/LICENSE-2.0
  3208. Unless required by applicable law or agreed to in writing, software
  3209. distributed under the License is distributed on an "AS IS" BASIS,
  3210. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3211. See the License for the specific language governing permissions and
  3212. limitations under the License.
  3213. */
  3214. /**
  3215. * @license bytebuffer.js (c) 2015 Daniel Wirtz <dcode@dcode.io>
  3216. * Backing buffer: ArrayBuffer, Accessor: Uint8Array
  3217. * Released under the Apache License, Version 2.0
  3218. * see: https://github.com/dcodeIO/bytebuffer.js for details
  3219. */
  3220. (function(global, factory) {
  3221. /* AMD */ if (typeof commonjsRequire === 'function' && 'object' === "object" && module && module["exports"])
  3222. module['exports'] = (function() {
  3223. var Long; try { Long = long_1; } catch (e) {}
  3224. return factory(Long);
  3225. })();
  3226. /* Global */ else
  3227. (global["dcodeIO"] = global["dcodeIO"] || {})["ByteBuffer"] = factory(global["dcodeIO"]["Long"]);
  3228. })(commonjsGlobal, function(Long) {
  3229. /**
  3230. * Constructs a new ByteBuffer.
  3231. * @class The swiss army knife for binary data in JavaScript.
  3232. * @exports ByteBuffer
  3233. * @constructor
  3234. * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
  3235. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  3236. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  3237. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  3238. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  3239. * @expose
  3240. */
  3241. var ByteBuffer = function(capacity, littleEndian, noAssert) {
  3242. if (typeof capacity === 'undefined')
  3243. capacity = ByteBuffer.DEFAULT_CAPACITY;
  3244. if (typeof littleEndian === 'undefined')
  3245. littleEndian = ByteBuffer.DEFAULT_ENDIAN;
  3246. if (typeof noAssert === 'undefined')
  3247. noAssert = ByteBuffer.DEFAULT_NOASSERT;
  3248. if (!noAssert) {
  3249. capacity = capacity | 0;
  3250. if (capacity < 0)
  3251. throw RangeError("Illegal capacity");
  3252. littleEndian = !!littleEndian;
  3253. noAssert = !!noAssert;
  3254. }
  3255. /**
  3256. * Backing ArrayBuffer.
  3257. * @type {!ArrayBuffer}
  3258. * @expose
  3259. */
  3260. this.buffer = capacity === 0 ? EMPTY_BUFFER : new ArrayBuffer(capacity);
  3261. /**
  3262. * Uint8Array utilized to manipulate the backing buffer. Becomes `null` if the backing buffer has a capacity of `0`.
  3263. * @type {?Uint8Array}
  3264. * @expose
  3265. */
  3266. this.view = capacity === 0 ? null : new Uint8Array(this.buffer);
  3267. /**
  3268. * Absolute read/write offset.
  3269. * @type {number}
  3270. * @expose
  3271. * @see ByteBuffer#flip
  3272. * @see ByteBuffer#clear
  3273. */
  3274. this.offset = 0;
  3275. /**
  3276. * Marked offset.
  3277. * @type {number}
  3278. * @expose
  3279. * @see ByteBuffer#mark
  3280. * @see ByteBuffer#reset
  3281. */
  3282. this.markedOffset = -1;
  3283. /**
  3284. * Absolute limit of the contained data. Set to the backing buffer's capacity upon allocation.
  3285. * @type {number}
  3286. * @expose
  3287. * @see ByteBuffer#flip
  3288. * @see ByteBuffer#clear
  3289. */
  3290. this.limit = capacity;
  3291. /**
  3292. * Whether to use little endian byte order, defaults to `false` for big endian.
  3293. * @type {boolean}
  3294. * @expose
  3295. */
  3296. this.littleEndian = littleEndian;
  3297. /**
  3298. * Whether to skip assertions of offsets and values, defaults to `false`.
  3299. * @type {boolean}
  3300. * @expose
  3301. */
  3302. this.noAssert = noAssert;
  3303. };
  3304. /**
  3305. * ByteBuffer version.
  3306. * @type {string}
  3307. * @const
  3308. * @expose
  3309. */
  3310. ByteBuffer.VERSION = "5.0.1";
  3311. /**
  3312. * Little endian constant that can be used instead of its boolean value. Evaluates to `true`.
  3313. * @type {boolean}
  3314. * @const
  3315. * @expose
  3316. */
  3317. ByteBuffer.LITTLE_ENDIAN = true;
  3318. /**
  3319. * Big endian constant that can be used instead of its boolean value. Evaluates to `false`.
  3320. * @type {boolean}
  3321. * @const
  3322. * @expose
  3323. */
  3324. ByteBuffer.BIG_ENDIAN = false;
  3325. /**
  3326. * Default initial capacity of `16`.
  3327. * @type {number}
  3328. * @expose
  3329. */
  3330. ByteBuffer.DEFAULT_CAPACITY = 16;
  3331. /**
  3332. * Default endianess of `false` for big endian.
  3333. * @type {boolean}
  3334. * @expose
  3335. */
  3336. ByteBuffer.DEFAULT_ENDIAN = ByteBuffer.BIG_ENDIAN;
  3337. /**
  3338. * Default no assertions flag of `false`.
  3339. * @type {boolean}
  3340. * @expose
  3341. */
  3342. ByteBuffer.DEFAULT_NOASSERT = false;
  3343. /**
  3344. * A `Long` class for representing a 64-bit two's-complement integer value. May be `null` if Long.js has not been loaded
  3345. * and int64 support is not available.
  3346. * @type {?Long}
  3347. * @const
  3348. * @see https://github.com/dcodeIO/long.js
  3349. * @expose
  3350. */
  3351. ByteBuffer.Long = Long || null;
  3352. /**
  3353. * @alias ByteBuffer.prototype
  3354. * @inner
  3355. */
  3356. var ByteBufferPrototype = ByteBuffer.prototype;
  3357. /**
  3358. * An indicator used to reliably determine if an object is a ByteBuffer or not.
  3359. * @type {boolean}
  3360. * @const
  3361. * @expose
  3362. * @private
  3363. */
  3364. ByteBufferPrototype.__isByteBuffer__;
  3365. Object.defineProperty(ByteBufferPrototype, "__isByteBuffer__", {
  3366. value: true,
  3367. enumerable: false,
  3368. configurable: false
  3369. });
  3370. // helpers
  3371. /**
  3372. * @type {!ArrayBuffer}
  3373. * @inner
  3374. */
  3375. var EMPTY_BUFFER = new ArrayBuffer(0);
  3376. /**
  3377. * String.fromCharCode reference for compile-time renaming.
  3378. * @type {function(...number):string}
  3379. * @inner
  3380. */
  3381. var stringFromCharCode = String.fromCharCode;
  3382. /**
  3383. * Creates a source function for a string.
  3384. * @param {string} s String to read from
  3385. * @returns {function():number|null} Source function returning the next char code respectively `null` if there are
  3386. * no more characters left.
  3387. * @throws {TypeError} If the argument is invalid
  3388. * @inner
  3389. */
  3390. function stringSource(s) {
  3391. var i=0; return function() {
  3392. return i < s.length ? s.charCodeAt(i++) : null;
  3393. };
  3394. }
  3395. /**
  3396. * Creates a destination function for a string.
  3397. * @returns {function(number=):undefined|string} Destination function successively called with the next char code.
  3398. * Returns the final string when called without arguments.
  3399. * @inner
  3400. */
  3401. function stringDestination() {
  3402. var cs = [], ps = []; return function() {
  3403. if (arguments.length === 0)
  3404. return ps.join('')+stringFromCharCode.apply(String, cs);
  3405. if (cs.length + arguments.length > 1024)
  3406. ps.push(stringFromCharCode.apply(String, cs)),
  3407. cs.length = 0;
  3408. Array.prototype.push.apply(cs, arguments);
  3409. };
  3410. }
  3411. /**
  3412. * Gets the accessor type.
  3413. * @returns {Function} `Buffer` under node.js, `Uint8Array` respectively `DataView` in the browser (classes)
  3414. * @expose
  3415. */
  3416. ByteBuffer.accessor = function() {
  3417. return Uint8Array;
  3418. };
  3419. /**
  3420. * Allocates a new ByteBuffer backed by a buffer of the specified capacity.
  3421. * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
  3422. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  3423. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  3424. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  3425. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  3426. * @returns {!ByteBuffer}
  3427. * @expose
  3428. */
  3429. ByteBuffer.allocate = function(capacity, littleEndian, noAssert) {
  3430. return new ByteBuffer(capacity, littleEndian, noAssert);
  3431. };
  3432. /**
  3433. * Concatenates multiple ByteBuffers into one.
  3434. * @param {!Array.<!ByteBuffer|!ArrayBuffer|!Uint8Array|string>} buffers Buffers to concatenate
  3435. * @param {(string|boolean)=} encoding String encoding if `buffers` contains a string ("base64", "hex", "binary",
  3436. * defaults to "utf8")
  3437. * @param {boolean=} littleEndian Whether to use little or big endian byte order for the resulting ByteBuffer. Defaults
  3438. * to {@link ByteBuffer.DEFAULT_ENDIAN}.
  3439. * @param {boolean=} noAssert Whether to skip assertions of offsets and values for the resulting ByteBuffer. Defaults to
  3440. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  3441. * @returns {!ByteBuffer} Concatenated ByteBuffer
  3442. * @expose
  3443. */
  3444. ByteBuffer.concat = function(buffers, encoding, littleEndian, noAssert) {
  3445. if (typeof encoding === 'boolean' || typeof encoding !== 'string') {
  3446. noAssert = littleEndian;
  3447. littleEndian = encoding;
  3448. encoding = undefined;
  3449. }
  3450. var capacity = 0;
  3451. for (var i=0, k=buffers.length, length; i<k; ++i) {
  3452. if (!ByteBuffer.isByteBuffer(buffers[i]))
  3453. buffers[i] = ByteBuffer.wrap(buffers[i], encoding);
  3454. length = buffers[i].limit - buffers[i].offset;
  3455. if (length > 0) capacity += length;
  3456. }
  3457. if (capacity === 0)
  3458. return new ByteBuffer(0, littleEndian, noAssert);
  3459. var bb = new ByteBuffer(capacity, littleEndian, noAssert),
  3460. bi;
  3461. i=0; while (i<k) {
  3462. bi = buffers[i++];
  3463. length = bi.limit - bi.offset;
  3464. if (length <= 0) continue;
  3465. bb.view.set(bi.view.subarray(bi.offset, bi.limit), bb.offset);
  3466. bb.offset += length;
  3467. }
  3468. bb.limit = bb.offset;
  3469. bb.offset = 0;
  3470. return bb;
  3471. };
  3472. /**
  3473. * Tests if the specified type is a ByteBuffer.
  3474. * @param {*} bb ByteBuffer to test
  3475. * @returns {boolean} `true` if it is a ByteBuffer, otherwise `false`
  3476. * @expose
  3477. */
  3478. ByteBuffer.isByteBuffer = function(bb) {
  3479. return (bb && bb["__isByteBuffer__"]) === true;
  3480. };
  3481. /**
  3482. * Gets the backing buffer type.
  3483. * @returns {Function} `Buffer` under node.js, `ArrayBuffer` in the browser (classes)
  3484. * @expose
  3485. */
  3486. ByteBuffer.type = function() {
  3487. return ArrayBuffer;
  3488. };
  3489. /**
  3490. * Wraps a buffer or a string. Sets the allocated ByteBuffer's {@link ByteBuffer#offset} to `0` and its
  3491. * {@link ByteBuffer#limit} to the length of the wrapped data.
  3492. * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string|!Array.<number>} buffer Anything that can be wrapped
  3493. * @param {(string|boolean)=} encoding String encoding if `buffer` is a string ("base64", "hex", "binary", defaults to
  3494. * "utf8")
  3495. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  3496. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  3497. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  3498. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  3499. * @returns {!ByteBuffer} A ByteBuffer wrapping `buffer`
  3500. * @expose
  3501. */
  3502. ByteBuffer.wrap = function(buffer, encoding, littleEndian, noAssert) {
  3503. if (typeof encoding !== 'string') {
  3504. noAssert = littleEndian;
  3505. littleEndian = encoding;
  3506. encoding = undefined;
  3507. }
  3508. if (typeof buffer === 'string') {
  3509. if (typeof encoding === 'undefined')
  3510. encoding = "utf8";
  3511. switch (encoding) {
  3512. case "base64":
  3513. return ByteBuffer.fromBase64(buffer, littleEndian);
  3514. case "hex":
  3515. return ByteBuffer.fromHex(buffer, littleEndian);
  3516. case "binary":
  3517. return ByteBuffer.fromBinary(buffer, littleEndian);
  3518. case "utf8":
  3519. return ByteBuffer.fromUTF8(buffer, littleEndian);
  3520. case "debug":
  3521. return ByteBuffer.fromDebug(buffer, littleEndian);
  3522. default:
  3523. throw Error("Unsupported encoding: "+encoding);
  3524. }
  3525. }
  3526. if (buffer === null || typeof buffer !== 'object')
  3527. throw TypeError("Illegal buffer");
  3528. var bb;
  3529. if (ByteBuffer.isByteBuffer(buffer)) {
  3530. bb = ByteBufferPrototype.clone.call(buffer);
  3531. bb.markedOffset = -1;
  3532. return bb;
  3533. }
  3534. if (buffer instanceof Uint8Array) { // Extract ArrayBuffer from Uint8Array
  3535. bb = new ByteBuffer(0, littleEndian, noAssert);
  3536. if (buffer.length > 0) { // Avoid references to more than one EMPTY_BUFFER
  3537. bb.buffer = buffer.buffer;
  3538. bb.offset = buffer.byteOffset;
  3539. bb.limit = buffer.byteOffset + buffer.byteLength;
  3540. bb.view = new Uint8Array(buffer.buffer);
  3541. }
  3542. } else if (buffer instanceof ArrayBuffer) { // Reuse ArrayBuffer
  3543. bb = new ByteBuffer(0, littleEndian, noAssert);
  3544. if (buffer.byteLength > 0) {
  3545. bb.buffer = buffer;
  3546. bb.offset = 0;
  3547. bb.limit = buffer.byteLength;
  3548. bb.view = buffer.byteLength > 0 ? new Uint8Array(buffer) : null;
  3549. }
  3550. } else if (Object.prototype.toString.call(buffer) === "[object Array]") { // Create from octets
  3551. bb = new ByteBuffer(buffer.length, littleEndian, noAssert);
  3552. bb.limit = buffer.length;
  3553. for (var i=0; i<buffer.length; ++i)
  3554. bb.view[i] = buffer[i];
  3555. } else
  3556. throw TypeError("Illegal buffer"); // Otherwise fail
  3557. return bb;
  3558. };
  3559. /**
  3560. * Writes the array as a bitset.
  3561. * @param {Array<boolean>} value Array of booleans to write
  3562. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
  3563. * @returns {!ByteBuffer}
  3564. * @expose
  3565. */
  3566. ByteBufferPrototype.writeBitSet = function(value, offset) {
  3567. var relative = typeof offset === 'undefined';
  3568. if (relative) offset = this.offset;
  3569. if (!this.noAssert) {
  3570. if (!(value instanceof Array))
  3571. throw TypeError("Illegal BitSet: Not an array");
  3572. if (typeof offset !== 'number' || offset % 1 !== 0)
  3573. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3574. offset >>>= 0;
  3575. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3576. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3577. }
  3578. var start = offset,
  3579. bits = value.length,
  3580. bytes = (bits >> 3),
  3581. bit = 0,
  3582. k;
  3583. offset += this.writeVarint32(bits,offset);
  3584. while(bytes--) {
  3585. k = (!!value[bit++] & 1) |
  3586. ((!!value[bit++] & 1) << 1) |
  3587. ((!!value[bit++] & 1) << 2) |
  3588. ((!!value[bit++] & 1) << 3) |
  3589. ((!!value[bit++] & 1) << 4) |
  3590. ((!!value[bit++] & 1) << 5) |
  3591. ((!!value[bit++] & 1) << 6) |
  3592. ((!!value[bit++] & 1) << 7);
  3593. this.writeByte(k,offset++);
  3594. }
  3595. if(bit < bits) {
  3596. var m = 0; k = 0;
  3597. while(bit < bits) k = k | ((!!value[bit++] & 1) << (m++));
  3598. this.writeByte(k,offset++);
  3599. }
  3600. if (relative) {
  3601. this.offset = offset;
  3602. return this;
  3603. }
  3604. return offset - start;
  3605. };
  3606. /**
  3607. * Reads a BitSet as an array of booleans.
  3608. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
  3609. * @returns {Array<boolean>
  3610. * @expose
  3611. */
  3612. ByteBufferPrototype.readBitSet = function(offset) {
  3613. var relative = typeof offset === 'undefined';
  3614. if (relative) offset = this.offset;
  3615. var ret = this.readVarint32(offset),
  3616. bits = ret.value,
  3617. bytes = (bits >> 3),
  3618. bit = 0,
  3619. value = [],
  3620. k;
  3621. offset += ret.length;
  3622. while(bytes--) {
  3623. k = this.readByte(offset++);
  3624. value[bit++] = !!(k & 0x01);
  3625. value[bit++] = !!(k & 0x02);
  3626. value[bit++] = !!(k & 0x04);
  3627. value[bit++] = !!(k & 0x08);
  3628. value[bit++] = !!(k & 0x10);
  3629. value[bit++] = !!(k & 0x20);
  3630. value[bit++] = !!(k & 0x40);
  3631. value[bit++] = !!(k & 0x80);
  3632. }
  3633. if(bit < bits) {
  3634. var m = 0;
  3635. k = this.readByte(offset++);
  3636. while(bit < bits) value[bit++] = !!((k >> (m++)) & 1);
  3637. }
  3638. if (relative) {
  3639. this.offset = offset;
  3640. }
  3641. return value;
  3642. };
  3643. /**
  3644. * Reads the specified number of bytes.
  3645. * @param {number} length Number of bytes to read
  3646. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
  3647. * @returns {!ByteBuffer}
  3648. * @expose
  3649. */
  3650. ByteBufferPrototype.readBytes = function(length, offset) {
  3651. var relative = typeof offset === 'undefined';
  3652. if (relative) offset = this.offset;
  3653. if (!this.noAssert) {
  3654. if (typeof offset !== 'number' || offset % 1 !== 0)
  3655. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3656. offset >>>= 0;
  3657. if (offset < 0 || offset + length > this.buffer.byteLength)
  3658. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength);
  3659. }
  3660. var slice = this.slice(offset, offset + length);
  3661. if (relative) this.offset += length;
  3662. return slice;
  3663. };
  3664. /**
  3665. * Writes a payload of bytes. This is an alias of {@link ByteBuffer#append}.
  3666. * @function
  3667. * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to write. If `source` is a ByteBuffer, its offsets
  3668. * will be modified according to the performed read operation.
  3669. * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
  3670. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  3671. * written if omitted.
  3672. * @returns {!ByteBuffer} this
  3673. * @expose
  3674. */
  3675. ByteBufferPrototype.writeBytes = ByteBufferPrototype.append;
  3676. // types/ints/int8
  3677. /**
  3678. * Writes an 8bit signed integer.
  3679. * @param {number} value Value to write
  3680. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  3681. * @returns {!ByteBuffer} this
  3682. * @expose
  3683. */
  3684. ByteBufferPrototype.writeInt8 = function(value, offset) {
  3685. var relative = typeof offset === 'undefined';
  3686. if (relative) offset = this.offset;
  3687. if (!this.noAssert) {
  3688. if (typeof value !== 'number' || value % 1 !== 0)
  3689. throw TypeError("Illegal value: "+value+" (not an integer)");
  3690. value |= 0;
  3691. if (typeof offset !== 'number' || offset % 1 !== 0)
  3692. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3693. offset >>>= 0;
  3694. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3695. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3696. }
  3697. offset += 1;
  3698. var capacity0 = this.buffer.byteLength;
  3699. if (offset > capacity0)
  3700. this.resize((capacity0 *= 2) > offset ? capacity0 : offset);
  3701. offset -= 1;
  3702. this.view[offset] = value;
  3703. if (relative) this.offset += 1;
  3704. return this;
  3705. };
  3706. /**
  3707. * Writes an 8bit signed integer. This is an alias of {@link ByteBuffer#writeInt8}.
  3708. * @function
  3709. * @param {number} value Value to write
  3710. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  3711. * @returns {!ByteBuffer} this
  3712. * @expose
  3713. */
  3714. ByteBufferPrototype.writeByte = ByteBufferPrototype.writeInt8;
  3715. /**
  3716. * Reads an 8bit signed integer.
  3717. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  3718. * @returns {number} Value read
  3719. * @expose
  3720. */
  3721. ByteBufferPrototype.readInt8 = function(offset) {
  3722. var relative = typeof offset === 'undefined';
  3723. if (relative) offset = this.offset;
  3724. if (!this.noAssert) {
  3725. if (typeof offset !== 'number' || offset % 1 !== 0)
  3726. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3727. offset >>>= 0;
  3728. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  3729. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  3730. }
  3731. var value = this.view[offset];
  3732. if ((value & 0x80) === 0x80) value = -(0xFF - value + 1); // Cast to signed
  3733. if (relative) this.offset += 1;
  3734. return value;
  3735. };
  3736. /**
  3737. * Reads an 8bit signed integer. This is an alias of {@link ByteBuffer#readInt8}.
  3738. * @function
  3739. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  3740. * @returns {number} Value read
  3741. * @expose
  3742. */
  3743. ByteBufferPrototype.readByte = ByteBufferPrototype.readInt8;
  3744. /**
  3745. * Writes an 8bit unsigned integer.
  3746. * @param {number} value Value to write
  3747. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  3748. * @returns {!ByteBuffer} this
  3749. * @expose
  3750. */
  3751. ByteBufferPrototype.writeUint8 = function(value, offset) {
  3752. var relative = typeof offset === 'undefined';
  3753. if (relative) offset = this.offset;
  3754. if (!this.noAssert) {
  3755. if (typeof value !== 'number' || value % 1 !== 0)
  3756. throw TypeError("Illegal value: "+value+" (not an integer)");
  3757. value >>>= 0;
  3758. if (typeof offset !== 'number' || offset % 1 !== 0)
  3759. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3760. offset >>>= 0;
  3761. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3762. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3763. }
  3764. offset += 1;
  3765. var capacity1 = this.buffer.byteLength;
  3766. if (offset > capacity1)
  3767. this.resize((capacity1 *= 2) > offset ? capacity1 : offset);
  3768. offset -= 1;
  3769. this.view[offset] = value;
  3770. if (relative) this.offset += 1;
  3771. return this;
  3772. };
  3773. /**
  3774. * Writes an 8bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint8}.
  3775. * @function
  3776. * @param {number} value Value to write
  3777. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  3778. * @returns {!ByteBuffer} this
  3779. * @expose
  3780. */
  3781. ByteBufferPrototype.writeUInt8 = ByteBufferPrototype.writeUint8;
  3782. /**
  3783. * Reads an 8bit unsigned integer.
  3784. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  3785. * @returns {number} Value read
  3786. * @expose
  3787. */
  3788. ByteBufferPrototype.readUint8 = function(offset) {
  3789. var relative = typeof offset === 'undefined';
  3790. if (relative) offset = this.offset;
  3791. if (!this.noAssert) {
  3792. if (typeof offset !== 'number' || offset % 1 !== 0)
  3793. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3794. offset >>>= 0;
  3795. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  3796. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  3797. }
  3798. var value = this.view[offset];
  3799. if (relative) this.offset += 1;
  3800. return value;
  3801. };
  3802. /**
  3803. * Reads an 8bit unsigned integer. This is an alias of {@link ByteBuffer#readUint8}.
  3804. * @function
  3805. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  3806. * @returns {number} Value read
  3807. * @expose
  3808. */
  3809. ByteBufferPrototype.readUInt8 = ByteBufferPrototype.readUint8;
  3810. // types/ints/int16
  3811. /**
  3812. * Writes a 16bit signed integer.
  3813. * @param {number} value Value to write
  3814. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  3815. * @throws {TypeError} If `offset` or `value` is not a valid number
  3816. * @throws {RangeError} If `offset` is out of bounds
  3817. * @expose
  3818. */
  3819. ByteBufferPrototype.writeInt16 = function(value, offset) {
  3820. var relative = typeof offset === 'undefined';
  3821. if (relative) offset = this.offset;
  3822. if (!this.noAssert) {
  3823. if (typeof value !== 'number' || value % 1 !== 0)
  3824. throw TypeError("Illegal value: "+value+" (not an integer)");
  3825. value |= 0;
  3826. if (typeof offset !== 'number' || offset % 1 !== 0)
  3827. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3828. offset >>>= 0;
  3829. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3830. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3831. }
  3832. offset += 2;
  3833. var capacity2 = this.buffer.byteLength;
  3834. if (offset > capacity2)
  3835. this.resize((capacity2 *= 2) > offset ? capacity2 : offset);
  3836. offset -= 2;
  3837. if (this.littleEndian) {
  3838. this.view[offset+1] = (value & 0xFF00) >>> 8;
  3839. this.view[offset ] = value & 0x00FF;
  3840. } else {
  3841. this.view[offset] = (value & 0xFF00) >>> 8;
  3842. this.view[offset+1] = value & 0x00FF;
  3843. }
  3844. if (relative) this.offset += 2;
  3845. return this;
  3846. };
  3847. /**
  3848. * Writes a 16bit signed integer. This is an alias of {@link ByteBuffer#writeInt16}.
  3849. * @function
  3850. * @param {number} value Value to write
  3851. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  3852. * @throws {TypeError} If `offset` or `value` is not a valid number
  3853. * @throws {RangeError} If `offset` is out of bounds
  3854. * @expose
  3855. */
  3856. ByteBufferPrototype.writeShort = ByteBufferPrototype.writeInt16;
  3857. /**
  3858. * Reads a 16bit signed integer.
  3859. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  3860. * @returns {number} Value read
  3861. * @throws {TypeError} If `offset` is not a valid number
  3862. * @throws {RangeError} If `offset` is out of bounds
  3863. * @expose
  3864. */
  3865. ByteBufferPrototype.readInt16 = function(offset) {
  3866. var relative = typeof offset === 'undefined';
  3867. if (relative) offset = this.offset;
  3868. if (!this.noAssert) {
  3869. if (typeof offset !== 'number' || offset % 1 !== 0)
  3870. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3871. offset >>>= 0;
  3872. if (offset < 0 || offset + 2 > this.buffer.byteLength)
  3873. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
  3874. }
  3875. var value = 0;
  3876. if (this.littleEndian) {
  3877. value = this.view[offset ];
  3878. value |= this.view[offset+1] << 8;
  3879. } else {
  3880. value = this.view[offset ] << 8;
  3881. value |= this.view[offset+1];
  3882. }
  3883. if ((value & 0x8000) === 0x8000) value = -(0xFFFF - value + 1); // Cast to signed
  3884. if (relative) this.offset += 2;
  3885. return value;
  3886. };
  3887. /**
  3888. * Reads a 16bit signed integer. This is an alias of {@link ByteBuffer#readInt16}.
  3889. * @function
  3890. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  3891. * @returns {number} Value read
  3892. * @throws {TypeError} If `offset` is not a valid number
  3893. * @throws {RangeError} If `offset` is out of bounds
  3894. * @expose
  3895. */
  3896. ByteBufferPrototype.readShort = ByteBufferPrototype.readInt16;
  3897. /**
  3898. * Writes a 16bit unsigned integer.
  3899. * @param {number} value Value to write
  3900. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  3901. * @throws {TypeError} If `offset` or `value` is not a valid number
  3902. * @throws {RangeError} If `offset` is out of bounds
  3903. * @expose
  3904. */
  3905. ByteBufferPrototype.writeUint16 = function(value, offset) {
  3906. var relative = typeof offset === 'undefined';
  3907. if (relative) offset = this.offset;
  3908. if (!this.noAssert) {
  3909. if (typeof value !== 'number' || value % 1 !== 0)
  3910. throw TypeError("Illegal value: "+value+" (not an integer)");
  3911. value >>>= 0;
  3912. if (typeof offset !== 'number' || offset % 1 !== 0)
  3913. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3914. offset >>>= 0;
  3915. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3916. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3917. }
  3918. offset += 2;
  3919. var capacity3 = this.buffer.byteLength;
  3920. if (offset > capacity3)
  3921. this.resize((capacity3 *= 2) > offset ? capacity3 : offset);
  3922. offset -= 2;
  3923. if (this.littleEndian) {
  3924. this.view[offset+1] = (value & 0xFF00) >>> 8;
  3925. this.view[offset ] = value & 0x00FF;
  3926. } else {
  3927. this.view[offset] = (value & 0xFF00) >>> 8;
  3928. this.view[offset+1] = value & 0x00FF;
  3929. }
  3930. if (relative) this.offset += 2;
  3931. return this;
  3932. };
  3933. /**
  3934. * Writes a 16bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint16}.
  3935. * @function
  3936. * @param {number} value Value to write
  3937. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  3938. * @throws {TypeError} If `offset` or `value` is not a valid number
  3939. * @throws {RangeError} If `offset` is out of bounds
  3940. * @expose
  3941. */
  3942. ByteBufferPrototype.writeUInt16 = ByteBufferPrototype.writeUint16;
  3943. /**
  3944. * Reads a 16bit unsigned integer.
  3945. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  3946. * @returns {number} Value read
  3947. * @throws {TypeError} If `offset` is not a valid number
  3948. * @throws {RangeError} If `offset` is out of bounds
  3949. * @expose
  3950. */
  3951. ByteBufferPrototype.readUint16 = function(offset) {
  3952. var relative = typeof offset === 'undefined';
  3953. if (relative) offset = this.offset;
  3954. if (!this.noAssert) {
  3955. if (typeof offset !== 'number' || offset % 1 !== 0)
  3956. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3957. offset >>>= 0;
  3958. if (offset < 0 || offset + 2 > this.buffer.byteLength)
  3959. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
  3960. }
  3961. var value = 0;
  3962. if (this.littleEndian) {
  3963. value = this.view[offset ];
  3964. value |= this.view[offset+1] << 8;
  3965. } else {
  3966. value = this.view[offset ] << 8;
  3967. value |= this.view[offset+1];
  3968. }
  3969. if (relative) this.offset += 2;
  3970. return value;
  3971. };
  3972. /**
  3973. * Reads a 16bit unsigned integer. This is an alias of {@link ByteBuffer#readUint16}.
  3974. * @function
  3975. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  3976. * @returns {number} Value read
  3977. * @throws {TypeError} If `offset` is not a valid number
  3978. * @throws {RangeError} If `offset` is out of bounds
  3979. * @expose
  3980. */
  3981. ByteBufferPrototype.readUInt16 = ByteBufferPrototype.readUint16;
  3982. // types/ints/int32
  3983. /**
  3984. * Writes a 32bit signed integer.
  3985. * @param {number} value Value to write
  3986. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  3987. * @expose
  3988. */
  3989. ByteBufferPrototype.writeInt32 = function(value, offset) {
  3990. var relative = typeof offset === 'undefined';
  3991. if (relative) offset = this.offset;
  3992. if (!this.noAssert) {
  3993. if (typeof value !== 'number' || value % 1 !== 0)
  3994. throw TypeError("Illegal value: "+value+" (not an integer)");
  3995. value |= 0;
  3996. if (typeof offset !== 'number' || offset % 1 !== 0)
  3997. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3998. offset >>>= 0;
  3999. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  4000. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  4001. }
  4002. offset += 4;
  4003. var capacity4 = this.buffer.byteLength;
  4004. if (offset > capacity4)
  4005. this.resize((capacity4 *= 2) > offset ? capacity4 : offset);
  4006. offset -= 4;
  4007. if (this.littleEndian) {
  4008. this.view[offset+3] = (value >>> 24) & 0xFF;
  4009. this.view[offset+2] = (value >>> 16) & 0xFF;
  4010. this.view[offset+1] = (value >>> 8) & 0xFF;
  4011. this.view[offset ] = value & 0xFF;
  4012. } else {
  4013. this.view[offset ] = (value >>> 24) & 0xFF;
  4014. this.view[offset+1] = (value >>> 16) & 0xFF;
  4015. this.view[offset+2] = (value >>> 8) & 0xFF;
  4016. this.view[offset+3] = value & 0xFF;
  4017. }
  4018. if (relative) this.offset += 4;
  4019. return this;
  4020. };
  4021. /**
  4022. * Writes a 32bit signed integer. This is an alias of {@link ByteBuffer#writeInt32}.
  4023. * @param {number} value Value to write
  4024. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  4025. * @expose
  4026. */
  4027. ByteBufferPrototype.writeInt = ByteBufferPrototype.writeInt32;
  4028. /**
  4029. * Reads a 32bit signed integer.
  4030. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  4031. * @returns {number} Value read
  4032. * @expose
  4033. */
  4034. ByteBufferPrototype.readInt32 = function(offset) {
  4035. var relative = typeof offset === 'undefined';
  4036. if (relative) offset = this.offset;
  4037. if (!this.noAssert) {
  4038. if (typeof offset !== 'number' || offset % 1 !== 0)
  4039. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4040. offset >>>= 0;
  4041. if (offset < 0 || offset + 4 > this.buffer.byteLength)
  4042. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
  4043. }
  4044. var value = 0;
  4045. if (this.littleEndian) {
  4046. value = this.view[offset+2] << 16;
  4047. value |= this.view[offset+1] << 8;
  4048. value |= this.view[offset ];
  4049. value += this.view[offset+3] << 24 >>> 0;
  4050. } else {
  4051. value = this.view[offset+1] << 16;
  4052. value |= this.view[offset+2] << 8;
  4053. value |= this.view[offset+3];
  4054. value += this.view[offset ] << 24 >>> 0;
  4055. }
  4056. value |= 0; // Cast to signed
  4057. if (relative) this.offset += 4;
  4058. return value;
  4059. };
  4060. /**
  4061. * Reads a 32bit signed integer. This is an alias of {@link ByteBuffer#readInt32}.
  4062. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `4` if omitted.
  4063. * @returns {number} Value read
  4064. * @expose
  4065. */
  4066. ByteBufferPrototype.readInt = ByteBufferPrototype.readInt32;
  4067. /**
  4068. * Writes a 32bit unsigned integer.
  4069. * @param {number} value Value to write
  4070. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  4071. * @expose
  4072. */
  4073. ByteBufferPrototype.writeUint32 = function(value, offset) {
  4074. var relative = typeof offset === 'undefined';
  4075. if (relative) offset = this.offset;
  4076. if (!this.noAssert) {
  4077. if (typeof value !== 'number' || value % 1 !== 0)
  4078. throw TypeError("Illegal value: "+value+" (not an integer)");
  4079. value >>>= 0;
  4080. if (typeof offset !== 'number' || offset % 1 !== 0)
  4081. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4082. offset >>>= 0;
  4083. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  4084. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  4085. }
  4086. offset += 4;
  4087. var capacity5 = this.buffer.byteLength;
  4088. if (offset > capacity5)
  4089. this.resize((capacity5 *= 2) > offset ? capacity5 : offset);
  4090. offset -= 4;
  4091. if (this.littleEndian) {
  4092. this.view[offset+3] = (value >>> 24) & 0xFF;
  4093. this.view[offset+2] = (value >>> 16) & 0xFF;
  4094. this.view[offset+1] = (value >>> 8) & 0xFF;
  4095. this.view[offset ] = value & 0xFF;
  4096. } else {
  4097. this.view[offset ] = (value >>> 24) & 0xFF;
  4098. this.view[offset+1] = (value >>> 16) & 0xFF;
  4099. this.view[offset+2] = (value >>> 8) & 0xFF;
  4100. this.view[offset+3] = value & 0xFF;
  4101. }
  4102. if (relative) this.offset += 4;
  4103. return this;
  4104. };
  4105. /**
  4106. * Writes a 32bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint32}.
  4107. * @function
  4108. * @param {number} value Value to write
  4109. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  4110. * @expose
  4111. */
  4112. ByteBufferPrototype.writeUInt32 = ByteBufferPrototype.writeUint32;
  4113. /**
  4114. * Reads a 32bit unsigned integer.
  4115. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  4116. * @returns {number} Value read
  4117. * @expose
  4118. */
  4119. ByteBufferPrototype.readUint32 = function(offset) {
  4120. var relative = typeof offset === 'undefined';
  4121. if (relative) offset = this.offset;
  4122. if (!this.noAssert) {
  4123. if (typeof offset !== 'number' || offset % 1 !== 0)
  4124. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4125. offset >>>= 0;
  4126. if (offset < 0 || offset + 4 > this.buffer.byteLength)
  4127. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
  4128. }
  4129. var value = 0;
  4130. if (this.littleEndian) {
  4131. value = this.view[offset+2] << 16;
  4132. value |= this.view[offset+1] << 8;
  4133. value |= this.view[offset ];
  4134. value += this.view[offset+3] << 24 >>> 0;
  4135. } else {
  4136. value = this.view[offset+1] << 16;
  4137. value |= this.view[offset+2] << 8;
  4138. value |= this.view[offset+3];
  4139. value += this.view[offset ] << 24 >>> 0;
  4140. }
  4141. if (relative) this.offset += 4;
  4142. return value;
  4143. };
  4144. /**
  4145. * Reads a 32bit unsigned integer. This is an alias of {@link ByteBuffer#readUint32}.
  4146. * @function
  4147. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  4148. * @returns {number} Value read
  4149. * @expose
  4150. */
  4151. ByteBufferPrototype.readUInt32 = ByteBufferPrototype.readUint32;
  4152. // types/ints/int64
  4153. if (Long) {
  4154. /**
  4155. * Writes a 64bit signed integer.
  4156. * @param {number|!Long} value Value to write
  4157. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  4158. * @returns {!ByteBuffer} this
  4159. * @expose
  4160. */
  4161. ByteBufferPrototype.writeInt64 = function(value, offset) {
  4162. var relative = typeof offset === 'undefined';
  4163. if (relative) offset = this.offset;
  4164. if (!this.noAssert) {
  4165. if (typeof value === 'number')
  4166. value = Long.fromNumber(value);
  4167. else if (typeof value === 'string')
  4168. value = Long.fromString(value);
  4169. else if (!(value && value instanceof Long))
  4170. throw TypeError("Illegal value: "+value+" (not an integer or Long)");
  4171. if (typeof offset !== 'number' || offset % 1 !== 0)
  4172. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4173. offset >>>= 0;
  4174. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  4175. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  4176. }
  4177. if (typeof value === 'number')
  4178. value = Long.fromNumber(value);
  4179. else if (typeof value === 'string')
  4180. value = Long.fromString(value);
  4181. offset += 8;
  4182. var capacity6 = this.buffer.byteLength;
  4183. if (offset > capacity6)
  4184. this.resize((capacity6 *= 2) > offset ? capacity6 : offset);
  4185. offset -= 8;
  4186. var lo = value.low,
  4187. hi = value.high;
  4188. if (this.littleEndian) {
  4189. this.view[offset+3] = (lo >>> 24) & 0xFF;
  4190. this.view[offset+2] = (lo >>> 16) & 0xFF;
  4191. this.view[offset+1] = (lo >>> 8) & 0xFF;
  4192. this.view[offset ] = lo & 0xFF;
  4193. offset += 4;
  4194. this.view[offset+3] = (hi >>> 24) & 0xFF;
  4195. this.view[offset+2] = (hi >>> 16) & 0xFF;
  4196. this.view[offset+1] = (hi >>> 8) & 0xFF;
  4197. this.view[offset ] = hi & 0xFF;
  4198. } else {
  4199. this.view[offset ] = (hi >>> 24) & 0xFF;
  4200. this.view[offset+1] = (hi >>> 16) & 0xFF;
  4201. this.view[offset+2] = (hi >>> 8) & 0xFF;
  4202. this.view[offset+3] = hi & 0xFF;
  4203. offset += 4;
  4204. this.view[offset ] = (lo >>> 24) & 0xFF;
  4205. this.view[offset+1] = (lo >>> 16) & 0xFF;
  4206. this.view[offset+2] = (lo >>> 8) & 0xFF;
  4207. this.view[offset+3] = lo & 0xFF;
  4208. }
  4209. if (relative) this.offset += 8;
  4210. return this;
  4211. };
  4212. /**
  4213. * Writes a 64bit signed integer. This is an alias of {@link ByteBuffer#writeInt64}.
  4214. * @param {number|!Long} value Value to write
  4215. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  4216. * @returns {!ByteBuffer} this
  4217. * @expose
  4218. */
  4219. ByteBufferPrototype.writeLong = ByteBufferPrototype.writeInt64;
  4220. /**
  4221. * Reads a 64bit signed integer.
  4222. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  4223. * @returns {!Long}
  4224. * @expose
  4225. */
  4226. ByteBufferPrototype.readInt64 = function(offset) {
  4227. var relative = typeof offset === 'undefined';
  4228. if (relative) offset = this.offset;
  4229. if (!this.noAssert) {
  4230. if (typeof offset !== 'number' || offset % 1 !== 0)
  4231. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4232. offset >>>= 0;
  4233. if (offset < 0 || offset + 8 > this.buffer.byteLength)
  4234. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
  4235. }
  4236. var lo = 0,
  4237. hi = 0;
  4238. if (this.littleEndian) {
  4239. lo = this.view[offset+2] << 16;
  4240. lo |= this.view[offset+1] << 8;
  4241. lo |= this.view[offset ];
  4242. lo += this.view[offset+3] << 24 >>> 0;
  4243. offset += 4;
  4244. hi = this.view[offset+2] << 16;
  4245. hi |= this.view[offset+1] << 8;
  4246. hi |= this.view[offset ];
  4247. hi += this.view[offset+3] << 24 >>> 0;
  4248. } else {
  4249. hi = this.view[offset+1] << 16;
  4250. hi |= this.view[offset+2] << 8;
  4251. hi |= this.view[offset+3];
  4252. hi += this.view[offset ] << 24 >>> 0;
  4253. offset += 4;
  4254. lo = this.view[offset+1] << 16;
  4255. lo |= this.view[offset+2] << 8;
  4256. lo |= this.view[offset+3];
  4257. lo += this.view[offset ] << 24 >>> 0;
  4258. }
  4259. var value = new Long(lo, hi, false);
  4260. if (relative) this.offset += 8;
  4261. return value;
  4262. };
  4263. /**
  4264. * Reads a 64bit signed integer. This is an alias of {@link ByteBuffer#readInt64}.
  4265. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  4266. * @returns {!Long}
  4267. * @expose
  4268. */
  4269. ByteBufferPrototype.readLong = ByteBufferPrototype.readInt64;
  4270. /**
  4271. * Writes a 64bit unsigned integer.
  4272. * @param {number|!Long} value Value to write
  4273. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  4274. * @returns {!ByteBuffer} this
  4275. * @expose
  4276. */
  4277. ByteBufferPrototype.writeUint64 = function(value, offset) {
  4278. var relative = typeof offset === 'undefined';
  4279. if (relative) offset = this.offset;
  4280. if (!this.noAssert) {
  4281. if (typeof value === 'number')
  4282. value = Long.fromNumber(value);
  4283. else if (typeof value === 'string')
  4284. value = Long.fromString(value);
  4285. else if (!(value && value instanceof Long))
  4286. throw TypeError("Illegal value: "+value+" (not an integer or Long)");
  4287. if (typeof offset !== 'number' || offset % 1 !== 0)
  4288. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4289. offset >>>= 0;
  4290. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  4291. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  4292. }
  4293. if (typeof value === 'number')
  4294. value = Long.fromNumber(value);
  4295. else if (typeof value === 'string')
  4296. value = Long.fromString(value);
  4297. offset += 8;
  4298. var capacity7 = this.buffer.byteLength;
  4299. if (offset > capacity7)
  4300. this.resize((capacity7 *= 2) > offset ? capacity7 : offset);
  4301. offset -= 8;
  4302. var lo = value.low,
  4303. hi = value.high;
  4304. if (this.littleEndian) {
  4305. this.view[offset+3] = (lo >>> 24) & 0xFF;
  4306. this.view[offset+2] = (lo >>> 16) & 0xFF;
  4307. this.view[offset+1] = (lo >>> 8) & 0xFF;
  4308. this.view[offset ] = lo & 0xFF;
  4309. offset += 4;
  4310. this.view[offset+3] = (hi >>> 24) & 0xFF;
  4311. this.view[offset+2] = (hi >>> 16) & 0xFF;
  4312. this.view[offset+1] = (hi >>> 8) & 0xFF;
  4313. this.view[offset ] = hi & 0xFF;
  4314. } else {
  4315. this.view[offset ] = (hi >>> 24) & 0xFF;
  4316. this.view[offset+1] = (hi >>> 16) & 0xFF;
  4317. this.view[offset+2] = (hi >>> 8) & 0xFF;
  4318. this.view[offset+3] = hi & 0xFF;
  4319. offset += 4;
  4320. this.view[offset ] = (lo >>> 24) & 0xFF;
  4321. this.view[offset+1] = (lo >>> 16) & 0xFF;
  4322. this.view[offset+2] = (lo >>> 8) & 0xFF;
  4323. this.view[offset+3] = lo & 0xFF;
  4324. }
  4325. if (relative) this.offset += 8;
  4326. return this;
  4327. };
  4328. /**
  4329. * Writes a 64bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint64}.
  4330. * @function
  4331. * @param {number|!Long} value Value to write
  4332. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  4333. * @returns {!ByteBuffer} this
  4334. * @expose
  4335. */
  4336. ByteBufferPrototype.writeUInt64 = ByteBufferPrototype.writeUint64;
  4337. /**
  4338. * Reads a 64bit unsigned integer.
  4339. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  4340. * @returns {!Long}
  4341. * @expose
  4342. */
  4343. ByteBufferPrototype.readUint64 = function(offset) {
  4344. var relative = typeof offset === 'undefined';
  4345. if (relative) offset = this.offset;
  4346. if (!this.noAssert) {
  4347. if (typeof offset !== 'number' || offset % 1 !== 0)
  4348. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4349. offset >>>= 0;
  4350. if (offset < 0 || offset + 8 > this.buffer.byteLength)
  4351. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
  4352. }
  4353. var lo = 0,
  4354. hi = 0;
  4355. if (this.littleEndian) {
  4356. lo = this.view[offset+2] << 16;
  4357. lo |= this.view[offset+1] << 8;
  4358. lo |= this.view[offset ];
  4359. lo += this.view[offset+3] << 24 >>> 0;
  4360. offset += 4;
  4361. hi = this.view[offset+2] << 16;
  4362. hi |= this.view[offset+1] << 8;
  4363. hi |= this.view[offset ];
  4364. hi += this.view[offset+3] << 24 >>> 0;
  4365. } else {
  4366. hi = this.view[offset+1] << 16;
  4367. hi |= this.view[offset+2] << 8;
  4368. hi |= this.view[offset+3];
  4369. hi += this.view[offset ] << 24 >>> 0;
  4370. offset += 4;
  4371. lo = this.view[offset+1] << 16;
  4372. lo |= this.view[offset+2] << 8;
  4373. lo |= this.view[offset+3];
  4374. lo += this.view[offset ] << 24 >>> 0;
  4375. }
  4376. var value = new Long(lo, hi, true);
  4377. if (relative) this.offset += 8;
  4378. return value;
  4379. };
  4380. /**
  4381. * Reads a 64bit unsigned integer. This is an alias of {@link ByteBuffer#readUint64}.
  4382. * @function
  4383. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  4384. * @returns {!Long}
  4385. * @expose
  4386. */
  4387. ByteBufferPrototype.readUInt64 = ByteBufferPrototype.readUint64;
  4388. } // Long
  4389. // types/floats/float32
  4390. /*
  4391. ieee754 - https://github.com/feross/ieee754
  4392. The MIT License (MIT)
  4393. Copyright (c) Feross Aboukhadijeh
  4394. Permission is hereby granted, free of charge, to any person obtaining a copy
  4395. of this software and associated documentation files (the "Software"), to deal
  4396. in the Software without restriction, including without limitation the rights
  4397. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  4398. copies of the Software, and to permit persons to whom the Software is
  4399. furnished to do so, subject to the following conditions:
  4400. The above copyright notice and this permission notice shall be included in
  4401. all copies or substantial portions of the Software.
  4402. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  4403. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  4404. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  4405. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  4406. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  4407. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  4408. THE SOFTWARE.
  4409. */
  4410. /**
  4411. * Reads an IEEE754 float from a byte array.
  4412. * @param {!Array} buffer
  4413. * @param {number} offset
  4414. * @param {boolean} isLE
  4415. * @param {number} mLen
  4416. * @param {number} nBytes
  4417. * @returns {number}
  4418. * @inner
  4419. */
  4420. function ieee754_read(buffer, offset, isLE, mLen, nBytes) {
  4421. var e, m,
  4422. eLen = nBytes * 8 - mLen - 1,
  4423. eMax = (1 << eLen) - 1,
  4424. eBias = eMax >> 1,
  4425. nBits = -7,
  4426. i = isLE ? (nBytes - 1) : 0,
  4427. d = isLE ? -1 : 1,
  4428. s = buffer[offset + i];
  4429. i += d;
  4430. e = s & ((1 << (-nBits)) - 1);
  4431. s >>= (-nBits);
  4432. nBits += eLen;
  4433. for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
  4434. m = e & ((1 << (-nBits)) - 1);
  4435. e >>= (-nBits);
  4436. nBits += mLen;
  4437. for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
  4438. if (e === 0) {
  4439. e = 1 - eBias;
  4440. } else if (e === eMax) {
  4441. return m ? NaN : ((s ? -1 : 1) * Infinity);
  4442. } else {
  4443. m = m + Math.pow(2, mLen);
  4444. e = e - eBias;
  4445. }
  4446. return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
  4447. }
  4448. /**
  4449. * Writes an IEEE754 float to a byte array.
  4450. * @param {!Array} buffer
  4451. * @param {number} value
  4452. * @param {number} offset
  4453. * @param {boolean} isLE
  4454. * @param {number} mLen
  4455. * @param {number} nBytes
  4456. * @inner
  4457. */
  4458. function ieee754_write(buffer, value, offset, isLE, mLen, nBytes) {
  4459. var e, m, c,
  4460. eLen = nBytes * 8 - mLen - 1,
  4461. eMax = (1 << eLen) - 1,
  4462. eBias = eMax >> 1,
  4463. rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
  4464. i = isLE ? 0 : (nBytes - 1),
  4465. d = isLE ? 1 : -1,
  4466. s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
  4467. value = Math.abs(value);
  4468. if (isNaN(value) || value === Infinity) {
  4469. m = isNaN(value) ? 1 : 0;
  4470. e = eMax;
  4471. } else {
  4472. e = Math.floor(Math.log(value) / Math.LN2);
  4473. if (value * (c = Math.pow(2, -e)) < 1) {
  4474. e--;
  4475. c *= 2;
  4476. }
  4477. if (e + eBias >= 1) {
  4478. value += rt / c;
  4479. } else {
  4480. value += rt * Math.pow(2, 1 - eBias);
  4481. }
  4482. if (value * c >= 2) {
  4483. e++;
  4484. c /= 2;
  4485. }
  4486. if (e + eBias >= eMax) {
  4487. m = 0;
  4488. e = eMax;
  4489. } else if (e + eBias >= 1) {
  4490. m = (value * c - 1) * Math.pow(2, mLen);
  4491. e = e + eBias;
  4492. } else {
  4493. m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
  4494. e = 0;
  4495. }
  4496. }
  4497. for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
  4498. e = (e << mLen) | m;
  4499. eLen += mLen;
  4500. for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
  4501. buffer[offset + i - d] |= s * 128;
  4502. }
  4503. /**
  4504. * Writes a 32bit float.
  4505. * @param {number} value Value to write
  4506. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  4507. * @returns {!ByteBuffer} this
  4508. * @expose
  4509. */
  4510. ByteBufferPrototype.writeFloat32 = function(value, offset) {
  4511. var relative = typeof offset === 'undefined';
  4512. if (relative) offset = this.offset;
  4513. if (!this.noAssert) {
  4514. if (typeof value !== 'number')
  4515. throw TypeError("Illegal value: "+value+" (not a number)");
  4516. if (typeof offset !== 'number' || offset % 1 !== 0)
  4517. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4518. offset >>>= 0;
  4519. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  4520. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  4521. }
  4522. offset += 4;
  4523. var capacity8 = this.buffer.byteLength;
  4524. if (offset > capacity8)
  4525. this.resize((capacity8 *= 2) > offset ? capacity8 : offset);
  4526. offset -= 4;
  4527. ieee754_write(this.view, value, offset, this.littleEndian, 23, 4);
  4528. if (relative) this.offset += 4;
  4529. return this;
  4530. };
  4531. /**
  4532. * Writes a 32bit float. This is an alias of {@link ByteBuffer#writeFloat32}.
  4533. * @function
  4534. * @param {number} value Value to write
  4535. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  4536. * @returns {!ByteBuffer} this
  4537. * @expose
  4538. */
  4539. ByteBufferPrototype.writeFloat = ByteBufferPrototype.writeFloat32;
  4540. /**
  4541. * Reads a 32bit float.
  4542. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  4543. * @returns {number}
  4544. * @expose
  4545. */
  4546. ByteBufferPrototype.readFloat32 = function(offset) {
  4547. var relative = typeof offset === 'undefined';
  4548. if (relative) offset = this.offset;
  4549. if (!this.noAssert) {
  4550. if (typeof offset !== 'number' || offset % 1 !== 0)
  4551. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4552. offset >>>= 0;
  4553. if (offset < 0 || offset + 4 > this.buffer.byteLength)
  4554. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
  4555. }
  4556. var value = ieee754_read(this.view, offset, this.littleEndian, 23, 4);
  4557. if (relative) this.offset += 4;
  4558. return value;
  4559. };
  4560. /**
  4561. * Reads a 32bit float. This is an alias of {@link ByteBuffer#readFloat32}.
  4562. * @function
  4563. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  4564. * @returns {number}
  4565. * @expose
  4566. */
  4567. ByteBufferPrototype.readFloat = ByteBufferPrototype.readFloat32;
  4568. // types/floats/float64
  4569. /**
  4570. * Writes a 64bit float.
  4571. * @param {number} value Value to write
  4572. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  4573. * @returns {!ByteBuffer} this
  4574. * @expose
  4575. */
  4576. ByteBufferPrototype.writeFloat64 = function(value, offset) {
  4577. var relative = typeof offset === 'undefined';
  4578. if (relative) offset = this.offset;
  4579. if (!this.noAssert) {
  4580. if (typeof value !== 'number')
  4581. throw TypeError("Illegal value: "+value+" (not a number)");
  4582. if (typeof offset !== 'number' || offset % 1 !== 0)
  4583. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4584. offset >>>= 0;
  4585. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  4586. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  4587. }
  4588. offset += 8;
  4589. var capacity9 = this.buffer.byteLength;
  4590. if (offset > capacity9)
  4591. this.resize((capacity9 *= 2) > offset ? capacity9 : offset);
  4592. offset -= 8;
  4593. ieee754_write(this.view, value, offset, this.littleEndian, 52, 8);
  4594. if (relative) this.offset += 8;
  4595. return this;
  4596. };
  4597. /**
  4598. * Writes a 64bit float. This is an alias of {@link ByteBuffer#writeFloat64}.
  4599. * @function
  4600. * @param {number} value Value to write
  4601. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  4602. * @returns {!ByteBuffer} this
  4603. * @expose
  4604. */
  4605. ByteBufferPrototype.writeDouble = ByteBufferPrototype.writeFloat64;
  4606. /**
  4607. * Reads a 64bit float.
  4608. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  4609. * @returns {number}
  4610. * @expose
  4611. */
  4612. ByteBufferPrototype.readFloat64 = function(offset) {
  4613. var relative = typeof offset === 'undefined';
  4614. if (relative) offset = this.offset;
  4615. if (!this.noAssert) {
  4616. if (typeof offset !== 'number' || offset % 1 !== 0)
  4617. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4618. offset >>>= 0;
  4619. if (offset < 0 || offset + 8 > this.buffer.byteLength)
  4620. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
  4621. }
  4622. var value = ieee754_read(this.view, offset, this.littleEndian, 52, 8);
  4623. if (relative) this.offset += 8;
  4624. return value;
  4625. };
  4626. /**
  4627. * Reads a 64bit float. This is an alias of {@link ByteBuffer#readFloat64}.
  4628. * @function
  4629. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  4630. * @returns {number}
  4631. * @expose
  4632. */
  4633. ByteBufferPrototype.readDouble = ByteBufferPrototype.readFloat64;
  4634. // types/varints/varint32
  4635. /**
  4636. * Maximum number of bytes required to store a 32bit base 128 variable-length integer.
  4637. * @type {number}
  4638. * @const
  4639. * @expose
  4640. */
  4641. ByteBuffer.MAX_VARINT32_BYTES = 5;
  4642. /**
  4643. * Calculates the actual number of bytes required to store a 32bit base 128 variable-length integer.
  4644. * @param {number} value Value to encode
  4645. * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT32_BYTES}
  4646. * @expose
  4647. */
  4648. ByteBuffer.calculateVarint32 = function(value) {
  4649. // ref: src/google/protobuf/io/coded_stream.cc
  4650. value = value >>> 0;
  4651. if (value < 1 << 7 ) return 1;
  4652. else if (value < 1 << 14) return 2;
  4653. else if (value < 1 << 21) return 3;
  4654. else if (value < 1 << 28) return 4;
  4655. else return 5;
  4656. };
  4657. /**
  4658. * Zigzag encodes a signed 32bit integer so that it can be effectively used with varint encoding.
  4659. * @param {number} n Signed 32bit integer
  4660. * @returns {number} Unsigned zigzag encoded 32bit integer
  4661. * @expose
  4662. */
  4663. ByteBuffer.zigZagEncode32 = function(n) {
  4664. return (((n |= 0) << 1) ^ (n >> 31)) >>> 0; // ref: src/google/protobuf/wire_format_lite.h
  4665. };
  4666. /**
  4667. * Decodes a zigzag encoded signed 32bit integer.
  4668. * @param {number} n Unsigned zigzag encoded 32bit integer
  4669. * @returns {number} Signed 32bit integer
  4670. * @expose
  4671. */
  4672. ByteBuffer.zigZagDecode32 = function(n) {
  4673. return ((n >>> 1) ^ -(n & 1)) | 0; // // ref: src/google/protobuf/wire_format_lite.h
  4674. };
  4675. /**
  4676. * Writes a 32bit base 128 variable-length integer.
  4677. * @param {number} value Value to write
  4678. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4679. * written if omitted.
  4680. * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written
  4681. * @expose
  4682. */
  4683. ByteBufferPrototype.writeVarint32 = function(value, offset) {
  4684. var relative = typeof offset === 'undefined';
  4685. if (relative) offset = this.offset;
  4686. if (!this.noAssert) {
  4687. if (typeof value !== 'number' || value % 1 !== 0)
  4688. throw TypeError("Illegal value: "+value+" (not an integer)");
  4689. value |= 0;
  4690. if (typeof offset !== 'number' || offset % 1 !== 0)
  4691. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4692. offset >>>= 0;
  4693. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  4694. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  4695. }
  4696. var size = ByteBuffer.calculateVarint32(value),
  4697. b;
  4698. offset += size;
  4699. var capacity10 = this.buffer.byteLength;
  4700. if (offset > capacity10)
  4701. this.resize((capacity10 *= 2) > offset ? capacity10 : offset);
  4702. offset -= size;
  4703. value >>>= 0;
  4704. while (value >= 0x80) {
  4705. b = (value & 0x7f) | 0x80;
  4706. this.view[offset++] = b;
  4707. value >>>= 7;
  4708. }
  4709. this.view[offset++] = value;
  4710. if (relative) {
  4711. this.offset = offset;
  4712. return this;
  4713. }
  4714. return size;
  4715. };
  4716. /**
  4717. * Writes a zig-zag encoded (signed) 32bit base 128 variable-length integer.
  4718. * @param {number} value Value to write
  4719. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4720. * written if omitted.
  4721. * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written
  4722. * @expose
  4723. */
  4724. ByteBufferPrototype.writeVarint32ZigZag = function(value, offset) {
  4725. return this.writeVarint32(ByteBuffer.zigZagEncode32(value), offset);
  4726. };
  4727. /**
  4728. * Reads a 32bit base 128 variable-length integer.
  4729. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4730. * written if omitted.
  4731. * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read
  4732. * and the actual number of bytes read.
  4733. * @throws {Error} If it's not a valid varint. Has a property `truncated = true` if there is not enough data available
  4734. * to fully decode the varint.
  4735. * @expose
  4736. */
  4737. ByteBufferPrototype.readVarint32 = function(offset) {
  4738. var relative = typeof offset === 'undefined';
  4739. if (relative) offset = this.offset;
  4740. if (!this.noAssert) {
  4741. if (typeof offset !== 'number' || offset % 1 !== 0)
  4742. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4743. offset >>>= 0;
  4744. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  4745. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  4746. }
  4747. var c = 0,
  4748. value = 0 >>> 0,
  4749. b;
  4750. do {
  4751. if (!this.noAssert && offset > this.limit) {
  4752. var err = Error("Truncated");
  4753. err['truncated'] = true;
  4754. throw err;
  4755. }
  4756. b = this.view[offset++];
  4757. if (c < 5)
  4758. value |= (b & 0x7f) << (7*c);
  4759. ++c;
  4760. } while ((b & 0x80) !== 0);
  4761. value |= 0;
  4762. if (relative) {
  4763. this.offset = offset;
  4764. return value;
  4765. }
  4766. return {
  4767. "value": value,
  4768. "length": c
  4769. };
  4770. };
  4771. /**
  4772. * Reads a zig-zag encoded (signed) 32bit base 128 variable-length integer.
  4773. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4774. * written if omitted.
  4775. * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read
  4776. * and the actual number of bytes read.
  4777. * @throws {Error} If it's not a valid varint
  4778. * @expose
  4779. */
  4780. ByteBufferPrototype.readVarint32ZigZag = function(offset) {
  4781. var val = this.readVarint32(offset);
  4782. if (typeof val === 'object')
  4783. val["value"] = ByteBuffer.zigZagDecode32(val["value"]);
  4784. else
  4785. val = ByteBuffer.zigZagDecode32(val);
  4786. return val;
  4787. };
  4788. // types/varints/varint64
  4789. if (Long) {
  4790. /**
  4791. * Maximum number of bytes required to store a 64bit base 128 variable-length integer.
  4792. * @type {number}
  4793. * @const
  4794. * @expose
  4795. */
  4796. ByteBuffer.MAX_VARINT64_BYTES = 10;
  4797. /**
  4798. * Calculates the actual number of bytes required to store a 64bit base 128 variable-length integer.
  4799. * @param {number|!Long} value Value to encode
  4800. * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT64_BYTES}
  4801. * @expose
  4802. */
  4803. ByteBuffer.calculateVarint64 = function(value) {
  4804. if (typeof value === 'number')
  4805. value = Long.fromNumber(value);
  4806. else if (typeof value === 'string')
  4807. value = Long.fromString(value);
  4808. // ref: src/google/protobuf/io/coded_stream.cc
  4809. var part0 = value.toInt() >>> 0,
  4810. part1 = value.shiftRightUnsigned(28).toInt() >>> 0,
  4811. part2 = value.shiftRightUnsigned(56).toInt() >>> 0;
  4812. if (part2 == 0) {
  4813. if (part1 == 0) {
  4814. if (part0 < 1 << 14)
  4815. return part0 < 1 << 7 ? 1 : 2;
  4816. else
  4817. return part0 < 1 << 21 ? 3 : 4;
  4818. } else {
  4819. if (part1 < 1 << 14)
  4820. return part1 < 1 << 7 ? 5 : 6;
  4821. else
  4822. return part1 < 1 << 21 ? 7 : 8;
  4823. }
  4824. } else
  4825. return part2 < 1 << 7 ? 9 : 10;
  4826. };
  4827. /**
  4828. * Zigzag encodes a signed 64bit integer so that it can be effectively used with varint encoding.
  4829. * @param {number|!Long} value Signed long
  4830. * @returns {!Long} Unsigned zigzag encoded long
  4831. * @expose
  4832. */
  4833. ByteBuffer.zigZagEncode64 = function(value) {
  4834. if (typeof value === 'number')
  4835. value = Long.fromNumber(value, false);
  4836. else if (typeof value === 'string')
  4837. value = Long.fromString(value, false);
  4838. else if (value.unsigned !== false) value = value.toSigned();
  4839. // ref: src/google/protobuf/wire_format_lite.h
  4840. return value.shiftLeft(1).xor(value.shiftRight(63)).toUnsigned();
  4841. };
  4842. /**
  4843. * Decodes a zigzag encoded signed 64bit integer.
  4844. * @param {!Long|number} value Unsigned zigzag encoded long or JavaScript number
  4845. * @returns {!Long} Signed long
  4846. * @expose
  4847. */
  4848. ByteBuffer.zigZagDecode64 = function(value) {
  4849. if (typeof value === 'number')
  4850. value = Long.fromNumber(value, false);
  4851. else if (typeof value === 'string')
  4852. value = Long.fromString(value, false);
  4853. else if (value.unsigned !== false) value = value.toSigned();
  4854. // ref: src/google/protobuf/wire_format_lite.h
  4855. return value.shiftRightUnsigned(1).xor(value.and(Long.ONE).toSigned().negate()).toSigned();
  4856. };
  4857. /**
  4858. * Writes a 64bit base 128 variable-length integer.
  4859. * @param {number|Long} value Value to write
  4860. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4861. * written if omitted.
  4862. * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written.
  4863. * @expose
  4864. */
  4865. ByteBufferPrototype.writeVarint64 = function(value, offset) {
  4866. var relative = typeof offset === 'undefined';
  4867. if (relative) offset = this.offset;
  4868. if (!this.noAssert) {
  4869. if (typeof value === 'number')
  4870. value = Long.fromNumber(value);
  4871. else if (typeof value === 'string')
  4872. value = Long.fromString(value);
  4873. else if (!(value && value instanceof Long))
  4874. throw TypeError("Illegal value: "+value+" (not an integer or Long)");
  4875. if (typeof offset !== 'number' || offset % 1 !== 0)
  4876. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4877. offset >>>= 0;
  4878. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  4879. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  4880. }
  4881. if (typeof value === 'number')
  4882. value = Long.fromNumber(value, false);
  4883. else if (typeof value === 'string')
  4884. value = Long.fromString(value, false);
  4885. else if (value.unsigned !== false) value = value.toSigned();
  4886. var size = ByteBuffer.calculateVarint64(value),
  4887. part0 = value.toInt() >>> 0,
  4888. part1 = value.shiftRightUnsigned(28).toInt() >>> 0,
  4889. part2 = value.shiftRightUnsigned(56).toInt() >>> 0;
  4890. offset += size;
  4891. var capacity11 = this.buffer.byteLength;
  4892. if (offset > capacity11)
  4893. this.resize((capacity11 *= 2) > offset ? capacity11 : offset);
  4894. offset -= size;
  4895. switch (size) {
  4896. case 10: this.view[offset+9] = (part2 >>> 7) & 0x01;
  4897. case 9 : this.view[offset+8] = size !== 9 ? (part2 ) | 0x80 : (part2 ) & 0x7F;
  4898. case 8 : this.view[offset+7] = size !== 8 ? (part1 >>> 21) | 0x80 : (part1 >>> 21) & 0x7F;
  4899. case 7 : this.view[offset+6] = size !== 7 ? (part1 >>> 14) | 0x80 : (part1 >>> 14) & 0x7F;
  4900. case 6 : this.view[offset+5] = size !== 6 ? (part1 >>> 7) | 0x80 : (part1 >>> 7) & 0x7F;
  4901. case 5 : this.view[offset+4] = size !== 5 ? (part1 ) | 0x80 : (part1 ) & 0x7F;
  4902. case 4 : this.view[offset+3] = size !== 4 ? (part0 >>> 21) | 0x80 : (part0 >>> 21) & 0x7F;
  4903. case 3 : this.view[offset+2] = size !== 3 ? (part0 >>> 14) | 0x80 : (part0 >>> 14) & 0x7F;
  4904. case 2 : this.view[offset+1] = size !== 2 ? (part0 >>> 7) | 0x80 : (part0 >>> 7) & 0x7F;
  4905. case 1 : this.view[offset ] = size !== 1 ? (part0 ) | 0x80 : (part0 ) & 0x7F;
  4906. }
  4907. if (relative) {
  4908. this.offset += size;
  4909. return this;
  4910. } else {
  4911. return size;
  4912. }
  4913. };
  4914. /**
  4915. * Writes a zig-zag encoded 64bit base 128 variable-length integer.
  4916. * @param {number|Long} value Value to write
  4917. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4918. * written if omitted.
  4919. * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written.
  4920. * @expose
  4921. */
  4922. ByteBufferPrototype.writeVarint64ZigZag = function(value, offset) {
  4923. return this.writeVarint64(ByteBuffer.zigZagEncode64(value), offset);
  4924. };
  4925. /**
  4926. * Reads a 64bit base 128 variable-length integer. Requires Long.js.
  4927. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4928. * read if omitted.
  4929. * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and
  4930. * the actual number of bytes read.
  4931. * @throws {Error} If it's not a valid varint
  4932. * @expose
  4933. */
  4934. ByteBufferPrototype.readVarint64 = function(offset) {
  4935. var relative = typeof offset === 'undefined';
  4936. if (relative) offset = this.offset;
  4937. if (!this.noAssert) {
  4938. if (typeof offset !== 'number' || offset % 1 !== 0)
  4939. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  4940. offset >>>= 0;
  4941. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  4942. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  4943. }
  4944. // ref: src/google/protobuf/io/coded_stream.cc
  4945. var start = offset,
  4946. part0 = 0,
  4947. part1 = 0,
  4948. part2 = 0,
  4949. b = 0;
  4950. b = this.view[offset++]; part0 = (b & 0x7F) ; if ( b & 0x80 ) {
  4951. b = this.view[offset++]; part0 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4952. b = this.view[offset++]; part0 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4953. b = this.view[offset++]; part0 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4954. b = this.view[offset++]; part1 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4955. b = this.view[offset++]; part1 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4956. b = this.view[offset++]; part1 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4957. b = this.view[offset++]; part1 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4958. b = this.view[offset++]; part2 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4959. b = this.view[offset++]; part2 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  4960. throw Error("Buffer overrun"); }}}}}}}}}}
  4961. var value = Long.fromBits(part0 | (part1 << 28), (part1 >>> 4) | (part2) << 24, false);
  4962. if (relative) {
  4963. this.offset = offset;
  4964. return value;
  4965. } else {
  4966. return {
  4967. 'value': value,
  4968. 'length': offset-start
  4969. };
  4970. }
  4971. };
  4972. /**
  4973. * Reads a zig-zag encoded 64bit base 128 variable-length integer. Requires Long.js.
  4974. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4975. * read if omitted.
  4976. * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and
  4977. * the actual number of bytes read.
  4978. * @throws {Error} If it's not a valid varint
  4979. * @expose
  4980. */
  4981. ByteBufferPrototype.readVarint64ZigZag = function(offset) {
  4982. var val = this.readVarint64(offset);
  4983. if (val && val['value'] instanceof Long)
  4984. val["value"] = ByteBuffer.zigZagDecode64(val["value"]);
  4985. else
  4986. val = ByteBuffer.zigZagDecode64(val);
  4987. return val;
  4988. };
  4989. } // Long
  4990. // types/strings/cstring
  4991. /**
  4992. * Writes a NULL-terminated UTF8 encoded string. For this to work the specified string must not contain any NULL
  4993. * characters itself.
  4994. * @param {string} str String to write
  4995. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  4996. * contained in `str` + 1 if omitted.
  4997. * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written
  4998. * @expose
  4999. */
  5000. ByteBufferPrototype.writeCString = function(str, offset) {
  5001. var relative = typeof offset === 'undefined';
  5002. if (relative) offset = this.offset;
  5003. var i,
  5004. k = str.length;
  5005. if (!this.noAssert) {
  5006. if (typeof str !== 'string')
  5007. throw TypeError("Illegal str: Not a string");
  5008. for (i=0; i<k; ++i) {
  5009. if (str.charCodeAt(i) === 0)
  5010. throw RangeError("Illegal str: Contains NULL-characters");
  5011. }
  5012. if (typeof offset !== 'number' || offset % 1 !== 0)
  5013. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  5014. offset >>>= 0;
  5015. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  5016. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  5017. }
  5018. // UTF8 strings do not contain zero bytes in between except for the zero character, so:
  5019. k = utfx.calculateUTF16asUTF8(stringSource(str))[1];
  5020. offset += k+1;
  5021. var capacity12 = this.buffer.byteLength;
  5022. if (offset > capacity12)
  5023. this.resize((capacity12 *= 2) > offset ? capacity12 : offset);
  5024. offset -= k+1;
  5025. utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
  5026. this.view[offset++] = b;
  5027. }.bind(this));
  5028. this.view[offset++] = 0;
  5029. if (relative) {
  5030. this.offset = offset;
  5031. return this;
  5032. }
  5033. return k;
  5034. };
  5035. /**
  5036. * Reads a NULL-terminated UTF8 encoded string. For this to work the string read must not contain any NULL characters
  5037. * itself.
  5038. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  5039. * read if omitted.
  5040. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
  5041. * read and the actual number of bytes read.
  5042. * @expose
  5043. */
  5044. ByteBufferPrototype.readCString = function(offset) {
  5045. var relative = typeof offset === 'undefined';
  5046. if (relative) offset = this.offset;
  5047. if (!this.noAssert) {
  5048. if (typeof offset !== 'number' || offset % 1 !== 0)
  5049. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  5050. offset >>>= 0;
  5051. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  5052. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  5053. }
  5054. var start = offset;
  5055. // UTF8 strings do not contain zero bytes in between except for the zero character itself, so:
  5056. var sd, b = -1;
  5057. utfx.decodeUTF8toUTF16(function() {
  5058. if (b === 0) return null;
  5059. if (offset >= this.limit)
  5060. throw RangeError("Illegal range: Truncated data, "+offset+" < "+this.limit);
  5061. b = this.view[offset++];
  5062. return b === 0 ? null : b;
  5063. }.bind(this), sd = stringDestination(), true);
  5064. if (relative) {
  5065. this.offset = offset;
  5066. return sd();
  5067. } else {
  5068. return {
  5069. "string": sd(),
  5070. "length": offset - start
  5071. };
  5072. }
  5073. };
  5074. // types/strings/istring
  5075. /**
  5076. * Writes a length as uint32 prefixed UTF8 encoded string.
  5077. * @param {string} str String to write
  5078. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  5079. * written if omitted.
  5080. * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written
  5081. * @expose
  5082. * @see ByteBuffer#writeVarint32
  5083. */
  5084. ByteBufferPrototype.writeIString = function(str, offset) {
  5085. var relative = typeof offset === 'undefined';
  5086. if (relative) offset = this.offset;
  5087. if (!this.noAssert) {
  5088. if (typeof str !== 'string')
  5089. throw TypeError("Illegal str: Not a string");
  5090. if (typeof offset !== 'number' || offset % 1 !== 0)
  5091. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  5092. offset >>>= 0;
  5093. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  5094. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  5095. }
  5096. var start = offset,
  5097. k;
  5098. k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1];
  5099. offset += 4+k;
  5100. var capacity13 = this.buffer.byteLength;
  5101. if (offset > capacity13)
  5102. this.resize((capacity13 *= 2) > offset ? capacity13 : offset);
  5103. offset -= 4+k;
  5104. if (this.littleEndian) {
  5105. this.view[offset+3] = (k >>> 24) & 0xFF;
  5106. this.view[offset+2] = (k >>> 16) & 0xFF;
  5107. this.view[offset+1] = (k >>> 8) & 0xFF;
  5108. this.view[offset ] = k & 0xFF;
  5109. } else {
  5110. this.view[offset ] = (k >>> 24) & 0xFF;
  5111. this.view[offset+1] = (k >>> 16) & 0xFF;
  5112. this.view[offset+2] = (k >>> 8) & 0xFF;
  5113. this.view[offset+3] = k & 0xFF;
  5114. }
  5115. offset += 4;
  5116. utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
  5117. this.view[offset++] = b;
  5118. }.bind(this));
  5119. if (offset !== start + 4 + k)
  5120. throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+4+k));
  5121. if (relative) {
  5122. this.offset = offset;
  5123. return this;
  5124. }
  5125. return offset - start;
  5126. };
  5127. /**
  5128. * Reads a length as uint32 prefixed UTF8 encoded string.
  5129. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  5130. * read if omitted.
  5131. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
  5132. * read and the actual number of bytes read.
  5133. * @expose
  5134. * @see ByteBuffer#readVarint32
  5135. */
  5136. ByteBufferPrototype.readIString = function(offset) {
  5137. var relative = typeof offset === 'undefined';
  5138. if (relative) offset = this.offset;
  5139. if (!this.noAssert) {
  5140. if (typeof offset !== 'number' || offset % 1 !== 0)
  5141. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  5142. offset >>>= 0;
  5143. if (offset < 0 || offset + 4 > this.buffer.byteLength)
  5144. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
  5145. }
  5146. var start = offset;
  5147. var len = this.readUint32(offset);
  5148. var str = this.readUTF8String(len, ByteBuffer.METRICS_BYTES, offset += 4);
  5149. offset += str['length'];
  5150. if (relative) {
  5151. this.offset = offset;
  5152. return str['string'];
  5153. } else {
  5154. return {
  5155. 'string': str['string'],
  5156. 'length': offset - start
  5157. };
  5158. }
  5159. };
  5160. // types/strings/utf8string
  5161. /**
  5162. * Metrics representing number of UTF8 characters. Evaluates to `c`.
  5163. * @type {string}
  5164. * @const
  5165. * @expose
  5166. */
  5167. ByteBuffer.METRICS_CHARS = 'c';
  5168. /**
  5169. * Metrics representing number of bytes. Evaluates to `b`.
  5170. * @type {string}
  5171. * @const
  5172. * @expose
  5173. */
  5174. ByteBuffer.METRICS_BYTES = 'b';
  5175. /**
  5176. * Writes an UTF8 encoded string.
  5177. * @param {string} str String to write
  5178. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted.
  5179. * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written.
  5180. * @expose
  5181. */
  5182. ByteBufferPrototype.writeUTF8String = function(str, offset) {
  5183. var relative = typeof offset === 'undefined';
  5184. if (relative) offset = this.offset;
  5185. if (!this.noAssert) {
  5186. if (typeof offset !== 'number' || offset % 1 !== 0)
  5187. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  5188. offset >>>= 0;
  5189. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  5190. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  5191. }
  5192. var k;
  5193. var start = offset;
  5194. k = utfx.calculateUTF16asUTF8(stringSource(str))[1];
  5195. offset += k;
  5196. var capacity14 = this.buffer.byteLength;
  5197. if (offset > capacity14)
  5198. this.resize((capacity14 *= 2) > offset ? capacity14 : offset);
  5199. offset -= k;
  5200. utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
  5201. this.view[offset++] = b;
  5202. }.bind(this));
  5203. if (relative) {
  5204. this.offset = offset;
  5205. return this;
  5206. }
  5207. return offset - start;
  5208. };
  5209. /**
  5210. * Writes an UTF8 encoded string. This is an alias of {@link ByteBuffer#writeUTF8String}.
  5211. * @function
  5212. * @param {string} str String to write
  5213. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted.
  5214. * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written.
  5215. * @expose
  5216. */
  5217. ByteBufferPrototype.writeString = ByteBufferPrototype.writeUTF8String;
  5218. /**
  5219. * Calculates the number of UTF8 characters of a string. JavaScript itself uses UTF-16, so that a string's
  5220. * `length` property does not reflect its actual UTF8 size if it contains code points larger than 0xFFFF.
  5221. * @param {string} str String to calculate
  5222. * @returns {number} Number of UTF8 characters
  5223. * @expose
  5224. */
  5225. ByteBuffer.calculateUTF8Chars = function(str) {
  5226. return utfx.calculateUTF16asUTF8(stringSource(str))[0];
  5227. };
  5228. /**
  5229. * Calculates the number of UTF8 bytes of a string.
  5230. * @param {string} str String to calculate
  5231. * @returns {number} Number of UTF8 bytes
  5232. * @expose
  5233. */
  5234. ByteBuffer.calculateUTF8Bytes = function(str) {
  5235. return utfx.calculateUTF16asUTF8(stringSource(str))[1];
  5236. };
  5237. /**
  5238. * Calculates the number of UTF8 bytes of a string. This is an alias of {@link ByteBuffer.calculateUTF8Bytes}.
  5239. * @function
  5240. * @param {string} str String to calculate
  5241. * @returns {number} Number of UTF8 bytes
  5242. * @expose
  5243. */
  5244. ByteBuffer.calculateString = ByteBuffer.calculateUTF8Bytes;
  5245. /**
  5246. * Reads an UTF8 encoded string.
  5247. * @param {number} length Number of characters or bytes to read.
  5248. * @param {string=} metrics Metrics specifying what `length` is meant to count. Defaults to
  5249. * {@link ByteBuffer.METRICS_CHARS}.
  5250. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  5251. * read if omitted.
  5252. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
  5253. * read and the actual number of bytes read.
  5254. * @expose
  5255. */
  5256. ByteBufferPrototype.readUTF8String = function(length, metrics, offset) {
  5257. if (typeof metrics === 'number') {
  5258. offset = metrics;
  5259. metrics = undefined;
  5260. }
  5261. var relative = typeof offset === 'undefined';
  5262. if (relative) offset = this.offset;
  5263. if (typeof metrics === 'undefined') metrics = ByteBuffer.METRICS_CHARS;
  5264. if (!this.noAssert) {
  5265. if (typeof length !== 'number' || length % 1 !== 0)
  5266. throw TypeError("Illegal length: "+length+" (not an integer)");
  5267. length |= 0;
  5268. if (typeof offset !== 'number' || offset % 1 !== 0)
  5269. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  5270. offset >>>= 0;
  5271. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  5272. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  5273. }
  5274. var i = 0,
  5275. start = offset,
  5276. sd;
  5277. if (metrics === ByteBuffer.METRICS_CHARS) { // The same for node and the browser
  5278. sd = stringDestination();
  5279. utfx.decodeUTF8(function() {
  5280. return i < length && offset < this.limit ? this.view[offset++] : null;
  5281. }.bind(this), function(cp) {
  5282. ++i; utfx.UTF8toUTF16(cp, sd);
  5283. });
  5284. if (i !== length)
  5285. throw RangeError("Illegal range: Truncated data, "+i+" == "+length);
  5286. if (relative) {
  5287. this.offset = offset;
  5288. return sd();
  5289. } else {
  5290. return {
  5291. "string": sd(),
  5292. "length": offset - start
  5293. };
  5294. }
  5295. } else if (metrics === ByteBuffer.METRICS_BYTES) {
  5296. if (!this.noAssert) {
  5297. if (typeof offset !== 'number' || offset % 1 !== 0)
  5298. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  5299. offset >>>= 0;
  5300. if (offset < 0 || offset + length > this.buffer.byteLength)
  5301. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength);
  5302. }
  5303. var k = offset + length;
  5304. utfx.decodeUTF8toUTF16(function() {
  5305. return offset < k ? this.view[offset++] : null;
  5306. }.bind(this), sd = stringDestination(), this.noAssert);
  5307. if (offset !== k)
  5308. throw RangeError("Illegal range: Truncated data, "+offset+" == "+k);
  5309. if (relative) {
  5310. this.offset = offset;
  5311. return sd();
  5312. } else {
  5313. return {
  5314. 'string': sd(),
  5315. 'length': offset - start
  5316. };
  5317. }
  5318. } else
  5319. throw TypeError("Unsupported metrics: "+metrics);
  5320. };
  5321. /**
  5322. * Reads an UTF8 encoded string. This is an alias of {@link ByteBuffer#readUTF8String}.
  5323. * @function
  5324. * @param {number} length Number of characters or bytes to read
  5325. * @param {number=} metrics Metrics specifying what `n` is meant to count. Defaults to
  5326. * {@link ByteBuffer.METRICS_CHARS}.
  5327. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  5328. * read if omitted.
  5329. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
  5330. * read and the actual number of bytes read.
  5331. * @expose
  5332. */
  5333. ByteBufferPrototype.readString = ByteBufferPrototype.readUTF8String;
  5334. // types/strings/vstring
  5335. /**
  5336. * Writes a length as varint32 prefixed UTF8 encoded string.
  5337. * @param {string} str String to write
  5338. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  5339. * written if omitted.
  5340. * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written
  5341. * @expose
  5342. * @see ByteBuffer#writeVarint32
  5343. */
  5344. ByteBufferPrototype.writeVString = function(str, offset) {
  5345. var relative = typeof offset === 'undefined';
  5346. if (relative) offset = this.offset;
  5347. if (!this.noAssert) {
  5348. if (typeof str !== 'string')
  5349. throw TypeError("Illegal str: Not a string");
  5350. if (typeof offset !== 'number' || offset % 1 !== 0)
  5351. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  5352. offset >>>= 0;
  5353. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  5354. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  5355. }
  5356. var start = offset,
  5357. k, l;
  5358. k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1];
  5359. l = ByteBuffer.calculateVarint32(k);
  5360. offset += l+k;
  5361. var capacity15 = this.buffer.byteLength;
  5362. if (offset > capacity15)
  5363. this.resize((capacity15 *= 2) > offset ? capacity15 : offset);
  5364. offset -= l+k;
  5365. offset += this.writeVarint32(k, offset);
  5366. utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
  5367. this.view[offset++] = b;
  5368. }.bind(this));
  5369. if (offset !== start+k+l)
  5370. throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+k+l));
  5371. if (relative) {
  5372. this.offset = offset;
  5373. return this;
  5374. }
  5375. return offset - start;
  5376. };
  5377. /**
  5378. * Reads a length as varint32 prefixed UTF8 encoded string.
  5379. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  5380. * read if omitted.
  5381. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
  5382. * read and the actual number of bytes read.
  5383. * @expose
  5384. * @see ByteBuffer#readVarint32
  5385. */
  5386. ByteBufferPrototype.readVString = function(offset) {
  5387. var relative = typeof offset === 'undefined';
  5388. if (relative) offset = this.offset;
  5389. if (!this.noAssert) {
  5390. if (typeof offset !== 'number' || offset % 1 !== 0)
  5391. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  5392. offset >>>= 0;
  5393. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  5394. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  5395. }
  5396. var start = offset;
  5397. var len = this.readVarint32(offset);
  5398. var str = this.readUTF8String(len['value'], ByteBuffer.METRICS_BYTES, offset += len['length']);
  5399. offset += str['length'];
  5400. if (relative) {
  5401. this.offset = offset;
  5402. return str['string'];
  5403. } else {
  5404. return {
  5405. 'string': str['string'],
  5406. 'length': offset - start
  5407. };
  5408. }
  5409. };
  5410. /**
  5411. * Appends some data to this ByteBuffer. This will overwrite any contents behind the specified offset up to the appended
  5412. * data's length.
  5413. * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to append. If `source` is a ByteBuffer, its offsets
  5414. * will be modified according to the performed read operation.
  5415. * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
  5416. * @param {number=} offset Offset to append at. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  5417. * written if omitted.
  5418. * @returns {!ByteBuffer} this
  5419. * @expose
  5420. * @example A relative `<01 02>03.append(<04 05>)` will result in `<01 02 04 05>, 04 05|`
  5421. * @example An absolute `<01 02>03.append(04 05>, 1)` will result in `<01 04>05, 04 05|`
  5422. */
  5423. ByteBufferPrototype.append = function(source, encoding, offset) {
  5424. if (typeof encoding === 'number' || typeof encoding !== 'string') {
  5425. offset = encoding;
  5426. encoding = undefined;
  5427. }
  5428. var relative = typeof offset === 'undefined';
  5429. if (relative) offset = this.offset;
  5430. if (!this.noAssert) {
  5431. if (typeof offset !== 'number' || offset % 1 !== 0)
  5432. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  5433. offset >>>= 0;
  5434. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  5435. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  5436. }
  5437. if (!(source instanceof ByteBuffer))
  5438. source = ByteBuffer.wrap(source, encoding);
  5439. var length = source.limit - source.offset;
  5440. if (length <= 0) return this; // Nothing to append
  5441. offset += length;
  5442. var capacity16 = this.buffer.byteLength;
  5443. if (offset > capacity16)
  5444. this.resize((capacity16 *= 2) > offset ? capacity16 : offset);
  5445. offset -= length;
  5446. this.view.set(source.view.subarray(source.offset, source.limit), offset);
  5447. source.offset += length;
  5448. if (relative) this.offset += length;
  5449. return this;
  5450. };
  5451. /**
  5452. * Appends this ByteBuffer's contents to another ByteBuffer. This will overwrite any contents at and after the
  5453. specified offset up to the length of this ByteBuffer's data.
  5454. * @param {!ByteBuffer} target Target ByteBuffer
  5455. * @param {number=} offset Offset to append to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  5456. * read if omitted.
  5457. * @returns {!ByteBuffer} this
  5458. * @expose
  5459. * @see ByteBuffer#append
  5460. */
  5461. ByteBufferPrototype.appendTo = function(target, offset) {
  5462. target.append(this, offset);
  5463. return this;
  5464. };
  5465. /**
  5466. * Enables or disables assertions of argument types and offsets. Assertions are enabled by default but you can opt to
  5467. * disable them if your code already makes sure that everything is valid.
  5468. * @param {boolean} assert `true` to enable assertions, otherwise `false`
  5469. * @returns {!ByteBuffer} this
  5470. * @expose
  5471. */
  5472. ByteBufferPrototype.assert = function(assert) {
  5473. this.noAssert = !assert;
  5474. return this;
  5475. };
  5476. /**
  5477. * Gets the capacity of this ByteBuffer's backing buffer.
  5478. * @returns {number} Capacity of the backing buffer
  5479. * @expose
  5480. */
  5481. ByteBufferPrototype.capacity = function() {
  5482. return this.buffer.byteLength;
  5483. };
  5484. /**
  5485. * Clears this ByteBuffer's offsets by setting {@link ByteBuffer#offset} to `0` and {@link ByteBuffer#limit} to the
  5486. * backing buffer's capacity. Discards {@link ByteBuffer#markedOffset}.
  5487. * @returns {!ByteBuffer} this
  5488. * @expose
  5489. */
  5490. ByteBufferPrototype.clear = function() {
  5491. this.offset = 0;
  5492. this.limit = this.buffer.byteLength;
  5493. this.markedOffset = -1;
  5494. return this;
  5495. };
  5496. /**
  5497. * Creates a cloned instance of this ByteBuffer, preset with this ByteBuffer's values for {@link ByteBuffer#offset},
  5498. * {@link ByteBuffer#markedOffset} and {@link ByteBuffer#limit}.
  5499. * @param {boolean=} copy Whether to copy the backing buffer or to return another view on the same, defaults to `false`
  5500. * @returns {!ByteBuffer} Cloned instance
  5501. * @expose
  5502. */
  5503. ByteBufferPrototype.clone = function(copy) {
  5504. var bb = new ByteBuffer(0, this.littleEndian, this.noAssert);
  5505. if (copy) {
  5506. bb.buffer = new ArrayBuffer(this.buffer.byteLength);
  5507. bb.view = new Uint8Array(bb.buffer);
  5508. } else {
  5509. bb.buffer = this.buffer;
  5510. bb.view = this.view;
  5511. }
  5512. bb.offset = this.offset;
  5513. bb.markedOffset = this.markedOffset;
  5514. bb.limit = this.limit;
  5515. return bb;
  5516. };
  5517. /**
  5518. * Compacts this ByteBuffer to be backed by a {@link ByteBuffer#buffer} of its contents' length. Contents are the bytes
  5519. * between {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. Will set `offset = 0` and `limit = capacity` and
  5520. * adapt {@link ByteBuffer#markedOffset} to the same relative position if set.
  5521. * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
  5522. * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
  5523. * @returns {!ByteBuffer} this
  5524. * @expose
  5525. */
  5526. ByteBufferPrototype.compact = function(begin, end) {
  5527. if (typeof begin === 'undefined') begin = this.offset;
  5528. if (typeof end === 'undefined') end = this.limit;
  5529. if (!this.noAssert) {
  5530. if (typeof begin !== 'number' || begin % 1 !== 0)
  5531. throw TypeError("Illegal begin: Not an integer");
  5532. begin >>>= 0;
  5533. if (typeof end !== 'number' || end % 1 !== 0)
  5534. throw TypeError("Illegal end: Not an integer");
  5535. end >>>= 0;
  5536. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  5537. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  5538. }
  5539. if (begin === 0 && end === this.buffer.byteLength)
  5540. return this; // Already compacted
  5541. var len = end - begin;
  5542. if (len === 0) {
  5543. this.buffer = EMPTY_BUFFER;
  5544. this.view = null;
  5545. if (this.markedOffset >= 0) this.markedOffset -= begin;
  5546. this.offset = 0;
  5547. this.limit = 0;
  5548. return this;
  5549. }
  5550. var buffer = new ArrayBuffer(len);
  5551. var view = new Uint8Array(buffer);
  5552. view.set(this.view.subarray(begin, end));
  5553. this.buffer = buffer;
  5554. this.view = view;
  5555. if (this.markedOffset >= 0) this.markedOffset -= begin;
  5556. this.offset = 0;
  5557. this.limit = len;
  5558. return this;
  5559. };
  5560. /**
  5561. * Creates a copy of this ByteBuffer's contents. Contents are the bytes between {@link ByteBuffer#offset} and
  5562. * {@link ByteBuffer#limit}.
  5563. * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
  5564. * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
  5565. * @returns {!ByteBuffer} Copy
  5566. * @expose
  5567. */
  5568. ByteBufferPrototype.copy = function(begin, end) {
  5569. if (typeof begin === 'undefined') begin = this.offset;
  5570. if (typeof end === 'undefined') end = this.limit;
  5571. if (!this.noAssert) {
  5572. if (typeof begin !== 'number' || begin % 1 !== 0)
  5573. throw TypeError("Illegal begin: Not an integer");
  5574. begin >>>= 0;
  5575. if (typeof end !== 'number' || end % 1 !== 0)
  5576. throw TypeError("Illegal end: Not an integer");
  5577. end >>>= 0;
  5578. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  5579. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  5580. }
  5581. if (begin === end)
  5582. return new ByteBuffer(0, this.littleEndian, this.noAssert);
  5583. var capacity = end - begin,
  5584. bb = new ByteBuffer(capacity, this.littleEndian, this.noAssert);
  5585. bb.offset = 0;
  5586. bb.limit = capacity;
  5587. if (bb.markedOffset >= 0) bb.markedOffset -= begin;
  5588. this.copyTo(bb, 0, begin, end);
  5589. return bb;
  5590. };
  5591. /**
  5592. * Copies this ByteBuffer's contents to another ByteBuffer. Contents are the bytes between {@link ByteBuffer#offset} and
  5593. * {@link ByteBuffer#limit}.
  5594. * @param {!ByteBuffer} target Target ByteBuffer
  5595. * @param {number=} targetOffset Offset to copy to. Will use and increase the target's {@link ByteBuffer#offset}
  5596. * by the number of bytes copied if omitted.
  5597. * @param {number=} sourceOffset Offset to start copying from. Will use and increase {@link ByteBuffer#offset} by the
  5598. * number of bytes copied if omitted.
  5599. * @param {number=} sourceLimit Offset to end copying from, defaults to {@link ByteBuffer#limit}
  5600. * @returns {!ByteBuffer} this
  5601. * @expose
  5602. */
  5603. ByteBufferPrototype.copyTo = function(target, targetOffset, sourceOffset, sourceLimit) {
  5604. var relative,
  5605. targetRelative;
  5606. if (!this.noAssert) {
  5607. if (!ByteBuffer.isByteBuffer(target))
  5608. throw TypeError("Illegal target: Not a ByteBuffer");
  5609. }
  5610. targetOffset = (targetRelative = typeof targetOffset === 'undefined') ? target.offset : targetOffset | 0;
  5611. sourceOffset = (relative = typeof sourceOffset === 'undefined') ? this.offset : sourceOffset | 0;
  5612. sourceLimit = typeof sourceLimit === 'undefined' ? this.limit : sourceLimit | 0;
  5613. if (targetOffset < 0 || targetOffset > target.buffer.byteLength)
  5614. throw RangeError("Illegal target range: 0 <= "+targetOffset+" <= "+target.buffer.byteLength);
  5615. if (sourceOffset < 0 || sourceLimit > this.buffer.byteLength)
  5616. throw RangeError("Illegal source range: 0 <= "+sourceOffset+" <= "+this.buffer.byteLength);
  5617. var len = sourceLimit - sourceOffset;
  5618. if (len === 0)
  5619. return target; // Nothing to copy
  5620. target.ensureCapacity(targetOffset + len);
  5621. target.view.set(this.view.subarray(sourceOffset, sourceLimit), targetOffset);
  5622. if (relative) this.offset += len;
  5623. if (targetRelative) target.offset += len;
  5624. return this;
  5625. };
  5626. /**
  5627. * Makes sure that this ByteBuffer is backed by a {@link ByteBuffer#buffer} of at least the specified capacity. If the
  5628. * current capacity is exceeded, it will be doubled. If double the current capacity is less than the required capacity,
  5629. * the required capacity will be used instead.
  5630. * @param {number} capacity Required capacity
  5631. * @returns {!ByteBuffer} this
  5632. * @expose
  5633. */
  5634. ByteBufferPrototype.ensureCapacity = function(capacity) {
  5635. var current = this.buffer.byteLength;
  5636. if (current < capacity)
  5637. return this.resize((current *= 2) > capacity ? current : capacity);
  5638. return this;
  5639. };
  5640. /**
  5641. * Overwrites this ByteBuffer's contents with the specified value. Contents are the bytes between
  5642. * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
  5643. * @param {number|string} value Byte value to fill with. If given as a string, the first character is used.
  5644. * @param {number=} begin Begin offset. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  5645. * written if omitted. defaults to {@link ByteBuffer#offset}.
  5646. * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
  5647. * @returns {!ByteBuffer} this
  5648. * @expose
  5649. * @example `someByteBuffer.clear().fill(0)` fills the entire backing buffer with zeroes
  5650. */
  5651. ByteBufferPrototype.fill = function(value, begin, end) {
  5652. var relative = typeof begin === 'undefined';
  5653. if (relative) begin = this.offset;
  5654. if (typeof value === 'string' && value.length > 0)
  5655. value = value.charCodeAt(0);
  5656. if (typeof begin === 'undefined') begin = this.offset;
  5657. if (typeof end === 'undefined') end = this.limit;
  5658. if (!this.noAssert) {
  5659. if (typeof value !== 'number' || value % 1 !== 0)
  5660. throw TypeError("Illegal value: "+value+" (not an integer)");
  5661. value |= 0;
  5662. if (typeof begin !== 'number' || begin % 1 !== 0)
  5663. throw TypeError("Illegal begin: Not an integer");
  5664. begin >>>= 0;
  5665. if (typeof end !== 'number' || end % 1 !== 0)
  5666. throw TypeError("Illegal end: Not an integer");
  5667. end >>>= 0;
  5668. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  5669. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  5670. }
  5671. if (begin >= end)
  5672. return this; // Nothing to fill
  5673. while (begin < end) this.view[begin++] = value;
  5674. if (relative) this.offset = begin;
  5675. return this;
  5676. };
  5677. /**
  5678. * Makes this ByteBuffer ready for a new sequence of write or relative read operations. Sets `limit = offset` and
  5679. * `offset = 0`. Make sure always to flip a ByteBuffer when all relative read or write operations are complete.
  5680. * @returns {!ByteBuffer} this
  5681. * @expose
  5682. */
  5683. ByteBufferPrototype.flip = function() {
  5684. this.limit = this.offset;
  5685. this.offset = 0;
  5686. return this;
  5687. };
  5688. /**
  5689. * Marks an offset on this ByteBuffer to be used later.
  5690. * @param {number=} offset Offset to mark. Defaults to {@link ByteBuffer#offset}.
  5691. * @returns {!ByteBuffer} this
  5692. * @throws {TypeError} If `offset` is not a valid number
  5693. * @throws {RangeError} If `offset` is out of bounds
  5694. * @see ByteBuffer#reset
  5695. * @expose
  5696. */
  5697. ByteBufferPrototype.mark = function(offset) {
  5698. offset = typeof offset === 'undefined' ? this.offset : offset;
  5699. if (!this.noAssert) {
  5700. if (typeof offset !== 'number' || offset % 1 !== 0)
  5701. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  5702. offset >>>= 0;
  5703. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  5704. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  5705. }
  5706. this.markedOffset = offset;
  5707. return this;
  5708. };
  5709. /**
  5710. * Sets the byte order.
  5711. * @param {boolean} littleEndian `true` for little endian byte order, `false` for big endian
  5712. * @returns {!ByteBuffer} this
  5713. * @expose
  5714. */
  5715. ByteBufferPrototype.order = function(littleEndian) {
  5716. if (!this.noAssert) {
  5717. if (typeof littleEndian !== 'boolean')
  5718. throw TypeError("Illegal littleEndian: Not a boolean");
  5719. }
  5720. this.littleEndian = !!littleEndian;
  5721. return this;
  5722. };
  5723. /**
  5724. * Switches (to) little endian byte order.
  5725. * @param {boolean=} littleEndian Defaults to `true`, otherwise uses big endian
  5726. * @returns {!ByteBuffer} this
  5727. * @expose
  5728. */
  5729. ByteBufferPrototype.LE = function(littleEndian) {
  5730. this.littleEndian = typeof littleEndian !== 'undefined' ? !!littleEndian : true;
  5731. return this;
  5732. };
  5733. /**
  5734. * Switches (to) big endian byte order.
  5735. * @param {boolean=} bigEndian Defaults to `true`, otherwise uses little endian
  5736. * @returns {!ByteBuffer} this
  5737. * @expose
  5738. */
  5739. ByteBufferPrototype.BE = function(bigEndian) {
  5740. this.littleEndian = typeof bigEndian !== 'undefined' ? !bigEndian : false;
  5741. return this;
  5742. };
  5743. /**
  5744. * Prepends some data to this ByteBuffer. This will overwrite any contents before the specified offset up to the
  5745. * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
  5746. * will be resized and its contents moved accordingly.
  5747. * @param {!ByteBuffer|string|!ArrayBuffer} source Data to prepend. If `source` is a ByteBuffer, its offset will be
  5748. * modified according to the performed read operation.
  5749. * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
  5750. * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
  5751. * prepended if omitted.
  5752. * @returns {!ByteBuffer} this
  5753. * @expose
  5754. * @example A relative `00<01 02 03>.prepend(<04 05>)` results in `<04 05 01 02 03>, 04 05|`
  5755. * @example An absolute `00<01 02 03>.prepend(<04 05>, 2)` results in `04<05 02 03>, 04 05|`
  5756. */
  5757. ByteBufferPrototype.prepend = function(source, encoding, offset) {
  5758. if (typeof encoding === 'number' || typeof encoding !== 'string') {
  5759. offset = encoding;
  5760. encoding = undefined;
  5761. }
  5762. var relative = typeof offset === 'undefined';
  5763. if (relative) offset = this.offset;
  5764. if (!this.noAssert) {
  5765. if (typeof offset !== 'number' || offset % 1 !== 0)
  5766. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  5767. offset >>>= 0;
  5768. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  5769. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  5770. }
  5771. if (!(source instanceof ByteBuffer))
  5772. source = ByteBuffer.wrap(source, encoding);
  5773. var len = source.limit - source.offset;
  5774. if (len <= 0) return this; // Nothing to prepend
  5775. var diff = len - offset;
  5776. if (diff > 0) { // Not enough space before offset, so resize + move
  5777. var buffer = new ArrayBuffer(this.buffer.byteLength + diff);
  5778. var view = new Uint8Array(buffer);
  5779. view.set(this.view.subarray(offset, this.buffer.byteLength), len);
  5780. this.buffer = buffer;
  5781. this.view = view;
  5782. this.offset += diff;
  5783. if (this.markedOffset >= 0) this.markedOffset += diff;
  5784. this.limit += diff;
  5785. offset += diff;
  5786. } else {
  5787. var arrayView = new Uint8Array(this.buffer);
  5788. }
  5789. this.view.set(source.view.subarray(source.offset, source.limit), offset - len);
  5790. source.offset = source.limit;
  5791. if (relative)
  5792. this.offset -= len;
  5793. return this;
  5794. };
  5795. /**
  5796. * Prepends this ByteBuffer to another ByteBuffer. This will overwrite any contents before the specified offset up to the
  5797. * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
  5798. * will be resized and its contents moved accordingly.
  5799. * @param {!ByteBuffer} target Target ByteBuffer
  5800. * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
  5801. * prepended if omitted.
  5802. * @returns {!ByteBuffer} this
  5803. * @expose
  5804. * @see ByteBuffer#prepend
  5805. */
  5806. ByteBufferPrototype.prependTo = function(target, offset) {
  5807. target.prepend(this, offset);
  5808. return this;
  5809. };
  5810. /**
  5811. * Prints debug information about this ByteBuffer's contents.
  5812. * @param {function(string)=} out Output function to call, defaults to console.log
  5813. * @expose
  5814. */
  5815. ByteBufferPrototype.printDebug = function(out) {
  5816. if (typeof out !== 'function') out = console.log.bind(console);
  5817. out(
  5818. this.toString()+"\n"+
  5819. "-------------------------------------------------------------------\n"+
  5820. this.toDebug(/* columns */ true)
  5821. );
  5822. };
  5823. /**
  5824. * Gets the number of remaining readable bytes. Contents are the bytes between {@link ByteBuffer#offset} and
  5825. * {@link ByteBuffer#limit}, so this returns `limit - offset`.
  5826. * @returns {number} Remaining readable bytes. May be negative if `offset > limit`.
  5827. * @expose
  5828. */
  5829. ByteBufferPrototype.remaining = function() {
  5830. return this.limit - this.offset;
  5831. };
  5832. /**
  5833. * Resets this ByteBuffer's {@link ByteBuffer#offset}. If an offset has been marked through {@link ByteBuffer#mark}
  5834. * before, `offset` will be set to {@link ByteBuffer#markedOffset}, which will then be discarded. If no offset has been
  5835. * marked, sets `offset = 0`.
  5836. * @returns {!ByteBuffer} this
  5837. * @see ByteBuffer#mark
  5838. * @expose
  5839. */
  5840. ByteBufferPrototype.reset = function() {
  5841. if (this.markedOffset >= 0) {
  5842. this.offset = this.markedOffset;
  5843. this.markedOffset = -1;
  5844. } else {
  5845. this.offset = 0;
  5846. }
  5847. return this;
  5848. };
  5849. /**
  5850. * Resizes this ByteBuffer to be backed by a buffer of at least the given capacity. Will do nothing if already that
  5851. * large or larger.
  5852. * @param {number} capacity Capacity required
  5853. * @returns {!ByteBuffer} this
  5854. * @throws {TypeError} If `capacity` is not a number
  5855. * @throws {RangeError} If `capacity < 0`
  5856. * @expose
  5857. */
  5858. ByteBufferPrototype.resize = function(capacity) {
  5859. if (!this.noAssert) {
  5860. if (typeof capacity !== 'number' || capacity % 1 !== 0)
  5861. throw TypeError("Illegal capacity: "+capacity+" (not an integer)");
  5862. capacity |= 0;
  5863. if (capacity < 0)
  5864. throw RangeError("Illegal capacity: 0 <= "+capacity);
  5865. }
  5866. if (this.buffer.byteLength < capacity) {
  5867. var buffer = new ArrayBuffer(capacity);
  5868. var view = new Uint8Array(buffer);
  5869. view.set(this.view);
  5870. this.buffer = buffer;
  5871. this.view = view;
  5872. }
  5873. return this;
  5874. };
  5875. /**
  5876. * Reverses this ByteBuffer's contents.
  5877. * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
  5878. * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
  5879. * @returns {!ByteBuffer} this
  5880. * @expose
  5881. */
  5882. ByteBufferPrototype.reverse = function(begin, end) {
  5883. if (typeof begin === 'undefined') begin = this.offset;
  5884. if (typeof end === 'undefined') end = this.limit;
  5885. if (!this.noAssert) {
  5886. if (typeof begin !== 'number' || begin % 1 !== 0)
  5887. throw TypeError("Illegal begin: Not an integer");
  5888. begin >>>= 0;
  5889. if (typeof end !== 'number' || end % 1 !== 0)
  5890. throw TypeError("Illegal end: Not an integer");
  5891. end >>>= 0;
  5892. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  5893. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  5894. }
  5895. if (begin === end)
  5896. return this; // Nothing to reverse
  5897. Array.prototype.reverse.call(this.view.subarray(begin, end));
  5898. return this;
  5899. };
  5900. /**
  5901. * Skips the next `length` bytes. This will just advance
  5902. * @param {number} length Number of bytes to skip. May also be negative to move the offset back.
  5903. * @returns {!ByteBuffer} this
  5904. * @expose
  5905. */
  5906. ByteBufferPrototype.skip = function(length) {
  5907. if (!this.noAssert) {
  5908. if (typeof length !== 'number' || length % 1 !== 0)
  5909. throw TypeError("Illegal length: "+length+" (not an integer)");
  5910. length |= 0;
  5911. }
  5912. var offset = this.offset + length;
  5913. if (!this.noAssert) {
  5914. if (offset < 0 || offset > this.buffer.byteLength)
  5915. throw RangeError("Illegal length: 0 <= "+this.offset+" + "+length+" <= "+this.buffer.byteLength);
  5916. }
  5917. this.offset = offset;
  5918. return this;
  5919. };
  5920. /**
  5921. * Slices this ByteBuffer by creating a cloned instance with `offset = begin` and `limit = end`.
  5922. * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
  5923. * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
  5924. * @returns {!ByteBuffer} Clone of this ByteBuffer with slicing applied, backed by the same {@link ByteBuffer#buffer}
  5925. * @expose
  5926. */
  5927. ByteBufferPrototype.slice = function(begin, end) {
  5928. if (typeof begin === 'undefined') begin = this.offset;
  5929. if (typeof end === 'undefined') end = this.limit;
  5930. if (!this.noAssert) {
  5931. if (typeof begin !== 'number' || begin % 1 !== 0)
  5932. throw TypeError("Illegal begin: Not an integer");
  5933. begin >>>= 0;
  5934. if (typeof end !== 'number' || end % 1 !== 0)
  5935. throw TypeError("Illegal end: Not an integer");
  5936. end >>>= 0;
  5937. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  5938. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  5939. }
  5940. var bb = this.clone();
  5941. bb.offset = begin;
  5942. bb.limit = end;
  5943. return bb;
  5944. };
  5945. /**
  5946. * Returns a copy of the backing buffer that contains this ByteBuffer's contents. Contents are the bytes between
  5947. * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
  5948. * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory if
  5949. * possible. Defaults to `false`
  5950. * @returns {!ArrayBuffer} Contents as an ArrayBuffer
  5951. * @expose
  5952. */
  5953. ByteBufferPrototype.toBuffer = function(forceCopy) {
  5954. var offset = this.offset,
  5955. limit = this.limit;
  5956. if (!this.noAssert) {
  5957. if (typeof offset !== 'number' || offset % 1 !== 0)
  5958. throw TypeError("Illegal offset: Not an integer");
  5959. offset >>>= 0;
  5960. if (typeof limit !== 'number' || limit % 1 !== 0)
  5961. throw TypeError("Illegal limit: Not an integer");
  5962. limit >>>= 0;
  5963. if (offset < 0 || offset > limit || limit > this.buffer.byteLength)
  5964. throw RangeError("Illegal range: 0 <= "+offset+" <= "+limit+" <= "+this.buffer.byteLength);
  5965. }
  5966. // NOTE: It's not possible to have another ArrayBuffer reference the same memory as the backing buffer. This is
  5967. // possible with Uint8Array#subarray only, but we have to return an ArrayBuffer by contract. So:
  5968. if (!forceCopy && offset === 0 && limit === this.buffer.byteLength)
  5969. return this.buffer;
  5970. if (offset === limit)
  5971. return EMPTY_BUFFER;
  5972. var buffer = new ArrayBuffer(limit - offset);
  5973. new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(offset, limit), 0);
  5974. return buffer;
  5975. };
  5976. /**
  5977. * Returns a raw buffer compacted to contain this ByteBuffer's contents. Contents are the bytes between
  5978. * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. This is an alias of {@link ByteBuffer#toBuffer}.
  5979. * @function
  5980. * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory.
  5981. * Defaults to `false`
  5982. * @returns {!ArrayBuffer} Contents as an ArrayBuffer
  5983. * @expose
  5984. */
  5985. ByteBufferPrototype.toArrayBuffer = ByteBufferPrototype.toBuffer;
  5986. /**
  5987. * Converts the ByteBuffer's contents to a string.
  5988. * @param {string=} encoding Output encoding. Returns an informative string representation if omitted but also allows
  5989. * direct conversion to "utf8", "hex", "base64" and "binary" encoding. "debug" returns a hex representation with
  5990. * highlighted offsets.
  5991. * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}
  5992. * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
  5993. * @returns {string} String representation
  5994. * @throws {Error} If `encoding` is invalid
  5995. * @expose
  5996. */
  5997. ByteBufferPrototype.toString = function(encoding, begin, end) {
  5998. if (typeof encoding === 'undefined')
  5999. return "ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")";
  6000. if (typeof encoding === 'number')
  6001. encoding = "utf8",
  6002. begin = encoding,
  6003. end = begin;
  6004. switch (encoding) {
  6005. case "utf8":
  6006. return this.toUTF8(begin, end);
  6007. case "base64":
  6008. return this.toBase64(begin, end);
  6009. case "hex":
  6010. return this.toHex(begin, end);
  6011. case "binary":
  6012. return this.toBinary(begin, end);
  6013. case "debug":
  6014. return this.toDebug();
  6015. case "columns":
  6016. return this.toColumns();
  6017. default:
  6018. throw Error("Unsupported encoding: "+encoding);
  6019. }
  6020. };
  6021. // lxiv-embeddable
  6022. /**
  6023. * lxiv-embeddable (c) 2014 Daniel Wirtz <dcode@dcode.io>
  6024. * Released under the Apache License, Version 2.0
  6025. * see: https://github.com/dcodeIO/lxiv for details
  6026. */
  6027. var lxiv = function() {
  6028. /**
  6029. * lxiv namespace.
  6030. * @type {!Object.<string,*>}
  6031. * @exports lxiv
  6032. */
  6033. var lxiv = {};
  6034. /**
  6035. * Character codes for output.
  6036. * @type {!Array.<number>}
  6037. * @inner
  6038. */
  6039. var aout = [
  6040. 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
  6041. 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102,
  6042. 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
  6043. 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47
  6044. ];
  6045. /**
  6046. * Character codes for input.
  6047. * @type {!Array.<number>}
  6048. * @inner
  6049. */
  6050. var ain = [];
  6051. for (var i=0, k=aout.length; i<k; ++i)
  6052. ain[aout[i]] = i;
  6053. /**
  6054. * Encodes bytes to base64 char codes.
  6055. * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if
  6056. * there are no more bytes left.
  6057. * @param {!function(number)} dst Characters destination as a function successively called with each encoded char
  6058. * code.
  6059. */
  6060. lxiv.encode = function(src, dst) {
  6061. var b, t;
  6062. while ((b = src()) !== null) {
  6063. dst(aout[(b>>2)&0x3f]);
  6064. t = (b&0x3)<<4;
  6065. if ((b = src()) !== null) {
  6066. t |= (b>>4)&0xf;
  6067. dst(aout[(t|((b>>4)&0xf))&0x3f]);
  6068. t = (b&0xf)<<2;
  6069. if ((b = src()) !== null)
  6070. dst(aout[(t|((b>>6)&0x3))&0x3f]),
  6071. dst(aout[b&0x3f]);
  6072. else
  6073. dst(aout[t&0x3f]),
  6074. dst(61);
  6075. } else
  6076. dst(aout[t&0x3f]),
  6077. dst(61),
  6078. dst(61);
  6079. }
  6080. };
  6081. /**
  6082. * Decodes base64 char codes to bytes.
  6083. * @param {!function():number|null} src Characters source as a function returning the next char code respectively
  6084. * `null` if there are no more characters left.
  6085. * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
  6086. * @throws {Error} If a character code is invalid
  6087. */
  6088. lxiv.decode = function(src, dst) {
  6089. var c, t1, t2;
  6090. function fail(c) {
  6091. throw Error("Illegal character code: "+c);
  6092. }
  6093. while ((c = src()) !== null) {
  6094. t1 = ain[c];
  6095. if (typeof t1 === 'undefined') fail(c);
  6096. if ((c = src()) !== null) {
  6097. t2 = ain[c];
  6098. if (typeof t2 === 'undefined') fail(c);
  6099. dst((t1<<2)>>>0|(t2&0x30)>>4);
  6100. if ((c = src()) !== null) {
  6101. t1 = ain[c];
  6102. if (typeof t1 === 'undefined')
  6103. if (c === 61) break; else fail(c);
  6104. dst(((t2&0xf)<<4)>>>0|(t1&0x3c)>>2);
  6105. if ((c = src()) !== null) {
  6106. t2 = ain[c];
  6107. if (typeof t2 === 'undefined')
  6108. if (c === 61) break; else fail(c);
  6109. dst(((t1&0x3)<<6)>>>0|t2);
  6110. }
  6111. }
  6112. }
  6113. }
  6114. };
  6115. /**
  6116. * Tests if a string is valid base64.
  6117. * @param {string} str String to test
  6118. * @returns {boolean} `true` if valid, otherwise `false`
  6119. */
  6120. lxiv.test = function(str) {
  6121. return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(str);
  6122. };
  6123. return lxiv;
  6124. }();
  6125. // encodings/base64
  6126. /**
  6127. * Encodes this ByteBuffer's contents to a base64 encoded string.
  6128. * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}.
  6129. * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}.
  6130. * @returns {string} Base64 encoded string
  6131. * @throws {RangeError} If `begin` or `end` is out of bounds
  6132. * @expose
  6133. */
  6134. ByteBufferPrototype.toBase64 = function(begin, end) {
  6135. if (typeof begin === 'undefined')
  6136. begin = this.offset;
  6137. if (typeof end === 'undefined')
  6138. end = this.limit;
  6139. begin = begin | 0; end = end | 0;
  6140. if (begin < 0 || end > this.capacity || begin > end)
  6141. throw RangeError("begin, end");
  6142. var sd; lxiv.encode(function() {
  6143. return begin < end ? this.view[begin++] : null;
  6144. }.bind(this), sd = stringDestination());
  6145. return sd();
  6146. };
  6147. /**
  6148. * Decodes a base64 encoded string to a ByteBuffer.
  6149. * @param {string} str String to decode
  6150. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  6151. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  6152. * @returns {!ByteBuffer} ByteBuffer
  6153. * @expose
  6154. */
  6155. ByteBuffer.fromBase64 = function(str, littleEndian) {
  6156. if (typeof str !== 'string')
  6157. throw TypeError("str");
  6158. var bb = new ByteBuffer(str.length/4*3, littleEndian),
  6159. i = 0;
  6160. lxiv.decode(stringSource(str), function(b) {
  6161. bb.view[i++] = b;
  6162. });
  6163. bb.limit = i;
  6164. return bb;
  6165. };
  6166. /**
  6167. * Encodes a binary string to base64 like `window.btoa` does.
  6168. * @param {string} str Binary string
  6169. * @returns {string} Base64 encoded string
  6170. * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.btoa
  6171. * @expose
  6172. */
  6173. ByteBuffer.btoa = function(str) {
  6174. return ByteBuffer.fromBinary(str).toBase64();
  6175. };
  6176. /**
  6177. * Decodes a base64 encoded string to binary like `window.atob` does.
  6178. * @param {string} b64 Base64 encoded string
  6179. * @returns {string} Binary string
  6180. * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.atob
  6181. * @expose
  6182. */
  6183. ByteBuffer.atob = function(b64) {
  6184. return ByteBuffer.fromBase64(b64).toBinary();
  6185. };
  6186. // encodings/binary
  6187. /**
  6188. * Encodes this ByteBuffer to a binary encoded string, that is using only characters 0x00-0xFF as bytes.
  6189. * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}.
  6190. * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}.
  6191. * @returns {string} Binary encoded string
  6192. * @throws {RangeError} If `offset > limit`
  6193. * @expose
  6194. */
  6195. ByteBufferPrototype.toBinary = function(begin, end) {
  6196. if (typeof begin === 'undefined')
  6197. begin = this.offset;
  6198. if (typeof end === 'undefined')
  6199. end = this.limit;
  6200. begin |= 0; end |= 0;
  6201. if (begin < 0 || end > this.capacity() || begin > end)
  6202. throw RangeError("begin, end");
  6203. if (begin === end)
  6204. return "";
  6205. var chars = [],
  6206. parts = [];
  6207. while (begin < end) {
  6208. chars.push(this.view[begin++]);
  6209. if (chars.length >= 1024)
  6210. parts.push(String.fromCharCode.apply(String, chars)),
  6211. chars = [];
  6212. }
  6213. return parts.join('') + String.fromCharCode.apply(String, chars);
  6214. };
  6215. /**
  6216. * Decodes a binary encoded string, that is using only characters 0x00-0xFF as bytes, to a ByteBuffer.
  6217. * @param {string} str String to decode
  6218. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  6219. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  6220. * @returns {!ByteBuffer} ByteBuffer
  6221. * @expose
  6222. */
  6223. ByteBuffer.fromBinary = function(str, littleEndian) {
  6224. if (typeof str !== 'string')
  6225. throw TypeError("str");
  6226. var i = 0,
  6227. k = str.length,
  6228. charCode,
  6229. bb = new ByteBuffer(k, littleEndian);
  6230. while (i<k) {
  6231. charCode = str.charCodeAt(i);
  6232. if (charCode > 0xff)
  6233. throw RangeError("illegal char code: "+charCode);
  6234. bb.view[i++] = charCode;
  6235. }
  6236. bb.limit = k;
  6237. return bb;
  6238. };
  6239. // encodings/debug
  6240. /**
  6241. * Encodes this ByteBuffer to a hex encoded string with marked offsets. Offset symbols are:
  6242. * * `<` : offset,
  6243. * * `'` : markedOffset,
  6244. * * `>` : limit,
  6245. * * `|` : offset and limit,
  6246. * * `[` : offset and markedOffset,
  6247. * * `]` : markedOffset and limit,
  6248. * * `!` : offset, markedOffset and limit
  6249. * @param {boolean=} columns If `true` returns two columns hex + ascii, defaults to `false`
  6250. * @returns {string|!Array.<string>} Debug string or array of lines if `asArray = true`
  6251. * @expose
  6252. * @example `>00'01 02<03` contains four bytes with `limit=0, markedOffset=1, offset=3`
  6253. * @example `00[01 02 03>` contains four bytes with `offset=markedOffset=1, limit=4`
  6254. * @example `00|01 02 03` contains four bytes with `offset=limit=1, markedOffset=-1`
  6255. * @example `|` contains zero bytes with `offset=limit=0, markedOffset=-1`
  6256. */
  6257. ByteBufferPrototype.toDebug = function(columns) {
  6258. var i = -1,
  6259. k = this.buffer.byteLength,
  6260. b,
  6261. hex = "",
  6262. asc = "",
  6263. out = "";
  6264. while (i<k) {
  6265. if (i !== -1) {
  6266. b = this.view[i];
  6267. if (b < 0x10) hex += "0"+b.toString(16).toUpperCase();
  6268. else hex += b.toString(16).toUpperCase();
  6269. if (columns)
  6270. asc += b > 32 && b < 127 ? String.fromCharCode(b) : '.';
  6271. }
  6272. ++i;
  6273. if (columns) {
  6274. if (i > 0 && i % 16 === 0 && i !== k) {
  6275. while (hex.length < 3*16+3) hex += " ";
  6276. out += hex+asc+"\n";
  6277. hex = asc = "";
  6278. }
  6279. }
  6280. if (i === this.offset && i === this.limit)
  6281. hex += i === this.markedOffset ? "!" : "|";
  6282. else if (i === this.offset)
  6283. hex += i === this.markedOffset ? "[" : "<";
  6284. else if (i === this.limit)
  6285. hex += i === this.markedOffset ? "]" : ">";
  6286. else
  6287. hex += i === this.markedOffset ? "'" : (columns || (i !== 0 && i !== k) ? " " : "");
  6288. }
  6289. if (columns && hex !== " ") {
  6290. while (hex.length < 3*16+3)
  6291. hex += " ";
  6292. out += hex + asc + "\n";
  6293. }
  6294. return columns ? out : hex;
  6295. };
  6296. /**
  6297. * Decodes a hex encoded string with marked offsets to a ByteBuffer.
  6298. * @param {string} str Debug string to decode (not be generated with `columns = true`)
  6299. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  6300. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  6301. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  6302. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  6303. * @returns {!ByteBuffer} ByteBuffer
  6304. * @expose
  6305. * @see ByteBuffer#toDebug
  6306. */
  6307. ByteBuffer.fromDebug = function(str, littleEndian, noAssert) {
  6308. var k = str.length,
  6309. bb = new ByteBuffer(((k+1)/3)|0, littleEndian, noAssert);
  6310. var i = 0, j = 0, ch, b,
  6311. rs = false, // Require symbol next
  6312. ho = false, hm = false, hl = false, // Already has offset (ho), markedOffset (hm), limit (hl)?
  6313. fail = false;
  6314. while (i<k) {
  6315. switch (ch = str.charAt(i++)) {
  6316. case '!':
  6317. if (!noAssert) {
  6318. if (ho || hm || hl) {
  6319. fail = true;
  6320. break;
  6321. }
  6322. ho = hm = hl = true;
  6323. }
  6324. bb.offset = bb.markedOffset = bb.limit = j;
  6325. rs = false;
  6326. break;
  6327. case '|':
  6328. if (!noAssert) {
  6329. if (ho || hl) {
  6330. fail = true;
  6331. break;
  6332. }
  6333. ho = hl = true;
  6334. }
  6335. bb.offset = bb.limit = j;
  6336. rs = false;
  6337. break;
  6338. case '[':
  6339. if (!noAssert) {
  6340. if (ho || hm) {
  6341. fail = true;
  6342. break;
  6343. }
  6344. ho = hm = true;
  6345. }
  6346. bb.offset = bb.markedOffset = j;
  6347. rs = false;
  6348. break;
  6349. case '<':
  6350. if (!noAssert) {
  6351. if (ho) {
  6352. fail = true;
  6353. break;
  6354. }
  6355. ho = true;
  6356. }
  6357. bb.offset = j;
  6358. rs = false;
  6359. break;
  6360. case ']':
  6361. if (!noAssert) {
  6362. if (hl || hm) {
  6363. fail = true;
  6364. break;
  6365. }
  6366. hl = hm = true;
  6367. }
  6368. bb.limit = bb.markedOffset = j;
  6369. rs = false;
  6370. break;
  6371. case '>':
  6372. if (!noAssert) {
  6373. if (hl) {
  6374. fail = true;
  6375. break;
  6376. }
  6377. hl = true;
  6378. }
  6379. bb.limit = j;
  6380. rs = false;
  6381. break;
  6382. case "'":
  6383. if (!noAssert) {
  6384. if (hm) {
  6385. fail = true;
  6386. break;
  6387. }
  6388. hm = true;
  6389. }
  6390. bb.markedOffset = j;
  6391. rs = false;
  6392. break;
  6393. case ' ':
  6394. rs = false;
  6395. break;
  6396. default:
  6397. if (!noAssert) {
  6398. if (rs) {
  6399. fail = true;
  6400. break;
  6401. }
  6402. }
  6403. b = parseInt(ch+str.charAt(i++), 16);
  6404. if (!noAssert) {
  6405. if (isNaN(b) || b < 0 || b > 255)
  6406. throw TypeError("Illegal str: Not a debug encoded string");
  6407. }
  6408. bb.view[j++] = b;
  6409. rs = true;
  6410. }
  6411. if (fail)
  6412. throw TypeError("Illegal str: Invalid symbol at "+i);
  6413. }
  6414. if (!noAssert) {
  6415. if (!ho || !hl)
  6416. throw TypeError("Illegal str: Missing offset or limit");
  6417. if (j<bb.buffer.byteLength)
  6418. throw TypeError("Illegal str: Not a debug encoded string (is it hex?) "+j+" < "+k);
  6419. }
  6420. return bb;
  6421. };
  6422. // encodings/hex
  6423. /**
  6424. * Encodes this ByteBuffer's contents to a hex encoded string.
  6425. * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}.
  6426. * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}.
  6427. * @returns {string} Hex encoded string
  6428. * @expose
  6429. */
  6430. ByteBufferPrototype.toHex = function(begin, end) {
  6431. begin = typeof begin === 'undefined' ? this.offset : begin;
  6432. end = typeof end === 'undefined' ? this.limit : end;
  6433. if (!this.noAssert) {
  6434. if (typeof begin !== 'number' || begin % 1 !== 0)
  6435. throw TypeError("Illegal begin: Not an integer");
  6436. begin >>>= 0;
  6437. if (typeof end !== 'number' || end % 1 !== 0)
  6438. throw TypeError("Illegal end: Not an integer");
  6439. end >>>= 0;
  6440. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  6441. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  6442. }
  6443. var out = new Array(end - begin),
  6444. b;
  6445. while (begin < end) {
  6446. b = this.view[begin++];
  6447. if (b < 0x10)
  6448. out.push("0", b.toString(16));
  6449. else out.push(b.toString(16));
  6450. }
  6451. return out.join('');
  6452. };
  6453. /**
  6454. * Decodes a hex encoded string to a ByteBuffer.
  6455. * @param {string} str String to decode
  6456. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  6457. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  6458. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  6459. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  6460. * @returns {!ByteBuffer} ByteBuffer
  6461. * @expose
  6462. */
  6463. ByteBuffer.fromHex = function(str, littleEndian, noAssert) {
  6464. if (!noAssert) {
  6465. if (typeof str !== 'string')
  6466. throw TypeError("Illegal str: Not a string");
  6467. if (str.length % 2 !== 0)
  6468. throw TypeError("Illegal str: Length not a multiple of 2");
  6469. }
  6470. var k = str.length,
  6471. bb = new ByteBuffer((k / 2) | 0, littleEndian),
  6472. b;
  6473. for (var i=0, j=0; i<k; i+=2) {
  6474. b = parseInt(str.substring(i, i+2), 16);
  6475. if (!noAssert)
  6476. if (!isFinite(b) || b < 0 || b > 255)
  6477. throw TypeError("Illegal str: Contains non-hex characters");
  6478. bb.view[j++] = b;
  6479. }
  6480. bb.limit = j;
  6481. return bb;
  6482. };
  6483. // utfx-embeddable
  6484. /**
  6485. * utfx-embeddable (c) 2014 Daniel Wirtz <dcode@dcode.io>
  6486. * Released under the Apache License, Version 2.0
  6487. * see: https://github.com/dcodeIO/utfx for details
  6488. */
  6489. var utfx = function() {
  6490. /**
  6491. * utfx namespace.
  6492. * @inner
  6493. * @type {!Object.<string,*>}
  6494. */
  6495. var utfx = {};
  6496. /**
  6497. * Maximum valid code point.
  6498. * @type {number}
  6499. * @const
  6500. */
  6501. utfx.MAX_CODEPOINT = 0x10FFFF;
  6502. /**
  6503. * Encodes UTF8 code points to UTF8 bytes.
  6504. * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
  6505. * respectively `null` if there are no more code points left or a single numeric code point.
  6506. * @param {!function(number)} dst Bytes destination as a function successively called with the next byte
  6507. */
  6508. utfx.encodeUTF8 = function(src, dst) {
  6509. var cp = null;
  6510. if (typeof src === 'number')
  6511. cp = src,
  6512. src = function() { return null; };
  6513. while (cp !== null || (cp = src()) !== null) {
  6514. if (cp < 0x80)
  6515. dst(cp&0x7F);
  6516. else if (cp < 0x800)
  6517. dst(((cp>>6)&0x1F)|0xC0),
  6518. dst((cp&0x3F)|0x80);
  6519. else if (cp < 0x10000)
  6520. dst(((cp>>12)&0x0F)|0xE0),
  6521. dst(((cp>>6)&0x3F)|0x80),
  6522. dst((cp&0x3F)|0x80);
  6523. else
  6524. dst(((cp>>18)&0x07)|0xF0),
  6525. dst(((cp>>12)&0x3F)|0x80),
  6526. dst(((cp>>6)&0x3F)|0x80),
  6527. dst((cp&0x3F)|0x80);
  6528. cp = null;
  6529. }
  6530. };
  6531. /**
  6532. * Decodes UTF8 bytes to UTF8 code points.
  6533. * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
  6534. * are no more bytes left.
  6535. * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point.
  6536. * @throws {RangeError} If a starting byte is invalid in UTF8
  6537. * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the
  6538. * remaining bytes.
  6539. */
  6540. utfx.decodeUTF8 = function(src, dst) {
  6541. var a, b, c, d, fail = function(b) {
  6542. b = b.slice(0, b.indexOf(null));
  6543. var err = Error(b.toString());
  6544. err.name = "TruncatedError";
  6545. err['bytes'] = b;
  6546. throw err;
  6547. };
  6548. while ((a = src()) !== null) {
  6549. if ((a&0x80) === 0)
  6550. dst(a);
  6551. else if ((a&0xE0) === 0xC0)
  6552. ((b = src()) === null) && fail([a, b]),
  6553. dst(((a&0x1F)<<6) | (b&0x3F));
  6554. else if ((a&0xF0) === 0xE0)
  6555. ((b=src()) === null || (c=src()) === null) && fail([a, b, c]),
  6556. dst(((a&0x0F)<<12) | ((b&0x3F)<<6) | (c&0x3F));
  6557. else if ((a&0xF8) === 0xF0)
  6558. ((b=src()) === null || (c=src()) === null || (d=src()) === null) && fail([a, b, c ,d]),
  6559. dst(((a&0x07)<<18) | ((b&0x3F)<<12) | ((c&0x3F)<<6) | (d&0x3F));
  6560. else throw RangeError("Illegal starting byte: "+a);
  6561. }
  6562. };
  6563. /**
  6564. * Converts UTF16 characters to UTF8 code points.
  6565. * @param {!function():number|null} src Characters source as a function returning the next char code respectively
  6566. * `null` if there are no more characters left.
  6567. * @param {!function(number)} dst Code points destination as a function successively called with each converted code
  6568. * point.
  6569. */
  6570. utfx.UTF16toUTF8 = function(src, dst) {
  6571. var c1, c2 = null;
  6572. while (true) {
  6573. if ((c1 = c2 !== null ? c2 : src()) === null)
  6574. break;
  6575. if (c1 >= 0xD800 && c1 <= 0xDFFF) {
  6576. if ((c2 = src()) !== null) {
  6577. if (c2 >= 0xDC00 && c2 <= 0xDFFF) {
  6578. dst((c1-0xD800)*0x400+c2-0xDC00+0x10000);
  6579. c2 = null; continue;
  6580. }
  6581. }
  6582. }
  6583. dst(c1);
  6584. }
  6585. if (c2 !== null) dst(c2);
  6586. };
  6587. /**
  6588. * Converts UTF8 code points to UTF16 characters.
  6589. * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
  6590. * respectively `null` if there are no more code points left or a single numeric code point.
  6591. * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
  6592. * @throws {RangeError} If a code point is out of range
  6593. */
  6594. utfx.UTF8toUTF16 = function(src, dst) {
  6595. var cp = null;
  6596. if (typeof src === 'number')
  6597. cp = src, src = function() { return null; };
  6598. while (cp !== null || (cp = src()) !== null) {
  6599. if (cp <= 0xFFFF)
  6600. dst(cp);
  6601. else
  6602. cp -= 0x10000,
  6603. dst((cp>>10)+0xD800),
  6604. dst((cp%0x400)+0xDC00);
  6605. cp = null;
  6606. }
  6607. };
  6608. /**
  6609. * Converts and encodes UTF16 characters to UTF8 bytes.
  6610. * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null`
  6611. * if there are no more characters left.
  6612. * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
  6613. */
  6614. utfx.encodeUTF16toUTF8 = function(src, dst) {
  6615. utfx.UTF16toUTF8(src, function(cp) {
  6616. utfx.encodeUTF8(cp, dst);
  6617. });
  6618. };
  6619. /**
  6620. * Decodes and converts UTF8 bytes to UTF16 characters.
  6621. * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
  6622. * are no more bytes left.
  6623. * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
  6624. * @throws {RangeError} If a starting byte is invalid in UTF8
  6625. * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes.
  6626. */
  6627. utfx.decodeUTF8toUTF16 = function(src, dst) {
  6628. utfx.decodeUTF8(src, function(cp) {
  6629. utfx.UTF8toUTF16(cp, dst);
  6630. });
  6631. };
  6632. /**
  6633. * Calculates the byte length of an UTF8 code point.
  6634. * @param {number} cp UTF8 code point
  6635. * @returns {number} Byte length
  6636. */
  6637. utfx.calculateCodePoint = function(cp) {
  6638. return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
  6639. };
  6640. /**
  6641. * Calculates the number of UTF8 bytes required to store UTF8 code points.
  6642. * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively
  6643. * `null` if there are no more code points left.
  6644. * @returns {number} The number of UTF8 bytes required
  6645. */
  6646. utfx.calculateUTF8 = function(src) {
  6647. var cp, l=0;
  6648. while ((cp = src()) !== null)
  6649. l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
  6650. return l;
  6651. };
  6652. /**
  6653. * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes.
  6654. * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively
  6655. * `null` if there are no more characters left.
  6656. * @returns {!Array.<number>} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1.
  6657. */
  6658. utfx.calculateUTF16asUTF8 = function(src) {
  6659. var n=0, l=0;
  6660. utfx.UTF16toUTF8(src, function(cp) {
  6661. ++n; l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
  6662. });
  6663. return [n,l];
  6664. };
  6665. return utfx;
  6666. }();
  6667. // encodings/utf8
  6668. /**
  6669. * Encodes this ByteBuffer's contents between {@link ByteBuffer#offset} and {@link ByteBuffer#limit} to an UTF8 encoded
  6670. * string.
  6671. * @returns {string} Hex encoded string
  6672. * @throws {RangeError} If `offset > limit`
  6673. * @expose
  6674. */
  6675. ByteBufferPrototype.toUTF8 = function(begin, end) {
  6676. if (typeof begin === 'undefined') begin = this.offset;
  6677. if (typeof end === 'undefined') end = this.limit;
  6678. if (!this.noAssert) {
  6679. if (typeof begin !== 'number' || begin % 1 !== 0)
  6680. throw TypeError("Illegal begin: Not an integer");
  6681. begin >>>= 0;
  6682. if (typeof end !== 'number' || end % 1 !== 0)
  6683. throw TypeError("Illegal end: Not an integer");
  6684. end >>>= 0;
  6685. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  6686. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  6687. }
  6688. var sd; try {
  6689. utfx.decodeUTF8toUTF16(function() {
  6690. return begin < end ? this.view[begin++] : null;
  6691. }.bind(this), sd = stringDestination());
  6692. } catch (e) {
  6693. if (begin !== end)
  6694. throw RangeError("Illegal range: Truncated data, "+begin+" != "+end);
  6695. }
  6696. return sd();
  6697. };
  6698. /**
  6699. * Decodes an UTF8 encoded string to a ByteBuffer.
  6700. * @param {string} str String to decode
  6701. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  6702. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  6703. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  6704. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  6705. * @returns {!ByteBuffer} ByteBuffer
  6706. * @expose
  6707. */
  6708. ByteBuffer.fromUTF8 = function(str, littleEndian, noAssert) {
  6709. if (!noAssert)
  6710. if (typeof str !== 'string')
  6711. throw TypeError("Illegal str: Not a string");
  6712. var bb = new ByteBuffer(utfx.calculateUTF16asUTF8(stringSource(str), true)[1], littleEndian, noAssert),
  6713. i = 0;
  6714. utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
  6715. bb.view[i++] = b;
  6716. });
  6717. bb.limit = i;
  6718. return bb;
  6719. };
  6720. return ByteBuffer;
  6721. });
  6722. });
  6723. var _nodeResolve_empty = {};
  6724. var _nodeResolve_empty$1 = /*#__PURE__*/Object.freeze({
  6725. __proto__: null,
  6726. 'default': _nodeResolve_empty
  6727. });
  6728. var require$$2 = getCjsExportFromNamespace(_nodeResolve_empty$1);
  6729. var protobufLight = createCommonjsModule(function (module) {
  6730. /*
  6731. Copyright 2013 Daniel Wirtz <dcode@dcode.io>
  6732. Licensed under the Apache License, Version 2.0 (the "License");
  6733. you may not use this file except in compliance with the License.
  6734. You may obtain a copy of the License at
  6735. http://www.apache.org/licenses/LICENSE-2.0
  6736. Unless required by applicable law or agreed to in writing, software
  6737. distributed under the License is distributed on an "AS IS" BASIS,
  6738. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  6739. See the License for the specific language governing permissions and
  6740. limitations under the License.
  6741. */
  6742. /**
  6743. * @license protobuf.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
  6744. * Released under the Apache License, Version 2.0
  6745. * see: https://github.com/dcodeIO/protobuf.js for details
  6746. */
  6747. (function(global, factory) {
  6748. /* AMD */ if (typeof commonjsRequire === "function" && 'object' === "object" && module && module["exports"])
  6749. module["exports"] = factory(bytebuffer, true);
  6750. /* Global */ else
  6751. (global["dcodeIO"] = global["dcodeIO"] || {})["ProtoBuf"] = factory(global["dcodeIO"]["ByteBuffer"]);
  6752. })(commonjsGlobal, function(ByteBuffer, isCommonJS) {
  6753. /**
  6754. * The ProtoBuf namespace.
  6755. * @exports ProtoBuf
  6756. * @namespace
  6757. * @expose
  6758. */
  6759. var ProtoBuf = {};
  6760. /**
  6761. * @type {!function(new: ByteBuffer, ...[*])}
  6762. * @expose
  6763. */
  6764. ProtoBuf.ByteBuffer = ByteBuffer;
  6765. /**
  6766. * @type {?function(new: Long, ...[*])}
  6767. * @expose
  6768. */
  6769. ProtoBuf.Long = ByteBuffer.Long || null;
  6770. /**
  6771. * ProtoBuf.js version.
  6772. * @type {string}
  6773. * @const
  6774. * @expose
  6775. */
  6776. ProtoBuf.VERSION = "5.0.3";
  6777. /**
  6778. * Wire types.
  6779. * @type {Object.<string,number>}
  6780. * @const
  6781. * @expose
  6782. */
  6783. ProtoBuf.WIRE_TYPES = {};
  6784. /**
  6785. * Varint wire type.
  6786. * @type {number}
  6787. * @expose
  6788. */
  6789. ProtoBuf.WIRE_TYPES.VARINT = 0;
  6790. /**
  6791. * Fixed 64 bits wire type.
  6792. * @type {number}
  6793. * @const
  6794. * @expose
  6795. */
  6796. ProtoBuf.WIRE_TYPES.BITS64 = 1;
  6797. /**
  6798. * Length delimited wire type.
  6799. * @type {number}
  6800. * @const
  6801. * @expose
  6802. */
  6803. ProtoBuf.WIRE_TYPES.LDELIM = 2;
  6804. /**
  6805. * Start group wire type.
  6806. * @type {number}
  6807. * @const
  6808. * @expose
  6809. */
  6810. ProtoBuf.WIRE_TYPES.STARTGROUP = 3;
  6811. /**
  6812. * End group wire type.
  6813. * @type {number}
  6814. * @const
  6815. * @expose
  6816. */
  6817. ProtoBuf.WIRE_TYPES.ENDGROUP = 4;
  6818. /**
  6819. * Fixed 32 bits wire type.
  6820. * @type {number}
  6821. * @const
  6822. * @expose
  6823. */
  6824. ProtoBuf.WIRE_TYPES.BITS32 = 5;
  6825. /**
  6826. * Packable wire types.
  6827. * @type {!Array.<number>}
  6828. * @const
  6829. * @expose
  6830. */
  6831. ProtoBuf.PACKABLE_WIRE_TYPES = [
  6832. ProtoBuf.WIRE_TYPES.VARINT,
  6833. ProtoBuf.WIRE_TYPES.BITS64,
  6834. ProtoBuf.WIRE_TYPES.BITS32
  6835. ];
  6836. /**
  6837. * Types.
  6838. * @dict
  6839. * @type {!Object.<string,{name: string, wireType: number, defaultValue: *}>}
  6840. * @const
  6841. * @expose
  6842. */
  6843. ProtoBuf.TYPES = {
  6844. // According to the protobuf spec.
  6845. "int32": {
  6846. name: "int32",
  6847. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  6848. defaultValue: 0
  6849. },
  6850. "uint32": {
  6851. name: "uint32",
  6852. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  6853. defaultValue: 0
  6854. },
  6855. "sint32": {
  6856. name: "sint32",
  6857. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  6858. defaultValue: 0
  6859. },
  6860. "int64": {
  6861. name: "int64",
  6862. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  6863. defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined
  6864. },
  6865. "uint64": {
  6866. name: "uint64",
  6867. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  6868. defaultValue: ProtoBuf.Long ? ProtoBuf.Long.UZERO : undefined
  6869. },
  6870. "sint64": {
  6871. name: "sint64",
  6872. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  6873. defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined
  6874. },
  6875. "bool": {
  6876. name: "bool",
  6877. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  6878. defaultValue: false
  6879. },
  6880. "double": {
  6881. name: "double",
  6882. wireType: ProtoBuf.WIRE_TYPES.BITS64,
  6883. defaultValue: 0
  6884. },
  6885. "string": {
  6886. name: "string",
  6887. wireType: ProtoBuf.WIRE_TYPES.LDELIM,
  6888. defaultValue: ""
  6889. },
  6890. "bytes": {
  6891. name: "bytes",
  6892. wireType: ProtoBuf.WIRE_TYPES.LDELIM,
  6893. defaultValue: null // overridden in the code, must be a unique instance
  6894. },
  6895. "fixed32": {
  6896. name: "fixed32",
  6897. wireType: ProtoBuf.WIRE_TYPES.BITS32,
  6898. defaultValue: 0
  6899. },
  6900. "sfixed32": {
  6901. name: "sfixed32",
  6902. wireType: ProtoBuf.WIRE_TYPES.BITS32,
  6903. defaultValue: 0
  6904. },
  6905. "fixed64": {
  6906. name: "fixed64",
  6907. wireType: ProtoBuf.WIRE_TYPES.BITS64,
  6908. defaultValue: ProtoBuf.Long ? ProtoBuf.Long.UZERO : undefined
  6909. },
  6910. "sfixed64": {
  6911. name: "sfixed64",
  6912. wireType: ProtoBuf.WIRE_TYPES.BITS64,
  6913. defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined
  6914. },
  6915. "float": {
  6916. name: "float",
  6917. wireType: ProtoBuf.WIRE_TYPES.BITS32,
  6918. defaultValue: 0
  6919. },
  6920. "enum": {
  6921. name: "enum",
  6922. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  6923. defaultValue: 0
  6924. },
  6925. "message": {
  6926. name: "message",
  6927. wireType: ProtoBuf.WIRE_TYPES.LDELIM,
  6928. defaultValue: null
  6929. },
  6930. "group": {
  6931. name: "group",
  6932. wireType: ProtoBuf.WIRE_TYPES.STARTGROUP,
  6933. defaultValue: null
  6934. }
  6935. };
  6936. /**
  6937. * Valid map key types.
  6938. * @type {!Array.<!Object.<string,{name: string, wireType: number, defaultValue: *}>>}
  6939. * @const
  6940. * @expose
  6941. */
  6942. ProtoBuf.MAP_KEY_TYPES = [
  6943. ProtoBuf.TYPES["int32"],
  6944. ProtoBuf.TYPES["sint32"],
  6945. ProtoBuf.TYPES["sfixed32"],
  6946. ProtoBuf.TYPES["uint32"],
  6947. ProtoBuf.TYPES["fixed32"],
  6948. ProtoBuf.TYPES["int64"],
  6949. ProtoBuf.TYPES["sint64"],
  6950. ProtoBuf.TYPES["sfixed64"],
  6951. ProtoBuf.TYPES["uint64"],
  6952. ProtoBuf.TYPES["fixed64"],
  6953. ProtoBuf.TYPES["bool"],
  6954. ProtoBuf.TYPES["string"],
  6955. ProtoBuf.TYPES["bytes"]
  6956. ];
  6957. /**
  6958. * Minimum field id.
  6959. * @type {number}
  6960. * @const
  6961. * @expose
  6962. */
  6963. ProtoBuf.ID_MIN = 1;
  6964. /**
  6965. * Maximum field id.
  6966. * @type {number}
  6967. * @const
  6968. * @expose
  6969. */
  6970. ProtoBuf.ID_MAX = 0x1FFFFFFF;
  6971. /**
  6972. * If set to `true`, field names will be converted from underscore notation to camel case. Defaults to `false`.
  6973. * Must be set prior to parsing.
  6974. * @type {boolean}
  6975. * @expose
  6976. */
  6977. ProtoBuf.convertFieldsToCamelCase = false;
  6978. /**
  6979. * By default, messages are populated with (setX, set_x) accessors for each field. This can be disabled by
  6980. * setting this to `false` prior to building messages.
  6981. * @type {boolean}
  6982. * @expose
  6983. */
  6984. ProtoBuf.populateAccessors = true;
  6985. /**
  6986. * By default, messages are populated with default values if a field is not present on the wire. To disable
  6987. * this behavior, set this setting to `false`.
  6988. * @type {boolean}
  6989. * @expose
  6990. */
  6991. ProtoBuf.populateDefaults = true;
  6992. /**
  6993. * @alias ProtoBuf.Util
  6994. * @expose
  6995. */
  6996. ProtoBuf.Util = (function() {
  6997. /**
  6998. * ProtoBuf utilities.
  6999. * @exports ProtoBuf.Util
  7000. * @namespace
  7001. */
  7002. var Util = {};
  7003. /**
  7004. * Flag if running in node or not.
  7005. * @type {boolean}
  7006. * @const
  7007. * @expose
  7008. */
  7009. Util.IS_NODE = !!(
  7010. typeof process === 'object' && process+'' === '[object process]' && !process['browser']
  7011. );
  7012. /**
  7013. * Constructs a XMLHttpRequest object.
  7014. * @return {XMLHttpRequest}
  7015. * @throws {Error} If XMLHttpRequest is not supported
  7016. * @expose
  7017. */
  7018. Util.XHR = function() {
  7019. // No dependencies please, ref: http://www.quirksmode.org/js/xmlhttp.html
  7020. var XMLHttpFactories = [
  7021. function () {return new XMLHttpRequest()},
  7022. function () {return new ActiveXObject("Msxml2.XMLHTTP")},
  7023. function () {return new ActiveXObject("Msxml3.XMLHTTP")},
  7024. function () {return new ActiveXObject("Microsoft.XMLHTTP")}
  7025. ];
  7026. /** @type {?XMLHttpRequest} */
  7027. var xhr = null;
  7028. for (var i=0;i<XMLHttpFactories.length;i++) {
  7029. try { xhr = XMLHttpFactories[i](); }
  7030. catch (e) { continue; }
  7031. break;
  7032. }
  7033. if (!xhr)
  7034. throw Error("XMLHttpRequest is not supported");
  7035. return xhr;
  7036. };
  7037. /**
  7038. * Fetches a resource.
  7039. * @param {string} path Resource path
  7040. * @param {function(?string)=} callback Callback receiving the resource's contents. If omitted the resource will
  7041. * be fetched synchronously. If the request failed, contents will be null.
  7042. * @return {?string|undefined} Resource contents if callback is omitted (null if the request failed), else undefined.
  7043. * @expose
  7044. */
  7045. Util.fetch = function(path, callback) {
  7046. if (callback && typeof callback != 'function')
  7047. callback = null;
  7048. if (Util.IS_NODE) {
  7049. var fs = require$$2;
  7050. if (callback) {
  7051. fs.readFile(path, function(err, data) {
  7052. if (err)
  7053. callback(null);
  7054. else
  7055. callback(""+data);
  7056. });
  7057. } else
  7058. try {
  7059. return fs.readFileSync(path);
  7060. } catch (e) {
  7061. return null;
  7062. }
  7063. } else {
  7064. var xhr = Util.XHR();
  7065. xhr.open('GET', path, callback ? true : false);
  7066. // xhr.setRequestHeader('User-Agent', 'XMLHTTP/1.0');
  7067. xhr.setRequestHeader('Accept', 'text/plain');
  7068. if (typeof xhr.overrideMimeType === 'function') xhr.overrideMimeType('text/plain');
  7069. if (callback) {
  7070. xhr.onreadystatechange = function() {
  7071. if (xhr.readyState != 4) return;
  7072. if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
  7073. callback(xhr.responseText);
  7074. else
  7075. callback(null);
  7076. };
  7077. if (xhr.readyState == 4)
  7078. return;
  7079. xhr.send(null);
  7080. } else {
  7081. xhr.send(null);
  7082. if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
  7083. return xhr.responseText;
  7084. return null;
  7085. }
  7086. }
  7087. };
  7088. /**
  7089. * Converts a string to camel case.
  7090. * @param {string} str
  7091. * @returns {string}
  7092. * @expose
  7093. */
  7094. Util.toCamelCase = function(str) {
  7095. return str.replace(/_([a-zA-Z])/g, function ($0, $1) {
  7096. return $1.toUpperCase();
  7097. });
  7098. };
  7099. return Util;
  7100. })();
  7101. /**
  7102. * Language expressions.
  7103. * @type {!Object.<string,!RegExp>}
  7104. * @expose
  7105. */
  7106. ProtoBuf.Lang = {
  7107. // Characters always ending a statement
  7108. DELIM: /[\s\{\}=;:\[\],'"\(\)<>]/g,
  7109. // Field rules
  7110. RULE: /^(?:required|optional|repeated|map)$/,
  7111. // Field types
  7112. TYPE: /^(?:double|float|int32|uint32|sint32|int64|uint64|sint64|fixed32|sfixed32|fixed64|sfixed64|bool|string|bytes)$/,
  7113. // Names
  7114. NAME: /^[a-zA-Z_][a-zA-Z_0-9]*$/,
  7115. // Type definitions
  7116. TYPEDEF: /^[a-zA-Z][a-zA-Z_0-9]*$/,
  7117. // Type references
  7118. TYPEREF: /^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/,
  7119. // Fully qualified type references
  7120. FQTYPEREF: /^(?:\.[a-zA-Z_][a-zA-Z_0-9]*)+$/,
  7121. // All numbers
  7122. NUMBER: /^-?(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+|([0-9]*(\.[0-9]*)?([Ee][+-]?[0-9]+)?)|inf|nan)$/,
  7123. // Decimal numbers
  7124. NUMBER_DEC: /^(?:[1-9][0-9]*|0)$/,
  7125. // Hexadecimal numbers
  7126. NUMBER_HEX: /^0[xX][0-9a-fA-F]+$/,
  7127. // Octal numbers
  7128. NUMBER_OCT: /^0[0-7]+$/,
  7129. // Floating point numbers
  7130. NUMBER_FLT: /^([0-9]*(\.[0-9]*)?([Ee][+-]?[0-9]+)?|inf|nan)$/,
  7131. // Booleans
  7132. BOOL: /^(?:true|false)$/i,
  7133. // Id numbers
  7134. ID: /^(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+)$/,
  7135. // Negative id numbers (enum values)
  7136. NEGID: /^\-?(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+)$/,
  7137. // Whitespaces
  7138. WHITESPACE: /\s/,
  7139. // All strings
  7140. STRING: /(?:"([^"\\]*(?:\\.[^"\\]*)*)")|(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g,
  7141. // Double quoted strings
  7142. STRING_DQ: /(?:"([^"\\]*(?:\\.[^"\\]*)*)")/g,
  7143. // Single quoted strings
  7144. STRING_SQ: /(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g
  7145. };
  7146. /**
  7147. * @alias ProtoBuf.Reflect
  7148. * @expose
  7149. */
  7150. ProtoBuf.Reflect = (function(ProtoBuf) {
  7151. /**
  7152. * Reflection types.
  7153. * @exports ProtoBuf.Reflect
  7154. * @namespace
  7155. */
  7156. var Reflect = {};
  7157. /**
  7158. * Constructs a Reflect base class.
  7159. * @exports ProtoBuf.Reflect.T
  7160. * @constructor
  7161. * @abstract
  7162. * @param {!ProtoBuf.Builder} builder Builder reference
  7163. * @param {?ProtoBuf.Reflect.T} parent Parent object
  7164. * @param {string} name Object name
  7165. */
  7166. var T = function(builder, parent, name) {
  7167. /**
  7168. * Builder reference.
  7169. * @type {!ProtoBuf.Builder}
  7170. * @expose
  7171. */
  7172. this.builder = builder;
  7173. /**
  7174. * Parent object.
  7175. * @type {?ProtoBuf.Reflect.T}
  7176. * @expose
  7177. */
  7178. this.parent = parent;
  7179. /**
  7180. * Object name in namespace.
  7181. * @type {string}
  7182. * @expose
  7183. */
  7184. this.name = name;
  7185. /**
  7186. * Fully qualified class name
  7187. * @type {string}
  7188. * @expose
  7189. */
  7190. this.className;
  7191. };
  7192. /**
  7193. * @alias ProtoBuf.Reflect.T.prototype
  7194. * @inner
  7195. */
  7196. var TPrototype = T.prototype;
  7197. /**
  7198. * Returns the fully qualified name of this object.
  7199. * @returns {string} Fully qualified name as of ".PATH.TO.THIS"
  7200. * @expose
  7201. */
  7202. TPrototype.fqn = function() {
  7203. var name = this.name,
  7204. ptr = this;
  7205. do {
  7206. ptr = ptr.parent;
  7207. if (ptr == null)
  7208. break;
  7209. name = ptr.name+"."+name;
  7210. } while (true);
  7211. return name;
  7212. };
  7213. /**
  7214. * Returns a string representation of this Reflect object (its fully qualified name).
  7215. * @param {boolean=} includeClass Set to true to include the class name. Defaults to false.
  7216. * @return String representation
  7217. * @expose
  7218. */
  7219. TPrototype.toString = function(includeClass) {
  7220. return (includeClass ? this.className + " " : "") + this.fqn();
  7221. };
  7222. /**
  7223. * Builds this type.
  7224. * @throws {Error} If this type cannot be built directly
  7225. * @expose
  7226. */
  7227. TPrototype.build = function() {
  7228. throw Error(this.toString(true)+" cannot be built directly");
  7229. };
  7230. /**
  7231. * @alias ProtoBuf.Reflect.T
  7232. * @expose
  7233. */
  7234. Reflect.T = T;
  7235. /**
  7236. * Constructs a new Namespace.
  7237. * @exports ProtoBuf.Reflect.Namespace
  7238. * @param {!ProtoBuf.Builder} builder Builder reference
  7239. * @param {?ProtoBuf.Reflect.Namespace} parent Namespace parent
  7240. * @param {string} name Namespace name
  7241. * @param {Object.<string,*>=} options Namespace options
  7242. * @param {string?} syntax The syntax level of this definition (e.g., proto3)
  7243. * @constructor
  7244. * @extends ProtoBuf.Reflect.T
  7245. */
  7246. var Namespace = function(builder, parent, name, options, syntax) {
  7247. T.call(this, builder, parent, name);
  7248. /**
  7249. * @override
  7250. */
  7251. this.className = "Namespace";
  7252. /**
  7253. * Children inside the namespace.
  7254. * @type {!Array.<ProtoBuf.Reflect.T>}
  7255. */
  7256. this.children = [];
  7257. /**
  7258. * Options.
  7259. * @type {!Object.<string, *>}
  7260. */
  7261. this.options = options || {};
  7262. /**
  7263. * Syntax level (e.g., proto2 or proto3).
  7264. * @type {!string}
  7265. */
  7266. this.syntax = syntax || "proto2";
  7267. };
  7268. /**
  7269. * @alias ProtoBuf.Reflect.Namespace.prototype
  7270. * @inner
  7271. */
  7272. var NamespacePrototype = Namespace.prototype = Object.create(T.prototype);
  7273. /**
  7274. * Returns an array of the namespace's children.
  7275. * @param {ProtoBuf.Reflect.T=} type Filter type (returns instances of this type only). Defaults to null (all children).
  7276. * @return {Array.<ProtoBuf.Reflect.T>}
  7277. * @expose
  7278. */
  7279. NamespacePrototype.getChildren = function(type) {
  7280. type = type || null;
  7281. if (type == null)
  7282. return this.children.slice();
  7283. var children = [];
  7284. for (var i=0, k=this.children.length; i<k; ++i)
  7285. if (this.children[i] instanceof type)
  7286. children.push(this.children[i]);
  7287. return children;
  7288. };
  7289. /**
  7290. * Adds a child to the namespace.
  7291. * @param {ProtoBuf.Reflect.T} child Child
  7292. * @throws {Error} If the child cannot be added (duplicate)
  7293. * @expose
  7294. */
  7295. NamespacePrototype.addChild = function(child) {
  7296. var other;
  7297. if (other = this.getChild(child.name)) {
  7298. // Try to revert camelcase transformation on collision
  7299. if (other instanceof Message.Field && other.name !== other.originalName && this.getChild(other.originalName) === null)
  7300. other.name = other.originalName; // Revert previous first (effectively keeps both originals)
  7301. else if (child instanceof Message.Field && child.name !== child.originalName && this.getChild(child.originalName) === null)
  7302. child.name = child.originalName;
  7303. else
  7304. throw Error("Duplicate name in namespace "+this.toString(true)+": "+child.name);
  7305. }
  7306. this.children.push(child);
  7307. };
  7308. /**
  7309. * Gets a child by its name or id.
  7310. * @param {string|number} nameOrId Child name or id
  7311. * @return {?ProtoBuf.Reflect.T} The child or null if not found
  7312. * @expose
  7313. */
  7314. NamespacePrototype.getChild = function(nameOrId) {
  7315. var key = typeof nameOrId === 'number' ? 'id' : 'name';
  7316. for (var i=0, k=this.children.length; i<k; ++i)
  7317. if (this.children[i][key] === nameOrId)
  7318. return this.children[i];
  7319. return null;
  7320. };
  7321. /**
  7322. * Resolves a reflect object inside of this namespace.
  7323. * @param {string|!Array.<string>} qn Qualified name to resolve
  7324. * @param {boolean=} excludeNonNamespace Excludes non-namespace types, defaults to `false`
  7325. * @return {?ProtoBuf.Reflect.Namespace} The resolved type or null if not found
  7326. * @expose
  7327. */
  7328. NamespacePrototype.resolve = function(qn, excludeNonNamespace) {
  7329. var part = typeof qn === 'string' ? qn.split(".") : qn,
  7330. ptr = this,
  7331. i = 0;
  7332. if (part[i] === "") { // Fully qualified name, e.g. ".My.Message'
  7333. while (ptr.parent !== null)
  7334. ptr = ptr.parent;
  7335. i++;
  7336. }
  7337. var child;
  7338. do {
  7339. do {
  7340. if (!(ptr instanceof Reflect.Namespace)) {
  7341. ptr = null;
  7342. break;
  7343. }
  7344. child = ptr.getChild(part[i]);
  7345. if (!child || !(child instanceof Reflect.T) || (excludeNonNamespace && !(child instanceof Reflect.Namespace))) {
  7346. ptr = null;
  7347. break;
  7348. }
  7349. ptr = child; i++;
  7350. } while (i < part.length);
  7351. if (ptr != null)
  7352. break; // Found
  7353. // Else search the parent
  7354. if (this.parent !== null)
  7355. return this.parent.resolve(qn, excludeNonNamespace);
  7356. } while (ptr != null);
  7357. return ptr;
  7358. };
  7359. /**
  7360. * Determines the shortest qualified name of the specified type, if any, relative to this namespace.
  7361. * @param {!ProtoBuf.Reflect.T} t Reflection type
  7362. * @returns {string} The shortest qualified name or, if there is none, the fqn
  7363. * @expose
  7364. */
  7365. NamespacePrototype.qn = function(t) {
  7366. var part = [], ptr = t;
  7367. do {
  7368. part.unshift(ptr.name);
  7369. ptr = ptr.parent;
  7370. } while (ptr !== null);
  7371. for (var len=1; len <= part.length; len++) {
  7372. var qn = part.slice(part.length-len);
  7373. if (t === this.resolve(qn, t instanceof Reflect.Namespace))
  7374. return qn.join(".");
  7375. }
  7376. return t.fqn();
  7377. };
  7378. /**
  7379. * Builds the namespace and returns the runtime counterpart.
  7380. * @return {Object.<string,Function|Object>} Runtime namespace
  7381. * @expose
  7382. */
  7383. NamespacePrototype.build = function() {
  7384. /** @dict */
  7385. var ns = {};
  7386. var children = this.children;
  7387. for (var i=0, k=children.length, child; i<k; ++i) {
  7388. child = children[i];
  7389. if (child instanceof Namespace)
  7390. ns[child.name] = child.build();
  7391. }
  7392. if (Object.defineProperty)
  7393. Object.defineProperty(ns, "$options", { "value": this.buildOpt() });
  7394. return ns;
  7395. };
  7396. /**
  7397. * Builds the namespace's '$options' property.
  7398. * @return {Object.<string,*>}
  7399. */
  7400. NamespacePrototype.buildOpt = function() {
  7401. var opt = {},
  7402. keys = Object.keys(this.options);
  7403. for (var i=0, k=keys.length; i<k; ++i) {
  7404. var key = keys[i],
  7405. val = this.options[keys[i]];
  7406. // TODO: Options are not resolved, yet.
  7407. // if (val instanceof Namespace) {
  7408. // opt[key] = val.build();
  7409. // } else {
  7410. opt[key] = val;
  7411. // }
  7412. }
  7413. return opt;
  7414. };
  7415. /**
  7416. * Gets the value assigned to the option with the specified name.
  7417. * @param {string=} name Returns the option value if specified, otherwise all options are returned.
  7418. * @return {*|Object.<string,*>}null} Option value or NULL if there is no such option
  7419. */
  7420. NamespacePrototype.getOption = function(name) {
  7421. if (typeof name === 'undefined')
  7422. return this.options;
  7423. return typeof this.options[name] !== 'undefined' ? this.options[name] : null;
  7424. };
  7425. /**
  7426. * @alias ProtoBuf.Reflect.Namespace
  7427. * @expose
  7428. */
  7429. Reflect.Namespace = Namespace;
  7430. /**
  7431. * Constructs a new Element implementation that checks and converts values for a
  7432. * particular field type, as appropriate.
  7433. *
  7434. * An Element represents a single value: either the value of a singular field,
  7435. * or a value contained in one entry of a repeated field or map field. This
  7436. * class does not implement these higher-level concepts; it only encapsulates
  7437. * the low-level typechecking and conversion.
  7438. *
  7439. * @exports ProtoBuf.Reflect.Element
  7440. * @param {{name: string, wireType: number}} type Resolved data type
  7441. * @param {ProtoBuf.Reflect.T|null} resolvedType Resolved type, if relevant
  7442. * (e.g. submessage field).
  7443. * @param {boolean} isMapKey Is this element a Map key? The value will be
  7444. * converted to string form if so.
  7445. * @param {string} syntax Syntax level of defining message type, e.g.,
  7446. * proto2 or proto3.
  7447. * @param {string} name Name of the field containing this element (for error
  7448. * messages)
  7449. * @constructor
  7450. */
  7451. var Element = function(type, resolvedType, isMapKey, syntax, name) {
  7452. /**
  7453. * Element type, as a string (e.g., int32).
  7454. * @type {{name: string, wireType: number}}
  7455. */
  7456. this.type = type;
  7457. /**
  7458. * Element type reference to submessage or enum definition, if needed.
  7459. * @type {ProtoBuf.Reflect.T|null}
  7460. */
  7461. this.resolvedType = resolvedType;
  7462. /**
  7463. * Element is a map key.
  7464. * @type {boolean}
  7465. */
  7466. this.isMapKey = isMapKey;
  7467. /**
  7468. * Syntax level of defining message type, e.g., proto2 or proto3.
  7469. * @type {string}
  7470. */
  7471. this.syntax = syntax;
  7472. /**
  7473. * Name of the field containing this element (for error messages)
  7474. * @type {string}
  7475. */
  7476. this.name = name;
  7477. if (isMapKey && ProtoBuf.MAP_KEY_TYPES.indexOf(type) < 0)
  7478. throw Error("Invalid map key type: " + type.name);
  7479. };
  7480. var ElementPrototype = Element.prototype;
  7481. /**
  7482. * Obtains a (new) default value for the specified type.
  7483. * @param type {string|{name: string, wireType: number}} Field type
  7484. * @returns {*} Default value
  7485. * @inner
  7486. */
  7487. function mkDefault(type) {
  7488. if (typeof type === 'string')
  7489. type = ProtoBuf.TYPES[type];
  7490. if (typeof type.defaultValue === 'undefined')
  7491. throw Error("default value for type "+type.name+" is not supported");
  7492. if (type == ProtoBuf.TYPES["bytes"])
  7493. return new ByteBuffer(0);
  7494. return type.defaultValue;
  7495. }
  7496. /**
  7497. * Returns the default value for this field in proto3.
  7498. * @function
  7499. * @param type {string|{name: string, wireType: number}} the field type
  7500. * @returns {*} Default value
  7501. */
  7502. Element.defaultFieldValue = mkDefault;
  7503. /**
  7504. * Makes a Long from a value.
  7505. * @param {{low: number, high: number, unsigned: boolean}|string|number} value Value
  7506. * @param {boolean=} unsigned Whether unsigned or not, defaults to reuse it from Long-like objects or to signed for
  7507. * strings and numbers
  7508. * @returns {!Long}
  7509. * @throws {Error} If the value cannot be converted to a Long
  7510. * @inner
  7511. */
  7512. function mkLong(value, unsigned) {
  7513. if (value && typeof value.low === 'number' && typeof value.high === 'number' && typeof value.unsigned === 'boolean'
  7514. && value.low === value.low && value.high === value.high)
  7515. return new ProtoBuf.Long(value.low, value.high, typeof unsigned === 'undefined' ? value.unsigned : unsigned);
  7516. if (typeof value === 'string')
  7517. return ProtoBuf.Long.fromString(value, unsigned || false, 10);
  7518. if (typeof value === 'number')
  7519. return ProtoBuf.Long.fromNumber(value, unsigned || false);
  7520. throw Error("not convertible to Long");
  7521. }
  7522. ElementPrototype.toString = function() {
  7523. return (this.name || '') + (this.isMapKey ? 'map' : 'value') + ' element';
  7524. };
  7525. /**
  7526. * Checks if the given value can be set for an element of this type (singular
  7527. * field or one element of a repeated field or map).
  7528. * @param {*} value Value to check
  7529. * @return {*} Verified, maybe adjusted, value
  7530. * @throws {Error} If the value cannot be verified for this element slot
  7531. * @expose
  7532. */
  7533. ElementPrototype.verifyValue = function(value) {
  7534. var self = this;
  7535. function fail(val, msg) {
  7536. throw Error("Illegal value for "+self.toString(true)+" of type "+self.type.name+": "+val+" ("+msg+")");
  7537. }
  7538. switch (this.type) {
  7539. // Signed 32bit
  7540. case ProtoBuf.TYPES["int32"]:
  7541. case ProtoBuf.TYPES["sint32"]:
  7542. case ProtoBuf.TYPES["sfixed32"]:
  7543. // Account for !NaN: value === value
  7544. if (typeof value !== 'number' || (value === value && value % 1 !== 0))
  7545. fail(typeof value, "not an integer");
  7546. return value > 4294967295 ? value | 0 : value;
  7547. // Unsigned 32bit
  7548. case ProtoBuf.TYPES["uint32"]:
  7549. case ProtoBuf.TYPES["fixed32"]:
  7550. if (typeof value !== 'number' || (value === value && value % 1 !== 0))
  7551. fail(typeof value, "not an integer");
  7552. return value < 0 ? value >>> 0 : value;
  7553. // Signed 64bit
  7554. case ProtoBuf.TYPES["int64"]:
  7555. case ProtoBuf.TYPES["sint64"]:
  7556. case ProtoBuf.TYPES["sfixed64"]: {
  7557. if (ProtoBuf.Long)
  7558. try {
  7559. return mkLong(value, false);
  7560. } catch (e) {
  7561. fail(typeof value, e.message);
  7562. }
  7563. else
  7564. fail(typeof value, "requires Long.js");
  7565. }
  7566. // Unsigned 64bit
  7567. case ProtoBuf.TYPES["uint64"]:
  7568. case ProtoBuf.TYPES["fixed64"]: {
  7569. if (ProtoBuf.Long)
  7570. try {
  7571. return mkLong(value, true);
  7572. } catch (e) {
  7573. fail(typeof value, e.message);
  7574. }
  7575. else
  7576. fail(typeof value, "requires Long.js");
  7577. }
  7578. // Bool
  7579. case ProtoBuf.TYPES["bool"]:
  7580. if (typeof value !== 'boolean')
  7581. fail(typeof value, "not a boolean");
  7582. return value;
  7583. // Float
  7584. case ProtoBuf.TYPES["float"]:
  7585. case ProtoBuf.TYPES["double"]:
  7586. if (typeof value !== 'number')
  7587. fail(typeof value, "not a number");
  7588. return value;
  7589. // Length-delimited string
  7590. case ProtoBuf.TYPES["string"]:
  7591. if (typeof value !== 'string' && !(value && value instanceof String))
  7592. fail(typeof value, "not a string");
  7593. return ""+value; // Convert String object to string
  7594. // Length-delimited bytes
  7595. case ProtoBuf.TYPES["bytes"]:
  7596. if (ByteBuffer.isByteBuffer(value))
  7597. return value;
  7598. return ByteBuffer.wrap(value, "base64");
  7599. // Constant enum value
  7600. case ProtoBuf.TYPES["enum"]: {
  7601. var values = this.resolvedType.getChildren(ProtoBuf.Reflect.Enum.Value);
  7602. for (i=0; i<values.length; i++)
  7603. if (values[i].name == value)
  7604. return values[i].id;
  7605. else if (values[i].id == value)
  7606. return values[i].id;
  7607. if (this.syntax === 'proto3') {
  7608. // proto3: just make sure it's an integer.
  7609. if (typeof value !== 'number' || (value === value && value % 1 !== 0))
  7610. fail(typeof value, "not an integer");
  7611. if (value > 4294967295 || value < 0)
  7612. fail(typeof value, "not in range for uint32");
  7613. return value;
  7614. } else {
  7615. // proto2 requires enum values to be valid.
  7616. fail(value, "not a valid enum value");
  7617. }
  7618. }
  7619. // Embedded message
  7620. case ProtoBuf.TYPES["group"]:
  7621. case ProtoBuf.TYPES["message"]: {
  7622. if (!value || typeof value !== 'object')
  7623. fail(typeof value, "object expected");
  7624. if (value instanceof this.resolvedType.clazz)
  7625. return value;
  7626. if (value instanceof ProtoBuf.Builder.Message) {
  7627. // Mismatched type: Convert to object (see: https://github.com/dcodeIO/ProtoBuf.js/issues/180)
  7628. var obj = {};
  7629. for (var i in value)
  7630. if (value.hasOwnProperty(i))
  7631. obj[i] = value[i];
  7632. value = obj;
  7633. }
  7634. // Else let's try to construct one from a key-value object
  7635. return new (this.resolvedType.clazz)(value); // May throw for a hundred of reasons
  7636. }
  7637. }
  7638. // We should never end here
  7639. throw Error("[INTERNAL] Illegal value for "+this.toString(true)+": "+value+" (undefined type "+this.type+")");
  7640. };
  7641. /**
  7642. * Calculates the byte length of an element on the wire.
  7643. * @param {number} id Field number
  7644. * @param {*} value Field value
  7645. * @returns {number} Byte length
  7646. * @throws {Error} If the value cannot be calculated
  7647. * @expose
  7648. */
  7649. ElementPrototype.calculateLength = function(id, value) {
  7650. if (value === null) return 0; // Nothing to encode
  7651. // Tag has already been written
  7652. var n;
  7653. switch (this.type) {
  7654. case ProtoBuf.TYPES["int32"]:
  7655. return value < 0 ? ByteBuffer.calculateVarint64(value) : ByteBuffer.calculateVarint32(value);
  7656. case ProtoBuf.TYPES["uint32"]:
  7657. return ByteBuffer.calculateVarint32(value);
  7658. case ProtoBuf.TYPES["sint32"]:
  7659. return ByteBuffer.calculateVarint32(ByteBuffer.zigZagEncode32(value));
  7660. case ProtoBuf.TYPES["fixed32"]:
  7661. case ProtoBuf.TYPES["sfixed32"]:
  7662. case ProtoBuf.TYPES["float"]:
  7663. return 4;
  7664. case ProtoBuf.TYPES["int64"]:
  7665. case ProtoBuf.TYPES["uint64"]:
  7666. return ByteBuffer.calculateVarint64(value);
  7667. case ProtoBuf.TYPES["sint64"]:
  7668. return ByteBuffer.calculateVarint64(ByteBuffer.zigZagEncode64(value));
  7669. case ProtoBuf.TYPES["fixed64"]:
  7670. case ProtoBuf.TYPES["sfixed64"]:
  7671. return 8;
  7672. case ProtoBuf.TYPES["bool"]:
  7673. return 1;
  7674. case ProtoBuf.TYPES["enum"]:
  7675. return ByteBuffer.calculateVarint32(value);
  7676. case ProtoBuf.TYPES["double"]:
  7677. return 8;
  7678. case ProtoBuf.TYPES["string"]:
  7679. n = ByteBuffer.calculateUTF8Bytes(value);
  7680. return ByteBuffer.calculateVarint32(n) + n;
  7681. case ProtoBuf.TYPES["bytes"]:
  7682. if (value.remaining() < 0)
  7683. throw Error("Illegal value for "+this.toString(true)+": "+value.remaining()+" bytes remaining");
  7684. return ByteBuffer.calculateVarint32(value.remaining()) + value.remaining();
  7685. case ProtoBuf.TYPES["message"]:
  7686. n = this.resolvedType.calculate(value);
  7687. return ByteBuffer.calculateVarint32(n) + n;
  7688. case ProtoBuf.TYPES["group"]:
  7689. n = this.resolvedType.calculate(value);
  7690. return n + ByteBuffer.calculateVarint32((id << 3) | ProtoBuf.WIRE_TYPES.ENDGROUP);
  7691. }
  7692. // We should never end here
  7693. throw Error("[INTERNAL] Illegal value to encode in "+this.toString(true)+": "+value+" (unknown type)");
  7694. };
  7695. /**
  7696. * Encodes a value to the specified buffer. Does not encode the key.
  7697. * @param {number} id Field number
  7698. * @param {*} value Field value
  7699. * @param {ByteBuffer} buffer ByteBuffer to encode to
  7700. * @return {ByteBuffer} The ByteBuffer for chaining
  7701. * @throws {Error} If the value cannot be encoded
  7702. * @expose
  7703. */
  7704. ElementPrototype.encodeValue = function(id, value, buffer) {
  7705. if (value === null) return buffer; // Nothing to encode
  7706. // Tag has already been written
  7707. switch (this.type) {
  7708. // 32bit signed varint
  7709. case ProtoBuf.TYPES["int32"]:
  7710. // "If you use int32 or int64 as the type for a negative number, the resulting varint is always ten bytes
  7711. // long – it is, effectively, treated like a very large unsigned integer." (see #122)
  7712. if (value < 0)
  7713. buffer.writeVarint64(value);
  7714. else
  7715. buffer.writeVarint32(value);
  7716. break;
  7717. // 32bit unsigned varint
  7718. case ProtoBuf.TYPES["uint32"]:
  7719. buffer.writeVarint32(value);
  7720. break;
  7721. // 32bit varint zig-zag
  7722. case ProtoBuf.TYPES["sint32"]:
  7723. buffer.writeVarint32ZigZag(value);
  7724. break;
  7725. // Fixed unsigned 32bit
  7726. case ProtoBuf.TYPES["fixed32"]:
  7727. buffer.writeUint32(value);
  7728. break;
  7729. // Fixed signed 32bit
  7730. case ProtoBuf.TYPES["sfixed32"]:
  7731. buffer.writeInt32(value);
  7732. break;
  7733. // 64bit varint as-is
  7734. case ProtoBuf.TYPES["int64"]:
  7735. case ProtoBuf.TYPES["uint64"]:
  7736. buffer.writeVarint64(value); // throws
  7737. break;
  7738. // 64bit varint zig-zag
  7739. case ProtoBuf.TYPES["sint64"]:
  7740. buffer.writeVarint64ZigZag(value); // throws
  7741. break;
  7742. // Fixed unsigned 64bit
  7743. case ProtoBuf.TYPES["fixed64"]:
  7744. buffer.writeUint64(value); // throws
  7745. break;
  7746. // Fixed signed 64bit
  7747. case ProtoBuf.TYPES["sfixed64"]:
  7748. buffer.writeInt64(value); // throws
  7749. break;
  7750. // Bool
  7751. case ProtoBuf.TYPES["bool"]:
  7752. if (typeof value === 'string')
  7753. buffer.writeVarint32(value.toLowerCase() === 'false' ? 0 : !!value);
  7754. else
  7755. buffer.writeVarint32(value ? 1 : 0);
  7756. break;
  7757. // Constant enum value
  7758. case ProtoBuf.TYPES["enum"]:
  7759. buffer.writeVarint32(value);
  7760. break;
  7761. // 32bit float
  7762. case ProtoBuf.TYPES["float"]:
  7763. buffer.writeFloat32(value);
  7764. break;
  7765. // 64bit float
  7766. case ProtoBuf.TYPES["double"]:
  7767. buffer.writeFloat64(value);
  7768. break;
  7769. // Length-delimited string
  7770. case ProtoBuf.TYPES["string"]:
  7771. buffer.writeVString(value);
  7772. break;
  7773. // Length-delimited bytes
  7774. case ProtoBuf.TYPES["bytes"]:
  7775. if (value.remaining() < 0)
  7776. throw Error("Illegal value for "+this.toString(true)+": "+value.remaining()+" bytes remaining");
  7777. var prevOffset = value.offset;
  7778. buffer.writeVarint32(value.remaining());
  7779. buffer.append(value);
  7780. value.offset = prevOffset;
  7781. break;
  7782. // Embedded message
  7783. case ProtoBuf.TYPES["message"]:
  7784. var bb = new ByteBuffer().LE();
  7785. this.resolvedType.encode(value, bb);
  7786. buffer.writeVarint32(bb.offset);
  7787. buffer.append(bb.flip());
  7788. break;
  7789. // Legacy group
  7790. case ProtoBuf.TYPES["group"]:
  7791. this.resolvedType.encode(value, buffer);
  7792. buffer.writeVarint32((id << 3) | ProtoBuf.WIRE_TYPES.ENDGROUP);
  7793. break;
  7794. default:
  7795. // We should never end here
  7796. throw Error("[INTERNAL] Illegal value to encode in "+this.toString(true)+": "+value+" (unknown type)");
  7797. }
  7798. return buffer;
  7799. };
  7800. /**
  7801. * Decode one element value from the specified buffer.
  7802. * @param {ByteBuffer} buffer ByteBuffer to decode from
  7803. * @param {number} wireType The field wire type
  7804. * @param {number} id The field number
  7805. * @return {*} Decoded value
  7806. * @throws {Error} If the field cannot be decoded
  7807. * @expose
  7808. */
  7809. ElementPrototype.decode = function(buffer, wireType, id) {
  7810. if (wireType != this.type.wireType)
  7811. throw Error("Unexpected wire type for element");
  7812. var value, nBytes;
  7813. switch (this.type) {
  7814. // 32bit signed varint
  7815. case ProtoBuf.TYPES["int32"]:
  7816. return buffer.readVarint32() | 0;
  7817. // 32bit unsigned varint
  7818. case ProtoBuf.TYPES["uint32"]:
  7819. return buffer.readVarint32() >>> 0;
  7820. // 32bit signed varint zig-zag
  7821. case ProtoBuf.TYPES["sint32"]:
  7822. return buffer.readVarint32ZigZag() | 0;
  7823. // Fixed 32bit unsigned
  7824. case ProtoBuf.TYPES["fixed32"]:
  7825. return buffer.readUint32() >>> 0;
  7826. case ProtoBuf.TYPES["sfixed32"]:
  7827. return buffer.readInt32() | 0;
  7828. // 64bit signed varint
  7829. case ProtoBuf.TYPES["int64"]:
  7830. return buffer.readVarint64();
  7831. // 64bit unsigned varint
  7832. case ProtoBuf.TYPES["uint64"]:
  7833. return buffer.readVarint64().toUnsigned();
  7834. // 64bit signed varint zig-zag
  7835. case ProtoBuf.TYPES["sint64"]:
  7836. return buffer.readVarint64ZigZag();
  7837. // Fixed 64bit unsigned
  7838. case ProtoBuf.TYPES["fixed64"]:
  7839. return buffer.readUint64();
  7840. // Fixed 64bit signed
  7841. case ProtoBuf.TYPES["sfixed64"]:
  7842. return buffer.readInt64();
  7843. // Bool varint
  7844. case ProtoBuf.TYPES["bool"]:
  7845. return !!buffer.readVarint32();
  7846. // Constant enum value (varint)
  7847. case ProtoBuf.TYPES["enum"]:
  7848. // The following Builder.Message#set will already throw
  7849. return buffer.readVarint32();
  7850. // 32bit float
  7851. case ProtoBuf.TYPES["float"]:
  7852. return buffer.readFloat();
  7853. // 64bit float
  7854. case ProtoBuf.TYPES["double"]:
  7855. return buffer.readDouble();
  7856. // Length-delimited string
  7857. case ProtoBuf.TYPES["string"]:
  7858. return buffer.readVString();
  7859. // Length-delimited bytes
  7860. case ProtoBuf.TYPES["bytes"]: {
  7861. nBytes = buffer.readVarint32();
  7862. if (buffer.remaining() < nBytes)
  7863. throw Error("Illegal number of bytes for "+this.toString(true)+": "+nBytes+" required but got only "+buffer.remaining());
  7864. value = buffer.clone(); // Offset already set
  7865. value.limit = value.offset+nBytes;
  7866. buffer.offset += nBytes;
  7867. return value;
  7868. }
  7869. // Length-delimited embedded message
  7870. case ProtoBuf.TYPES["message"]: {
  7871. nBytes = buffer.readVarint32();
  7872. return this.resolvedType.decode(buffer, nBytes);
  7873. }
  7874. // Legacy group
  7875. case ProtoBuf.TYPES["group"]:
  7876. return this.resolvedType.decode(buffer, -1, id);
  7877. }
  7878. // We should never end here
  7879. throw Error("[INTERNAL] Illegal decode type");
  7880. };
  7881. /**
  7882. * Converts a value from a string to the canonical element type.
  7883. *
  7884. * Legal only when isMapKey is true.
  7885. *
  7886. * @param {string} str The string value
  7887. * @returns {*} The value
  7888. */
  7889. ElementPrototype.valueFromString = function(str) {
  7890. if (!this.isMapKey) {
  7891. throw Error("valueFromString() called on non-map-key element");
  7892. }
  7893. switch (this.type) {
  7894. case ProtoBuf.TYPES["int32"]:
  7895. case ProtoBuf.TYPES["sint32"]:
  7896. case ProtoBuf.TYPES["sfixed32"]:
  7897. case ProtoBuf.TYPES["uint32"]:
  7898. case ProtoBuf.TYPES["fixed32"]:
  7899. return this.verifyValue(parseInt(str));
  7900. case ProtoBuf.TYPES["int64"]:
  7901. case ProtoBuf.TYPES["sint64"]:
  7902. case ProtoBuf.TYPES["sfixed64"]:
  7903. case ProtoBuf.TYPES["uint64"]:
  7904. case ProtoBuf.TYPES["fixed64"]:
  7905. // Long-based fields support conversions from string already.
  7906. return this.verifyValue(str);
  7907. case ProtoBuf.TYPES["bool"]:
  7908. return str === "true";
  7909. case ProtoBuf.TYPES["string"]:
  7910. return this.verifyValue(str);
  7911. case ProtoBuf.TYPES["bytes"]:
  7912. return ByteBuffer.fromBinary(str);
  7913. }
  7914. };
  7915. /**
  7916. * Converts a value from the canonical element type to a string.
  7917. *
  7918. * It should be the case that `valueFromString(valueToString(val))` returns
  7919. * a value equivalent to `verifyValue(val)` for every legal value of `val`
  7920. * according to this element type.
  7921. *
  7922. * This may be used when the element must be stored or used as a string,
  7923. * e.g., as a map key on an Object.
  7924. *
  7925. * Legal only when isMapKey is true.
  7926. *
  7927. * @param {*} val The value
  7928. * @returns {string} The string form of the value.
  7929. */
  7930. ElementPrototype.valueToString = function(value) {
  7931. if (!this.isMapKey) {
  7932. throw Error("valueToString() called on non-map-key element");
  7933. }
  7934. if (this.type === ProtoBuf.TYPES["bytes"]) {
  7935. return value.toString("binary");
  7936. } else {
  7937. return value.toString();
  7938. }
  7939. };
  7940. /**
  7941. * @alias ProtoBuf.Reflect.Element
  7942. * @expose
  7943. */
  7944. Reflect.Element = Element;
  7945. /**
  7946. * Constructs a new Message.
  7947. * @exports ProtoBuf.Reflect.Message
  7948. * @param {!ProtoBuf.Builder} builder Builder reference
  7949. * @param {!ProtoBuf.Reflect.Namespace} parent Parent message or namespace
  7950. * @param {string} name Message name
  7951. * @param {Object.<string,*>=} options Message options
  7952. * @param {boolean=} isGroup `true` if this is a legacy group
  7953. * @param {string?} syntax The syntax level of this definition (e.g., proto3)
  7954. * @constructor
  7955. * @extends ProtoBuf.Reflect.Namespace
  7956. */
  7957. var Message = function(builder, parent, name, options, isGroup, syntax) {
  7958. Namespace.call(this, builder, parent, name, options, syntax);
  7959. /**
  7960. * @override
  7961. */
  7962. this.className = "Message";
  7963. /**
  7964. * Extensions range.
  7965. * @type {!Array.<number>|undefined}
  7966. * @expose
  7967. */
  7968. this.extensions = undefined;
  7969. /**
  7970. * Runtime message class.
  7971. * @type {?function(new:ProtoBuf.Builder.Message)}
  7972. * @expose
  7973. */
  7974. this.clazz = null;
  7975. /**
  7976. * Whether this is a legacy group or not.
  7977. * @type {boolean}
  7978. * @expose
  7979. */
  7980. this.isGroup = !!isGroup;
  7981. // The following cached collections are used to efficiently iterate over or look up fields when decoding.
  7982. /**
  7983. * Cached fields.
  7984. * @type {?Array.<!ProtoBuf.Reflect.Message.Field>}
  7985. * @private
  7986. */
  7987. this._fields = null;
  7988. /**
  7989. * Cached fields by id.
  7990. * @type {?Object.<number,!ProtoBuf.Reflect.Message.Field>}
  7991. * @private
  7992. */
  7993. this._fieldsById = null;
  7994. /**
  7995. * Cached fields by name.
  7996. * @type {?Object.<string,!ProtoBuf.Reflect.Message.Field>}
  7997. * @private
  7998. */
  7999. this._fieldsByName = null;
  8000. };
  8001. /**
  8002. * @alias ProtoBuf.Reflect.Message.prototype
  8003. * @inner
  8004. */
  8005. var MessagePrototype = Message.prototype = Object.create(Namespace.prototype);
  8006. /**
  8007. * Builds the message and returns the runtime counterpart, which is a fully functional class.
  8008. * @see ProtoBuf.Builder.Message
  8009. * @param {boolean=} rebuild Whether to rebuild or not, defaults to false
  8010. * @return {ProtoBuf.Reflect.Message} Message class
  8011. * @throws {Error} If the message cannot be built
  8012. * @expose
  8013. */
  8014. MessagePrototype.build = function(rebuild) {
  8015. if (this.clazz && !rebuild)
  8016. return this.clazz;
  8017. // Create the runtime Message class in its own scope
  8018. var clazz = (function(ProtoBuf, T) {
  8019. var fields = T.getChildren(ProtoBuf.Reflect.Message.Field),
  8020. oneofs = T.getChildren(ProtoBuf.Reflect.Message.OneOf);
  8021. /**
  8022. * Constructs a new runtime Message.
  8023. * @name ProtoBuf.Builder.Message
  8024. * @class Barebone of all runtime messages.
  8025. * @param {!Object.<string,*>|string} values Preset values
  8026. * @param {...string} var_args
  8027. * @constructor
  8028. * @throws {Error} If the message cannot be created
  8029. */
  8030. var Message = function(values, var_args) {
  8031. ProtoBuf.Builder.Message.call(this);
  8032. // Create virtual oneof properties
  8033. for (var i=0, k=oneofs.length; i<k; ++i)
  8034. this[oneofs[i].name] = null;
  8035. // Create fields and set default values
  8036. for (i=0, k=fields.length; i<k; ++i) {
  8037. var field = fields[i];
  8038. this[field.name] =
  8039. field.repeated ? [] :
  8040. (field.map ? new ProtoBuf.Map(field) : null);
  8041. if ((field.required || T.syntax === 'proto3') &&
  8042. field.defaultValue !== null)
  8043. this[field.name] = field.defaultValue;
  8044. }
  8045. if (arguments.length > 0) {
  8046. var value;
  8047. // Set field values from a values object
  8048. if (arguments.length === 1 && values !== null && typeof values === 'object' &&
  8049. /* not _another_ Message */ (typeof values.encode !== 'function' || values instanceof Message) &&
  8050. /* not a repeated field */ !Array.isArray(values) &&
  8051. /* not a Map */ !(values instanceof ProtoBuf.Map) &&
  8052. /* not a ByteBuffer */ !ByteBuffer.isByteBuffer(values) &&
  8053. /* not an ArrayBuffer */ !(values instanceof ArrayBuffer) &&
  8054. /* not a Long */ !(ProtoBuf.Long && values instanceof ProtoBuf.Long)) {
  8055. this.$set(values);
  8056. } else // Set field values from arguments, in declaration order
  8057. for (i=0, k=arguments.length; i<k; ++i)
  8058. if (typeof (value = arguments[i]) !== 'undefined')
  8059. this.$set(fields[i].name, value); // May throw
  8060. }
  8061. };
  8062. /**
  8063. * @alias ProtoBuf.Builder.Message.prototype
  8064. * @inner
  8065. */
  8066. var MessagePrototype = Message.prototype = Object.create(ProtoBuf.Builder.Message.prototype);
  8067. /**
  8068. * Adds a value to a repeated field.
  8069. * @name ProtoBuf.Builder.Message#add
  8070. * @function
  8071. * @param {string} key Field name
  8072. * @param {*} value Value to add
  8073. * @param {boolean=} noAssert Whether to assert the value or not (asserts by default)
  8074. * @returns {!ProtoBuf.Builder.Message} this
  8075. * @throws {Error} If the value cannot be added
  8076. * @expose
  8077. */
  8078. MessagePrototype.add = function(key, value, noAssert) {
  8079. var field = T._fieldsByName[key];
  8080. if (!noAssert) {
  8081. if (!field)
  8082. throw Error(this+"#"+key+" is undefined");
  8083. if (!(field instanceof ProtoBuf.Reflect.Message.Field))
  8084. throw Error(this+"#"+key+" is not a field: "+field.toString(true)); // May throw if it's an enum or embedded message
  8085. if (!field.repeated)
  8086. throw Error(this+"#"+key+" is not a repeated field");
  8087. value = field.verifyValue(value, true);
  8088. }
  8089. if (this[key] === null)
  8090. this[key] = [];
  8091. this[key].push(value);
  8092. return this;
  8093. };
  8094. /**
  8095. * Adds a value to a repeated field. This is an alias for {@link ProtoBuf.Builder.Message#add}.
  8096. * @name ProtoBuf.Builder.Message#$add
  8097. * @function
  8098. * @param {string} key Field name
  8099. * @param {*} value Value to add
  8100. * @param {boolean=} noAssert Whether to assert the value or not (asserts by default)
  8101. * @returns {!ProtoBuf.Builder.Message} this
  8102. * @throws {Error} If the value cannot be added
  8103. * @expose
  8104. */
  8105. MessagePrototype.$add = MessagePrototype.add;
  8106. /**
  8107. * Sets a field's value.
  8108. * @name ProtoBuf.Builder.Message#set
  8109. * @function
  8110. * @param {string|!Object.<string,*>} keyOrObj String key or plain object holding multiple values
  8111. * @param {(*|boolean)=} value Value to set if key is a string, otherwise omitted
  8112. * @param {boolean=} noAssert Whether to not assert for an actual field / proper value type, defaults to `false`
  8113. * @returns {!ProtoBuf.Builder.Message} this
  8114. * @throws {Error} If the value cannot be set
  8115. * @expose
  8116. */
  8117. MessagePrototype.set = function(keyOrObj, value, noAssert) {
  8118. if (keyOrObj && typeof keyOrObj === 'object') {
  8119. noAssert = value;
  8120. for (var ikey in keyOrObj) {
  8121. // Check if virtual oneof field - don't set these
  8122. if (keyOrObj.hasOwnProperty(ikey) && typeof (value = keyOrObj[ikey]) !== 'undefined' && T._oneofsByName[ikey] === undefined)
  8123. this.$set(ikey, value, noAssert);
  8124. }
  8125. return this;
  8126. }
  8127. var field = T._fieldsByName[keyOrObj];
  8128. if (!noAssert) {
  8129. if (!field)
  8130. throw Error(this+"#"+keyOrObj+" is not a field: undefined");
  8131. if (!(field instanceof ProtoBuf.Reflect.Message.Field))
  8132. throw Error(this+"#"+keyOrObj+" is not a field: "+field.toString(true));
  8133. this[field.name] = (value = field.verifyValue(value)); // May throw
  8134. } else
  8135. this[keyOrObj] = value;
  8136. if (field && field.oneof) { // Field is part of an OneOf (not a virtual OneOf field)
  8137. var currentField = this[field.oneof.name]; // Virtual field references currently set field
  8138. if (value !== null) {
  8139. if (currentField !== null && currentField !== field.name)
  8140. this[currentField] = null; // Clear currently set field
  8141. this[field.oneof.name] = field.name; // Point virtual field at this field
  8142. } else if (/* value === null && */currentField === keyOrObj)
  8143. this[field.oneof.name] = null; // Clear virtual field (current field explicitly cleared)
  8144. }
  8145. return this;
  8146. };
  8147. /**
  8148. * Sets a field's value. This is an alias for [@link ProtoBuf.Builder.Message#set}.
  8149. * @name ProtoBuf.Builder.Message#$set
  8150. * @function
  8151. * @param {string|!Object.<string,*>} keyOrObj String key or plain object holding multiple values
  8152. * @param {(*|boolean)=} value Value to set if key is a string, otherwise omitted
  8153. * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
  8154. * @throws {Error} If the value cannot be set
  8155. * @expose
  8156. */
  8157. MessagePrototype.$set = MessagePrototype.set;
  8158. /**
  8159. * Gets a field's value.
  8160. * @name ProtoBuf.Builder.Message#get
  8161. * @function
  8162. * @param {string} key Key
  8163. * @param {boolean=} noAssert Whether to not assert for an actual field, defaults to `false`
  8164. * @return {*} Value
  8165. * @throws {Error} If there is no such field
  8166. * @expose
  8167. */
  8168. MessagePrototype.get = function(key, noAssert) {
  8169. if (noAssert)
  8170. return this[key];
  8171. var field = T._fieldsByName[key];
  8172. if (!field || !(field instanceof ProtoBuf.Reflect.Message.Field))
  8173. throw Error(this+"#"+key+" is not a field: undefined");
  8174. if (!(field instanceof ProtoBuf.Reflect.Message.Field))
  8175. throw Error(this+"#"+key+" is not a field: "+field.toString(true));
  8176. return this[field.name];
  8177. };
  8178. /**
  8179. * Gets a field's value. This is an alias for {@link ProtoBuf.Builder.Message#$get}.
  8180. * @name ProtoBuf.Builder.Message#$get
  8181. * @function
  8182. * @param {string} key Key
  8183. * @return {*} Value
  8184. * @throws {Error} If there is no such field
  8185. * @expose
  8186. */
  8187. MessagePrototype.$get = MessagePrototype.get;
  8188. // Getters and setters
  8189. for (var i=0; i<fields.length; i++) {
  8190. var field = fields[i];
  8191. // no setters for extension fields as these are named by their fqn
  8192. if (field instanceof ProtoBuf.Reflect.Message.ExtensionField)
  8193. continue;
  8194. if (T.builder.options['populateAccessors'])
  8195. (function(field) {
  8196. // set/get[SomeValue]
  8197. var Name = field.originalName.replace(/(_[a-zA-Z])/g, function(match) {
  8198. return match.toUpperCase().replace('_','');
  8199. });
  8200. Name = Name.substring(0,1).toUpperCase() + Name.substring(1);
  8201. // set/get_[some_value] FIXME: Do we really need these?
  8202. var name = field.originalName.replace(/([A-Z])/g, function(match) {
  8203. return "_"+match;
  8204. });
  8205. /**
  8206. * The current field's unbound setter function.
  8207. * @function
  8208. * @param {*} value
  8209. * @param {boolean=} noAssert
  8210. * @returns {!ProtoBuf.Builder.Message}
  8211. * @inner
  8212. */
  8213. var setter = function(value, noAssert) {
  8214. this[field.name] = noAssert ? value : field.verifyValue(value);
  8215. return this;
  8216. };
  8217. /**
  8218. * The current field's unbound getter function.
  8219. * @function
  8220. * @returns {*}
  8221. * @inner
  8222. */
  8223. var getter = function() {
  8224. return this[field.name];
  8225. };
  8226. if (T.getChild("set"+Name) === null)
  8227. /**
  8228. * Sets a value. This method is present for each field, but only if there is no name conflict with
  8229. * another field.
  8230. * @name ProtoBuf.Builder.Message#set[SomeField]
  8231. * @function
  8232. * @param {*} value Value to set
  8233. * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
  8234. * @returns {!ProtoBuf.Builder.Message} this
  8235. * @abstract
  8236. * @throws {Error} If the value cannot be set
  8237. */
  8238. MessagePrototype["set"+Name] = setter;
  8239. if (T.getChild("set_"+name) === null)
  8240. /**
  8241. * Sets a value. This method is present for each field, but only if there is no name conflict with
  8242. * another field.
  8243. * @name ProtoBuf.Builder.Message#set_[some_field]
  8244. * @function
  8245. * @param {*} value Value to set
  8246. * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
  8247. * @returns {!ProtoBuf.Builder.Message} this
  8248. * @abstract
  8249. * @throws {Error} If the value cannot be set
  8250. */
  8251. MessagePrototype["set_"+name] = setter;
  8252. if (T.getChild("get"+Name) === null)
  8253. /**
  8254. * Gets a value. This method is present for each field, but only if there is no name conflict with
  8255. * another field.
  8256. * @name ProtoBuf.Builder.Message#get[SomeField]
  8257. * @function
  8258. * @abstract
  8259. * @return {*} The value
  8260. */
  8261. MessagePrototype["get"+Name] = getter;
  8262. if (T.getChild("get_"+name) === null)
  8263. /**
  8264. * Gets a value. This method is present for each field, but only if there is no name conflict with
  8265. * another field.
  8266. * @name ProtoBuf.Builder.Message#get_[some_field]
  8267. * @function
  8268. * @return {*} The value
  8269. * @abstract
  8270. */
  8271. MessagePrototype["get_"+name] = getter;
  8272. })(field);
  8273. }
  8274. // En-/decoding
  8275. /**
  8276. * Encodes the message.
  8277. * @name ProtoBuf.Builder.Message#$encode
  8278. * @function
  8279. * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.
  8280. * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
  8281. * @return {!ByteBuffer} Encoded message as a ByteBuffer
  8282. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  8283. * returns the encoded ByteBuffer in the `encoded` property on the error.
  8284. * @expose
  8285. * @see ProtoBuf.Builder.Message#encode64
  8286. * @see ProtoBuf.Builder.Message#encodeHex
  8287. * @see ProtoBuf.Builder.Message#encodeAB
  8288. */
  8289. MessagePrototype.encode = function(buffer, noVerify) {
  8290. if (typeof buffer === 'boolean')
  8291. noVerify = buffer,
  8292. buffer = undefined;
  8293. var isNew = false;
  8294. if (!buffer)
  8295. buffer = new ByteBuffer(),
  8296. isNew = true;
  8297. var le = buffer.littleEndian;
  8298. try {
  8299. T.encode(this, buffer.LE(), noVerify);
  8300. return (isNew ? buffer.flip() : buffer).LE(le);
  8301. } catch (e) {
  8302. buffer.LE(le);
  8303. throw(e);
  8304. }
  8305. };
  8306. /**
  8307. * Encodes a message using the specified data payload.
  8308. * @param {!Object.<string,*>} data Data payload
  8309. * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.
  8310. * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
  8311. * @return {!ByteBuffer} Encoded message as a ByteBuffer
  8312. * @expose
  8313. */
  8314. Message.encode = function(data, buffer, noVerify) {
  8315. return new Message(data).encode(buffer, noVerify);
  8316. };
  8317. /**
  8318. * Calculates the byte length of the message.
  8319. * @name ProtoBuf.Builder.Message#calculate
  8320. * @function
  8321. * @returns {number} Byte length
  8322. * @throws {Error} If the message cannot be calculated or if required fields are missing.
  8323. * @expose
  8324. */
  8325. MessagePrototype.calculate = function() {
  8326. return T.calculate(this);
  8327. };
  8328. /**
  8329. * Encodes the varint32 length-delimited message.
  8330. * @name ProtoBuf.Builder.Message#encodeDelimited
  8331. * @function
  8332. * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.
  8333. * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
  8334. * @return {!ByteBuffer} Encoded message as a ByteBuffer
  8335. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  8336. * returns the encoded ByteBuffer in the `encoded` property on the error.
  8337. * @expose
  8338. */
  8339. MessagePrototype.encodeDelimited = function(buffer, noVerify) {
  8340. var isNew = false;
  8341. if (!buffer)
  8342. buffer = new ByteBuffer(),
  8343. isNew = true;
  8344. var enc = new ByteBuffer().LE();
  8345. T.encode(this, enc, noVerify).flip();
  8346. buffer.writeVarint32(enc.remaining());
  8347. buffer.append(enc);
  8348. return isNew ? buffer.flip() : buffer;
  8349. };
  8350. /**
  8351. * Directly encodes the message to an ArrayBuffer.
  8352. * @name ProtoBuf.Builder.Message#encodeAB
  8353. * @function
  8354. * @return {ArrayBuffer} Encoded message as ArrayBuffer
  8355. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  8356. * returns the encoded ArrayBuffer in the `encoded` property on the error.
  8357. * @expose
  8358. */
  8359. MessagePrototype.encodeAB = function() {
  8360. try {
  8361. return this.encode().toArrayBuffer();
  8362. } catch (e) {
  8363. if (e["encoded"]) e["encoded"] = e["encoded"].toArrayBuffer();
  8364. throw(e);
  8365. }
  8366. };
  8367. /**
  8368. * Returns the message as an ArrayBuffer. This is an alias for {@link ProtoBuf.Builder.Message#encodeAB}.
  8369. * @name ProtoBuf.Builder.Message#toArrayBuffer
  8370. * @function
  8371. * @return {ArrayBuffer} Encoded message as ArrayBuffer
  8372. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  8373. * returns the encoded ArrayBuffer in the `encoded` property on the error.
  8374. * @expose
  8375. */
  8376. MessagePrototype.toArrayBuffer = MessagePrototype.encodeAB;
  8377. /**
  8378. * Directly encodes the message to a node Buffer.
  8379. * @name ProtoBuf.Builder.Message#encodeNB
  8380. * @function
  8381. * @return {!Buffer}
  8382. * @throws {Error} If the message cannot be encoded, not running under node.js or if required fields are
  8383. * missing. The later still returns the encoded node Buffer in the `encoded` property on the error.
  8384. * @expose
  8385. */
  8386. MessagePrototype.encodeNB = function() {
  8387. try {
  8388. return this.encode().toBuffer();
  8389. } catch (e) {
  8390. if (e["encoded"]) e["encoded"] = e["encoded"].toBuffer();
  8391. throw(e);
  8392. }
  8393. };
  8394. /**
  8395. * Returns the message as a node Buffer. This is an alias for {@link ProtoBuf.Builder.Message#encodeNB}.
  8396. * @name ProtoBuf.Builder.Message#toBuffer
  8397. * @function
  8398. * @return {!Buffer}
  8399. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  8400. * returns the encoded node Buffer in the `encoded` property on the error.
  8401. * @expose
  8402. */
  8403. MessagePrototype.toBuffer = MessagePrototype.encodeNB;
  8404. /**
  8405. * Directly encodes the message to a base64 encoded string.
  8406. * @name ProtoBuf.Builder.Message#encode64
  8407. * @function
  8408. * @return {string} Base64 encoded string
  8409. * @throws {Error} If the underlying buffer cannot be encoded or if required fields are missing. The later
  8410. * still returns the encoded base64 string in the `encoded` property on the error.
  8411. * @expose
  8412. */
  8413. MessagePrototype.encode64 = function() {
  8414. try {
  8415. return this.encode().toBase64();
  8416. } catch (e) {
  8417. if (e["encoded"]) e["encoded"] = e["encoded"].toBase64();
  8418. throw(e);
  8419. }
  8420. };
  8421. /**
  8422. * Returns the message as a base64 encoded string. This is an alias for {@link ProtoBuf.Builder.Message#encode64}.
  8423. * @name ProtoBuf.Builder.Message#toBase64
  8424. * @function
  8425. * @return {string} Base64 encoded string
  8426. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  8427. * returns the encoded base64 string in the `encoded` property on the error.
  8428. * @expose
  8429. */
  8430. MessagePrototype.toBase64 = MessagePrototype.encode64;
  8431. /**
  8432. * Directly encodes the message to a hex encoded string.
  8433. * @name ProtoBuf.Builder.Message#encodeHex
  8434. * @function
  8435. * @return {string} Hex encoded string
  8436. * @throws {Error} If the underlying buffer cannot be encoded or if required fields are missing. The later
  8437. * still returns the encoded hex string in the `encoded` property on the error.
  8438. * @expose
  8439. */
  8440. MessagePrototype.encodeHex = function() {
  8441. try {
  8442. return this.encode().toHex();
  8443. } catch (e) {
  8444. if (e["encoded"]) e["encoded"] = e["encoded"].toHex();
  8445. throw(e);
  8446. }
  8447. };
  8448. /**
  8449. * Returns the message as a hex encoded string. This is an alias for {@link ProtoBuf.Builder.Message#encodeHex}.
  8450. * @name ProtoBuf.Builder.Message#toHex
  8451. * @function
  8452. * @return {string} Hex encoded string
  8453. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  8454. * returns the encoded hex string in the `encoded` property on the error.
  8455. * @expose
  8456. */
  8457. MessagePrototype.toHex = MessagePrototype.encodeHex;
  8458. /**
  8459. * Clones a message object or field value to a raw object.
  8460. * @param {*} obj Object to clone
  8461. * @param {boolean} binaryAsBase64 Whether to include binary data as base64 strings or as a buffer otherwise
  8462. * @param {boolean} longsAsStrings Whether to encode longs as strings
  8463. * @param {!ProtoBuf.Reflect.T=} resolvedType The resolved field type if a field
  8464. * @returns {*} Cloned object
  8465. * @inner
  8466. */
  8467. function cloneRaw(obj, binaryAsBase64, longsAsStrings, resolvedType) {
  8468. if (obj === null || typeof obj !== 'object') {
  8469. // Convert enum values to their respective names
  8470. if (resolvedType && resolvedType instanceof ProtoBuf.Reflect.Enum) {
  8471. var name = ProtoBuf.Reflect.Enum.getName(resolvedType.object, obj);
  8472. if (name !== null)
  8473. return name;
  8474. }
  8475. // Pass-through string, number, boolean, null...
  8476. return obj;
  8477. }
  8478. // Convert ByteBuffers to raw buffer or strings
  8479. if (ByteBuffer.isByteBuffer(obj))
  8480. return binaryAsBase64 ? obj.toBase64() : obj.toBuffer();
  8481. // Convert Longs to proper objects or strings
  8482. if (ProtoBuf.Long.isLong(obj))
  8483. return longsAsStrings ? obj.toString() : ProtoBuf.Long.fromValue(obj);
  8484. var clone;
  8485. // Clone arrays
  8486. if (Array.isArray(obj)) {
  8487. clone = [];
  8488. obj.forEach(function(v, k) {
  8489. clone[k] = cloneRaw(v, binaryAsBase64, longsAsStrings, resolvedType);
  8490. });
  8491. return clone;
  8492. }
  8493. clone = {};
  8494. // Convert maps to objects
  8495. if (obj instanceof ProtoBuf.Map) {
  8496. var it = obj.entries();
  8497. for (var e = it.next(); !e.done; e = it.next())
  8498. clone[obj.keyElem.valueToString(e.value[0])] = cloneRaw(e.value[1], binaryAsBase64, longsAsStrings, obj.valueElem.resolvedType);
  8499. return clone;
  8500. }
  8501. // Everything else is a non-null object
  8502. var type = obj.$type,
  8503. field = undefined;
  8504. for (var i in obj)
  8505. if (obj.hasOwnProperty(i)) {
  8506. if (type && (field = type.getChild(i)))
  8507. clone[i] = cloneRaw(obj[i], binaryAsBase64, longsAsStrings, field.resolvedType);
  8508. else
  8509. clone[i] = cloneRaw(obj[i], binaryAsBase64, longsAsStrings);
  8510. }
  8511. return clone;
  8512. }
  8513. /**
  8514. * Returns the message's raw payload.
  8515. * @param {boolean=} binaryAsBase64 Whether to include binary data as base64 strings instead of Buffers, defaults to `false`
  8516. * @param {boolean} longsAsStrings Whether to encode longs as strings
  8517. * @returns {Object.<string,*>} Raw payload
  8518. * @expose
  8519. */
  8520. MessagePrototype.toRaw = function(binaryAsBase64, longsAsStrings) {
  8521. return cloneRaw(this, !!binaryAsBase64, !!longsAsStrings, this.$type);
  8522. };
  8523. /**
  8524. * Encodes a message to JSON.
  8525. * @returns {string} JSON string
  8526. * @expose
  8527. */
  8528. MessagePrototype.encodeJSON = function() {
  8529. return JSON.stringify(
  8530. cloneRaw(this,
  8531. /* binary-as-base64 */ true,
  8532. /* longs-as-strings */ true,
  8533. this.$type
  8534. )
  8535. );
  8536. };
  8537. /**
  8538. * Decodes a message from the specified buffer or string.
  8539. * @name ProtoBuf.Builder.Message.decode
  8540. * @function
  8541. * @param {!ByteBuffer|!ArrayBuffer|!Buffer|string} buffer Buffer to decode from
  8542. * @param {(number|string)=} length Message length. Defaults to decode all the remainig data.
  8543. * @param {string=} enc Encoding if buffer is a string: hex, utf8 (not recommended), defaults to base64
  8544. * @return {!ProtoBuf.Builder.Message} Decoded message
  8545. * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
  8546. * returns the decoded message with missing fields in the `decoded` property on the error.
  8547. * @expose
  8548. * @see ProtoBuf.Builder.Message.decode64
  8549. * @see ProtoBuf.Builder.Message.decodeHex
  8550. */
  8551. Message.decode = function(buffer, length, enc) {
  8552. if (typeof length === 'string')
  8553. enc = length,
  8554. length = -1;
  8555. if (typeof buffer === 'string')
  8556. buffer = ByteBuffer.wrap(buffer, enc ? enc : "base64");
  8557. else if (!ByteBuffer.isByteBuffer(buffer))
  8558. buffer = ByteBuffer.wrap(buffer); // May throw
  8559. var le = buffer.littleEndian;
  8560. try {
  8561. var msg = T.decode(buffer.LE(), length);
  8562. buffer.LE(le);
  8563. return msg;
  8564. } catch (e) {
  8565. buffer.LE(le);
  8566. throw(e);
  8567. }
  8568. };
  8569. /**
  8570. * Decodes a varint32 length-delimited message from the specified buffer or string.
  8571. * @name ProtoBuf.Builder.Message.decodeDelimited
  8572. * @function
  8573. * @param {!ByteBuffer|!ArrayBuffer|!Buffer|string} buffer Buffer to decode from
  8574. * @param {string=} enc Encoding if buffer is a string: hex, utf8 (not recommended), defaults to base64
  8575. * @return {ProtoBuf.Builder.Message} Decoded message or `null` if not enough bytes are available yet
  8576. * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
  8577. * returns the decoded message with missing fields in the `decoded` property on the error.
  8578. * @expose
  8579. */
  8580. Message.decodeDelimited = function(buffer, enc) {
  8581. if (typeof buffer === 'string')
  8582. buffer = ByteBuffer.wrap(buffer, enc ? enc : "base64");
  8583. else if (!ByteBuffer.isByteBuffer(buffer))
  8584. buffer = ByteBuffer.wrap(buffer); // May throw
  8585. if (buffer.remaining() < 1)
  8586. return null;
  8587. var off = buffer.offset,
  8588. len = buffer.readVarint32();
  8589. if (buffer.remaining() < len) {
  8590. buffer.offset = off;
  8591. return null;
  8592. }
  8593. try {
  8594. var msg = T.decode(buffer.slice(buffer.offset, buffer.offset + len).LE());
  8595. buffer.offset += len;
  8596. return msg;
  8597. } catch (err) {
  8598. buffer.offset += len;
  8599. throw err;
  8600. }
  8601. };
  8602. /**
  8603. * Decodes the message from the specified base64 encoded string.
  8604. * @name ProtoBuf.Builder.Message.decode64
  8605. * @function
  8606. * @param {string} str String to decode from
  8607. * @return {!ProtoBuf.Builder.Message} Decoded message
  8608. * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
  8609. * returns the decoded message with missing fields in the `decoded` property on the error.
  8610. * @expose
  8611. */
  8612. Message.decode64 = function(str) {
  8613. return Message.decode(str, "base64");
  8614. };
  8615. /**
  8616. * Decodes the message from the specified hex encoded string.
  8617. * @name ProtoBuf.Builder.Message.decodeHex
  8618. * @function
  8619. * @param {string} str String to decode from
  8620. * @return {!ProtoBuf.Builder.Message} Decoded message
  8621. * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
  8622. * returns the decoded message with missing fields in the `decoded` property on the error.
  8623. * @expose
  8624. */
  8625. Message.decodeHex = function(str) {
  8626. return Message.decode(str, "hex");
  8627. };
  8628. /**
  8629. * Decodes the message from a JSON string.
  8630. * @name ProtoBuf.Builder.Message.decodeJSON
  8631. * @function
  8632. * @param {string} str String to decode from
  8633. * @return {!ProtoBuf.Builder.Message} Decoded message
  8634. * @throws {Error} If the message cannot be decoded or if required fields are
  8635. * missing.
  8636. * @expose
  8637. */
  8638. Message.decodeJSON = function(str) {
  8639. return new Message(JSON.parse(str));
  8640. };
  8641. // Utility
  8642. /**
  8643. * Returns a string representation of this Message.
  8644. * @name ProtoBuf.Builder.Message#toString
  8645. * @function
  8646. * @return {string} String representation as of ".Fully.Qualified.MessageName"
  8647. * @expose
  8648. */
  8649. MessagePrototype.toString = function() {
  8650. return T.toString();
  8651. };
  8652. if (Object.defineProperty)
  8653. Object.defineProperty(Message, '$options', { "value": T.buildOpt() }),
  8654. Object.defineProperty(MessagePrototype, "$options", { "value": Message["$options"] }),
  8655. Object.defineProperty(Message, "$type", { "value": T }),
  8656. Object.defineProperty(MessagePrototype, "$type", { "value": T });
  8657. return Message;
  8658. })(ProtoBuf, this);
  8659. // Static enums and prototyped sub-messages / cached collections
  8660. this._fields = [];
  8661. this._fieldsById = {};
  8662. this._fieldsByName = {};
  8663. this._oneofsByName = {};
  8664. for (var i=0, k=this.children.length, child; i<k; i++) {
  8665. child = this.children[i];
  8666. if (child instanceof Enum || child instanceof Message || child instanceof Service) {
  8667. if (clazz.hasOwnProperty(child.name))
  8668. throw Error("Illegal reflect child of "+this.toString(true)+": "+child.toString(true)+" cannot override static property '"+child.name+"'");
  8669. clazz[child.name] = child.build();
  8670. } else if (child instanceof Message.Field)
  8671. child.build(),
  8672. this._fields.push(child),
  8673. this._fieldsById[child.id] = child,
  8674. this._fieldsByName[child.name] = child;
  8675. else if (child instanceof Message.OneOf) {
  8676. this._oneofsByName[child.name] = child;
  8677. }
  8678. else if (!(child instanceof Message.OneOf) && !(child instanceof Extension)) // Not built
  8679. throw Error("Illegal reflect child of "+this.toString(true)+": "+this.children[i].toString(true));
  8680. }
  8681. return this.clazz = clazz;
  8682. };
  8683. /**
  8684. * Encodes a runtime message's contents to the specified buffer.
  8685. * @param {!ProtoBuf.Builder.Message} message Runtime message to encode
  8686. * @param {ByteBuffer} buffer ByteBuffer to write to
  8687. * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
  8688. * @return {ByteBuffer} The ByteBuffer for chaining
  8689. * @throws {Error} If required fields are missing or the message cannot be encoded for another reason
  8690. * @expose
  8691. */
  8692. MessagePrototype.encode = function(message, buffer, noVerify) {
  8693. var fieldMissing = null,
  8694. field;
  8695. for (var i=0, k=this._fields.length, val; i<k; ++i) {
  8696. field = this._fields[i];
  8697. val = message[field.name];
  8698. if (field.required && val === null) {
  8699. if (fieldMissing === null)
  8700. fieldMissing = field;
  8701. } else
  8702. field.encode(noVerify ? val : field.verifyValue(val), buffer, message);
  8703. }
  8704. if (fieldMissing !== null) {
  8705. var err = Error("Missing at least one required field for "+this.toString(true)+": "+fieldMissing);
  8706. err["encoded"] = buffer; // Still expose what we got
  8707. throw(err);
  8708. }
  8709. return buffer;
  8710. };
  8711. /**
  8712. * Calculates a runtime message's byte length.
  8713. * @param {!ProtoBuf.Builder.Message} message Runtime message to encode
  8714. * @returns {number} Byte length
  8715. * @throws {Error} If required fields are missing or the message cannot be calculated for another reason
  8716. * @expose
  8717. */
  8718. MessagePrototype.calculate = function(message) {
  8719. for (var n=0, i=0, k=this._fields.length, field, val; i<k; ++i) {
  8720. field = this._fields[i];
  8721. val = message[field.name];
  8722. if (field.required && val === null)
  8723. throw Error("Missing at least one required field for "+this.toString(true)+": "+field);
  8724. else
  8725. n += field.calculate(val, message);
  8726. }
  8727. return n;
  8728. };
  8729. /**
  8730. * Skips all data until the end of the specified group has been reached.
  8731. * @param {number} expectedId Expected GROUPEND id
  8732. * @param {!ByteBuffer} buf ByteBuffer
  8733. * @returns {boolean} `true` if a value as been skipped, `false` if the end has been reached
  8734. * @throws {Error} If it wasn't possible to find the end of the group (buffer overrun or end tag mismatch)
  8735. * @inner
  8736. */
  8737. function skipTillGroupEnd(expectedId, buf) {
  8738. var tag = buf.readVarint32(), // Throws on OOB
  8739. wireType = tag & 0x07,
  8740. id = tag >>> 3;
  8741. switch (wireType) {
  8742. case ProtoBuf.WIRE_TYPES.VARINT:
  8743. do tag = buf.readUint8();
  8744. while ((tag & 0x80) === 0x80);
  8745. break;
  8746. case ProtoBuf.WIRE_TYPES.BITS64:
  8747. buf.offset += 8;
  8748. break;
  8749. case ProtoBuf.WIRE_TYPES.LDELIM:
  8750. tag = buf.readVarint32(); // reads the varint
  8751. buf.offset += tag; // skips n bytes
  8752. break;
  8753. case ProtoBuf.WIRE_TYPES.STARTGROUP:
  8754. skipTillGroupEnd(id, buf);
  8755. break;
  8756. case ProtoBuf.WIRE_TYPES.ENDGROUP:
  8757. if (id === expectedId)
  8758. return false;
  8759. else
  8760. throw Error("Illegal GROUPEND after unknown group: "+id+" ("+expectedId+" expected)");
  8761. case ProtoBuf.WIRE_TYPES.BITS32:
  8762. buf.offset += 4;
  8763. break;
  8764. default:
  8765. throw Error("Illegal wire type in unknown group "+expectedId+": "+wireType);
  8766. }
  8767. return true;
  8768. }
  8769. /**
  8770. * Decodes an encoded message and returns the decoded message.
  8771. * @param {ByteBuffer} buffer ByteBuffer to decode from
  8772. * @param {number=} length Message length. Defaults to decode all remaining data.
  8773. * @param {number=} expectedGroupEndId Expected GROUPEND id if this is a legacy group
  8774. * @return {ProtoBuf.Builder.Message} Decoded message
  8775. * @throws {Error} If the message cannot be decoded
  8776. * @expose
  8777. */
  8778. MessagePrototype.decode = function(buffer, length, expectedGroupEndId) {
  8779. if (typeof length !== 'number')
  8780. length = -1;
  8781. var start = buffer.offset,
  8782. msg = new (this.clazz)(),
  8783. tag, wireType, id, field;
  8784. while (buffer.offset < start+length || (length === -1 && buffer.remaining() > 0)) {
  8785. tag = buffer.readVarint32();
  8786. wireType = tag & 0x07;
  8787. id = tag >>> 3;
  8788. if (wireType === ProtoBuf.WIRE_TYPES.ENDGROUP) {
  8789. if (id !== expectedGroupEndId)
  8790. throw Error("Illegal group end indicator for "+this.toString(true)+": "+id+" ("+(expectedGroupEndId ? expectedGroupEndId+" expected" : "not a group")+")");
  8791. break;
  8792. }
  8793. if (!(field = this._fieldsById[id])) {
  8794. // "messages created by your new code can be parsed by your old code: old binaries simply ignore the new field when parsing."
  8795. switch (wireType) {
  8796. case ProtoBuf.WIRE_TYPES.VARINT:
  8797. buffer.readVarint32();
  8798. break;
  8799. case ProtoBuf.WIRE_TYPES.BITS32:
  8800. buffer.offset += 4;
  8801. break;
  8802. case ProtoBuf.WIRE_TYPES.BITS64:
  8803. buffer.offset += 8;
  8804. break;
  8805. case ProtoBuf.WIRE_TYPES.LDELIM:
  8806. var len = buffer.readVarint32();
  8807. buffer.offset += len;
  8808. break;
  8809. case ProtoBuf.WIRE_TYPES.STARTGROUP:
  8810. while (skipTillGroupEnd(id, buffer)) {}
  8811. break;
  8812. default:
  8813. throw Error("Illegal wire type for unknown field "+id+" in "+this.toString(true)+"#decode: "+wireType);
  8814. }
  8815. continue;
  8816. }
  8817. if (field.repeated && !field.options["packed"]) {
  8818. msg[field.name].push(field.decode(wireType, buffer));
  8819. } else if (field.map) {
  8820. var keyval = field.decode(wireType, buffer);
  8821. msg[field.name].set(keyval[0], keyval[1]);
  8822. } else {
  8823. msg[field.name] = field.decode(wireType, buffer);
  8824. if (field.oneof) { // Field is part of an OneOf (not a virtual OneOf field)
  8825. var currentField = msg[field.oneof.name]; // Virtual field references currently set field
  8826. if (currentField !== null && currentField !== field.name)
  8827. msg[currentField] = null; // Clear currently set field
  8828. msg[field.oneof.name] = field.name; // Point virtual field at this field
  8829. }
  8830. }
  8831. }
  8832. // Check if all required fields are present and set default values for optional fields that are not
  8833. for (var i=0, k=this._fields.length; i<k; ++i) {
  8834. field = this._fields[i];
  8835. if (msg[field.name] === null) {
  8836. if (this.syntax === "proto3") { // Proto3 sets default values by specification
  8837. msg[field.name] = field.defaultValue;
  8838. } else if (field.required) {
  8839. var err = Error("Missing at least one required field for " + this.toString(true) + ": " + field.name);
  8840. err["decoded"] = msg; // Still expose what we got
  8841. throw(err);
  8842. } else if (ProtoBuf.populateDefaults && field.defaultValue !== null)
  8843. msg[field.name] = field.defaultValue;
  8844. }
  8845. }
  8846. return msg;
  8847. };
  8848. /**
  8849. * @alias ProtoBuf.Reflect.Message
  8850. * @expose
  8851. */
  8852. Reflect.Message = Message;
  8853. /**
  8854. * Constructs a new Message Field.
  8855. * @exports ProtoBuf.Reflect.Message.Field
  8856. * @param {!ProtoBuf.Builder} builder Builder reference
  8857. * @param {!ProtoBuf.Reflect.Message} message Message reference
  8858. * @param {string} rule Rule, one of requried, optional, repeated
  8859. * @param {string?} keytype Key data type, if any.
  8860. * @param {string} type Data type, e.g. int32
  8861. * @param {string} name Field name
  8862. * @param {number} id Unique field id
  8863. * @param {Object.<string,*>=} options Options
  8864. * @param {!ProtoBuf.Reflect.Message.OneOf=} oneof Enclosing OneOf
  8865. * @param {string?} syntax The syntax level of this definition (e.g., proto3)
  8866. * @constructor
  8867. * @extends ProtoBuf.Reflect.T
  8868. */
  8869. var Field = function(builder, message, rule, keytype, type, name, id, options, oneof, syntax) {
  8870. T.call(this, builder, message, name);
  8871. /**
  8872. * @override
  8873. */
  8874. this.className = "Message.Field";
  8875. /**
  8876. * Message field required flag.
  8877. * @type {boolean}
  8878. * @expose
  8879. */
  8880. this.required = rule === "required";
  8881. /**
  8882. * Message field repeated flag.
  8883. * @type {boolean}
  8884. * @expose
  8885. */
  8886. this.repeated = rule === "repeated";
  8887. /**
  8888. * Message field map flag.
  8889. * @type {boolean}
  8890. * @expose
  8891. */
  8892. this.map = rule === "map";
  8893. /**
  8894. * Message field key type. Type reference string if unresolved, protobuf
  8895. * type if resolved. Valid only if this.map === true, null otherwise.
  8896. * @type {string|{name: string, wireType: number}|null}
  8897. * @expose
  8898. */
  8899. this.keyType = keytype || null;
  8900. /**
  8901. * Message field type. Type reference string if unresolved, protobuf type if
  8902. * resolved. In a map field, this is the value type.
  8903. * @type {string|{name: string, wireType: number}}
  8904. * @expose
  8905. */
  8906. this.type = type;
  8907. /**
  8908. * Resolved type reference inside the global namespace.
  8909. * @type {ProtoBuf.Reflect.T|null}
  8910. * @expose
  8911. */
  8912. this.resolvedType = null;
  8913. /**
  8914. * Unique message field id.
  8915. * @type {number}
  8916. * @expose
  8917. */
  8918. this.id = id;
  8919. /**
  8920. * Message field options.
  8921. * @type {!Object.<string,*>}
  8922. * @dict
  8923. * @expose
  8924. */
  8925. this.options = options || {};
  8926. /**
  8927. * Default value.
  8928. * @type {*}
  8929. * @expose
  8930. */
  8931. this.defaultValue = null;
  8932. /**
  8933. * Enclosing OneOf.
  8934. * @type {?ProtoBuf.Reflect.Message.OneOf}
  8935. * @expose
  8936. */
  8937. this.oneof = oneof || null;
  8938. /**
  8939. * Syntax level of this definition (e.g., proto3).
  8940. * @type {string}
  8941. * @expose
  8942. */
  8943. this.syntax = syntax || 'proto2';
  8944. /**
  8945. * Original field name.
  8946. * @type {string}
  8947. * @expose
  8948. */
  8949. this.originalName = this.name; // Used to revert camelcase transformation on naming collisions
  8950. /**
  8951. * Element implementation. Created in build() after types are resolved.
  8952. * @type {ProtoBuf.Element}
  8953. * @expose
  8954. */
  8955. this.element = null;
  8956. /**
  8957. * Key element implementation, for map fields. Created in build() after
  8958. * types are resolved.
  8959. * @type {ProtoBuf.Element}
  8960. * @expose
  8961. */
  8962. this.keyElement = null;
  8963. // Convert field names to camel case notation if the override is set
  8964. if (this.builder.options['convertFieldsToCamelCase'] && !(this instanceof Message.ExtensionField))
  8965. this.name = ProtoBuf.Util.toCamelCase(this.name);
  8966. };
  8967. /**
  8968. * @alias ProtoBuf.Reflect.Message.Field.prototype
  8969. * @inner
  8970. */
  8971. var FieldPrototype = Field.prototype = Object.create(T.prototype);
  8972. /**
  8973. * Builds the field.
  8974. * @override
  8975. * @expose
  8976. */
  8977. FieldPrototype.build = function() {
  8978. this.element = new Element(this.type, this.resolvedType, false, this.syntax, this.name);
  8979. if (this.map)
  8980. this.keyElement = new Element(this.keyType, undefined, true, this.syntax, this.name);
  8981. // In proto3, fields do not have field presence, and every field is set to
  8982. // its type's default value ("", 0, 0.0, or false).
  8983. if (this.syntax === 'proto3' && !this.repeated && !this.map)
  8984. this.defaultValue = Element.defaultFieldValue(this.type);
  8985. // Otherwise, default values are present when explicitly specified
  8986. else if (typeof this.options['default'] !== 'undefined')
  8987. this.defaultValue = this.verifyValue(this.options['default']);
  8988. };
  8989. /**
  8990. * Checks if the given value can be set for this field.
  8991. * @param {*} value Value to check
  8992. * @param {boolean=} skipRepeated Whether to skip the repeated value check or not. Defaults to false.
  8993. * @return {*} Verified, maybe adjusted, value
  8994. * @throws {Error} If the value cannot be set for this field
  8995. * @expose
  8996. */
  8997. FieldPrototype.verifyValue = function(value, skipRepeated) {
  8998. skipRepeated = skipRepeated || false;
  8999. var self = this;
  9000. function fail(val, msg) {
  9001. throw Error("Illegal value for "+self.toString(true)+" of type "+self.type.name+": "+val+" ("+msg+")");
  9002. }
  9003. if (value === null) { // NULL values for optional fields
  9004. if (this.required)
  9005. fail(typeof value, "required");
  9006. if (this.syntax === 'proto3' && this.type !== ProtoBuf.TYPES["message"])
  9007. fail(typeof value, "proto3 field without field presence cannot be null");
  9008. return null;
  9009. }
  9010. var i;
  9011. if (this.repeated && !skipRepeated) { // Repeated values as arrays
  9012. if (!Array.isArray(value))
  9013. value = [value];
  9014. var res = [];
  9015. for (i=0; i<value.length; i++)
  9016. res.push(this.element.verifyValue(value[i]));
  9017. return res;
  9018. }
  9019. if (this.map && !skipRepeated) { // Map values as objects
  9020. if (!(value instanceof ProtoBuf.Map)) {
  9021. // If not already a Map, attempt to convert.
  9022. if (!(value instanceof Object)) {
  9023. fail(typeof value,
  9024. "expected ProtoBuf.Map or raw object for map field");
  9025. }
  9026. return new ProtoBuf.Map(this, value);
  9027. } else {
  9028. return value;
  9029. }
  9030. }
  9031. // All non-repeated fields expect no array
  9032. if (!this.repeated && Array.isArray(value))
  9033. fail(typeof value, "no array expected");
  9034. return this.element.verifyValue(value);
  9035. };
  9036. /**
  9037. * Determines whether the field will have a presence on the wire given its
  9038. * value.
  9039. * @param {*} value Verified field value
  9040. * @param {!ProtoBuf.Builder.Message} message Runtime message
  9041. * @return {boolean} Whether the field will be present on the wire
  9042. */
  9043. FieldPrototype.hasWirePresence = function(value, message) {
  9044. if (this.syntax !== 'proto3')
  9045. return (value !== null);
  9046. if (this.oneof && message[this.oneof.name] === this.name)
  9047. return true;
  9048. switch (this.type) {
  9049. case ProtoBuf.TYPES["int32"]:
  9050. case ProtoBuf.TYPES["sint32"]:
  9051. case ProtoBuf.TYPES["sfixed32"]:
  9052. case ProtoBuf.TYPES["uint32"]:
  9053. case ProtoBuf.TYPES["fixed32"]:
  9054. return value !== 0;
  9055. case ProtoBuf.TYPES["int64"]:
  9056. case ProtoBuf.TYPES["sint64"]:
  9057. case ProtoBuf.TYPES["sfixed64"]:
  9058. case ProtoBuf.TYPES["uint64"]:
  9059. case ProtoBuf.TYPES["fixed64"]:
  9060. return value.low !== 0 || value.high !== 0;
  9061. case ProtoBuf.TYPES["bool"]:
  9062. return value;
  9063. case ProtoBuf.TYPES["float"]:
  9064. case ProtoBuf.TYPES["double"]:
  9065. return value !== 0.0;
  9066. case ProtoBuf.TYPES["string"]:
  9067. return value.length > 0;
  9068. case ProtoBuf.TYPES["bytes"]:
  9069. return value.remaining() > 0;
  9070. case ProtoBuf.TYPES["enum"]:
  9071. return value !== 0;
  9072. case ProtoBuf.TYPES["message"]:
  9073. return value !== null;
  9074. default:
  9075. return true;
  9076. }
  9077. };
  9078. /**
  9079. * Encodes the specified field value to the specified buffer.
  9080. * @param {*} value Verified field value
  9081. * @param {ByteBuffer} buffer ByteBuffer to encode to
  9082. * @param {!ProtoBuf.Builder.Message} message Runtime message
  9083. * @return {ByteBuffer} The ByteBuffer for chaining
  9084. * @throws {Error} If the field cannot be encoded
  9085. * @expose
  9086. */
  9087. FieldPrototype.encode = function(value, buffer, message) {
  9088. if (this.type === null || typeof this.type !== 'object')
  9089. throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);
  9090. if (value === null || (this.repeated && value.length == 0))
  9091. return buffer; // Optional omitted
  9092. try {
  9093. if (this.repeated) {
  9094. var i;
  9095. // "Only repeated fields of primitive numeric types (types which use the varint, 32-bit, or 64-bit wire
  9096. // types) can be declared 'packed'."
  9097. if (this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {
  9098. // "All of the elements of the field are packed into a single key-value pair with wire type 2
  9099. // (length-delimited). Each element is encoded the same way it would be normally, except without a
  9100. // tag preceding it."
  9101. buffer.writeVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
  9102. buffer.ensureCapacity(buffer.offset += 1); // We do not know the length yet, so let's assume a varint of length 1
  9103. var start = buffer.offset; // Remember where the contents begin
  9104. for (i=0; i<value.length; i++)
  9105. this.element.encodeValue(this.id, value[i], buffer);
  9106. var len = buffer.offset-start,
  9107. varintLen = ByteBuffer.calculateVarint32(len);
  9108. if (varintLen > 1) { // We need to move the contents
  9109. var contents = buffer.slice(start, buffer.offset);
  9110. start += varintLen-1;
  9111. buffer.offset = start;
  9112. buffer.append(contents);
  9113. }
  9114. buffer.writeVarint32(len, start-varintLen);
  9115. } else {
  9116. // "If your message definition has repeated elements (without the [packed=true] option), the encoded
  9117. // message has zero or more key-value pairs with the same tag number"
  9118. for (i=0; i<value.length; i++)
  9119. buffer.writeVarint32((this.id << 3) | this.type.wireType),
  9120. this.element.encodeValue(this.id, value[i], buffer);
  9121. }
  9122. } else if (this.map) {
  9123. // Write out each map entry as a submessage.
  9124. value.forEach(function(val, key, m) {
  9125. // Compute the length of the submessage (key, val) pair.
  9126. var length =
  9127. ByteBuffer.calculateVarint32((1 << 3) | this.keyType.wireType) +
  9128. this.keyElement.calculateLength(1, key) +
  9129. ByteBuffer.calculateVarint32((2 << 3) | this.type.wireType) +
  9130. this.element.calculateLength(2, val);
  9131. // Submessage with wire type of length-delimited.
  9132. buffer.writeVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
  9133. buffer.writeVarint32(length);
  9134. // Write out the key and val.
  9135. buffer.writeVarint32((1 << 3) | this.keyType.wireType);
  9136. this.keyElement.encodeValue(1, key, buffer);
  9137. buffer.writeVarint32((2 << 3) | this.type.wireType);
  9138. this.element.encodeValue(2, val, buffer);
  9139. }, this);
  9140. } else {
  9141. if (this.hasWirePresence(value, message)) {
  9142. buffer.writeVarint32((this.id << 3) | this.type.wireType);
  9143. this.element.encodeValue(this.id, value, buffer);
  9144. }
  9145. }
  9146. } catch (e) {
  9147. throw Error("Illegal value for "+this.toString(true)+": "+value+" ("+e+")");
  9148. }
  9149. return buffer;
  9150. };
  9151. /**
  9152. * Calculates the length of this field's value on the network level.
  9153. * @param {*} value Field value
  9154. * @param {!ProtoBuf.Builder.Message} message Runtime message
  9155. * @returns {number} Byte length
  9156. * @expose
  9157. */
  9158. FieldPrototype.calculate = function(value, message) {
  9159. value = this.verifyValue(value); // May throw
  9160. if (this.type === null || typeof this.type !== 'object')
  9161. throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);
  9162. if (value === null || (this.repeated && value.length == 0))
  9163. return 0; // Optional omitted
  9164. var n = 0;
  9165. try {
  9166. if (this.repeated) {
  9167. var i, ni;
  9168. if (this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {
  9169. n += ByteBuffer.calculateVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
  9170. ni = 0;
  9171. for (i=0; i<value.length; i++)
  9172. ni += this.element.calculateLength(this.id, value[i]);
  9173. n += ByteBuffer.calculateVarint32(ni);
  9174. n += ni;
  9175. } else {
  9176. for (i=0; i<value.length; i++)
  9177. n += ByteBuffer.calculateVarint32((this.id << 3) | this.type.wireType),
  9178. n += this.element.calculateLength(this.id, value[i]);
  9179. }
  9180. } else if (this.map) {
  9181. // Each map entry becomes a submessage.
  9182. value.forEach(function(val, key, m) {
  9183. // Compute the length of the submessage (key, val) pair.
  9184. var length =
  9185. ByteBuffer.calculateVarint32((1 << 3) | this.keyType.wireType) +
  9186. this.keyElement.calculateLength(1, key) +
  9187. ByteBuffer.calculateVarint32((2 << 3) | this.type.wireType) +
  9188. this.element.calculateLength(2, val);
  9189. n += ByteBuffer.calculateVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
  9190. n += ByteBuffer.calculateVarint32(length);
  9191. n += length;
  9192. }, this);
  9193. } else {
  9194. if (this.hasWirePresence(value, message)) {
  9195. n += ByteBuffer.calculateVarint32((this.id << 3) | this.type.wireType);
  9196. n += this.element.calculateLength(this.id, value);
  9197. }
  9198. }
  9199. } catch (e) {
  9200. throw Error("Illegal value for "+this.toString(true)+": "+value+" ("+e+")");
  9201. }
  9202. return n;
  9203. };
  9204. /**
  9205. * Decode the field value from the specified buffer.
  9206. * @param {number} wireType Leading wire type
  9207. * @param {ByteBuffer} buffer ByteBuffer to decode from
  9208. * @param {boolean=} skipRepeated Whether to skip the repeated check or not. Defaults to false.
  9209. * @return {*} Decoded value: array for packed repeated fields, [key, value] for
  9210. * map fields, or an individual value otherwise.
  9211. * @throws {Error} If the field cannot be decoded
  9212. * @expose
  9213. */
  9214. FieldPrototype.decode = function(wireType, buffer, skipRepeated) {
  9215. var value, nBytes;
  9216. // We expect wireType to match the underlying type's wireType unless we see
  9217. // a packed repeated field, or unless this is a map field.
  9218. var wireTypeOK =
  9219. (!this.map && wireType == this.type.wireType) ||
  9220. (!skipRepeated && this.repeated && this.options["packed"] &&
  9221. wireType == ProtoBuf.WIRE_TYPES.LDELIM) ||
  9222. (this.map && wireType == ProtoBuf.WIRE_TYPES.LDELIM);
  9223. if (!wireTypeOK)
  9224. throw Error("Illegal wire type for field "+this.toString(true)+": "+wireType+" ("+this.type.wireType+" expected)");
  9225. // Handle packed repeated fields.
  9226. if (wireType == ProtoBuf.WIRE_TYPES.LDELIM && this.repeated && this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {
  9227. if (!skipRepeated) {
  9228. nBytes = buffer.readVarint32();
  9229. nBytes = buffer.offset + nBytes; // Limit
  9230. var values = [];
  9231. while (buffer.offset < nBytes)
  9232. values.push(this.decode(this.type.wireType, buffer, true));
  9233. return values;
  9234. }
  9235. // Read the next value otherwise...
  9236. }
  9237. // Handle maps.
  9238. if (this.map) {
  9239. // Read one (key, value) submessage, and return [key, value]
  9240. var key = Element.defaultFieldValue(this.keyType);
  9241. value = Element.defaultFieldValue(this.type);
  9242. // Read the length
  9243. nBytes = buffer.readVarint32();
  9244. if (buffer.remaining() < nBytes)
  9245. throw Error("Illegal number of bytes for "+this.toString(true)+": "+nBytes+" required but got only "+buffer.remaining());
  9246. // Get a sub-buffer of this key/value submessage
  9247. var msgbuf = buffer.clone();
  9248. msgbuf.limit = msgbuf.offset + nBytes;
  9249. buffer.offset += nBytes;
  9250. while (msgbuf.remaining() > 0) {
  9251. var tag = msgbuf.readVarint32();
  9252. wireType = tag & 0x07;
  9253. var id = tag >>> 3;
  9254. if (id === 1) {
  9255. key = this.keyElement.decode(msgbuf, wireType, id);
  9256. } else if (id === 2) {
  9257. value = this.element.decode(msgbuf, wireType, id);
  9258. } else {
  9259. throw Error("Unexpected tag in map field key/value submessage");
  9260. }
  9261. }
  9262. return [key, value];
  9263. }
  9264. // Handle singular and non-packed repeated field values.
  9265. return this.element.decode(buffer, wireType, this.id);
  9266. };
  9267. /**
  9268. * @alias ProtoBuf.Reflect.Message.Field
  9269. * @expose
  9270. */
  9271. Reflect.Message.Field = Field;
  9272. /**
  9273. * Constructs a new Message ExtensionField.
  9274. * @exports ProtoBuf.Reflect.Message.ExtensionField
  9275. * @param {!ProtoBuf.Builder} builder Builder reference
  9276. * @param {!ProtoBuf.Reflect.Message} message Message reference
  9277. * @param {string} rule Rule, one of requried, optional, repeated
  9278. * @param {string} type Data type, e.g. int32
  9279. * @param {string} name Field name
  9280. * @param {number} id Unique field id
  9281. * @param {!Object.<string,*>=} options Options
  9282. * @constructor
  9283. * @extends ProtoBuf.Reflect.Message.Field
  9284. */
  9285. var ExtensionField = function(builder, message, rule, type, name, id, options) {
  9286. Field.call(this, builder, message, rule, /* keytype = */ null, type, name, id, options);
  9287. /**
  9288. * Extension reference.
  9289. * @type {!ProtoBuf.Reflect.Extension}
  9290. * @expose
  9291. */
  9292. this.extension;
  9293. };
  9294. // Extends Field
  9295. ExtensionField.prototype = Object.create(Field.prototype);
  9296. /**
  9297. * @alias ProtoBuf.Reflect.Message.ExtensionField
  9298. * @expose
  9299. */
  9300. Reflect.Message.ExtensionField = ExtensionField;
  9301. /**
  9302. * Constructs a new Message OneOf.
  9303. * @exports ProtoBuf.Reflect.Message.OneOf
  9304. * @param {!ProtoBuf.Builder} builder Builder reference
  9305. * @param {!ProtoBuf.Reflect.Message} message Message reference
  9306. * @param {string} name OneOf name
  9307. * @constructor
  9308. * @extends ProtoBuf.Reflect.T
  9309. */
  9310. var OneOf = function(builder, message, name) {
  9311. T.call(this, builder, message, name);
  9312. /**
  9313. * Enclosed fields.
  9314. * @type {!Array.<!ProtoBuf.Reflect.Message.Field>}
  9315. * @expose
  9316. */
  9317. this.fields = [];
  9318. };
  9319. /**
  9320. * @alias ProtoBuf.Reflect.Message.OneOf
  9321. * @expose
  9322. */
  9323. Reflect.Message.OneOf = OneOf;
  9324. /**
  9325. * Constructs a new Enum.
  9326. * @exports ProtoBuf.Reflect.Enum
  9327. * @param {!ProtoBuf.Builder} builder Builder reference
  9328. * @param {!ProtoBuf.Reflect.T} parent Parent Reflect object
  9329. * @param {string} name Enum name
  9330. * @param {Object.<string,*>=} options Enum options
  9331. * @param {string?} syntax The syntax level (e.g., proto3)
  9332. * @constructor
  9333. * @extends ProtoBuf.Reflect.Namespace
  9334. */
  9335. var Enum = function(builder, parent, name, options, syntax) {
  9336. Namespace.call(this, builder, parent, name, options, syntax);
  9337. /**
  9338. * @override
  9339. */
  9340. this.className = "Enum";
  9341. /**
  9342. * Runtime enum object.
  9343. * @type {Object.<string,number>|null}
  9344. * @expose
  9345. */
  9346. this.object = null;
  9347. };
  9348. /**
  9349. * Gets the string name of an enum value.
  9350. * @param {!ProtoBuf.Builder.Enum} enm Runtime enum
  9351. * @param {number} value Enum value
  9352. * @returns {?string} Name or `null` if not present
  9353. * @expose
  9354. */
  9355. Enum.getName = function(enm, value) {
  9356. var keys = Object.keys(enm);
  9357. for (var i=0, key; i<keys.length; ++i)
  9358. if (enm[key = keys[i]] === value)
  9359. return key;
  9360. return null;
  9361. };
  9362. /**
  9363. * @alias ProtoBuf.Reflect.Enum.prototype
  9364. * @inner
  9365. */
  9366. var EnumPrototype = Enum.prototype = Object.create(Namespace.prototype);
  9367. /**
  9368. * Builds this enum and returns the runtime counterpart.
  9369. * @param {boolean} rebuild Whether to rebuild or not, defaults to false
  9370. * @returns {!Object.<string,number>}
  9371. * @expose
  9372. */
  9373. EnumPrototype.build = function(rebuild) {
  9374. if (this.object && !rebuild)
  9375. return this.object;
  9376. var enm = new ProtoBuf.Builder.Enum(),
  9377. values = this.getChildren(Enum.Value);
  9378. for (var i=0, k=values.length; i<k; ++i)
  9379. enm[values[i]['name']] = values[i]['id'];
  9380. if (Object.defineProperty)
  9381. Object.defineProperty(enm, '$options', {
  9382. "value": this.buildOpt(),
  9383. "enumerable": false
  9384. });
  9385. return this.object = enm;
  9386. };
  9387. /**
  9388. * @alias ProtoBuf.Reflect.Enum
  9389. * @expose
  9390. */
  9391. Reflect.Enum = Enum;
  9392. /**
  9393. * Constructs a new Enum Value.
  9394. * @exports ProtoBuf.Reflect.Enum.Value
  9395. * @param {!ProtoBuf.Builder} builder Builder reference
  9396. * @param {!ProtoBuf.Reflect.Enum} enm Enum reference
  9397. * @param {string} name Field name
  9398. * @param {number} id Unique field id
  9399. * @constructor
  9400. * @extends ProtoBuf.Reflect.T
  9401. */
  9402. var Value = function(builder, enm, name, id) {
  9403. T.call(this, builder, enm, name);
  9404. /**
  9405. * @override
  9406. */
  9407. this.className = "Enum.Value";
  9408. /**
  9409. * Unique enum value id.
  9410. * @type {number}
  9411. * @expose
  9412. */
  9413. this.id = id;
  9414. };
  9415. // Extends T
  9416. Value.prototype = Object.create(T.prototype);
  9417. /**
  9418. * @alias ProtoBuf.Reflect.Enum.Value
  9419. * @expose
  9420. */
  9421. Reflect.Enum.Value = Value;
  9422. /**
  9423. * An extension (field).
  9424. * @exports ProtoBuf.Reflect.Extension
  9425. * @constructor
  9426. * @param {!ProtoBuf.Builder} builder Builder reference
  9427. * @param {!ProtoBuf.Reflect.T} parent Parent object
  9428. * @param {string} name Object name
  9429. * @param {!ProtoBuf.Reflect.Message.Field} field Extension field
  9430. */
  9431. var Extension = function(builder, parent, name, field) {
  9432. T.call(this, builder, parent, name);
  9433. /**
  9434. * Extended message field.
  9435. * @type {!ProtoBuf.Reflect.Message.Field}
  9436. * @expose
  9437. */
  9438. this.field = field;
  9439. };
  9440. // Extends T
  9441. Extension.prototype = Object.create(T.prototype);
  9442. /**
  9443. * @alias ProtoBuf.Reflect.Extension
  9444. * @expose
  9445. */
  9446. Reflect.Extension = Extension;
  9447. /**
  9448. * Constructs a new Service.
  9449. * @exports ProtoBuf.Reflect.Service
  9450. * @param {!ProtoBuf.Builder} builder Builder reference
  9451. * @param {!ProtoBuf.Reflect.Namespace} root Root
  9452. * @param {string} name Service name
  9453. * @param {Object.<string,*>=} options Options
  9454. * @constructor
  9455. * @extends ProtoBuf.Reflect.Namespace
  9456. */
  9457. var Service = function(builder, root, name, options) {
  9458. Namespace.call(this, builder, root, name, options);
  9459. /**
  9460. * @override
  9461. */
  9462. this.className = "Service";
  9463. /**
  9464. * Built runtime service class.
  9465. * @type {?function(new:ProtoBuf.Builder.Service)}
  9466. */
  9467. this.clazz = null;
  9468. };
  9469. /**
  9470. * @alias ProtoBuf.Reflect.Service.prototype
  9471. * @inner
  9472. */
  9473. var ServicePrototype = Service.prototype = Object.create(Namespace.prototype);
  9474. /**
  9475. * Builds the service and returns the runtime counterpart, which is a fully functional class.
  9476. * @see ProtoBuf.Builder.Service
  9477. * @param {boolean=} rebuild Whether to rebuild or not
  9478. * @return {Function} Service class
  9479. * @throws {Error} If the message cannot be built
  9480. * @expose
  9481. */
  9482. ServicePrototype.build = function(rebuild) {
  9483. if (this.clazz && !rebuild)
  9484. return this.clazz;
  9485. // Create the runtime Service class in its own scope
  9486. return this.clazz = (function(ProtoBuf, T) {
  9487. /**
  9488. * Constructs a new runtime Service.
  9489. * @name ProtoBuf.Builder.Service
  9490. * @param {function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))=} rpcImpl RPC implementation receiving the method name and the message
  9491. * @class Barebone of all runtime services.
  9492. * @constructor
  9493. * @throws {Error} If the service cannot be created
  9494. */
  9495. var Service = function(rpcImpl) {
  9496. ProtoBuf.Builder.Service.call(this);
  9497. /**
  9498. * Service implementation.
  9499. * @name ProtoBuf.Builder.Service#rpcImpl
  9500. * @type {!function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))}
  9501. * @expose
  9502. */
  9503. this.rpcImpl = rpcImpl || function(name, msg, callback) {
  9504. // This is what a user has to implement: A function receiving the method name, the actual message to
  9505. // send (type checked) and the callback that's either provided with the error as its first
  9506. // argument or null and the actual response message.
  9507. setTimeout(callback.bind(this, Error("Not implemented, see: https://github.com/dcodeIO/ProtoBuf.js/wiki/Services")), 0); // Must be async!
  9508. };
  9509. };
  9510. /**
  9511. * @alias ProtoBuf.Builder.Service.prototype
  9512. * @inner
  9513. */
  9514. var ServicePrototype = Service.prototype = Object.create(ProtoBuf.Builder.Service.prototype);
  9515. /**
  9516. * Asynchronously performs an RPC call using the given RPC implementation.
  9517. * @name ProtoBuf.Builder.Service.[Method]
  9518. * @function
  9519. * @param {!function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))} rpcImpl RPC implementation
  9520. * @param {ProtoBuf.Builder.Message} req Request
  9521. * @param {function(Error, (ProtoBuf.Builder.Message|ByteBuffer|Buffer|string)=)} callback Callback receiving
  9522. * the error if any and the response either as a pre-parsed message or as its raw bytes
  9523. * @abstract
  9524. */
  9525. /**
  9526. * Asynchronously performs an RPC call using the instance's RPC implementation.
  9527. * @name ProtoBuf.Builder.Service#[Method]
  9528. * @function
  9529. * @param {ProtoBuf.Builder.Message} req Request
  9530. * @param {function(Error, (ProtoBuf.Builder.Message|ByteBuffer|Buffer|string)=)} callback Callback receiving
  9531. * the error if any and the response either as a pre-parsed message or as its raw bytes
  9532. * @abstract
  9533. */
  9534. var rpc = T.getChildren(ProtoBuf.Reflect.Service.RPCMethod);
  9535. for (var i=0; i<rpc.length; i++) {
  9536. (function(method) {
  9537. // service#Method(message, callback)
  9538. ServicePrototype[method.name] = function(req, callback) {
  9539. try {
  9540. try {
  9541. // If given as a buffer, decode the request. Will throw a TypeError if not a valid buffer.
  9542. req = method.resolvedRequestType.clazz.decode(ByteBuffer.wrap(req));
  9543. } catch (err) {
  9544. if (!(err instanceof TypeError))
  9545. throw err;
  9546. }
  9547. if (req === null || typeof req !== 'object')
  9548. throw Error("Illegal arguments");
  9549. if (!(req instanceof method.resolvedRequestType.clazz))
  9550. req = new method.resolvedRequestType.clazz(req);
  9551. this.rpcImpl(method.fqn(), req, function(err, res) { // Assumes that this is properly async
  9552. if (err) {
  9553. callback(err);
  9554. return;
  9555. }
  9556. // Coalesce to empty string when service response has empty content
  9557. if (res === null)
  9558. res = '';
  9559. try { res = method.resolvedResponseType.clazz.decode(res); } catch (notABuffer) {}
  9560. if (!res || !(res instanceof method.resolvedResponseType.clazz)) {
  9561. callback(Error("Illegal response type received in service method "+ T.name+"#"+method.name));
  9562. return;
  9563. }
  9564. callback(null, res);
  9565. });
  9566. } catch (err) {
  9567. setTimeout(callback.bind(this, err), 0);
  9568. }
  9569. };
  9570. // Service.Method(rpcImpl, message, callback)
  9571. Service[method.name] = function(rpcImpl, req, callback) {
  9572. new Service(rpcImpl)[method.name](req, callback);
  9573. };
  9574. if (Object.defineProperty)
  9575. Object.defineProperty(Service[method.name], "$options", { "value": method.buildOpt() }),
  9576. Object.defineProperty(ServicePrototype[method.name], "$options", { "value": Service[method.name]["$options"] });
  9577. })(rpc[i]);
  9578. }
  9579. if (Object.defineProperty)
  9580. Object.defineProperty(Service, "$options", { "value": T.buildOpt() }),
  9581. Object.defineProperty(ServicePrototype, "$options", { "value": Service["$options"] }),
  9582. Object.defineProperty(Service, "$type", { "value": T }),
  9583. Object.defineProperty(ServicePrototype, "$type", { "value": T });
  9584. return Service;
  9585. })(ProtoBuf, this);
  9586. };
  9587. /**
  9588. * @alias ProtoBuf.Reflect.Service
  9589. * @expose
  9590. */
  9591. Reflect.Service = Service;
  9592. /**
  9593. * Abstract service method.
  9594. * @exports ProtoBuf.Reflect.Service.Method
  9595. * @param {!ProtoBuf.Builder} builder Builder reference
  9596. * @param {!ProtoBuf.Reflect.Service} svc Service
  9597. * @param {string} name Method name
  9598. * @param {Object.<string,*>=} options Options
  9599. * @constructor
  9600. * @extends ProtoBuf.Reflect.T
  9601. */
  9602. var Method = function(builder, svc, name, options) {
  9603. T.call(this, builder, svc, name);
  9604. /**
  9605. * @override
  9606. */
  9607. this.className = "Service.Method";
  9608. /**
  9609. * Options.
  9610. * @type {Object.<string, *>}
  9611. * @expose
  9612. */
  9613. this.options = options || {};
  9614. };
  9615. /**
  9616. * @alias ProtoBuf.Reflect.Service.Method.prototype
  9617. * @inner
  9618. */
  9619. var MethodPrototype = Method.prototype = Object.create(T.prototype);
  9620. /**
  9621. * Builds the method's '$options' property.
  9622. * @name ProtoBuf.Reflect.Service.Method#buildOpt
  9623. * @function
  9624. * @return {Object.<string,*>}
  9625. */
  9626. MethodPrototype.buildOpt = NamespacePrototype.buildOpt;
  9627. /**
  9628. * @alias ProtoBuf.Reflect.Service.Method
  9629. * @expose
  9630. */
  9631. Reflect.Service.Method = Method;
  9632. /**
  9633. * RPC service method.
  9634. * @exports ProtoBuf.Reflect.Service.RPCMethod
  9635. * @param {!ProtoBuf.Builder} builder Builder reference
  9636. * @param {!ProtoBuf.Reflect.Service} svc Service
  9637. * @param {string} name Method name
  9638. * @param {string} request Request message name
  9639. * @param {string} response Response message name
  9640. * @param {boolean} request_stream Whether requests are streamed
  9641. * @param {boolean} response_stream Whether responses are streamed
  9642. * @param {Object.<string,*>=} options Options
  9643. * @constructor
  9644. * @extends ProtoBuf.Reflect.Service.Method
  9645. */
  9646. var RPCMethod = function(builder, svc, name, request, response, request_stream, response_stream, options) {
  9647. Method.call(this, builder, svc, name, options);
  9648. /**
  9649. * @override
  9650. */
  9651. this.className = "Service.RPCMethod";
  9652. /**
  9653. * Request message name.
  9654. * @type {string}
  9655. * @expose
  9656. */
  9657. this.requestName = request;
  9658. /**
  9659. * Response message name.
  9660. * @type {string}
  9661. * @expose
  9662. */
  9663. this.responseName = response;
  9664. /**
  9665. * Whether requests are streamed
  9666. * @type {bool}
  9667. * @expose
  9668. */
  9669. this.requestStream = request_stream;
  9670. /**
  9671. * Whether responses are streamed
  9672. * @type {bool}
  9673. * @expose
  9674. */
  9675. this.responseStream = response_stream;
  9676. /**
  9677. * Resolved request message type.
  9678. * @type {ProtoBuf.Reflect.Message}
  9679. * @expose
  9680. */
  9681. this.resolvedRequestType = null;
  9682. /**
  9683. * Resolved response message type.
  9684. * @type {ProtoBuf.Reflect.Message}
  9685. * @expose
  9686. */
  9687. this.resolvedResponseType = null;
  9688. };
  9689. // Extends Method
  9690. RPCMethod.prototype = Object.create(Method.prototype);
  9691. /**
  9692. * @alias ProtoBuf.Reflect.Service.RPCMethod
  9693. * @expose
  9694. */
  9695. Reflect.Service.RPCMethod = RPCMethod;
  9696. return Reflect;
  9697. })(ProtoBuf);
  9698. /**
  9699. * @alias ProtoBuf.Builder
  9700. * @expose
  9701. */
  9702. ProtoBuf.Builder = (function(ProtoBuf, Lang, Reflect) {
  9703. /**
  9704. * Constructs a new Builder.
  9705. * @exports ProtoBuf.Builder
  9706. * @class Provides the functionality to build protocol messages.
  9707. * @param {Object.<string,*>=} options Options
  9708. * @constructor
  9709. */
  9710. var Builder = function(options) {
  9711. /**
  9712. * Namespace.
  9713. * @type {ProtoBuf.Reflect.Namespace}
  9714. * @expose
  9715. */
  9716. this.ns = new Reflect.Namespace(this, null, ""); // Global namespace
  9717. /**
  9718. * Namespace pointer.
  9719. * @type {ProtoBuf.Reflect.T}
  9720. * @expose
  9721. */
  9722. this.ptr = this.ns;
  9723. /**
  9724. * Resolved flag.
  9725. * @type {boolean}
  9726. * @expose
  9727. */
  9728. this.resolved = false;
  9729. /**
  9730. * The current building result.
  9731. * @type {Object.<string,ProtoBuf.Builder.Message|Object>|null}
  9732. * @expose
  9733. */
  9734. this.result = null;
  9735. /**
  9736. * Imported files.
  9737. * @type {Array.<string>}
  9738. * @expose
  9739. */
  9740. this.files = {};
  9741. /**
  9742. * Import root override.
  9743. * @type {?string}
  9744. * @expose
  9745. */
  9746. this.importRoot = null;
  9747. /**
  9748. * Options.
  9749. * @type {!Object.<string, *>}
  9750. * @expose
  9751. */
  9752. this.options = options || {};
  9753. };
  9754. /**
  9755. * @alias ProtoBuf.Builder.prototype
  9756. * @inner
  9757. */
  9758. var BuilderPrototype = Builder.prototype;
  9759. // ----- Definition tests -----
  9760. /**
  9761. * Tests if a definition most likely describes a message.
  9762. * @param {!Object} def
  9763. * @returns {boolean}
  9764. * @expose
  9765. */
  9766. Builder.isMessage = function(def) {
  9767. // Messages require a string name
  9768. if (typeof def["name"] !== 'string')
  9769. return false;
  9770. // Messages do not contain values (enum) or rpc methods (service)
  9771. if (typeof def["values"] !== 'undefined' || typeof def["rpc"] !== 'undefined')
  9772. return false;
  9773. return true;
  9774. };
  9775. /**
  9776. * Tests if a definition most likely describes a message field.
  9777. * @param {!Object} def
  9778. * @returns {boolean}
  9779. * @expose
  9780. */
  9781. Builder.isMessageField = function(def) {
  9782. // Message fields require a string rule, name and type and an id
  9783. if (typeof def["rule"] !== 'string' || typeof def["name"] !== 'string' || typeof def["type"] !== 'string' || typeof def["id"] === 'undefined')
  9784. return false;
  9785. return true;
  9786. };
  9787. /**
  9788. * Tests if a definition most likely describes an enum.
  9789. * @param {!Object} def
  9790. * @returns {boolean}
  9791. * @expose
  9792. */
  9793. Builder.isEnum = function(def) {
  9794. // Enums require a string name
  9795. if (typeof def["name"] !== 'string')
  9796. return false;
  9797. // Enums require at least one value
  9798. if (typeof def["values"] === 'undefined' || !Array.isArray(def["values"]) || def["values"].length === 0)
  9799. return false;
  9800. return true;
  9801. };
  9802. /**
  9803. * Tests if a definition most likely describes a service.
  9804. * @param {!Object} def
  9805. * @returns {boolean}
  9806. * @expose
  9807. */
  9808. Builder.isService = function(def) {
  9809. // Services require a string name and an rpc object
  9810. if (typeof def["name"] !== 'string' || typeof def["rpc"] !== 'object' || !def["rpc"])
  9811. return false;
  9812. return true;
  9813. };
  9814. /**
  9815. * Tests if a definition most likely describes an extended message
  9816. * @param {!Object} def
  9817. * @returns {boolean}
  9818. * @expose
  9819. */
  9820. Builder.isExtend = function(def) {
  9821. // Extends rquire a string ref
  9822. if (typeof def["ref"] !== 'string')
  9823. return false;
  9824. return true;
  9825. };
  9826. // ----- Building -----
  9827. /**
  9828. * Resets the pointer to the root namespace.
  9829. * @returns {!ProtoBuf.Builder} this
  9830. * @expose
  9831. */
  9832. BuilderPrototype.reset = function() {
  9833. this.ptr = this.ns;
  9834. return this;
  9835. };
  9836. /**
  9837. * Defines a namespace on top of the current pointer position and places the pointer on it.
  9838. * @param {string} namespace
  9839. * @return {!ProtoBuf.Builder} this
  9840. * @expose
  9841. */
  9842. BuilderPrototype.define = function(namespace) {
  9843. if (typeof namespace !== 'string' || !Lang.TYPEREF.test(namespace))
  9844. throw Error("illegal namespace: "+namespace);
  9845. namespace.split(".").forEach(function(part) {
  9846. var ns = this.ptr.getChild(part);
  9847. if (ns === null) // Keep existing
  9848. this.ptr.addChild(ns = new Reflect.Namespace(this, this.ptr, part));
  9849. this.ptr = ns;
  9850. }, this);
  9851. return this;
  9852. };
  9853. /**
  9854. * Creates the specified definitions at the current pointer position.
  9855. * @param {!Array.<!Object>} defs Messages, enums or services to create
  9856. * @returns {!ProtoBuf.Builder} this
  9857. * @throws {Error} If a message definition is invalid
  9858. * @expose
  9859. */
  9860. BuilderPrototype.create = function(defs) {
  9861. if (!defs)
  9862. return this; // Nothing to create
  9863. if (!Array.isArray(defs))
  9864. defs = [defs];
  9865. else {
  9866. if (defs.length === 0)
  9867. return this;
  9868. defs = defs.slice();
  9869. }
  9870. // It's quite hard to keep track of scopes and memory here, so let's do this iteratively.
  9871. var stack = [defs];
  9872. while (stack.length > 0) {
  9873. defs = stack.pop();
  9874. if (!Array.isArray(defs)) // Stack always contains entire namespaces
  9875. throw Error("not a valid namespace: "+JSON.stringify(defs));
  9876. while (defs.length > 0) {
  9877. var def = defs.shift(); // Namespaces always contain an array of messages, enums and services
  9878. if (Builder.isMessage(def)) {
  9879. var obj = new Reflect.Message(this, this.ptr, def["name"], def["options"], def["isGroup"], def["syntax"]);
  9880. // Create OneOfs
  9881. var oneofs = {};
  9882. if (def["oneofs"])
  9883. Object.keys(def["oneofs"]).forEach(function(name) {
  9884. obj.addChild(oneofs[name] = new Reflect.Message.OneOf(this, obj, name));
  9885. }, this);
  9886. // Create fields
  9887. if (def["fields"])
  9888. def["fields"].forEach(function(fld) {
  9889. if (obj.getChild(fld["id"]|0) !== null)
  9890. throw Error("duplicate or invalid field id in "+obj.name+": "+fld['id']);
  9891. if (fld["options"] && typeof fld["options"] !== 'object')
  9892. throw Error("illegal field options in "+obj.name+"#"+fld["name"]);
  9893. var oneof = null;
  9894. if (typeof fld["oneof"] === 'string' && !(oneof = oneofs[fld["oneof"]]))
  9895. throw Error("illegal oneof in "+obj.name+"#"+fld["name"]+": "+fld["oneof"]);
  9896. fld = new Reflect.Message.Field(this, obj, fld["rule"], fld["keytype"], fld["type"], fld["name"], fld["id"], fld["options"], oneof, def["syntax"]);
  9897. if (oneof)
  9898. oneof.fields.push(fld);
  9899. obj.addChild(fld);
  9900. }, this);
  9901. // Push children to stack
  9902. var subObj = [];
  9903. if (def["enums"])
  9904. def["enums"].forEach(function(enm) {
  9905. subObj.push(enm);
  9906. });
  9907. if (def["messages"])
  9908. def["messages"].forEach(function(msg) {
  9909. subObj.push(msg);
  9910. });
  9911. if (def["services"])
  9912. def["services"].forEach(function(svc) {
  9913. subObj.push(svc);
  9914. });
  9915. // Set extension ranges
  9916. if (def["extensions"]) {
  9917. if (typeof def["extensions"][0] === 'number') // pre 5.0.1
  9918. obj.extensions = [ def["extensions"] ];
  9919. else
  9920. obj.extensions = def["extensions"];
  9921. }
  9922. // Create on top of current namespace
  9923. this.ptr.addChild(obj);
  9924. if (subObj.length > 0) {
  9925. stack.push(defs); // Push the current level back
  9926. defs = subObj; // Continue processing sub level
  9927. subObj = null;
  9928. this.ptr = obj; // And move the pointer to this namespace
  9929. obj = null;
  9930. continue;
  9931. }
  9932. subObj = null;
  9933. } else if (Builder.isEnum(def)) {
  9934. obj = new Reflect.Enum(this, this.ptr, def["name"], def["options"], def["syntax"]);
  9935. def["values"].forEach(function(val) {
  9936. obj.addChild(new Reflect.Enum.Value(this, obj, val["name"], val["id"]));
  9937. }, this);
  9938. this.ptr.addChild(obj);
  9939. } else if (Builder.isService(def)) {
  9940. obj = new Reflect.Service(this, this.ptr, def["name"], def["options"]);
  9941. Object.keys(def["rpc"]).forEach(function(name) {
  9942. var mtd = def["rpc"][name];
  9943. obj.addChild(new Reflect.Service.RPCMethod(this, obj, name, mtd["request"], mtd["response"], !!mtd["request_stream"], !!mtd["response_stream"], mtd["options"]));
  9944. }, this);
  9945. this.ptr.addChild(obj);
  9946. } else if (Builder.isExtend(def)) {
  9947. obj = this.ptr.resolve(def["ref"], true);
  9948. if (obj) {
  9949. def["fields"].forEach(function(fld) {
  9950. if (obj.getChild(fld['id']|0) !== null)
  9951. throw Error("duplicate extended field id in "+obj.name+": "+fld['id']);
  9952. // Check if field id is allowed to be extended
  9953. if (obj.extensions) {
  9954. var valid = false;
  9955. obj.extensions.forEach(function(range) {
  9956. if (fld["id"] >= range[0] && fld["id"] <= range[1])
  9957. valid = true;
  9958. });
  9959. if (!valid)
  9960. throw Error("illegal extended field id in "+obj.name+": "+fld['id']+" (not within valid ranges)");
  9961. }
  9962. // Convert extension field names to camel case notation if the override is set
  9963. var name = fld["name"];
  9964. if (this.options['convertFieldsToCamelCase'])
  9965. name = ProtoBuf.Util.toCamelCase(name);
  9966. // see #161: Extensions use their fully qualified name as their runtime key and...
  9967. var field = new Reflect.Message.ExtensionField(this, obj, fld["rule"], fld["type"], this.ptr.fqn()+'.'+name, fld["id"], fld["options"]);
  9968. // ...are added on top of the current namespace as an extension which is used for
  9969. // resolving their type later on (the extension always keeps the original name to
  9970. // prevent naming collisions)
  9971. var ext = new Reflect.Extension(this, this.ptr, fld["name"], field);
  9972. field.extension = ext;
  9973. this.ptr.addChild(ext);
  9974. obj.addChild(field);
  9975. }, this);
  9976. } else if (!/\.?google\.protobuf\./.test(def["ref"])) // Silently skip internal extensions
  9977. throw Error("extended message "+def["ref"]+" is not defined");
  9978. } else
  9979. throw Error("not a valid definition: "+JSON.stringify(def));
  9980. def = null;
  9981. obj = null;
  9982. }
  9983. // Break goes here
  9984. defs = null;
  9985. this.ptr = this.ptr.parent; // Namespace done, continue at parent
  9986. }
  9987. this.resolved = false; // Require re-resolve
  9988. this.result = null; // Require re-build
  9989. return this;
  9990. };
  9991. /**
  9992. * Propagates syntax to all children.
  9993. * @param {!Object} parent
  9994. * @inner
  9995. */
  9996. function propagateSyntax(parent) {
  9997. if (parent['messages']) {
  9998. parent['messages'].forEach(function(child) {
  9999. child["syntax"] = parent["syntax"];
  10000. propagateSyntax(child);
  10001. });
  10002. }
  10003. if (parent['enums']) {
  10004. parent['enums'].forEach(function(child) {
  10005. child["syntax"] = parent["syntax"];
  10006. });
  10007. }
  10008. }
  10009. /**
  10010. * Imports another definition into this builder.
  10011. * @param {Object.<string,*>} json Parsed import
  10012. * @param {(string|{root: string, file: string})=} filename Imported file name
  10013. * @returns {!ProtoBuf.Builder} this
  10014. * @throws {Error} If the definition or file cannot be imported
  10015. * @expose
  10016. */
  10017. BuilderPrototype["import"] = function(json, filename) {
  10018. var delim = '/';
  10019. // Make sure to skip duplicate imports
  10020. if (typeof filename === 'string') {
  10021. if (ProtoBuf.Util.IS_NODE)
  10022. filename = require$$2['resolve'](filename);
  10023. if (this.files[filename] === true)
  10024. return this.reset();
  10025. this.files[filename] = true;
  10026. } else if (typeof filename === 'object') { // Object with root, file.
  10027. var root = filename.root;
  10028. if (ProtoBuf.Util.IS_NODE)
  10029. root = require$$2['resolve'](root);
  10030. if (root.indexOf("\\") >= 0 || filename.file.indexOf("\\") >= 0)
  10031. delim = '\\';
  10032. var fname;
  10033. if (ProtoBuf.Util.IS_NODE)
  10034. fname = require$$2['join'](root, filename.file);
  10035. else
  10036. fname = root + delim + filename.file;
  10037. if (this.files[fname] === true)
  10038. return this.reset();
  10039. this.files[fname] = true;
  10040. }
  10041. // Import imports
  10042. if (json['imports'] && json['imports'].length > 0) {
  10043. var importRoot,
  10044. resetRoot = false;
  10045. if (typeof filename === 'object') { // If an import root is specified, override
  10046. this.importRoot = filename["root"]; resetRoot = true; // ... and reset afterwards
  10047. importRoot = this.importRoot;
  10048. filename = filename["file"];
  10049. if (importRoot.indexOf("\\") >= 0 || filename.indexOf("\\") >= 0)
  10050. delim = '\\';
  10051. } else if (typeof filename === 'string') {
  10052. if (this.importRoot) // If import root is overridden, use it
  10053. importRoot = this.importRoot;
  10054. else { // Otherwise compute from filename
  10055. if (filename.indexOf("/") >= 0) { // Unix
  10056. importRoot = filename.replace(/\/[^\/]*$/, "");
  10057. if (/* /file.proto */ importRoot === "")
  10058. importRoot = "/";
  10059. } else if (filename.indexOf("\\") >= 0) { // Windows
  10060. importRoot = filename.replace(/\\[^\\]*$/, "");
  10061. delim = '\\';
  10062. } else
  10063. importRoot = ".";
  10064. }
  10065. } else
  10066. importRoot = null;
  10067. for (var i=0; i<json['imports'].length; i++) {
  10068. if (typeof json['imports'][i] === 'string') { // Import file
  10069. if (!importRoot)
  10070. throw Error("cannot determine import root");
  10071. var importFilename = json['imports'][i];
  10072. if (importFilename === "google/protobuf/descriptor.proto")
  10073. continue; // Not needed and therefore not used
  10074. if (ProtoBuf.Util.IS_NODE)
  10075. importFilename = require$$2['join'](importRoot, importFilename);
  10076. else
  10077. importFilename = importRoot + delim + importFilename;
  10078. if (this.files[importFilename] === true)
  10079. continue; // Already imported
  10080. if (/\.proto$/i.test(importFilename) && !ProtoBuf.DotProto) // If this is a light build
  10081. importFilename = importFilename.replace(/\.proto$/, ".json"); // always load the JSON file
  10082. var contents = ProtoBuf.Util.fetch(importFilename);
  10083. if (contents === null)
  10084. throw Error("failed to import '"+importFilename+"' in '"+filename+"': file not found");
  10085. if (/\.json$/i.test(importFilename)) // Always possible
  10086. this["import"](JSON.parse(contents+""), importFilename); // May throw
  10087. else
  10088. this["import"](ProtoBuf.DotProto.Parser.parse(contents), importFilename); // May throw
  10089. } else // Import structure
  10090. if (!filename)
  10091. this["import"](json['imports'][i]);
  10092. else if (/\.(\w+)$/.test(filename)) // With extension: Append _importN to the name portion to make it unique
  10093. this["import"](json['imports'][i], filename.replace(/^(.+)\.(\w+)$/, function($0, $1, $2) { return $1+"_import"+i+"."+$2; }));
  10094. else // Without extension: Append _importN to make it unique
  10095. this["import"](json['imports'][i], filename+"_import"+i);
  10096. }
  10097. if (resetRoot) // Reset import root override when all imports are done
  10098. this.importRoot = null;
  10099. }
  10100. // Import structures
  10101. if (json['package'])
  10102. this.define(json['package']);
  10103. if (json['syntax'])
  10104. propagateSyntax(json);
  10105. var base = this.ptr;
  10106. if (json['options'])
  10107. Object.keys(json['options']).forEach(function(key) {
  10108. base.options[key] = json['options'][key];
  10109. });
  10110. if (json['messages'])
  10111. this.create(json['messages']),
  10112. this.ptr = base;
  10113. if (json['enums'])
  10114. this.create(json['enums']),
  10115. this.ptr = base;
  10116. if (json['services'])
  10117. this.create(json['services']),
  10118. this.ptr = base;
  10119. if (json['extends'])
  10120. this.create(json['extends']);
  10121. return this.reset();
  10122. };
  10123. /**
  10124. * Resolves all namespace objects.
  10125. * @throws {Error} If a type cannot be resolved
  10126. * @returns {!ProtoBuf.Builder} this
  10127. * @expose
  10128. */
  10129. BuilderPrototype.resolveAll = function() {
  10130. // Resolve all reflected objects
  10131. var res;
  10132. if (this.ptr == null || typeof this.ptr.type === 'object')
  10133. return this; // Done (already resolved)
  10134. if (this.ptr instanceof Reflect.Namespace) { // Resolve children
  10135. this.ptr.children.forEach(function(child) {
  10136. this.ptr = child;
  10137. this.resolveAll();
  10138. }, this);
  10139. } else if (this.ptr instanceof Reflect.Message.Field) { // Resolve type
  10140. if (!Lang.TYPE.test(this.ptr.type)) {
  10141. if (!Lang.TYPEREF.test(this.ptr.type))
  10142. throw Error("illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.type);
  10143. res = (this.ptr instanceof Reflect.Message.ExtensionField ? this.ptr.extension.parent : this.ptr.parent).resolve(this.ptr.type, true);
  10144. if (!res)
  10145. throw Error("unresolvable type reference in "+this.ptr.toString(true)+": "+this.ptr.type);
  10146. this.ptr.resolvedType = res;
  10147. if (res instanceof Reflect.Enum) {
  10148. this.ptr.type = ProtoBuf.TYPES["enum"];
  10149. if (this.ptr.syntax === 'proto3' && res.syntax !== 'proto3')
  10150. throw Error("proto3 message cannot reference proto2 enum");
  10151. }
  10152. else if (res instanceof Reflect.Message)
  10153. this.ptr.type = res.isGroup ? ProtoBuf.TYPES["group"] : ProtoBuf.TYPES["message"];
  10154. else
  10155. throw Error("illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.type);
  10156. } else
  10157. this.ptr.type = ProtoBuf.TYPES[this.ptr.type];
  10158. // If it's a map field, also resolve the key type. The key type can be only a numeric, string, or bool type
  10159. // (i.e., no enums or messages), so we don't need to resolve against the current namespace.
  10160. if (this.ptr.map) {
  10161. if (!Lang.TYPE.test(this.ptr.keyType))
  10162. throw Error("illegal key type for map field in "+this.ptr.toString(true)+": "+this.ptr.keyType);
  10163. this.ptr.keyType = ProtoBuf.TYPES[this.ptr.keyType];
  10164. }
  10165. // If it's a repeated and packable field then proto3 mandates it should be packed by
  10166. // default
  10167. if (
  10168. this.ptr.syntax === 'proto3' &&
  10169. this.ptr.repeated && this.ptr.options.packed === undefined &&
  10170. ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.ptr.type.wireType) !== -1
  10171. ) {
  10172. this.ptr.options.packed = true;
  10173. }
  10174. } else if (this.ptr instanceof ProtoBuf.Reflect.Service.Method) {
  10175. if (this.ptr instanceof ProtoBuf.Reflect.Service.RPCMethod) {
  10176. res = this.ptr.parent.resolve(this.ptr.requestName, true);
  10177. if (!res || !(res instanceof ProtoBuf.Reflect.Message))
  10178. throw Error("Illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.requestName);
  10179. this.ptr.resolvedRequestType = res;
  10180. res = this.ptr.parent.resolve(this.ptr.responseName, true);
  10181. if (!res || !(res instanceof ProtoBuf.Reflect.Message))
  10182. throw Error("Illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.responseName);
  10183. this.ptr.resolvedResponseType = res;
  10184. } else // Should not happen as nothing else is implemented
  10185. throw Error("illegal service type in "+this.ptr.toString(true));
  10186. } else if (
  10187. !(this.ptr instanceof ProtoBuf.Reflect.Message.OneOf) && // Not built
  10188. !(this.ptr instanceof ProtoBuf.Reflect.Extension) && // Not built
  10189. !(this.ptr instanceof ProtoBuf.Reflect.Enum.Value) // Built in enum
  10190. )
  10191. throw Error("illegal object in namespace: "+typeof(this.ptr)+": "+this.ptr);
  10192. return this.reset();
  10193. };
  10194. /**
  10195. * Builds the protocol. This will first try to resolve all definitions and, if this has been successful,
  10196. * return the built package.
  10197. * @param {(string|Array.<string>)=} path Specifies what to return. If omitted, the entire namespace will be returned.
  10198. * @returns {!ProtoBuf.Builder.Message|!Object.<string,*>}
  10199. * @throws {Error} If a type could not be resolved
  10200. * @expose
  10201. */
  10202. BuilderPrototype.build = function(path) {
  10203. this.reset();
  10204. if (!this.resolved)
  10205. this.resolveAll(),
  10206. this.resolved = true,
  10207. this.result = null; // Require re-build
  10208. if (this.result === null) // (Re-)Build
  10209. this.result = this.ns.build();
  10210. if (!path)
  10211. return this.result;
  10212. var part = typeof path === 'string' ? path.split(".") : path,
  10213. ptr = this.result; // Build namespace pointer (no hasChild etc.)
  10214. for (var i=0; i<part.length; i++)
  10215. if (ptr[part[i]])
  10216. ptr = ptr[part[i]];
  10217. else {
  10218. ptr = null;
  10219. break;
  10220. }
  10221. return ptr;
  10222. };
  10223. /**
  10224. * Similar to {@link ProtoBuf.Builder#build}, but looks up the internal reflection descriptor.
  10225. * @param {string=} path Specifies what to return. If omitted, the entire namespace wiil be returned.
  10226. * @param {boolean=} excludeNonNamespace Excludes non-namespace types like fields, defaults to `false`
  10227. * @returns {?ProtoBuf.Reflect.T} Reflection descriptor or `null` if not found
  10228. */
  10229. BuilderPrototype.lookup = function(path, excludeNonNamespace) {
  10230. return path ? this.ns.resolve(path, excludeNonNamespace) : this.ns;
  10231. };
  10232. /**
  10233. * Returns a string representation of this object.
  10234. * @return {string} String representation as of "Builder"
  10235. * @expose
  10236. */
  10237. BuilderPrototype.toString = function() {
  10238. return "Builder";
  10239. };
  10240. // ----- Base classes -----
  10241. // Exist for the sole purpose of being able to "... instanceof ProtoBuf.Builder.Message" etc.
  10242. /**
  10243. * @alias ProtoBuf.Builder.Message
  10244. */
  10245. Builder.Message = function() {};
  10246. /**
  10247. * @alias ProtoBuf.Builder.Enum
  10248. */
  10249. Builder.Enum = function() {};
  10250. /**
  10251. * @alias ProtoBuf.Builder.Message
  10252. */
  10253. Builder.Service = function() {};
  10254. return Builder;
  10255. })(ProtoBuf, ProtoBuf.Lang, ProtoBuf.Reflect);
  10256. /**
  10257. * @alias ProtoBuf.Map
  10258. * @expose
  10259. */
  10260. ProtoBuf.Map = (function(ProtoBuf, Reflect) {
  10261. /**
  10262. * Constructs a new Map. A Map is a container that is used to implement map
  10263. * fields on message objects. It closely follows the ES6 Map API; however,
  10264. * it is distinct because we do not want to depend on external polyfills or
  10265. * on ES6 itself.
  10266. *
  10267. * @exports ProtoBuf.Map
  10268. * @param {!ProtoBuf.Reflect.Field} field Map field
  10269. * @param {Object.<string,*>=} contents Initial contents
  10270. * @constructor
  10271. */
  10272. var Map = function(field, contents) {
  10273. if (!field.map)
  10274. throw Error("field is not a map");
  10275. /**
  10276. * The field corresponding to this map.
  10277. * @type {!ProtoBuf.Reflect.Field}
  10278. */
  10279. this.field = field;
  10280. /**
  10281. * Element instance corresponding to key type.
  10282. * @type {!ProtoBuf.Reflect.Element}
  10283. */
  10284. this.keyElem = new Reflect.Element(field.keyType, null, true, field.syntax);
  10285. /**
  10286. * Element instance corresponding to value type.
  10287. * @type {!ProtoBuf.Reflect.Element}
  10288. */
  10289. this.valueElem = new Reflect.Element(field.type, field.resolvedType, false, field.syntax);
  10290. /**
  10291. * Internal map: stores mapping of (string form of key) -> (key, value)
  10292. * pair.
  10293. *
  10294. * We provide map semantics for arbitrary key types, but we build on top
  10295. * of an Object, which has only string keys. In order to avoid the need
  10296. * to convert a string key back to its native type in many situations,
  10297. * we store the native key value alongside the value. Thus, we only need
  10298. * a one-way mapping from a key type to its string form that guarantees
  10299. * uniqueness and equality (i.e., str(K1) === str(K2) if and only if K1
  10300. * === K2).
  10301. *
  10302. * @type {!Object<string, {key: *, value: *}>}
  10303. */
  10304. this.map = {};
  10305. /**
  10306. * Returns the number of elements in the map.
  10307. */
  10308. Object.defineProperty(this, "size", {
  10309. get: function() { return Object.keys(this.map).length; }
  10310. });
  10311. // Fill initial contents from a raw object.
  10312. if (contents) {
  10313. var keys = Object.keys(contents);
  10314. for (var i = 0; i < keys.length; i++) {
  10315. var key = this.keyElem.valueFromString(keys[i]);
  10316. var val = this.valueElem.verifyValue(contents[keys[i]]);
  10317. this.map[this.keyElem.valueToString(key)] =
  10318. { key: key, value: val };
  10319. }
  10320. }
  10321. };
  10322. var MapPrototype = Map.prototype;
  10323. /**
  10324. * Helper: return an iterator over an array.
  10325. * @param {!Array<*>} arr the array
  10326. * @returns {!Object} an iterator
  10327. * @inner
  10328. */
  10329. function arrayIterator(arr) {
  10330. var idx = 0;
  10331. return {
  10332. next: function() {
  10333. if (idx < arr.length)
  10334. return { done: false, value: arr[idx++] };
  10335. return { done: true };
  10336. }
  10337. }
  10338. }
  10339. /**
  10340. * Clears the map.
  10341. */
  10342. MapPrototype.clear = function() {
  10343. this.map = {};
  10344. };
  10345. /**
  10346. * Deletes a particular key from the map.
  10347. * @returns {boolean} Whether any entry with this key was deleted.
  10348. */
  10349. MapPrototype["delete"] = function(key) {
  10350. var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));
  10351. var hadKey = keyValue in this.map;
  10352. delete this.map[keyValue];
  10353. return hadKey;
  10354. };
  10355. /**
  10356. * Returns an iterator over [key, value] pairs in the map.
  10357. * @returns {Object} The iterator
  10358. */
  10359. MapPrototype.entries = function() {
  10360. var entries = [];
  10361. var strKeys = Object.keys(this.map);
  10362. for (var i = 0, entry; i < strKeys.length; i++)
  10363. entries.push([(entry=this.map[strKeys[i]]).key, entry.value]);
  10364. return arrayIterator(entries);
  10365. };
  10366. /**
  10367. * Returns an iterator over keys in the map.
  10368. * @returns {Object} The iterator
  10369. */
  10370. MapPrototype.keys = function() {
  10371. var keys = [];
  10372. var strKeys = Object.keys(this.map);
  10373. for (var i = 0; i < strKeys.length; i++)
  10374. keys.push(this.map[strKeys[i]].key);
  10375. return arrayIterator(keys);
  10376. };
  10377. /**
  10378. * Returns an iterator over values in the map.
  10379. * @returns {!Object} The iterator
  10380. */
  10381. MapPrototype.values = function() {
  10382. var values = [];
  10383. var strKeys = Object.keys(this.map);
  10384. for (var i = 0; i < strKeys.length; i++)
  10385. values.push(this.map[strKeys[i]].value);
  10386. return arrayIterator(values);
  10387. };
  10388. /**
  10389. * Iterates over entries in the map, calling a function on each.
  10390. * @param {function(this:*, *, *, *)} cb The callback to invoke with value, key, and map arguments.
  10391. * @param {Object=} thisArg The `this` value for the callback
  10392. */
  10393. MapPrototype.forEach = function(cb, thisArg) {
  10394. var strKeys = Object.keys(this.map);
  10395. for (var i = 0, entry; i < strKeys.length; i++)
  10396. cb.call(thisArg, (entry=this.map[strKeys[i]]).value, entry.key, this);
  10397. };
  10398. /**
  10399. * Sets a key in the map to the given value.
  10400. * @param {*} key The key
  10401. * @param {*} value The value
  10402. * @returns {!ProtoBuf.Map} The map instance
  10403. */
  10404. MapPrototype.set = function(key, value) {
  10405. var keyValue = this.keyElem.verifyValue(key);
  10406. var valValue = this.valueElem.verifyValue(value);
  10407. this.map[this.keyElem.valueToString(keyValue)] =
  10408. { key: keyValue, value: valValue };
  10409. return this;
  10410. };
  10411. /**
  10412. * Gets the value corresponding to a key in the map.
  10413. * @param {*} key The key
  10414. * @returns {*|undefined} The value, or `undefined` if key not present
  10415. */
  10416. MapPrototype.get = function(key) {
  10417. var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));
  10418. if (!(keyValue in this.map))
  10419. return undefined;
  10420. return this.map[keyValue].value;
  10421. };
  10422. /**
  10423. * Determines whether the given key is present in the map.
  10424. * @param {*} key The key
  10425. * @returns {boolean} `true` if the key is present
  10426. */
  10427. MapPrototype.has = function(key) {
  10428. var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));
  10429. return (keyValue in this.map);
  10430. };
  10431. return Map;
  10432. })(ProtoBuf, ProtoBuf.Reflect);
  10433. /**
  10434. * Constructs a new empty Builder.
  10435. * @param {Object.<string,*>=} options Builder options, defaults to global options set on ProtoBuf
  10436. * @return {!ProtoBuf.Builder} Builder
  10437. * @expose
  10438. */
  10439. ProtoBuf.newBuilder = function(options) {
  10440. options = options || {};
  10441. if (typeof options['convertFieldsToCamelCase'] === 'undefined')
  10442. options['convertFieldsToCamelCase'] = ProtoBuf.convertFieldsToCamelCase;
  10443. if (typeof options['populateAccessors'] === 'undefined')
  10444. options['populateAccessors'] = ProtoBuf.populateAccessors;
  10445. return new ProtoBuf.Builder(options);
  10446. };
  10447. /**
  10448. * Loads a .json definition and returns the Builder.
  10449. * @param {!*|string} json JSON definition
  10450. * @param {(ProtoBuf.Builder|string|{root: string, file: string})=} builder Builder to append to. Will create a new one if omitted.
  10451. * @param {(string|{root: string, file: string})=} filename The corresponding file name if known. Must be specified for imports.
  10452. * @return {ProtoBuf.Builder} Builder to create new messages
  10453. * @throws {Error} If the definition cannot be parsed or built
  10454. * @expose
  10455. */
  10456. ProtoBuf.loadJson = function(json, builder, filename) {
  10457. if (typeof builder === 'string' || (builder && typeof builder["file"] === 'string' && typeof builder["root"] === 'string'))
  10458. filename = builder,
  10459. builder = null;
  10460. if (!builder || typeof builder !== 'object')
  10461. builder = ProtoBuf.newBuilder();
  10462. if (typeof json === 'string')
  10463. json = JSON.parse(json);
  10464. builder["import"](json, filename);
  10465. builder.resolveAll();
  10466. return builder;
  10467. };
  10468. /**
  10469. * Loads a .json file and returns the Builder.
  10470. * @param {string|!{root: string, file: string}} filename Path to json file or an object specifying 'file' with
  10471. * an overridden 'root' path for all imported files.
  10472. * @param {function(?Error, !ProtoBuf.Builder=)=} callback Callback that will receive `null` as the first and
  10473. * the Builder as its second argument on success, otherwise the error as its first argument. If omitted, the
  10474. * file will be read synchronously and this function will return the Builder.
  10475. * @param {ProtoBuf.Builder=} builder Builder to append to. Will create a new one if omitted.
  10476. * @return {?ProtoBuf.Builder|undefined} The Builder if synchronous (no callback specified, will be NULL if the
  10477. * request has failed), else undefined
  10478. * @expose
  10479. */
  10480. ProtoBuf.loadJsonFile = function(filename, callback, builder) {
  10481. if (callback && typeof callback === 'object')
  10482. builder = callback,
  10483. callback = null;
  10484. else if (!callback || typeof callback !== 'function')
  10485. callback = null;
  10486. if (callback)
  10487. return ProtoBuf.Util.fetch(typeof filename === 'string' ? filename : filename["root"]+"/"+filename["file"], function(contents) {
  10488. if (contents === null) {
  10489. callback(Error("Failed to fetch file"));
  10490. return;
  10491. }
  10492. try {
  10493. callback(null, ProtoBuf.loadJson(JSON.parse(contents), builder, filename));
  10494. } catch (e) {
  10495. callback(e);
  10496. }
  10497. });
  10498. var contents = ProtoBuf.Util.fetch(typeof filename === 'object' ? filename["root"]+"/"+filename["file"] : filename);
  10499. return contents === null ? null : ProtoBuf.loadJson(JSON.parse(contents), builder, filename);
  10500. };
  10501. return ProtoBuf;
  10502. });
  10503. });
  10504. var messageCompiled = protobufLight.newBuilder({})['import']({
  10505. package: 'push_server.messages2',
  10506. syntax: 'proto2',
  10507. options: {
  10508. objc_class_prefix: 'AVIM'
  10509. },
  10510. messages: [{
  10511. name: 'JsonObjectMessage',
  10512. syntax: 'proto2',
  10513. fields: [{
  10514. rule: 'required',
  10515. type: 'string',
  10516. name: 'data',
  10517. id: 1
  10518. }]
  10519. }, {
  10520. name: 'UnreadTuple',
  10521. syntax: 'proto2',
  10522. fields: [{
  10523. rule: 'required',
  10524. type: 'string',
  10525. name: 'cid',
  10526. id: 1
  10527. }, {
  10528. rule: 'required',
  10529. type: 'int32',
  10530. name: 'unread',
  10531. id: 2
  10532. }, {
  10533. rule: 'optional',
  10534. type: 'string',
  10535. name: 'mid',
  10536. id: 3
  10537. }, {
  10538. rule: 'optional',
  10539. type: 'int64',
  10540. name: 'timestamp',
  10541. id: 4
  10542. }, {
  10543. rule: 'optional',
  10544. type: 'string',
  10545. name: 'from',
  10546. id: 5
  10547. }, {
  10548. rule: 'optional',
  10549. type: 'string',
  10550. name: 'data',
  10551. id: 6
  10552. }, {
  10553. rule: 'optional',
  10554. type: 'int64',
  10555. name: 'patchTimestamp',
  10556. id: 7
  10557. }, {
  10558. rule: 'optional',
  10559. type: 'bool',
  10560. name: 'mentioned',
  10561. id: 8
  10562. }, {
  10563. rule: 'optional',
  10564. type: 'bytes',
  10565. name: 'binaryMsg',
  10566. id: 9
  10567. }, {
  10568. rule: 'optional',
  10569. type: 'int32',
  10570. name: 'convType',
  10571. id: 10
  10572. }]
  10573. }, {
  10574. name: 'LogItem',
  10575. syntax: 'proto2',
  10576. fields: [{
  10577. rule: 'optional',
  10578. type: 'string',
  10579. name: 'from',
  10580. id: 1
  10581. }, {
  10582. rule: 'optional',
  10583. type: 'string',
  10584. name: 'data',
  10585. id: 2
  10586. }, {
  10587. rule: 'optional',
  10588. type: 'int64',
  10589. name: 'timestamp',
  10590. id: 3
  10591. }, {
  10592. rule: 'optional',
  10593. type: 'string',
  10594. name: 'msgId',
  10595. id: 4
  10596. }, {
  10597. rule: 'optional',
  10598. type: 'int64',
  10599. name: 'ackAt',
  10600. id: 5
  10601. }, {
  10602. rule: 'optional',
  10603. type: 'int64',
  10604. name: 'readAt',
  10605. id: 6
  10606. }, {
  10607. rule: 'optional',
  10608. type: 'int64',
  10609. name: 'patchTimestamp',
  10610. id: 7
  10611. }, {
  10612. rule: 'optional',
  10613. type: 'bool',
  10614. name: 'mentionAll',
  10615. id: 8
  10616. }, {
  10617. rule: 'repeated',
  10618. type: 'string',
  10619. name: 'mentionPids',
  10620. id: 9
  10621. }, {
  10622. rule: 'optional',
  10623. type: 'bool',
  10624. name: 'bin',
  10625. id: 10
  10626. }, {
  10627. rule: 'optional',
  10628. type: 'int32',
  10629. name: 'convType',
  10630. id: 11
  10631. }]
  10632. }, {
  10633. name: 'ConvMemberInfo',
  10634. syntax: 'proto2',
  10635. fields: [{
  10636. rule: 'optional',
  10637. type: 'string',
  10638. name: 'pid',
  10639. id: 1
  10640. }, {
  10641. rule: 'optional',
  10642. type: 'string',
  10643. name: 'role',
  10644. id: 2
  10645. }, {
  10646. rule: 'optional',
  10647. type: 'string',
  10648. name: 'infoId',
  10649. id: 3
  10650. }]
  10651. }, {
  10652. name: 'DataCommand',
  10653. syntax: 'proto2',
  10654. fields: [{
  10655. rule: 'repeated',
  10656. type: 'string',
  10657. name: 'ids',
  10658. id: 1
  10659. }, {
  10660. rule: 'repeated',
  10661. type: 'JsonObjectMessage',
  10662. name: 'msg',
  10663. id: 2
  10664. }, {
  10665. rule: 'optional',
  10666. type: 'bool',
  10667. name: 'offline',
  10668. id: 3
  10669. }]
  10670. }, {
  10671. name: 'SessionCommand',
  10672. syntax: 'proto2',
  10673. fields: [{
  10674. rule: 'optional',
  10675. type: 'int64',
  10676. name: 't',
  10677. id: 1
  10678. }, {
  10679. rule: 'optional',
  10680. type: 'string',
  10681. name: 'n',
  10682. id: 2
  10683. }, {
  10684. rule: 'optional',
  10685. type: 'string',
  10686. name: 's',
  10687. id: 3
  10688. }, {
  10689. rule: 'optional',
  10690. type: 'string',
  10691. name: 'ua',
  10692. id: 4
  10693. }, {
  10694. rule: 'optional',
  10695. type: 'bool',
  10696. name: 'r',
  10697. id: 5
  10698. }, {
  10699. rule: 'optional',
  10700. type: 'string',
  10701. name: 'tag',
  10702. id: 6
  10703. }, {
  10704. rule: 'optional',
  10705. type: 'string',
  10706. name: 'deviceId',
  10707. id: 7
  10708. }, {
  10709. rule: 'repeated',
  10710. type: 'string',
  10711. name: 'sessionPeerIds',
  10712. id: 8
  10713. }, {
  10714. rule: 'repeated',
  10715. type: 'string',
  10716. name: 'onlineSessionPeerIds',
  10717. id: 9
  10718. }, {
  10719. rule: 'optional',
  10720. type: 'string',
  10721. name: 'st',
  10722. id: 10
  10723. }, {
  10724. rule: 'optional',
  10725. type: 'int32',
  10726. name: 'stTtl',
  10727. id: 11
  10728. }, {
  10729. rule: 'optional',
  10730. type: 'int32',
  10731. name: 'code',
  10732. id: 12
  10733. }, {
  10734. rule: 'optional',
  10735. type: 'string',
  10736. name: 'reason',
  10737. id: 13
  10738. }, {
  10739. rule: 'optional',
  10740. type: 'string',
  10741. name: 'deviceToken',
  10742. id: 14
  10743. }, {
  10744. rule: 'optional',
  10745. type: 'bool',
  10746. name: 'sp',
  10747. id: 15
  10748. }, {
  10749. rule: 'optional',
  10750. type: 'string',
  10751. name: 'detail',
  10752. id: 16
  10753. }, {
  10754. rule: 'optional',
  10755. type: 'int64',
  10756. name: 'lastUnreadNotifTime',
  10757. id: 17
  10758. }, {
  10759. rule: 'optional',
  10760. type: 'int64',
  10761. name: 'lastPatchTime',
  10762. id: 18
  10763. }, {
  10764. rule: 'optional',
  10765. type: 'int64',
  10766. name: 'configBitmap',
  10767. id: 19
  10768. }]
  10769. }, {
  10770. name: 'ErrorCommand',
  10771. syntax: 'proto2',
  10772. fields: [{
  10773. rule: 'required',
  10774. type: 'int32',
  10775. name: 'code',
  10776. id: 1
  10777. }, {
  10778. rule: 'required',
  10779. type: 'string',
  10780. name: 'reason',
  10781. id: 2
  10782. }, {
  10783. rule: 'optional',
  10784. type: 'int32',
  10785. name: 'appCode',
  10786. id: 3
  10787. }, {
  10788. rule: 'optional',
  10789. type: 'string',
  10790. name: 'detail',
  10791. id: 4
  10792. }, {
  10793. rule: 'repeated',
  10794. type: 'string',
  10795. name: 'pids',
  10796. id: 5
  10797. }, {
  10798. rule: 'optional',
  10799. type: 'string',
  10800. name: 'appMsg',
  10801. id: 6
  10802. }]
  10803. }, {
  10804. name: 'DirectCommand',
  10805. syntax: 'proto2',
  10806. fields: [{
  10807. rule: 'optional',
  10808. type: 'string',
  10809. name: 'msg',
  10810. id: 1
  10811. }, {
  10812. rule: 'optional',
  10813. type: 'string',
  10814. name: 'uid',
  10815. id: 2
  10816. }, {
  10817. rule: 'optional',
  10818. type: 'string',
  10819. name: 'fromPeerId',
  10820. id: 3
  10821. }, {
  10822. rule: 'optional',
  10823. type: 'int64',
  10824. name: 'timestamp',
  10825. id: 4
  10826. }, {
  10827. rule: 'optional',
  10828. type: 'bool',
  10829. name: 'offline',
  10830. id: 5
  10831. }, {
  10832. rule: 'optional',
  10833. type: 'bool',
  10834. name: 'hasMore',
  10835. id: 6
  10836. }, {
  10837. rule: 'repeated',
  10838. type: 'string',
  10839. name: 'toPeerIds',
  10840. id: 7
  10841. }, {
  10842. rule: 'optional',
  10843. type: 'bool',
  10844. name: 'r',
  10845. id: 10
  10846. }, {
  10847. rule: 'optional',
  10848. type: 'string',
  10849. name: 'cid',
  10850. id: 11
  10851. }, {
  10852. rule: 'optional',
  10853. type: 'string',
  10854. name: 'id',
  10855. id: 12
  10856. }, {
  10857. rule: 'optional',
  10858. type: 'bool',
  10859. name: 'transient',
  10860. id: 13
  10861. }, {
  10862. rule: 'optional',
  10863. type: 'string',
  10864. name: 'dt',
  10865. id: 14
  10866. }, {
  10867. rule: 'optional',
  10868. type: 'string',
  10869. name: 'roomId',
  10870. id: 15
  10871. }, {
  10872. rule: 'optional',
  10873. type: 'string',
  10874. name: 'pushData',
  10875. id: 16
  10876. }, {
  10877. rule: 'optional',
  10878. type: 'bool',
  10879. name: 'will',
  10880. id: 17
  10881. }, {
  10882. rule: 'optional',
  10883. type: 'int64',
  10884. name: 'patchTimestamp',
  10885. id: 18
  10886. }, {
  10887. rule: 'optional',
  10888. type: 'bytes',
  10889. name: 'binaryMsg',
  10890. id: 19
  10891. }, {
  10892. rule: 'repeated',
  10893. type: 'string',
  10894. name: 'mentionPids',
  10895. id: 20
  10896. }, {
  10897. rule: 'optional',
  10898. type: 'bool',
  10899. name: 'mentionAll',
  10900. id: 21
  10901. }, {
  10902. rule: 'optional',
  10903. type: 'int32',
  10904. name: 'convType',
  10905. id: 22
  10906. }]
  10907. }, {
  10908. name: 'AckCommand',
  10909. syntax: 'proto2',
  10910. fields: [{
  10911. rule: 'optional',
  10912. type: 'int32',
  10913. name: 'code',
  10914. id: 1
  10915. }, {
  10916. rule: 'optional',
  10917. type: 'string',
  10918. name: 'reason',
  10919. id: 2
  10920. }, {
  10921. rule: 'optional',
  10922. type: 'string',
  10923. name: 'mid',
  10924. id: 3
  10925. }, {
  10926. rule: 'optional',
  10927. type: 'string',
  10928. name: 'cid',
  10929. id: 4
  10930. }, {
  10931. rule: 'optional',
  10932. type: 'int64',
  10933. name: 't',
  10934. id: 5
  10935. }, {
  10936. rule: 'optional',
  10937. type: 'string',
  10938. name: 'uid',
  10939. id: 6
  10940. }, {
  10941. rule: 'optional',
  10942. type: 'int64',
  10943. name: 'fromts',
  10944. id: 7
  10945. }, {
  10946. rule: 'optional',
  10947. type: 'int64',
  10948. name: 'tots',
  10949. id: 8
  10950. }, {
  10951. rule: 'optional',
  10952. type: 'string',
  10953. name: 'type',
  10954. id: 9
  10955. }, {
  10956. rule: 'repeated',
  10957. type: 'string',
  10958. name: 'ids',
  10959. id: 10
  10960. }, {
  10961. rule: 'optional',
  10962. type: 'int32',
  10963. name: 'appCode',
  10964. id: 11
  10965. }, {
  10966. rule: 'optional',
  10967. type: 'string',
  10968. name: 'appMsg',
  10969. id: 12
  10970. }]
  10971. }, {
  10972. name: 'UnreadCommand',
  10973. syntax: 'proto2',
  10974. fields: [{
  10975. rule: 'repeated',
  10976. type: 'UnreadTuple',
  10977. name: 'convs',
  10978. id: 1
  10979. }, {
  10980. rule: 'optional',
  10981. type: 'int64',
  10982. name: 'notifTime',
  10983. id: 2
  10984. }]
  10985. }, {
  10986. name: 'ConvCommand',
  10987. syntax: 'proto2',
  10988. fields: [{
  10989. rule: 'repeated',
  10990. type: 'string',
  10991. name: 'm',
  10992. id: 1
  10993. }, {
  10994. rule: 'optional',
  10995. type: 'bool',
  10996. name: 'transient',
  10997. id: 2
  10998. }, {
  10999. rule: 'optional',
  11000. type: 'bool',
  11001. name: 'unique',
  11002. id: 3
  11003. }, {
  11004. rule: 'optional',
  11005. type: 'string',
  11006. name: 'cid',
  11007. id: 4
  11008. }, {
  11009. rule: 'optional',
  11010. type: 'string',
  11011. name: 'cdate',
  11012. id: 5
  11013. }, {
  11014. rule: 'optional',
  11015. type: 'string',
  11016. name: 'initBy',
  11017. id: 6
  11018. }, {
  11019. rule: 'optional',
  11020. type: 'string',
  11021. name: 'sort',
  11022. id: 7
  11023. }, {
  11024. rule: 'optional',
  11025. type: 'int32',
  11026. name: 'limit',
  11027. id: 8
  11028. }, {
  11029. rule: 'optional',
  11030. type: 'int32',
  11031. name: 'skip',
  11032. id: 9
  11033. }, {
  11034. rule: 'optional',
  11035. type: 'int32',
  11036. name: 'flag',
  11037. id: 10
  11038. }, {
  11039. rule: 'optional',
  11040. type: 'int32',
  11041. name: 'count',
  11042. id: 11
  11043. }, {
  11044. rule: 'optional',
  11045. type: 'string',
  11046. name: 'udate',
  11047. id: 12
  11048. }, {
  11049. rule: 'optional',
  11050. type: 'int64',
  11051. name: 't',
  11052. id: 13
  11053. }, {
  11054. rule: 'optional',
  11055. type: 'string',
  11056. name: 'n',
  11057. id: 14
  11058. }, {
  11059. rule: 'optional',
  11060. type: 'string',
  11061. name: 's',
  11062. id: 15
  11063. }, {
  11064. rule: 'optional',
  11065. type: 'bool',
  11066. name: 'statusSub',
  11067. id: 16
  11068. }, {
  11069. rule: 'optional',
  11070. type: 'bool',
  11071. name: 'statusPub',
  11072. id: 17
  11073. }, {
  11074. rule: 'optional',
  11075. type: 'int32',
  11076. name: 'statusTTL',
  11077. id: 18
  11078. }, {
  11079. rule: 'optional',
  11080. type: 'string',
  11081. name: 'uniqueId',
  11082. id: 19
  11083. }, {
  11084. rule: 'optional',
  11085. type: 'string',
  11086. name: 'targetClientId',
  11087. id: 20
  11088. }, {
  11089. rule: 'optional',
  11090. type: 'int64',
  11091. name: 'maxReadTimestamp',
  11092. id: 21
  11093. }, {
  11094. rule: 'optional',
  11095. type: 'int64',
  11096. name: 'maxAckTimestamp',
  11097. id: 22
  11098. }, {
  11099. rule: 'optional',
  11100. type: 'bool',
  11101. name: 'queryAllMembers',
  11102. id: 23
  11103. }, {
  11104. rule: 'repeated',
  11105. type: 'MaxReadTuple',
  11106. name: 'maxReadTuples',
  11107. id: 24
  11108. }, {
  11109. rule: 'repeated',
  11110. type: 'string',
  11111. name: 'cids',
  11112. id: 25
  11113. }, {
  11114. rule: 'optional',
  11115. type: 'ConvMemberInfo',
  11116. name: 'info',
  11117. id: 26
  11118. }, {
  11119. rule: 'optional',
  11120. type: 'bool',
  11121. name: 'tempConv',
  11122. id: 27
  11123. }, {
  11124. rule: 'optional',
  11125. type: 'int32',
  11126. name: 'tempConvTTL',
  11127. id: 28
  11128. }, {
  11129. rule: 'repeated',
  11130. type: 'string',
  11131. name: 'tempConvIds',
  11132. id: 29
  11133. }, {
  11134. rule: 'repeated',
  11135. type: 'string',
  11136. name: 'allowedPids',
  11137. id: 30
  11138. }, {
  11139. rule: 'repeated',
  11140. type: 'ErrorCommand',
  11141. name: 'failedPids',
  11142. id: 31
  11143. }, {
  11144. rule: 'optional',
  11145. type: 'string',
  11146. name: 'next',
  11147. id: 40
  11148. }, {
  11149. rule: 'optional',
  11150. type: 'JsonObjectMessage',
  11151. name: 'results',
  11152. id: 100
  11153. }, {
  11154. rule: 'optional',
  11155. type: 'JsonObjectMessage',
  11156. name: 'where',
  11157. id: 101
  11158. }, {
  11159. rule: 'optional',
  11160. type: 'JsonObjectMessage',
  11161. name: 'attr',
  11162. id: 103
  11163. }, {
  11164. rule: 'optional',
  11165. type: 'JsonObjectMessage',
  11166. name: 'attrModified',
  11167. id: 104
  11168. }]
  11169. }, {
  11170. name: 'RoomCommand',
  11171. syntax: 'proto2',
  11172. fields: [{
  11173. rule: 'optional',
  11174. type: 'string',
  11175. name: 'roomId',
  11176. id: 1
  11177. }, {
  11178. rule: 'optional',
  11179. type: 'string',
  11180. name: 's',
  11181. id: 2
  11182. }, {
  11183. rule: 'optional',
  11184. type: 'int64',
  11185. name: 't',
  11186. id: 3
  11187. }, {
  11188. rule: 'optional',
  11189. type: 'string',
  11190. name: 'n',
  11191. id: 4
  11192. }, {
  11193. rule: 'optional',
  11194. type: 'bool',
  11195. name: 'transient',
  11196. id: 5
  11197. }, {
  11198. rule: 'repeated',
  11199. type: 'string',
  11200. name: 'roomPeerIds',
  11201. id: 6
  11202. }, {
  11203. rule: 'optional',
  11204. type: 'string',
  11205. name: 'byPeerId',
  11206. id: 7
  11207. }]
  11208. }, {
  11209. name: 'LogsCommand',
  11210. syntax: 'proto2',
  11211. fields: [{
  11212. rule: 'optional',
  11213. type: 'string',
  11214. name: 'cid',
  11215. id: 1
  11216. }, {
  11217. rule: 'optional',
  11218. type: 'int32',
  11219. name: 'l',
  11220. id: 2
  11221. }, {
  11222. rule: 'optional',
  11223. type: 'int32',
  11224. name: 'limit',
  11225. id: 3
  11226. }, {
  11227. rule: 'optional',
  11228. type: 'int64',
  11229. name: 't',
  11230. id: 4
  11231. }, {
  11232. rule: 'optional',
  11233. type: 'int64',
  11234. name: 'tt',
  11235. id: 5
  11236. }, {
  11237. rule: 'optional',
  11238. type: 'string',
  11239. name: 'tmid',
  11240. id: 6
  11241. }, {
  11242. rule: 'optional',
  11243. type: 'string',
  11244. name: 'mid',
  11245. id: 7
  11246. }, {
  11247. rule: 'optional',
  11248. type: 'string',
  11249. name: 'checksum',
  11250. id: 8
  11251. }, {
  11252. rule: 'optional',
  11253. type: 'bool',
  11254. name: 'stored',
  11255. id: 9
  11256. }, {
  11257. rule: 'optional',
  11258. type: 'QueryDirection',
  11259. name: 'direction',
  11260. id: 10,
  11261. options: {
  11262. default: 'OLD'
  11263. }
  11264. }, {
  11265. rule: 'optional',
  11266. type: 'bool',
  11267. name: 'tIncluded',
  11268. id: 11
  11269. }, {
  11270. rule: 'optional',
  11271. type: 'bool',
  11272. name: 'ttIncluded',
  11273. id: 12
  11274. }, {
  11275. rule: 'optional',
  11276. type: 'int32',
  11277. name: 'lctype',
  11278. id: 13
  11279. }, {
  11280. rule: 'repeated',
  11281. type: 'LogItem',
  11282. name: 'logs',
  11283. id: 105
  11284. }],
  11285. enums: [{
  11286. name: 'QueryDirection',
  11287. syntax: 'proto2',
  11288. values: [{
  11289. name: 'OLD',
  11290. id: 1
  11291. }, {
  11292. name: 'NEW',
  11293. id: 2
  11294. }]
  11295. }]
  11296. }, {
  11297. name: 'RcpCommand',
  11298. syntax: 'proto2',
  11299. fields: [{
  11300. rule: 'optional',
  11301. type: 'string',
  11302. name: 'id',
  11303. id: 1
  11304. }, {
  11305. rule: 'optional',
  11306. type: 'string',
  11307. name: 'cid',
  11308. id: 2
  11309. }, {
  11310. rule: 'optional',
  11311. type: 'int64',
  11312. name: 't',
  11313. id: 3
  11314. }, {
  11315. rule: 'optional',
  11316. type: 'bool',
  11317. name: 'read',
  11318. id: 4
  11319. }, {
  11320. rule: 'optional',
  11321. type: 'string',
  11322. name: 'from',
  11323. id: 5
  11324. }]
  11325. }, {
  11326. name: 'ReadTuple',
  11327. syntax: 'proto2',
  11328. fields: [{
  11329. rule: 'required',
  11330. type: 'string',
  11331. name: 'cid',
  11332. id: 1
  11333. }, {
  11334. rule: 'optional',
  11335. type: 'int64',
  11336. name: 'timestamp',
  11337. id: 2
  11338. }, {
  11339. rule: 'optional',
  11340. type: 'string',
  11341. name: 'mid',
  11342. id: 3
  11343. }]
  11344. }, {
  11345. name: 'MaxReadTuple',
  11346. syntax: 'proto2',
  11347. fields: [{
  11348. rule: 'optional',
  11349. type: 'string',
  11350. name: 'pid',
  11351. id: 1
  11352. }, {
  11353. rule: 'optional',
  11354. type: 'int64',
  11355. name: 'maxAckTimestamp',
  11356. id: 2
  11357. }, {
  11358. rule: 'optional',
  11359. type: 'int64',
  11360. name: 'maxReadTimestamp',
  11361. id: 3
  11362. }]
  11363. }, {
  11364. name: 'ReadCommand',
  11365. syntax: 'proto2',
  11366. fields: [{
  11367. rule: 'optional',
  11368. type: 'string',
  11369. name: 'cid',
  11370. id: 1
  11371. }, {
  11372. rule: 'repeated',
  11373. type: 'string',
  11374. name: 'cids',
  11375. id: 2
  11376. }, {
  11377. rule: 'repeated',
  11378. type: 'ReadTuple',
  11379. name: 'convs',
  11380. id: 3
  11381. }]
  11382. }, {
  11383. name: 'PresenceCommand',
  11384. syntax: 'proto2',
  11385. fields: [{
  11386. rule: 'optional',
  11387. type: 'StatusType',
  11388. name: 'status',
  11389. id: 1
  11390. }, {
  11391. rule: 'repeated',
  11392. type: 'string',
  11393. name: 'sessionPeerIds',
  11394. id: 2
  11395. }, {
  11396. rule: 'optional',
  11397. type: 'string',
  11398. name: 'cid',
  11399. id: 3
  11400. }]
  11401. }, {
  11402. name: 'ReportCommand',
  11403. syntax: 'proto2',
  11404. fields: [{
  11405. rule: 'optional',
  11406. type: 'bool',
  11407. name: 'initiative',
  11408. id: 1
  11409. }, {
  11410. rule: 'optional',
  11411. type: 'string',
  11412. name: 'type',
  11413. id: 2
  11414. }, {
  11415. rule: 'optional',
  11416. type: 'string',
  11417. name: 'data',
  11418. id: 3
  11419. }]
  11420. }, {
  11421. name: 'PatchItem',
  11422. syntax: 'proto2',
  11423. fields: [{
  11424. rule: 'optional',
  11425. type: 'string',
  11426. name: 'cid',
  11427. id: 1
  11428. }, {
  11429. rule: 'optional',
  11430. type: 'string',
  11431. name: 'mid',
  11432. id: 2
  11433. }, {
  11434. rule: 'optional',
  11435. type: 'int64',
  11436. name: 'timestamp',
  11437. id: 3
  11438. }, {
  11439. rule: 'optional',
  11440. type: 'bool',
  11441. name: 'recall',
  11442. id: 4
  11443. }, {
  11444. rule: 'optional',
  11445. type: 'string',
  11446. name: 'data',
  11447. id: 5
  11448. }, {
  11449. rule: 'optional',
  11450. type: 'int64',
  11451. name: 'patchTimestamp',
  11452. id: 6
  11453. }, {
  11454. rule: 'optional',
  11455. type: 'string',
  11456. name: 'from',
  11457. id: 7
  11458. }, {
  11459. rule: 'optional',
  11460. type: 'bytes',
  11461. name: 'binaryMsg',
  11462. id: 8
  11463. }, {
  11464. rule: 'optional',
  11465. type: 'bool',
  11466. name: 'mentionAll',
  11467. id: 9
  11468. }, {
  11469. rule: 'repeated',
  11470. type: 'string',
  11471. name: 'mentionPids',
  11472. id: 10
  11473. }, {
  11474. rule: 'optional',
  11475. type: 'int64',
  11476. name: 'patchCode',
  11477. id: 11
  11478. }, {
  11479. rule: 'optional',
  11480. type: 'string',
  11481. name: 'patchReason',
  11482. id: 12
  11483. }]
  11484. }, {
  11485. name: 'PatchCommand',
  11486. syntax: 'proto2',
  11487. fields: [{
  11488. rule: 'repeated',
  11489. type: 'PatchItem',
  11490. name: 'patches',
  11491. id: 1
  11492. }, {
  11493. rule: 'optional',
  11494. type: 'int64',
  11495. name: 'lastPatchTime',
  11496. id: 2
  11497. }]
  11498. }, {
  11499. name: 'PubsubCommand',
  11500. syntax: 'proto2',
  11501. fields: [{
  11502. rule: 'optional',
  11503. type: 'string',
  11504. name: 'cid',
  11505. id: 1
  11506. }, {
  11507. rule: 'repeated',
  11508. type: 'string',
  11509. name: 'cids',
  11510. id: 2
  11511. }, {
  11512. rule: 'optional',
  11513. type: 'string',
  11514. name: 'topic',
  11515. id: 3
  11516. }, {
  11517. rule: 'optional',
  11518. type: 'string',
  11519. name: 'subtopic',
  11520. id: 4
  11521. }, {
  11522. rule: 'repeated',
  11523. type: 'string',
  11524. name: 'topics',
  11525. id: 5
  11526. }, {
  11527. rule: 'repeated',
  11528. type: 'string',
  11529. name: 'subtopics',
  11530. id: 6
  11531. }, {
  11532. rule: 'optional',
  11533. type: 'JsonObjectMessage',
  11534. name: 'results',
  11535. id: 7
  11536. }]
  11537. }, {
  11538. name: 'BlacklistCommand',
  11539. syntax: 'proto2',
  11540. fields: [{
  11541. rule: 'optional',
  11542. type: 'string',
  11543. name: 'srcCid',
  11544. id: 1
  11545. }, {
  11546. rule: 'repeated',
  11547. type: 'string',
  11548. name: 'toPids',
  11549. id: 2
  11550. }, {
  11551. rule: 'optional',
  11552. type: 'string',
  11553. name: 'srcPid',
  11554. id: 3
  11555. }, {
  11556. rule: 'repeated',
  11557. type: 'string',
  11558. name: 'toCids',
  11559. id: 4
  11560. }, {
  11561. rule: 'optional',
  11562. type: 'int32',
  11563. name: 'limit',
  11564. id: 5
  11565. }, {
  11566. rule: 'optional',
  11567. type: 'string',
  11568. name: 'next',
  11569. id: 6
  11570. }, {
  11571. rule: 'repeated',
  11572. type: 'string',
  11573. name: 'blockedPids',
  11574. id: 8
  11575. }, {
  11576. rule: 'repeated',
  11577. type: 'string',
  11578. name: 'blockedCids',
  11579. id: 9
  11580. }, {
  11581. rule: 'repeated',
  11582. type: 'string',
  11583. name: 'allowedPids',
  11584. id: 10
  11585. }, {
  11586. rule: 'repeated',
  11587. type: 'ErrorCommand',
  11588. name: 'failedPids',
  11589. id: 11
  11590. }, {
  11591. rule: 'optional',
  11592. type: 'int64',
  11593. name: 't',
  11594. id: 12
  11595. }, {
  11596. rule: 'optional',
  11597. type: 'string',
  11598. name: 'n',
  11599. id: 13
  11600. }, {
  11601. rule: 'optional',
  11602. type: 'string',
  11603. name: 's',
  11604. id: 14
  11605. }]
  11606. }, {
  11607. name: 'GenericCommand',
  11608. syntax: 'proto2',
  11609. fields: [{
  11610. rule: 'optional',
  11611. type: 'CommandType',
  11612. name: 'cmd',
  11613. id: 1
  11614. }, {
  11615. rule: 'optional',
  11616. type: 'OpType',
  11617. name: 'op',
  11618. id: 2
  11619. }, {
  11620. rule: 'optional',
  11621. type: 'string',
  11622. name: 'appId',
  11623. id: 3
  11624. }, {
  11625. rule: 'optional',
  11626. type: 'string',
  11627. name: 'peerId',
  11628. id: 4
  11629. }, {
  11630. rule: 'optional',
  11631. type: 'int32',
  11632. name: 'i',
  11633. id: 5
  11634. }, {
  11635. rule: 'optional',
  11636. type: 'string',
  11637. name: 'installationId',
  11638. id: 6
  11639. }, {
  11640. rule: 'optional',
  11641. type: 'int32',
  11642. name: 'priority',
  11643. id: 7
  11644. }, {
  11645. rule: 'optional',
  11646. type: 'int32',
  11647. name: 'service',
  11648. id: 8
  11649. }, {
  11650. rule: 'optional',
  11651. type: 'int64',
  11652. name: 'serverTs',
  11653. id: 9
  11654. }, {
  11655. rule: 'optional',
  11656. type: 'int64',
  11657. name: 'clientTs',
  11658. id: 10
  11659. }, {
  11660. rule: 'optional',
  11661. type: 'int32',
  11662. name: 'notificationType',
  11663. id: 11
  11664. }, {
  11665. rule: 'optional',
  11666. type: 'DataCommand',
  11667. name: 'dataMessage',
  11668. id: 101
  11669. }, {
  11670. rule: 'optional',
  11671. type: 'SessionCommand',
  11672. name: 'sessionMessage',
  11673. id: 102
  11674. }, {
  11675. rule: 'optional',
  11676. type: 'ErrorCommand',
  11677. name: 'errorMessage',
  11678. id: 103
  11679. }, {
  11680. rule: 'optional',
  11681. type: 'DirectCommand',
  11682. name: 'directMessage',
  11683. id: 104
  11684. }, {
  11685. rule: 'optional',
  11686. type: 'AckCommand',
  11687. name: 'ackMessage',
  11688. id: 105
  11689. }, {
  11690. rule: 'optional',
  11691. type: 'UnreadCommand',
  11692. name: 'unreadMessage',
  11693. id: 106
  11694. }, {
  11695. rule: 'optional',
  11696. type: 'ReadCommand',
  11697. name: 'readMessage',
  11698. id: 107
  11699. }, {
  11700. rule: 'optional',
  11701. type: 'RcpCommand',
  11702. name: 'rcpMessage',
  11703. id: 108
  11704. }, {
  11705. rule: 'optional',
  11706. type: 'LogsCommand',
  11707. name: 'logsMessage',
  11708. id: 109
  11709. }, {
  11710. rule: 'optional',
  11711. type: 'ConvCommand',
  11712. name: 'convMessage',
  11713. id: 110
  11714. }, {
  11715. rule: 'optional',
  11716. type: 'RoomCommand',
  11717. name: 'roomMessage',
  11718. id: 111
  11719. }, {
  11720. rule: 'optional',
  11721. type: 'PresenceCommand',
  11722. name: 'presenceMessage',
  11723. id: 112
  11724. }, {
  11725. rule: 'optional',
  11726. type: 'ReportCommand',
  11727. name: 'reportMessage',
  11728. id: 113
  11729. }, {
  11730. rule: 'optional',
  11731. type: 'PatchCommand',
  11732. name: 'patchMessage',
  11733. id: 114
  11734. }, {
  11735. rule: 'optional',
  11736. type: 'PubsubCommand',
  11737. name: 'pubsubMessage',
  11738. id: 115
  11739. }, {
  11740. rule: 'optional',
  11741. type: 'BlacklistCommand',
  11742. name: 'blacklistMessage',
  11743. id: 116
  11744. }]
  11745. }],
  11746. enums: [{
  11747. name: 'CommandType',
  11748. syntax: 'proto2',
  11749. values: [{
  11750. name: 'session',
  11751. id: 0
  11752. }, {
  11753. name: 'conv',
  11754. id: 1
  11755. }, {
  11756. name: 'direct',
  11757. id: 2
  11758. }, {
  11759. name: 'ack',
  11760. id: 3
  11761. }, {
  11762. name: 'rcp',
  11763. id: 4
  11764. }, {
  11765. name: 'unread',
  11766. id: 5
  11767. }, {
  11768. name: 'logs',
  11769. id: 6
  11770. }, {
  11771. name: 'error',
  11772. id: 7
  11773. }, {
  11774. name: 'login',
  11775. id: 8
  11776. }, {
  11777. name: 'data',
  11778. id: 9
  11779. }, {
  11780. name: 'room',
  11781. id: 10
  11782. }, {
  11783. name: 'read',
  11784. id: 11
  11785. }, {
  11786. name: 'presence',
  11787. id: 12
  11788. }, {
  11789. name: 'report',
  11790. id: 13
  11791. }, {
  11792. name: 'echo',
  11793. id: 14
  11794. }, {
  11795. name: 'loggedin',
  11796. id: 15
  11797. }, {
  11798. name: 'logout',
  11799. id: 16
  11800. }, {
  11801. name: 'loggedout',
  11802. id: 17
  11803. }, {
  11804. name: 'patch',
  11805. id: 18
  11806. }, {
  11807. name: 'pubsub',
  11808. id: 19
  11809. }, {
  11810. name: 'blacklist',
  11811. id: 20
  11812. }, {
  11813. name: 'goaway',
  11814. id: 21
  11815. }]
  11816. }, {
  11817. name: 'OpType',
  11818. syntax: 'proto2',
  11819. values: [{
  11820. name: 'open',
  11821. id: 1
  11822. }, {
  11823. name: 'add',
  11824. id: 2
  11825. }, {
  11826. name: 'remove',
  11827. id: 3
  11828. }, {
  11829. name: 'close',
  11830. id: 4
  11831. }, {
  11832. name: 'opened',
  11833. id: 5
  11834. }, {
  11835. name: 'closed',
  11836. id: 6
  11837. }, {
  11838. name: 'query',
  11839. id: 7
  11840. }, {
  11841. name: 'query_result',
  11842. id: 8
  11843. }, {
  11844. name: 'conflict',
  11845. id: 9
  11846. }, {
  11847. name: 'added',
  11848. id: 10
  11849. }, {
  11850. name: 'removed',
  11851. id: 11
  11852. }, {
  11853. name: 'refresh',
  11854. id: 12
  11855. }, {
  11856. name: 'refreshed',
  11857. id: 13
  11858. }, {
  11859. name: 'start',
  11860. id: 30
  11861. }, {
  11862. name: 'started',
  11863. id: 31
  11864. }, {
  11865. name: 'joined',
  11866. id: 32
  11867. }, {
  11868. name: 'members_joined',
  11869. id: 33
  11870. }, {
  11871. name: 'left',
  11872. id: 39
  11873. }, {
  11874. name: 'members_left',
  11875. id: 40
  11876. }, {
  11877. name: 'results',
  11878. id: 42
  11879. }, {
  11880. name: 'count',
  11881. id: 43
  11882. }, {
  11883. name: 'result',
  11884. id: 44
  11885. }, {
  11886. name: 'update',
  11887. id: 45
  11888. }, {
  11889. name: 'updated',
  11890. id: 46
  11891. }, {
  11892. name: 'mute',
  11893. id: 47
  11894. }, {
  11895. name: 'unmute',
  11896. id: 48
  11897. }, {
  11898. name: 'status',
  11899. id: 49
  11900. }, {
  11901. name: 'members',
  11902. id: 50
  11903. }, {
  11904. name: 'max_read',
  11905. id: 51
  11906. }, {
  11907. name: 'is_member',
  11908. id: 52
  11909. }, {
  11910. name: 'member_info_update',
  11911. id: 53
  11912. }, {
  11913. name: 'member_info_updated',
  11914. id: 54
  11915. }, {
  11916. name: 'member_info_changed',
  11917. id: 55
  11918. }, {
  11919. name: 'join',
  11920. id: 80
  11921. }, {
  11922. name: 'invite',
  11923. id: 81
  11924. }, {
  11925. name: 'leave',
  11926. id: 82
  11927. }, {
  11928. name: 'kick',
  11929. id: 83
  11930. }, {
  11931. name: 'reject',
  11932. id: 84
  11933. }, {
  11934. name: 'invited',
  11935. id: 85
  11936. }, {
  11937. name: 'kicked',
  11938. id: 86
  11939. }, {
  11940. name: 'upload',
  11941. id: 100
  11942. }, {
  11943. name: 'uploaded',
  11944. id: 101
  11945. }, {
  11946. name: 'subscribe',
  11947. id: 120
  11948. }, {
  11949. name: 'subscribed',
  11950. id: 121
  11951. }, {
  11952. name: 'unsubscribe',
  11953. id: 122
  11954. }, {
  11955. name: 'unsubscribed',
  11956. id: 123
  11957. }, {
  11958. name: 'is_subscribed',
  11959. id: 124
  11960. }, {
  11961. name: 'modify',
  11962. id: 150
  11963. }, {
  11964. name: 'modified',
  11965. id: 151
  11966. }, {
  11967. name: 'block',
  11968. id: 170
  11969. }, {
  11970. name: 'unblock',
  11971. id: 171
  11972. }, {
  11973. name: 'blocked',
  11974. id: 172
  11975. }, {
  11976. name: 'unblocked',
  11977. id: 173
  11978. }, {
  11979. name: 'members_blocked',
  11980. id: 174
  11981. }, {
  11982. name: 'members_unblocked',
  11983. id: 175
  11984. }, {
  11985. name: 'check_block',
  11986. id: 176
  11987. }, {
  11988. name: 'check_result',
  11989. id: 177
  11990. }, {
  11991. name: 'add_shutup',
  11992. id: 180
  11993. }, {
  11994. name: 'remove_shutup',
  11995. id: 181
  11996. }, {
  11997. name: 'query_shutup',
  11998. id: 182
  11999. }, {
  12000. name: 'shutup_added',
  12001. id: 183
  12002. }, {
  12003. name: 'shutup_removed',
  12004. id: 184
  12005. }, {
  12006. name: 'shutup_result',
  12007. id: 185
  12008. }, {
  12009. name: 'shutuped',
  12010. id: 186
  12011. }, {
  12012. name: 'unshutuped',
  12013. id: 187
  12014. }, {
  12015. name: 'members_shutuped',
  12016. id: 188
  12017. }, {
  12018. name: 'members_unshutuped',
  12019. id: 189
  12020. }, {
  12021. name: 'check_shutup',
  12022. id: 190
  12023. }]
  12024. }, {
  12025. name: 'StatusType',
  12026. syntax: 'proto2',
  12027. values: [{
  12028. name: 'on',
  12029. id: 1
  12030. }, {
  12031. name: 'off',
  12032. id: 2
  12033. }]
  12034. }],
  12035. isNamespace: true
  12036. }).build();
  12037. const {
  12038. JsonObjectMessage,
  12039. UnreadTuple,
  12040. LogItem,
  12041. DataCommand,
  12042. SessionCommand,
  12043. ErrorCommand,
  12044. DirectCommand,
  12045. AckCommand,
  12046. UnreadCommand,
  12047. ConvCommand,
  12048. RoomCommand,
  12049. LogsCommand,
  12050. RcpCommand,
  12051. ReadTuple,
  12052. MaxReadTuple,
  12053. ReadCommand,
  12054. PresenceCommand,
  12055. ReportCommand,
  12056. GenericCommand,
  12057. BlacklistCommand,
  12058. PatchCommand,
  12059. PatchItem,
  12060. ConvMemberInfo,
  12061. CommandType,
  12062. OpType,
  12063. StatusType
  12064. } = messageCompiled.push_server.messages2;
  12065. var message = /*#__PURE__*/Object.freeze({
  12066. __proto__: null,
  12067. JsonObjectMessage: JsonObjectMessage,
  12068. UnreadTuple: UnreadTuple,
  12069. LogItem: LogItem,
  12070. DataCommand: DataCommand,
  12071. SessionCommand: SessionCommand,
  12072. ErrorCommand: ErrorCommand,
  12073. DirectCommand: DirectCommand,
  12074. AckCommand: AckCommand,
  12075. UnreadCommand: UnreadCommand,
  12076. ConvCommand: ConvCommand,
  12077. RoomCommand: RoomCommand,
  12078. LogsCommand: LogsCommand,
  12079. RcpCommand: RcpCommand,
  12080. ReadTuple: ReadTuple,
  12081. MaxReadTuple: MaxReadTuple,
  12082. ReadCommand: ReadCommand,
  12083. PresenceCommand: PresenceCommand,
  12084. ReportCommand: ReportCommand,
  12085. GenericCommand: GenericCommand,
  12086. BlacklistCommand: BlacklistCommand,
  12087. PatchCommand: PatchCommand,
  12088. PatchItem: PatchItem,
  12089. ConvMemberInfo: ConvMemberInfo,
  12090. CommandType: CommandType,
  12091. OpType: OpType,
  12092. StatusType: StatusType
  12093. });
  12094. var eventemitter3 = createCommonjsModule(function (module) {
  12095. var has = Object.prototype.hasOwnProperty
  12096. , prefix = '~';
  12097. /**
  12098. * Constructor to create a storage for our `EE` objects.
  12099. * An `Events` instance is a plain object whose properties are event names.
  12100. *
  12101. * @constructor
  12102. * @private
  12103. */
  12104. function Events() {}
  12105. //
  12106. // We try to not inherit from `Object.prototype`. In some engines creating an
  12107. // instance in this way is faster than calling `Object.create(null)` directly.
  12108. // If `Object.create(null)` is not supported we prefix the event names with a
  12109. // character to make sure that the built-in object properties are not
  12110. // overridden or used as an attack vector.
  12111. //
  12112. if (Object.create) {
  12113. Events.prototype = Object.create(null);
  12114. //
  12115. // This hack is needed because the `__proto__` property is still inherited in
  12116. // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
  12117. //
  12118. if (!new Events().__proto__) prefix = false;
  12119. }
  12120. /**
  12121. * Representation of a single event listener.
  12122. *
  12123. * @param {Function} fn The listener function.
  12124. * @param {*} context The context to invoke the listener with.
  12125. * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
  12126. * @constructor
  12127. * @private
  12128. */
  12129. function EE(fn, context, once) {
  12130. this.fn = fn;
  12131. this.context = context;
  12132. this.once = once || false;
  12133. }
  12134. /**
  12135. * Add a listener for a given event.
  12136. *
  12137. * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
  12138. * @param {(String|Symbol)} event The event name.
  12139. * @param {Function} fn The listener function.
  12140. * @param {*} context The context to invoke the listener with.
  12141. * @param {Boolean} once Specify if the listener is a one-time listener.
  12142. * @returns {EventEmitter}
  12143. * @private
  12144. */
  12145. function addListener(emitter, event, fn, context, once) {
  12146. if (typeof fn !== 'function') {
  12147. throw new TypeError('The listener must be a function');
  12148. }
  12149. var listener = new EE(fn, context || emitter, once)
  12150. , evt = prefix ? prefix + event : event;
  12151. if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
  12152. else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
  12153. else emitter._events[evt] = [emitter._events[evt], listener];
  12154. return emitter;
  12155. }
  12156. /**
  12157. * Clear event by name.
  12158. *
  12159. * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
  12160. * @param {(String|Symbol)} evt The Event name.
  12161. * @private
  12162. */
  12163. function clearEvent(emitter, evt) {
  12164. if (--emitter._eventsCount === 0) emitter._events = new Events();
  12165. else delete emitter._events[evt];
  12166. }
  12167. /**
  12168. * Minimal `EventEmitter` interface that is molded against the Node.js
  12169. * `EventEmitter` interface.
  12170. *
  12171. * @constructor
  12172. * @public
  12173. */
  12174. function EventEmitter() {
  12175. this._events = new Events();
  12176. this._eventsCount = 0;
  12177. }
  12178. /**
  12179. * Return an array listing the events for which the emitter has registered
  12180. * listeners.
  12181. *
  12182. * @returns {Array}
  12183. * @public
  12184. */
  12185. EventEmitter.prototype.eventNames = function eventNames() {
  12186. var names = []
  12187. , events
  12188. , name;
  12189. if (this._eventsCount === 0) return names;
  12190. for (name in (events = this._events)) {
  12191. if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
  12192. }
  12193. if (Object.getOwnPropertySymbols) {
  12194. return names.concat(Object.getOwnPropertySymbols(events));
  12195. }
  12196. return names;
  12197. };
  12198. /**
  12199. * Return the listeners registered for a given event.
  12200. *
  12201. * @param {(String|Symbol)} event The event name.
  12202. * @returns {Array} The registered listeners.
  12203. * @public
  12204. */
  12205. EventEmitter.prototype.listeners = function listeners(event) {
  12206. var evt = prefix ? prefix + event : event
  12207. , handlers = this._events[evt];
  12208. if (!handlers) return [];
  12209. if (handlers.fn) return [handlers.fn];
  12210. for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
  12211. ee[i] = handlers[i].fn;
  12212. }
  12213. return ee;
  12214. };
  12215. /**
  12216. * Return the number of listeners listening to a given event.
  12217. *
  12218. * @param {(String|Symbol)} event The event name.
  12219. * @returns {Number} The number of listeners.
  12220. * @public
  12221. */
  12222. EventEmitter.prototype.listenerCount = function listenerCount(event) {
  12223. var evt = prefix ? prefix + event : event
  12224. , listeners = this._events[evt];
  12225. if (!listeners) return 0;
  12226. if (listeners.fn) return 1;
  12227. return listeners.length;
  12228. };
  12229. /**
  12230. * Calls each of the listeners registered for a given event.
  12231. *
  12232. * @param {(String|Symbol)} event The event name.
  12233. * @returns {Boolean} `true` if the event had listeners, else `false`.
  12234. * @public
  12235. */
  12236. EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
  12237. var evt = prefix ? prefix + event : event;
  12238. if (!this._events[evt]) return false;
  12239. var listeners = this._events[evt]
  12240. , len = arguments.length
  12241. , args
  12242. , i;
  12243. if (listeners.fn) {
  12244. if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
  12245. switch (len) {
  12246. case 1: return listeners.fn.call(listeners.context), true;
  12247. case 2: return listeners.fn.call(listeners.context, a1), true;
  12248. case 3: return listeners.fn.call(listeners.context, a1, a2), true;
  12249. case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
  12250. case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
  12251. case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
  12252. }
  12253. for (i = 1, args = new Array(len -1); i < len; i++) {
  12254. args[i - 1] = arguments[i];
  12255. }
  12256. listeners.fn.apply(listeners.context, args);
  12257. } else {
  12258. var length = listeners.length
  12259. , j;
  12260. for (i = 0; i < length; i++) {
  12261. if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
  12262. switch (len) {
  12263. case 1: listeners[i].fn.call(listeners[i].context); break;
  12264. case 2: listeners[i].fn.call(listeners[i].context, a1); break;
  12265. case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
  12266. case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
  12267. default:
  12268. if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
  12269. args[j - 1] = arguments[j];
  12270. }
  12271. listeners[i].fn.apply(listeners[i].context, args);
  12272. }
  12273. }
  12274. }
  12275. return true;
  12276. };
  12277. /**
  12278. * Add a listener for a given event.
  12279. *
  12280. * @param {(String|Symbol)} event The event name.
  12281. * @param {Function} fn The listener function.
  12282. * @param {*} [context=this] The context to invoke the listener with.
  12283. * @returns {EventEmitter} `this`.
  12284. * @public
  12285. */
  12286. EventEmitter.prototype.on = function on(event, fn, context) {
  12287. return addListener(this, event, fn, context, false);
  12288. };
  12289. /**
  12290. * Add a one-time listener for a given event.
  12291. *
  12292. * @param {(String|Symbol)} event The event name.
  12293. * @param {Function} fn The listener function.
  12294. * @param {*} [context=this] The context to invoke the listener with.
  12295. * @returns {EventEmitter} `this`.
  12296. * @public
  12297. */
  12298. EventEmitter.prototype.once = function once(event, fn, context) {
  12299. return addListener(this, event, fn, context, true);
  12300. };
  12301. /**
  12302. * Remove the listeners of a given event.
  12303. *
  12304. * @param {(String|Symbol)} event The event name.
  12305. * @param {Function} fn Only remove the listeners that match this function.
  12306. * @param {*} context Only remove the listeners that have this context.
  12307. * @param {Boolean} once Only remove one-time listeners.
  12308. * @returns {EventEmitter} `this`.
  12309. * @public
  12310. */
  12311. EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
  12312. var evt = prefix ? prefix + event : event;
  12313. if (!this._events[evt]) return this;
  12314. if (!fn) {
  12315. clearEvent(this, evt);
  12316. return this;
  12317. }
  12318. var listeners = this._events[evt];
  12319. if (listeners.fn) {
  12320. if (
  12321. listeners.fn === fn &&
  12322. (!once || listeners.once) &&
  12323. (!context || listeners.context === context)
  12324. ) {
  12325. clearEvent(this, evt);
  12326. }
  12327. } else {
  12328. for (var i = 0, events = [], length = listeners.length; i < length; i++) {
  12329. if (
  12330. listeners[i].fn !== fn ||
  12331. (once && !listeners[i].once) ||
  12332. (context && listeners[i].context !== context)
  12333. ) {
  12334. events.push(listeners[i]);
  12335. }
  12336. }
  12337. //
  12338. // Reset the array, or remove it completely if we have no more listeners.
  12339. //
  12340. if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
  12341. else clearEvent(this, evt);
  12342. }
  12343. return this;
  12344. };
  12345. /**
  12346. * Remove all listeners, or those of the specified event.
  12347. *
  12348. * @param {(String|Symbol)} [event] The event name.
  12349. * @returns {EventEmitter} `this`.
  12350. * @public
  12351. */
  12352. EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
  12353. var evt;
  12354. if (event) {
  12355. evt = prefix ? prefix + event : event;
  12356. if (this._events[evt]) clearEvent(this, evt);
  12357. } else {
  12358. this._events = new Events();
  12359. this._eventsCount = 0;
  12360. }
  12361. return this;
  12362. };
  12363. //
  12364. // Alias methods names because people roll like that.
  12365. //
  12366. EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
  12367. EventEmitter.prototype.addListener = EventEmitter.prototype.on;
  12368. //
  12369. // Expose the prefix.
  12370. //
  12371. EventEmitter.prefixed = prefix;
  12372. //
  12373. // Allow `EventEmitter` to be imported as module namespace.
  12374. //
  12375. EventEmitter.EventEmitter = EventEmitter;
  12376. //
  12377. // Expose the module.
  12378. //
  12379. {
  12380. module.exports = EventEmitter;
  12381. }
  12382. });
  12383. /**
  12384. * Helpers.
  12385. */
  12386. var s = 1000;
  12387. var m = s * 60;
  12388. var h = m * 60;
  12389. var d = h * 24;
  12390. var w = d * 7;
  12391. var y = d * 365.25;
  12392. /**
  12393. * Parse or format the given `val`.
  12394. *
  12395. * Options:
  12396. *
  12397. * - `long` verbose formatting [false]
  12398. *
  12399. * @param {String|Number} val
  12400. * @param {Object} [options]
  12401. * @throws {Error} throw an error if val is not a non-empty string or a number
  12402. * @return {String|Number}
  12403. * @api public
  12404. */
  12405. var ms = function(val, options) {
  12406. options = options || {};
  12407. var type = typeof val;
  12408. if (type === 'string' && val.length > 0) {
  12409. return parse(val);
  12410. } else if (type === 'number' && isNaN(val) === false) {
  12411. return options.long ? fmtLong(val) : fmtShort(val);
  12412. }
  12413. throw new Error(
  12414. 'val is not a non-empty string or a valid number. val=' +
  12415. JSON.stringify(val)
  12416. );
  12417. };
  12418. /**
  12419. * Parse the given `str` and return milliseconds.
  12420. *
  12421. * @param {String} str
  12422. * @return {Number}
  12423. * @api private
  12424. */
  12425. function parse(str) {
  12426. str = String(str);
  12427. if (str.length > 100) {
  12428. return;
  12429. }
  12430. var match = /^((?:\d+)?\-?\d?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
  12431. str
  12432. );
  12433. if (!match) {
  12434. return;
  12435. }
  12436. var n = parseFloat(match[1]);
  12437. var type = (match[2] || 'ms').toLowerCase();
  12438. switch (type) {
  12439. case 'years':
  12440. case 'year':
  12441. case 'yrs':
  12442. case 'yr':
  12443. case 'y':
  12444. return n * y;
  12445. case 'weeks':
  12446. case 'week':
  12447. case 'w':
  12448. return n * w;
  12449. case 'days':
  12450. case 'day':
  12451. case 'd':
  12452. return n * d;
  12453. case 'hours':
  12454. case 'hour':
  12455. case 'hrs':
  12456. case 'hr':
  12457. case 'h':
  12458. return n * h;
  12459. case 'minutes':
  12460. case 'minute':
  12461. case 'mins':
  12462. case 'min':
  12463. case 'm':
  12464. return n * m;
  12465. case 'seconds':
  12466. case 'second':
  12467. case 'secs':
  12468. case 'sec':
  12469. case 's':
  12470. return n * s;
  12471. case 'milliseconds':
  12472. case 'millisecond':
  12473. case 'msecs':
  12474. case 'msec':
  12475. case 'ms':
  12476. return n;
  12477. default:
  12478. return undefined;
  12479. }
  12480. }
  12481. /**
  12482. * Short format for `ms`.
  12483. *
  12484. * @param {Number} ms
  12485. * @return {String}
  12486. * @api private
  12487. */
  12488. function fmtShort(ms) {
  12489. var msAbs = Math.abs(ms);
  12490. if (msAbs >= d) {
  12491. return Math.round(ms / d) + 'd';
  12492. }
  12493. if (msAbs >= h) {
  12494. return Math.round(ms / h) + 'h';
  12495. }
  12496. if (msAbs >= m) {
  12497. return Math.round(ms / m) + 'm';
  12498. }
  12499. if (msAbs >= s) {
  12500. return Math.round(ms / s) + 's';
  12501. }
  12502. return ms + 'ms';
  12503. }
  12504. /**
  12505. * Long format for `ms`.
  12506. *
  12507. * @param {Number} ms
  12508. * @return {String}
  12509. * @api private
  12510. */
  12511. function fmtLong(ms) {
  12512. var msAbs = Math.abs(ms);
  12513. if (msAbs >= d) {
  12514. return plural(ms, msAbs, d, 'day');
  12515. }
  12516. if (msAbs >= h) {
  12517. return plural(ms, msAbs, h, 'hour');
  12518. }
  12519. if (msAbs >= m) {
  12520. return plural(ms, msAbs, m, 'minute');
  12521. }
  12522. if (msAbs >= s) {
  12523. return plural(ms, msAbs, s, 'second');
  12524. }
  12525. return ms + ' ms';
  12526. }
  12527. /**
  12528. * Pluralization helper.
  12529. */
  12530. function plural(ms, msAbs, n, name) {
  12531. var isPlural = msAbs >= n * 1.5;
  12532. return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
  12533. }
  12534. /**
  12535. * This is the common logic for both the Node.js and web browser
  12536. * implementations of `debug()`.
  12537. */
  12538. function setup(env) {
  12539. createDebug.debug = createDebug;
  12540. createDebug.default = createDebug;
  12541. createDebug.coerce = coerce;
  12542. createDebug.disable = disable;
  12543. createDebug.enable = enable;
  12544. createDebug.enabled = enabled;
  12545. createDebug.humanize = ms;
  12546. Object.keys(env).forEach(function (key) {
  12547. createDebug[key] = env[key];
  12548. });
  12549. /**
  12550. * Active `debug` instances.
  12551. */
  12552. createDebug.instances = [];
  12553. /**
  12554. * The currently active debug mode names, and names to skip.
  12555. */
  12556. createDebug.names = [];
  12557. createDebug.skips = [];
  12558. /**
  12559. * Map of special "%n" handling functions, for the debug "format" argument.
  12560. *
  12561. * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
  12562. */
  12563. createDebug.formatters = {};
  12564. /**
  12565. * Selects a color for a debug namespace
  12566. * @param {String} namespace The namespace string for the for the debug instance to be colored
  12567. * @return {Number|String} An ANSI color code for the given namespace
  12568. * @api private
  12569. */
  12570. function selectColor(namespace) {
  12571. var hash = 0;
  12572. for (var i = 0; i < namespace.length; i++) {
  12573. hash = (hash << 5) - hash + namespace.charCodeAt(i);
  12574. hash |= 0; // Convert to 32bit integer
  12575. }
  12576. return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
  12577. }
  12578. createDebug.selectColor = selectColor;
  12579. /**
  12580. * Create a debugger with the given `namespace`.
  12581. *
  12582. * @param {String} namespace
  12583. * @return {Function}
  12584. * @api public
  12585. */
  12586. function createDebug(namespace) {
  12587. var prevTime;
  12588. function debug() {
  12589. // Disabled?
  12590. if (!debug.enabled) {
  12591. return;
  12592. }
  12593. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  12594. args[_key] = arguments[_key];
  12595. }
  12596. var self = debug; // Set `diff` timestamp
  12597. var curr = Number(new Date());
  12598. var ms = curr - (prevTime || curr);
  12599. self.diff = ms;
  12600. self.prev = prevTime;
  12601. self.curr = curr;
  12602. prevTime = curr;
  12603. args[0] = createDebug.coerce(args[0]);
  12604. if (typeof args[0] !== 'string') {
  12605. // Anything else let's inspect with %O
  12606. args.unshift('%O');
  12607. } // Apply any `formatters` transformations
  12608. var index = 0;
  12609. args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) {
  12610. // If we encounter an escaped % then don't increase the array index
  12611. if (match === '%%') {
  12612. return match;
  12613. }
  12614. index++;
  12615. var formatter = createDebug.formatters[format];
  12616. if (typeof formatter === 'function') {
  12617. var val = args[index];
  12618. match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format`
  12619. args.splice(index, 1);
  12620. index--;
  12621. }
  12622. return match;
  12623. }); // Apply env-specific formatting (colors, etc.)
  12624. createDebug.formatArgs.call(self, args);
  12625. var logFn = self.log || createDebug.log;
  12626. logFn.apply(self, args);
  12627. }
  12628. debug.namespace = namespace;
  12629. debug.enabled = createDebug.enabled(namespace);
  12630. debug.useColors = createDebug.useColors();
  12631. debug.color = selectColor(namespace);
  12632. debug.destroy = destroy;
  12633. debug.extend = extend; // Debug.formatArgs = formatArgs;
  12634. // debug.rawLog = rawLog;
  12635. // env-specific initialization logic for debug instances
  12636. if (typeof createDebug.init === 'function') {
  12637. createDebug.init(debug);
  12638. }
  12639. createDebug.instances.push(debug);
  12640. return debug;
  12641. }
  12642. function destroy() {
  12643. var index = createDebug.instances.indexOf(this);
  12644. if (index !== -1) {
  12645. createDebug.instances.splice(index, 1);
  12646. return true;
  12647. }
  12648. return false;
  12649. }
  12650. function extend(namespace, delimiter) {
  12651. return createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
  12652. }
  12653. /**
  12654. * Enables a debug mode by namespaces. This can include modes
  12655. * separated by a colon and wildcards.
  12656. *
  12657. * @param {String} namespaces
  12658. * @api public
  12659. */
  12660. function enable(namespaces) {
  12661. createDebug.save(namespaces);
  12662. createDebug.names = [];
  12663. createDebug.skips = [];
  12664. var i;
  12665. var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
  12666. var len = split.length;
  12667. for (i = 0; i < len; i++) {
  12668. if (!split[i]) {
  12669. // ignore empty strings
  12670. continue;
  12671. }
  12672. namespaces = split[i].replace(/\*/g, '.*?');
  12673. if (namespaces[0] === '-') {
  12674. createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
  12675. } else {
  12676. createDebug.names.push(new RegExp('^' + namespaces + '$'));
  12677. }
  12678. }
  12679. for (i = 0; i < createDebug.instances.length; i++) {
  12680. var instance = createDebug.instances[i];
  12681. instance.enabled = createDebug.enabled(instance.namespace);
  12682. }
  12683. }
  12684. /**
  12685. * Disable debug output.
  12686. *
  12687. * @api public
  12688. */
  12689. function disable() {
  12690. createDebug.enable('');
  12691. }
  12692. /**
  12693. * Returns true if the given mode name is enabled, false otherwise.
  12694. *
  12695. * @param {String} name
  12696. * @return {Boolean}
  12697. * @api public
  12698. */
  12699. function enabled(name) {
  12700. if (name[name.length - 1] === '*') {
  12701. return true;
  12702. }
  12703. var i;
  12704. var len;
  12705. for (i = 0, len = createDebug.skips.length; i < len; i++) {
  12706. if (createDebug.skips[i].test(name)) {
  12707. return false;
  12708. }
  12709. }
  12710. for (i = 0, len = createDebug.names.length; i < len; i++) {
  12711. if (createDebug.names[i].test(name)) {
  12712. return true;
  12713. }
  12714. }
  12715. return false;
  12716. }
  12717. /**
  12718. * Coerce `val`.
  12719. *
  12720. * @param {Mixed} val
  12721. * @return {Mixed}
  12722. * @api private
  12723. */
  12724. function coerce(val) {
  12725. if (val instanceof Error) {
  12726. return val.stack || val.message;
  12727. }
  12728. return val;
  12729. }
  12730. createDebug.enable(createDebug.load());
  12731. return createDebug;
  12732. }
  12733. var common = setup;
  12734. var browser = createCommonjsModule(function (module, exports) {
  12735. function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
  12736. /* eslint-env browser */
  12737. /**
  12738. * This is the web browser implementation of `debug()`.
  12739. */
  12740. exports.log = log;
  12741. exports.formatArgs = formatArgs;
  12742. exports.save = save;
  12743. exports.load = load;
  12744. exports.useColors = useColors;
  12745. exports.storage = localstorage();
  12746. /**
  12747. * Colors.
  12748. */
  12749. exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33'];
  12750. /**
  12751. * Currently only WebKit-based Web Inspectors, Firefox >= v31,
  12752. * and the Firebug extension (any Firefox version) are known
  12753. * to support "%c" CSS customizations.
  12754. *
  12755. * TODO: add a `localStorage` variable to explicitly enable/disable colors
  12756. */
  12757. // eslint-disable-next-line complexity
  12758. function useColors() {
  12759. // NB: In an Electron preload script, document will be defined but not fully
  12760. // initialized. Since we know we're in Chrome, we'll just detect this case
  12761. // explicitly
  12762. if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
  12763. return true;
  12764. } // Internet Explorer and Edge do not support colors.
  12765. if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
  12766. return false;
  12767. } // Is webkit? http://stackoverflow.com/a/16459606/376773
  12768. // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
  12769. return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773
  12770. typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?
  12771. // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
  12772. typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker
  12773. typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
  12774. }
  12775. /**
  12776. * Colorize log arguments if enabled.
  12777. *
  12778. * @api public
  12779. */
  12780. function formatArgs(args) {
  12781. args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff);
  12782. if (!this.useColors) {
  12783. return;
  12784. }
  12785. var c = 'color: ' + this.color;
  12786. args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other
  12787. // arguments passed either before or after the %c, so we need to
  12788. // figure out the correct index to insert the CSS into
  12789. var index = 0;
  12790. var lastC = 0;
  12791. args[0].replace(/%[a-zA-Z%]/g, function (match) {
  12792. if (match === '%%') {
  12793. return;
  12794. }
  12795. index++;
  12796. if (match === '%c') {
  12797. // We only are interested in the *last* %c
  12798. // (the user may have provided their own)
  12799. lastC = index;
  12800. }
  12801. });
  12802. args.splice(lastC, 0, c);
  12803. }
  12804. /**
  12805. * Invokes `console.log()` when available.
  12806. * No-op when `console.log` is not a "function".
  12807. *
  12808. * @api public
  12809. */
  12810. function log() {
  12811. var _console;
  12812. // This hackery is required for IE8/9, where
  12813. // the `console.log` function doesn't have 'apply'
  12814. return (typeof console === "undefined" ? "undefined" : _typeof(console)) === 'object' && console.log && (_console = console).log.apply(_console, arguments);
  12815. }
  12816. /**
  12817. * Save `namespaces`.
  12818. *
  12819. * @param {String} namespaces
  12820. * @api private
  12821. */
  12822. function save(namespaces) {
  12823. try {
  12824. if (namespaces) {
  12825. exports.storage.setItem('debug', namespaces);
  12826. } else {
  12827. exports.storage.removeItem('debug');
  12828. }
  12829. } catch (error) {// Swallow
  12830. // XXX (@Qix-) should we be logging these?
  12831. }
  12832. }
  12833. /**
  12834. * Load `namespaces`.
  12835. *
  12836. * @return {String} returns the previously persisted debug modes
  12837. * @api private
  12838. */
  12839. function load() {
  12840. var r;
  12841. try {
  12842. r = exports.storage.getItem('debug');
  12843. } catch (error) {} // Swallow
  12844. // XXX (@Qix-) should we be logging these?
  12845. // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
  12846. if (!r && typeof process !== 'undefined' && 'env' in process) {
  12847. r = process.env.DEBUG;
  12848. }
  12849. return r;
  12850. }
  12851. /**
  12852. * Localstorage attempts to return the localstorage.
  12853. *
  12854. * This is necessary because safari throws
  12855. * when a user disables cookies/localstorage
  12856. * and you attempt to access it.
  12857. *
  12858. * @return {LocalStorage}
  12859. * @api private
  12860. */
  12861. function localstorage() {
  12862. try {
  12863. // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
  12864. // The Browser also has localStorage in the global context.
  12865. return localStorage;
  12866. } catch (error) {// Swallow
  12867. // XXX (@Qix-) should we be logging these?
  12868. }
  12869. }
  12870. module.exports = common(exports);
  12871. var formatters = module.exports.formatters;
  12872. /**
  12873. * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
  12874. */
  12875. formatters.j = function (v) {
  12876. try {
  12877. return JSON.stringify(v);
  12878. } catch (error) {
  12879. return '[UnexpectedJSONParseError]: ' + error.message;
  12880. }
  12881. };
  12882. });
  12883. var browser_1 = browser.log;
  12884. var browser_2 = browser.formatArgs;
  12885. var browser_3 = browser.save;
  12886. var browser_4 = browser.load;
  12887. var browser_5 = browser.useColors;
  12888. var browser_6 = browser.storage;
  12889. var browser_7 = browser.colors;
  12890. /**
  12891. * Copies the values of `source` to `array`.
  12892. *
  12893. * @private
  12894. * @param {Array} source The array to copy values from.
  12895. * @param {Array} [array=[]] The array to copy values to.
  12896. * @returns {Array} Returns `array`.
  12897. */
  12898. function copyArray(source, array) {
  12899. var index = -1,
  12900. length = source.length;
  12901. array || (array = Array(length));
  12902. while (++index < length) {
  12903. array[index] = source[index];
  12904. }
  12905. return array;
  12906. }
  12907. var _copyArray = copyArray;
  12908. /* Built-in method references for those with the same name as other `lodash` methods. */
  12909. var nativeFloor = Math.floor,
  12910. nativeRandom = Math.random;
  12911. /**
  12912. * The base implementation of `_.random` without support for returning
  12913. * floating-point numbers.
  12914. *
  12915. * @private
  12916. * @param {number} lower The lower bound.
  12917. * @param {number} upper The upper bound.
  12918. * @returns {number} Returns the random number.
  12919. */
  12920. function baseRandom(lower, upper) {
  12921. return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
  12922. }
  12923. var _baseRandom = baseRandom;
  12924. /**
  12925. * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
  12926. *
  12927. * @private
  12928. * @param {Array} array The array to shuffle.
  12929. * @param {number} [size=array.length] The size of `array`.
  12930. * @returns {Array} Returns `array`.
  12931. */
  12932. function shuffleSelf(array, size) {
  12933. var index = -1,
  12934. length = array.length,
  12935. lastIndex = length - 1;
  12936. size = size === undefined ? length : size;
  12937. while (++index < size) {
  12938. var rand = _baseRandom(index, lastIndex),
  12939. value = array[rand];
  12940. array[rand] = array[index];
  12941. array[index] = value;
  12942. }
  12943. array.length = size;
  12944. return array;
  12945. }
  12946. var _shuffleSelf = shuffleSelf;
  12947. /**
  12948. * A specialized version of `_.shuffle` for arrays.
  12949. *
  12950. * @private
  12951. * @param {Array} array The array to shuffle.
  12952. * @returns {Array} Returns the new shuffled array.
  12953. */
  12954. function arrayShuffle(array) {
  12955. return _shuffleSelf(_copyArray(array));
  12956. }
  12957. var _arrayShuffle = arrayShuffle;
  12958. /**
  12959. * A specialized version of `_.map` for arrays without support for iteratee
  12960. * shorthands.
  12961. *
  12962. * @private
  12963. * @param {Array} [array] The array to iterate over.
  12964. * @param {Function} iteratee The function invoked per iteration.
  12965. * @returns {Array} Returns the new mapped array.
  12966. */
  12967. function arrayMap(array, iteratee) {
  12968. var index = -1,
  12969. length = array == null ? 0 : array.length,
  12970. result = Array(length);
  12971. while (++index < length) {
  12972. result[index] = iteratee(array[index], index, array);
  12973. }
  12974. return result;
  12975. }
  12976. var _arrayMap = arrayMap;
  12977. /**
  12978. * The base implementation of `_.values` and `_.valuesIn` which creates an
  12979. * array of `object` property values corresponding to the property names
  12980. * of `props`.
  12981. *
  12982. * @private
  12983. * @param {Object} object The object to query.
  12984. * @param {Array} props The property names to get values for.
  12985. * @returns {Object} Returns the array of property values.
  12986. */
  12987. function baseValues(object, props) {
  12988. return _arrayMap(props, function(key) {
  12989. return object[key];
  12990. });
  12991. }
  12992. var _baseValues = baseValues;
  12993. /**
  12994. * The base implementation of `_.times` without support for iteratee shorthands
  12995. * or max array length checks.
  12996. *
  12997. * @private
  12998. * @param {number} n The number of times to invoke `iteratee`.
  12999. * @param {Function} iteratee The function invoked per iteration.
  13000. * @returns {Array} Returns the array of results.
  13001. */
  13002. function baseTimes(n, iteratee) {
  13003. var index = -1,
  13004. result = Array(n);
  13005. while (++index < n) {
  13006. result[index] = iteratee(index);
  13007. }
  13008. return result;
  13009. }
  13010. var _baseTimes = baseTimes;
  13011. /** Detect free variable `global` from Node.js. */
  13012. var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
  13013. var _freeGlobal = freeGlobal;
  13014. /** Detect free variable `self`. */
  13015. var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
  13016. /** Used as a reference to the global object. */
  13017. var root = _freeGlobal || freeSelf || Function('return this')();
  13018. var _root = root;
  13019. /** Built-in value references. */
  13020. var Symbol$1 = _root.Symbol;
  13021. var _Symbol = Symbol$1;
  13022. /** Used for built-in method references. */
  13023. var objectProto = Object.prototype;
  13024. /** Used to check objects for own properties. */
  13025. var hasOwnProperty = objectProto.hasOwnProperty;
  13026. /**
  13027. * Used to resolve the
  13028. * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
  13029. * of values.
  13030. */
  13031. var nativeObjectToString = objectProto.toString;
  13032. /** Built-in value references. */
  13033. var symToStringTag = _Symbol ? _Symbol.toStringTag : undefined;
  13034. /**
  13035. * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
  13036. *
  13037. * @private
  13038. * @param {*} value The value to query.
  13039. * @returns {string} Returns the raw `toStringTag`.
  13040. */
  13041. function getRawTag(value) {
  13042. var isOwn = hasOwnProperty.call(value, symToStringTag),
  13043. tag = value[symToStringTag];
  13044. try {
  13045. value[symToStringTag] = undefined;
  13046. var unmasked = true;
  13047. } catch (e) {}
  13048. var result = nativeObjectToString.call(value);
  13049. if (unmasked) {
  13050. if (isOwn) {
  13051. value[symToStringTag] = tag;
  13052. } else {
  13053. delete value[symToStringTag];
  13054. }
  13055. }
  13056. return result;
  13057. }
  13058. var _getRawTag = getRawTag;
  13059. /** Used for built-in method references. */
  13060. var objectProto$1 = Object.prototype;
  13061. /**
  13062. * Used to resolve the
  13063. * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
  13064. * of values.
  13065. */
  13066. var nativeObjectToString$1 = objectProto$1.toString;
  13067. /**
  13068. * Converts `value` to a string using `Object.prototype.toString`.
  13069. *
  13070. * @private
  13071. * @param {*} value The value to convert.
  13072. * @returns {string} Returns the converted string.
  13073. */
  13074. function objectToString(value) {
  13075. return nativeObjectToString$1.call(value);
  13076. }
  13077. var _objectToString = objectToString;
  13078. /** `Object#toString` result references. */
  13079. var nullTag = '[object Null]',
  13080. undefinedTag = '[object Undefined]';
  13081. /** Built-in value references. */
  13082. var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined;
  13083. /**
  13084. * The base implementation of `getTag` without fallbacks for buggy environments.
  13085. *
  13086. * @private
  13087. * @param {*} value The value to query.
  13088. * @returns {string} Returns the `toStringTag`.
  13089. */
  13090. function baseGetTag(value) {
  13091. if (value == null) {
  13092. return value === undefined ? undefinedTag : nullTag;
  13093. }
  13094. return (symToStringTag$1 && symToStringTag$1 in Object(value))
  13095. ? _getRawTag(value)
  13096. : _objectToString(value);
  13097. }
  13098. var _baseGetTag = baseGetTag;
  13099. /**
  13100. * Checks if `value` is object-like. A value is object-like if it's not `null`
  13101. * and has a `typeof` result of "object".
  13102. *
  13103. * @static
  13104. * @memberOf _
  13105. * @since 4.0.0
  13106. * @category Lang
  13107. * @param {*} value The value to check.
  13108. * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
  13109. * @example
  13110. *
  13111. * _.isObjectLike({});
  13112. * // => true
  13113. *
  13114. * _.isObjectLike([1, 2, 3]);
  13115. * // => true
  13116. *
  13117. * _.isObjectLike(_.noop);
  13118. * // => false
  13119. *
  13120. * _.isObjectLike(null);
  13121. * // => false
  13122. */
  13123. function isObjectLike(value) {
  13124. return value != null && typeof value == 'object';
  13125. }
  13126. var isObjectLike_1 = isObjectLike;
  13127. /** `Object#toString` result references. */
  13128. var argsTag = '[object Arguments]';
  13129. /**
  13130. * The base implementation of `_.isArguments`.
  13131. *
  13132. * @private
  13133. * @param {*} value The value to check.
  13134. * @returns {boolean} Returns `true` if `value` is an `arguments` object,
  13135. */
  13136. function baseIsArguments(value) {
  13137. return isObjectLike_1(value) && _baseGetTag(value) == argsTag;
  13138. }
  13139. var _baseIsArguments = baseIsArguments;
  13140. /** Used for built-in method references. */
  13141. var objectProto$2 = Object.prototype;
  13142. /** Used to check objects for own properties. */
  13143. var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
  13144. /** Built-in value references. */
  13145. var propertyIsEnumerable = objectProto$2.propertyIsEnumerable;
  13146. /**
  13147. * Checks if `value` is likely an `arguments` object.
  13148. *
  13149. * @static
  13150. * @memberOf _
  13151. * @since 0.1.0
  13152. * @category Lang
  13153. * @param {*} value The value to check.
  13154. * @returns {boolean} Returns `true` if `value` is an `arguments` object,
  13155. * else `false`.
  13156. * @example
  13157. *
  13158. * _.isArguments(function() { return arguments; }());
  13159. * // => true
  13160. *
  13161. * _.isArguments([1, 2, 3]);
  13162. * // => false
  13163. */
  13164. var isArguments = _baseIsArguments(function() { return arguments; }()) ? _baseIsArguments : function(value) {
  13165. return isObjectLike_1(value) && hasOwnProperty$1.call(value, 'callee') &&
  13166. !propertyIsEnumerable.call(value, 'callee');
  13167. };
  13168. var isArguments_1 = isArguments;
  13169. /**
  13170. * Checks if `value` is classified as an `Array` object.
  13171. *
  13172. * @static
  13173. * @memberOf _
  13174. * @since 0.1.0
  13175. * @category Lang
  13176. * @param {*} value The value to check.
  13177. * @returns {boolean} Returns `true` if `value` is an array, else `false`.
  13178. * @example
  13179. *
  13180. * _.isArray([1, 2, 3]);
  13181. * // => true
  13182. *
  13183. * _.isArray(document.body.children);
  13184. * // => false
  13185. *
  13186. * _.isArray('abc');
  13187. * // => false
  13188. *
  13189. * _.isArray(_.noop);
  13190. * // => false
  13191. */
  13192. var isArray = Array.isArray;
  13193. var isArray_1 = isArray;
  13194. /**
  13195. * This method returns `false`.
  13196. *
  13197. * @static
  13198. * @memberOf _
  13199. * @since 4.13.0
  13200. * @category Util
  13201. * @returns {boolean} Returns `false`.
  13202. * @example
  13203. *
  13204. * _.times(2, _.stubFalse);
  13205. * // => [false, false]
  13206. */
  13207. function stubFalse() {
  13208. return false;
  13209. }
  13210. var stubFalse_1 = stubFalse;
  13211. var isBuffer_1 = createCommonjsModule(function (module, exports) {
  13212. /** Detect free variable `exports`. */
  13213. var freeExports = exports && !exports.nodeType && exports;
  13214. /** Detect free variable `module`. */
  13215. var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
  13216. /** Detect the popular CommonJS extension `module.exports`. */
  13217. var moduleExports = freeModule && freeModule.exports === freeExports;
  13218. /** Built-in value references. */
  13219. var Buffer = moduleExports ? _root.Buffer : undefined;
  13220. /* Built-in method references for those with the same name as other `lodash` methods. */
  13221. var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
  13222. /**
  13223. * Checks if `value` is a buffer.
  13224. *
  13225. * @static
  13226. * @memberOf _
  13227. * @since 4.3.0
  13228. * @category Lang
  13229. * @param {*} value The value to check.
  13230. * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
  13231. * @example
  13232. *
  13233. * _.isBuffer(new Buffer(2));
  13234. * // => true
  13235. *
  13236. * _.isBuffer(new Uint8Array(2));
  13237. * // => false
  13238. */
  13239. var isBuffer = nativeIsBuffer || stubFalse_1;
  13240. module.exports = isBuffer;
  13241. });
  13242. /** Used as references for various `Number` constants. */
  13243. var MAX_SAFE_INTEGER = 9007199254740991;
  13244. /** Used to detect unsigned integer values. */
  13245. var reIsUint = /^(?:0|[1-9]\d*)$/;
  13246. /**
  13247. * Checks if `value` is a valid array-like index.
  13248. *
  13249. * @private
  13250. * @param {*} value The value to check.
  13251. * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
  13252. * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
  13253. */
  13254. function isIndex(value, length) {
  13255. var type = typeof value;
  13256. length = length == null ? MAX_SAFE_INTEGER : length;
  13257. return !!length &&
  13258. (type == 'number' ||
  13259. (type != 'symbol' && reIsUint.test(value))) &&
  13260. (value > -1 && value % 1 == 0 && value < length);
  13261. }
  13262. var _isIndex = isIndex;
  13263. /** Used as references for various `Number` constants. */
  13264. var MAX_SAFE_INTEGER$1 = 9007199254740991;
  13265. /**
  13266. * Checks if `value` is a valid array-like length.
  13267. *
  13268. * **Note:** This method is loosely based on
  13269. * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
  13270. *
  13271. * @static
  13272. * @memberOf _
  13273. * @since 4.0.0
  13274. * @category Lang
  13275. * @param {*} value The value to check.
  13276. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
  13277. * @example
  13278. *
  13279. * _.isLength(3);
  13280. * // => true
  13281. *
  13282. * _.isLength(Number.MIN_VALUE);
  13283. * // => false
  13284. *
  13285. * _.isLength(Infinity);
  13286. * // => false
  13287. *
  13288. * _.isLength('3');
  13289. * // => false
  13290. */
  13291. function isLength(value) {
  13292. return typeof value == 'number' &&
  13293. value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1;
  13294. }
  13295. var isLength_1 = isLength;
  13296. /** `Object#toString` result references. */
  13297. var argsTag$1 = '[object Arguments]',
  13298. arrayTag = '[object Array]',
  13299. boolTag = '[object Boolean]',
  13300. dateTag = '[object Date]',
  13301. errorTag = '[object Error]',
  13302. funcTag = '[object Function]',
  13303. mapTag = '[object Map]',
  13304. numberTag = '[object Number]',
  13305. objectTag = '[object Object]',
  13306. regexpTag = '[object RegExp]',
  13307. setTag = '[object Set]',
  13308. stringTag = '[object String]',
  13309. weakMapTag = '[object WeakMap]';
  13310. var arrayBufferTag = '[object ArrayBuffer]',
  13311. dataViewTag = '[object DataView]',
  13312. float32Tag = '[object Float32Array]',
  13313. float64Tag = '[object Float64Array]',
  13314. int8Tag = '[object Int8Array]',
  13315. int16Tag = '[object Int16Array]',
  13316. int32Tag = '[object Int32Array]',
  13317. uint8Tag = '[object Uint8Array]',
  13318. uint8ClampedTag = '[object Uint8ClampedArray]',
  13319. uint16Tag = '[object Uint16Array]',
  13320. uint32Tag = '[object Uint32Array]';
  13321. /** Used to identify `toStringTag` values of typed arrays. */
  13322. var typedArrayTags = {};
  13323. typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
  13324. typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
  13325. typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
  13326. typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
  13327. typedArrayTags[uint32Tag] = true;
  13328. typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] =
  13329. typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
  13330. typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
  13331. typedArrayTags[errorTag] = typedArrayTags[funcTag] =
  13332. typedArrayTags[mapTag] = typedArrayTags[numberTag] =
  13333. typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
  13334. typedArrayTags[setTag] = typedArrayTags[stringTag] =
  13335. typedArrayTags[weakMapTag] = false;
  13336. /**
  13337. * The base implementation of `_.isTypedArray` without Node.js optimizations.
  13338. *
  13339. * @private
  13340. * @param {*} value The value to check.
  13341. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
  13342. */
  13343. function baseIsTypedArray(value) {
  13344. return isObjectLike_1(value) &&
  13345. isLength_1(value.length) && !!typedArrayTags[_baseGetTag(value)];
  13346. }
  13347. var _baseIsTypedArray = baseIsTypedArray;
  13348. /**
  13349. * The base implementation of `_.unary` without support for storing metadata.
  13350. *
  13351. * @private
  13352. * @param {Function} func The function to cap arguments for.
  13353. * @returns {Function} Returns the new capped function.
  13354. */
  13355. function baseUnary(func) {
  13356. return function(value) {
  13357. return func(value);
  13358. };
  13359. }
  13360. var _baseUnary = baseUnary;
  13361. var _nodeUtil = createCommonjsModule(function (module, exports) {
  13362. /** Detect free variable `exports`. */
  13363. var freeExports = exports && !exports.nodeType && exports;
  13364. /** Detect free variable `module`. */
  13365. var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
  13366. /** Detect the popular CommonJS extension `module.exports`. */
  13367. var moduleExports = freeModule && freeModule.exports === freeExports;
  13368. /** Detect free variable `process` from Node.js. */
  13369. var freeProcess = moduleExports && _freeGlobal.process;
  13370. /** Used to access faster Node.js helpers. */
  13371. var nodeUtil = (function() {
  13372. try {
  13373. // Use `util.types` for Node.js 10+.
  13374. var types = freeModule && freeModule.require && freeModule.require('util').types;
  13375. if (types) {
  13376. return types;
  13377. }
  13378. // Legacy `process.binding('util')` for Node.js < 10.
  13379. return freeProcess && freeProcess.binding && freeProcess.binding('util');
  13380. } catch (e) {}
  13381. }());
  13382. module.exports = nodeUtil;
  13383. });
  13384. /* Node.js helper references. */
  13385. var nodeIsTypedArray = _nodeUtil && _nodeUtil.isTypedArray;
  13386. /**
  13387. * Checks if `value` is classified as a typed array.
  13388. *
  13389. * @static
  13390. * @memberOf _
  13391. * @since 3.0.0
  13392. * @category Lang
  13393. * @param {*} value The value to check.
  13394. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
  13395. * @example
  13396. *
  13397. * _.isTypedArray(new Uint8Array);
  13398. * // => true
  13399. *
  13400. * _.isTypedArray([]);
  13401. * // => false
  13402. */
  13403. var isTypedArray = nodeIsTypedArray ? _baseUnary(nodeIsTypedArray) : _baseIsTypedArray;
  13404. var isTypedArray_1 = isTypedArray;
  13405. /** Used for built-in method references. */
  13406. var objectProto$3 = Object.prototype;
  13407. /** Used to check objects for own properties. */
  13408. var hasOwnProperty$2 = objectProto$3.hasOwnProperty;
  13409. /**
  13410. * Creates an array of the enumerable property names of the array-like `value`.
  13411. *
  13412. * @private
  13413. * @param {*} value The value to query.
  13414. * @param {boolean} inherited Specify returning inherited property names.
  13415. * @returns {Array} Returns the array of property names.
  13416. */
  13417. function arrayLikeKeys(value, inherited) {
  13418. var isArr = isArray_1(value),
  13419. isArg = !isArr && isArguments_1(value),
  13420. isBuff = !isArr && !isArg && isBuffer_1(value),
  13421. isType = !isArr && !isArg && !isBuff && isTypedArray_1(value),
  13422. skipIndexes = isArr || isArg || isBuff || isType,
  13423. result = skipIndexes ? _baseTimes(value.length, String) : [],
  13424. length = result.length;
  13425. for (var key in value) {
  13426. if ((inherited || hasOwnProperty$2.call(value, key)) &&
  13427. !(skipIndexes && (
  13428. // Safari 9 has enumerable `arguments.length` in strict mode.
  13429. key == 'length' ||
  13430. // Node.js 0.10 has enumerable non-index properties on buffers.
  13431. (isBuff && (key == 'offset' || key == 'parent')) ||
  13432. // PhantomJS 2 has enumerable non-index properties on typed arrays.
  13433. (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
  13434. // Skip index properties.
  13435. _isIndex(key, length)
  13436. ))) {
  13437. result.push(key);
  13438. }
  13439. }
  13440. return result;
  13441. }
  13442. var _arrayLikeKeys = arrayLikeKeys;
  13443. /** Used for built-in method references. */
  13444. var objectProto$4 = Object.prototype;
  13445. /**
  13446. * Checks if `value` is likely a prototype object.
  13447. *
  13448. * @private
  13449. * @param {*} value The value to check.
  13450. * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
  13451. */
  13452. function isPrototype(value) {
  13453. var Ctor = value && value.constructor,
  13454. proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$4;
  13455. return value === proto;
  13456. }
  13457. var _isPrototype = isPrototype;
  13458. /**
  13459. * Creates a unary function that invokes `func` with its argument transformed.
  13460. *
  13461. * @private
  13462. * @param {Function} func The function to wrap.
  13463. * @param {Function} transform The argument transform.
  13464. * @returns {Function} Returns the new function.
  13465. */
  13466. function overArg(func, transform) {
  13467. return function(arg) {
  13468. return func(transform(arg));
  13469. };
  13470. }
  13471. var _overArg = overArg;
  13472. /* Built-in method references for those with the same name as other `lodash` methods. */
  13473. var nativeKeys = _overArg(Object.keys, Object);
  13474. var _nativeKeys = nativeKeys;
  13475. /** Used for built-in method references. */
  13476. var objectProto$5 = Object.prototype;
  13477. /** Used to check objects for own properties. */
  13478. var hasOwnProperty$3 = objectProto$5.hasOwnProperty;
  13479. /**
  13480. * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
  13481. *
  13482. * @private
  13483. * @param {Object} object The object to query.
  13484. * @returns {Array} Returns the array of property names.
  13485. */
  13486. function baseKeys(object) {
  13487. if (!_isPrototype(object)) {
  13488. return _nativeKeys(object);
  13489. }
  13490. var result = [];
  13491. for (var key in Object(object)) {
  13492. if (hasOwnProperty$3.call(object, key) && key != 'constructor') {
  13493. result.push(key);
  13494. }
  13495. }
  13496. return result;
  13497. }
  13498. var _baseKeys = baseKeys;
  13499. /**
  13500. * Checks if `value` is the
  13501. * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
  13502. * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  13503. *
  13504. * @static
  13505. * @memberOf _
  13506. * @since 0.1.0
  13507. * @category Lang
  13508. * @param {*} value The value to check.
  13509. * @returns {boolean} Returns `true` if `value` is an object, else `false`.
  13510. * @example
  13511. *
  13512. * _.isObject({});
  13513. * // => true
  13514. *
  13515. * _.isObject([1, 2, 3]);
  13516. * // => true
  13517. *
  13518. * _.isObject(_.noop);
  13519. * // => true
  13520. *
  13521. * _.isObject(null);
  13522. * // => false
  13523. */
  13524. function isObject$1(value) {
  13525. var type = typeof value;
  13526. return value != null && (type == 'object' || type == 'function');
  13527. }
  13528. var isObject_1$1 = isObject$1;
  13529. /** `Object#toString` result references. */
  13530. var asyncTag = '[object AsyncFunction]',
  13531. funcTag$1 = '[object Function]',
  13532. genTag = '[object GeneratorFunction]',
  13533. proxyTag = '[object Proxy]';
  13534. /**
  13535. * Checks if `value` is classified as a `Function` object.
  13536. *
  13537. * @static
  13538. * @memberOf _
  13539. * @since 0.1.0
  13540. * @category Lang
  13541. * @param {*} value The value to check.
  13542. * @returns {boolean} Returns `true` if `value` is a function, else `false`.
  13543. * @example
  13544. *
  13545. * _.isFunction(_);
  13546. * // => true
  13547. *
  13548. * _.isFunction(/abc/);
  13549. * // => false
  13550. */
  13551. function isFunction(value) {
  13552. if (!isObject_1$1(value)) {
  13553. return false;
  13554. }
  13555. // The use of `Object#toString` avoids issues with the `typeof` operator
  13556. // in Safari 9 which returns 'object' for typed arrays and other constructors.
  13557. var tag = _baseGetTag(value);
  13558. return tag == funcTag$1 || tag == genTag || tag == asyncTag || tag == proxyTag;
  13559. }
  13560. var isFunction_1 = isFunction;
  13561. /**
  13562. * Checks if `value` is array-like. A value is considered array-like if it's
  13563. * not a function and has a `value.length` that's an integer greater than or
  13564. * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
  13565. *
  13566. * @static
  13567. * @memberOf _
  13568. * @since 4.0.0
  13569. * @category Lang
  13570. * @param {*} value The value to check.
  13571. * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
  13572. * @example
  13573. *
  13574. * _.isArrayLike([1, 2, 3]);
  13575. * // => true
  13576. *
  13577. * _.isArrayLike(document.body.children);
  13578. * // => true
  13579. *
  13580. * _.isArrayLike('abc');
  13581. * // => true
  13582. *
  13583. * _.isArrayLike(_.noop);
  13584. * // => false
  13585. */
  13586. function isArrayLike(value) {
  13587. return value != null && isLength_1(value.length) && !isFunction_1(value);
  13588. }
  13589. var isArrayLike_1 = isArrayLike;
  13590. /**
  13591. * Creates an array of the own enumerable property names of `object`.
  13592. *
  13593. * **Note:** Non-object values are coerced to objects. See the
  13594. * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
  13595. * for more details.
  13596. *
  13597. * @static
  13598. * @since 0.1.0
  13599. * @memberOf _
  13600. * @category Object
  13601. * @param {Object} object The object to query.
  13602. * @returns {Array} Returns the array of property names.
  13603. * @example
  13604. *
  13605. * function Foo() {
  13606. * this.a = 1;
  13607. * this.b = 2;
  13608. * }
  13609. *
  13610. * Foo.prototype.c = 3;
  13611. *
  13612. * _.keys(new Foo);
  13613. * // => ['a', 'b'] (iteration order is not guaranteed)
  13614. *
  13615. * _.keys('hi');
  13616. * // => ['0', '1']
  13617. */
  13618. function keys(object) {
  13619. return isArrayLike_1(object) ? _arrayLikeKeys(object) : _baseKeys(object);
  13620. }
  13621. var keys_1 = keys;
  13622. /**
  13623. * Creates an array of the own enumerable string keyed property values of `object`.
  13624. *
  13625. * **Note:** Non-object values are coerced to objects.
  13626. *
  13627. * @static
  13628. * @since 0.1.0
  13629. * @memberOf _
  13630. * @category Object
  13631. * @param {Object} object The object to query.
  13632. * @returns {Array} Returns the array of property values.
  13633. * @example
  13634. *
  13635. * function Foo() {
  13636. * this.a = 1;
  13637. * this.b = 2;
  13638. * }
  13639. *
  13640. * Foo.prototype.c = 3;
  13641. *
  13642. * _.values(new Foo);
  13643. * // => [1, 2] (iteration order is not guaranteed)
  13644. *
  13645. * _.values('hi');
  13646. * // => ['h', 'i']
  13647. */
  13648. function values(object) {
  13649. return object == null ? [] : _baseValues(object, keys_1(object));
  13650. }
  13651. var values_1 = values;
  13652. /**
  13653. * The base implementation of `_.shuffle`.
  13654. *
  13655. * @private
  13656. * @param {Array|Object} collection The collection to shuffle.
  13657. * @returns {Array} Returns the new shuffled array.
  13658. */
  13659. function baseShuffle(collection) {
  13660. return _shuffleSelf(values_1(collection));
  13661. }
  13662. var _baseShuffle = baseShuffle;
  13663. /**
  13664. * Creates an array of shuffled values, using a version of the
  13665. * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
  13666. *
  13667. * @static
  13668. * @memberOf _
  13669. * @since 0.1.0
  13670. * @category Collection
  13671. * @param {Array|Object} collection The collection to shuffle.
  13672. * @returns {Array} Returns the new shuffled array.
  13673. * @example
  13674. *
  13675. * _.shuffle([1, 2, 3, 4]);
  13676. * // => [4, 1, 3, 2]
  13677. */
  13678. function shuffle(collection) {
  13679. var func = isArray_1(collection) ? _arrayShuffle : _baseShuffle;
  13680. return func(collection);
  13681. }
  13682. var shuffle_1 = shuffle;
  13683. function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
  13684. var desc = {};
  13685. Object.keys(descriptor).forEach(function (key) {
  13686. desc[key] = descriptor[key];
  13687. });
  13688. desc.enumerable = !!desc.enumerable;
  13689. desc.configurable = !!desc.configurable;
  13690. if ('value' in desc || desc.initializer) {
  13691. desc.writable = true;
  13692. }
  13693. desc = decorators.slice().reverse().reduce(function (desc, decorator) {
  13694. return decorator(target, property, desc) || desc;
  13695. }, desc);
  13696. if (context && desc.initializer !== void 0) {
  13697. desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
  13698. desc.initializer = undefined;
  13699. }
  13700. if (desc.initializer === void 0) {
  13701. Object.defineProperty(target, property, desc);
  13702. desc = null;
  13703. }
  13704. return desc;
  13705. }
  13706. var stateMachine = createCommonjsModule(function (module, exports) {
  13707. /*
  13708. Javascript State Machine Library - https://github.com/jakesgordon/javascript-state-machine
  13709. Copyright (c) 2012, 2013, 2014, 2015, Jake Gordon and contributors
  13710. Released under the MIT license - https://github.com/jakesgordon/javascript-state-machine/blob/master/LICENSE
  13711. */
  13712. (function () {
  13713. var StateMachine = {
  13714. //---------------------------------------------------------------------------
  13715. VERSION: "2.4.0",
  13716. //---------------------------------------------------------------------------
  13717. Result: {
  13718. SUCCEEDED: 1, // the event transitioned successfully from one state to another
  13719. NOTRANSITION: 2, // the event was successfull but no state transition was necessary
  13720. CANCELLED: 3, // the event was cancelled by the caller in a beforeEvent callback
  13721. PENDING: 4 // the event is asynchronous and the caller is in control of when the transition occurs
  13722. },
  13723. Error: {
  13724. INVALID_TRANSITION: 100, // caller tried to fire an event that was innapropriate in the current state
  13725. PENDING_TRANSITION: 200, // caller tried to fire an event while an async transition was still pending
  13726. INVALID_CALLBACK: 300 // caller provided callback function threw an exception
  13727. },
  13728. WILDCARD: '*',
  13729. ASYNC: 'async',
  13730. //---------------------------------------------------------------------------
  13731. create: function(cfg, target) {
  13732. var initial = (typeof cfg.initial == 'string') ? { state: cfg.initial } : cfg.initial; // allow for a simple string, or an object with { state: 'foo', event: 'setup', defer: true|false }
  13733. var terminal = cfg.terminal || cfg['final'];
  13734. var fsm = target || cfg.target || {};
  13735. var events = cfg.events || [];
  13736. var callbacks = cfg.callbacks || {};
  13737. var map = {}; // track state transitions allowed for an event { event: { from: [ to ] } }
  13738. var transitions = {}; // track events allowed from a state { state: [ event ] }
  13739. var add = function(e) {
  13740. var from = Array.isArray(e.from) ? e.from : (e.from ? [e.from] : [StateMachine.WILDCARD]); // allow 'wildcard' transition if 'from' is not specified
  13741. map[e.name] = map[e.name] || {};
  13742. for (var n = 0 ; n < from.length ; n++) {
  13743. transitions[from[n]] = transitions[from[n]] || [];
  13744. transitions[from[n]].push(e.name);
  13745. map[e.name][from[n]] = e.to || from[n]; // allow no-op transition if 'to' is not specified
  13746. }
  13747. if (e.to)
  13748. transitions[e.to] = transitions[e.to] || [];
  13749. };
  13750. if (initial) {
  13751. initial.event = initial.event || 'startup';
  13752. add({ name: initial.event, from: 'none', to: initial.state });
  13753. }
  13754. for(var n = 0 ; n < events.length ; n++)
  13755. add(events[n]);
  13756. for(var name in map) {
  13757. if (map.hasOwnProperty(name))
  13758. fsm[name] = StateMachine.buildEvent(name, map[name]);
  13759. }
  13760. for(var name in callbacks) {
  13761. if (callbacks.hasOwnProperty(name))
  13762. fsm[name] = callbacks[name];
  13763. }
  13764. fsm.current = 'none';
  13765. fsm.is = function(state) { return Array.isArray(state) ? (state.indexOf(this.current) >= 0) : (this.current === state); };
  13766. fsm.can = function(event) { return !this.transition && (map[event] !== undefined) && (map[event].hasOwnProperty(this.current) || map[event].hasOwnProperty(StateMachine.WILDCARD)); };
  13767. fsm.cannot = function(event) { return !this.can(event); };
  13768. fsm.transitions = function() { return (transitions[this.current] || []).concat(transitions[StateMachine.WILDCARD] || []); };
  13769. fsm.isFinished = function() { return this.is(terminal); };
  13770. fsm.error = cfg.error || function(name, from, to, args, error, msg, e) { throw e || msg; }; // default behavior when something unexpected happens is to throw an exception, but caller can override this behavior if desired (see github issue #3 and #17)
  13771. fsm.states = function() { return Object.keys(transitions).sort() };
  13772. if (initial && !initial.defer)
  13773. fsm[initial.event]();
  13774. return fsm;
  13775. },
  13776. //===========================================================================
  13777. doCallback: function(fsm, func, name, from, to, args) {
  13778. if (func) {
  13779. try {
  13780. return func.apply(fsm, [name, from, to].concat(args));
  13781. }
  13782. catch(e) {
  13783. return fsm.error(name, from, to, args, StateMachine.Error.INVALID_CALLBACK, "an exception occurred in a caller-provided callback function", e);
  13784. }
  13785. }
  13786. },
  13787. beforeAnyEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbeforeevent'], name, from, to, args); },
  13788. afterAnyEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafterevent'] || fsm['onevent'], name, from, to, args); },
  13789. leaveAnyState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleavestate'], name, from, to, args); },
  13790. enterAnyState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenterstate'] || fsm['onstate'], name, from, to, args); },
  13791. changeState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onchangestate'], name, from, to, args); },
  13792. beforeThisEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbefore' + name], name, from, to, args); },
  13793. afterThisEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafter' + name] || fsm['on' + name], name, from, to, args); },
  13794. leaveThisState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleave' + from], name, from, to, args); },
  13795. enterThisState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenter' + to] || fsm['on' + to], name, from, to, args); },
  13796. beforeEvent: function(fsm, name, from, to, args) {
  13797. if ((false === StateMachine.beforeThisEvent(fsm, name, from, to, args)) ||
  13798. (false === StateMachine.beforeAnyEvent( fsm, name, from, to, args)))
  13799. return false;
  13800. },
  13801. afterEvent: function(fsm, name, from, to, args) {
  13802. StateMachine.afterThisEvent(fsm, name, from, to, args);
  13803. StateMachine.afterAnyEvent( fsm, name, from, to, args);
  13804. },
  13805. leaveState: function(fsm, name, from, to, args) {
  13806. var specific = StateMachine.leaveThisState(fsm, name, from, to, args),
  13807. general = StateMachine.leaveAnyState( fsm, name, from, to, args);
  13808. if ((false === specific) || (false === general))
  13809. return false;
  13810. else if ((StateMachine.ASYNC === specific) || (StateMachine.ASYNC === general))
  13811. return StateMachine.ASYNC;
  13812. },
  13813. enterState: function(fsm, name, from, to, args) {
  13814. StateMachine.enterThisState(fsm, name, from, to, args);
  13815. StateMachine.enterAnyState( fsm, name, from, to, args);
  13816. },
  13817. //===========================================================================
  13818. buildEvent: function(name, map) {
  13819. return function() {
  13820. var from = this.current;
  13821. var to = map[from] || (map[StateMachine.WILDCARD] != StateMachine.WILDCARD ? map[StateMachine.WILDCARD] : from) || from;
  13822. var args = Array.prototype.slice.call(arguments); // turn arguments into pure array
  13823. if (this.transition)
  13824. return this.error(name, from, to, args, StateMachine.Error.PENDING_TRANSITION, "event " + name + " inappropriate because previous transition did not complete");
  13825. if (this.cannot(name))
  13826. return this.error(name, from, to, args, StateMachine.Error.INVALID_TRANSITION, "event " + name + " inappropriate in current state " + this.current);
  13827. if (false === StateMachine.beforeEvent(this, name, from, to, args))
  13828. return StateMachine.Result.CANCELLED;
  13829. if (from === to) {
  13830. StateMachine.afterEvent(this, name, from, to, args);
  13831. return StateMachine.Result.NOTRANSITION;
  13832. }
  13833. // prepare a transition method for use EITHER lower down, or by caller if they want an async transition (indicated by an ASYNC return value from leaveState)
  13834. var fsm = this;
  13835. this.transition = function() {
  13836. fsm.transition = null; // this method should only ever be called once
  13837. fsm.current = to;
  13838. StateMachine.enterState( fsm, name, from, to, args);
  13839. StateMachine.changeState(fsm, name, from, to, args);
  13840. StateMachine.afterEvent( fsm, name, from, to, args);
  13841. return StateMachine.Result.SUCCEEDED;
  13842. };
  13843. this.transition.cancel = function() { // provide a way for caller to cancel async transition if desired (issue #22)
  13844. fsm.transition = null;
  13845. StateMachine.afterEvent(fsm, name, from, to, args);
  13846. };
  13847. var leave = StateMachine.leaveState(this, name, from, to, args);
  13848. if (false === leave) {
  13849. this.transition = null;
  13850. return StateMachine.Result.CANCELLED;
  13851. }
  13852. else if (StateMachine.ASYNC === leave) {
  13853. return StateMachine.Result.PENDING;
  13854. }
  13855. else {
  13856. if (this.transition) // need to check in case user manually called transition() but forgot to return StateMachine.ASYNC
  13857. return this.transition();
  13858. }
  13859. };
  13860. }
  13861. }; // StateMachine
  13862. //===========================================================================
  13863. //======
  13864. // NODE
  13865. //======
  13866. {
  13867. if ( module.exports) {
  13868. exports = module.exports = StateMachine;
  13869. }
  13870. exports.StateMachine = StateMachine;
  13871. }
  13872. }());
  13873. });
  13874. var stateMachine_1 = stateMachine.StateMachine;
  13875. const adapters = {};
  13876. const getAdapter = name => {
  13877. const adapter = adapters[name];
  13878. if (adapter === undefined) {
  13879. throw new Error(`${name} adapter is not configured`);
  13880. }
  13881. return adapter;
  13882. };
  13883. /**
  13884. * 指定 Adapters
  13885. * @function
  13886. * @memberof module:leancloud-realtime
  13887. * @param {Adapters} newAdapters Adapters 的类型请参考 {@link https://url.leanapp.cn/adapter-type-definitions @leancloud/adapter-types} 中的定义
  13888. */
  13889. const setAdapters = newAdapters => {
  13890. Object.assign(adapters, newAdapters);
  13891. };
  13892. /** Built-in value references. */
  13893. var getPrototype = _overArg(Object.getPrototypeOf, Object);
  13894. var _getPrototype = getPrototype;
  13895. /** `Object#toString` result references. */
  13896. var objectTag$1 = '[object Object]';
  13897. /** Used for built-in method references. */
  13898. var funcProto = Function.prototype,
  13899. objectProto$6 = Object.prototype;
  13900. /** Used to resolve the decompiled source of functions. */
  13901. var funcToString = funcProto.toString;
  13902. /** Used to check objects for own properties. */
  13903. var hasOwnProperty$4 = objectProto$6.hasOwnProperty;
  13904. /** Used to infer the `Object` constructor. */
  13905. var objectCtorString = funcToString.call(Object);
  13906. /**
  13907. * Checks if `value` is a plain object, that is, an object created by the
  13908. * `Object` constructor or one with a `[[Prototype]]` of `null`.
  13909. *
  13910. * @static
  13911. * @memberOf _
  13912. * @since 0.8.0
  13913. * @category Lang
  13914. * @param {*} value The value to check.
  13915. * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
  13916. * @example
  13917. *
  13918. * function Foo() {
  13919. * this.a = 1;
  13920. * }
  13921. *
  13922. * _.isPlainObject(new Foo);
  13923. * // => false
  13924. *
  13925. * _.isPlainObject([1, 2, 3]);
  13926. * // => false
  13927. *
  13928. * _.isPlainObject({ 'x': 0, 'y': 0 });
  13929. * // => true
  13930. *
  13931. * _.isPlainObject(Object.create(null));
  13932. * // => true
  13933. */
  13934. function isPlainObject(value) {
  13935. if (!isObjectLike_1(value) || _baseGetTag(value) != objectTag$1) {
  13936. return false;
  13937. }
  13938. var proto = _getPrototype(value);
  13939. if (proto === null) {
  13940. return true;
  13941. }
  13942. var Ctor = hasOwnProperty$4.call(proto, 'constructor') && proto.constructor;
  13943. return typeof Ctor == 'function' && Ctor instanceof Ctor &&
  13944. funcToString.call(Ctor) == objectCtorString;
  13945. }
  13946. var isPlainObject_1 = isPlainObject;
  13947. /* eslint-disable */
  13948. var global$1 = typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : {};
  13949. const EXPIRED = Symbol('expired');
  13950. const debug = browser('LC:Expirable');
  13951. class Expirable {
  13952. constructor(value, ttl) {
  13953. this.originalValue = value;
  13954. if (typeof ttl === 'number') {
  13955. this.expiredAt = Date.now() + ttl;
  13956. }
  13957. }
  13958. get value() {
  13959. const expired = this.expiredAt && this.expiredAt <= Date.now();
  13960. if (expired) debug(`expired: ${this.originalValue}`);
  13961. return expired ? EXPIRED : this.originalValue;
  13962. }
  13963. }
  13964. Expirable.EXPIRED = EXPIRED;
  13965. const debug$1 = browser('LC:Cache');
  13966. class Cache {
  13967. constructor(name = 'anonymous') {
  13968. this.name = name;
  13969. this._map = {};
  13970. }
  13971. get(key) {
  13972. const cache = this._map[key];
  13973. if (cache) {
  13974. const {
  13975. value
  13976. } = cache;
  13977. if (value !== Expirable.EXPIRED) {
  13978. debug$1('[%s] hit: %s', this.name, key);
  13979. return value;
  13980. }
  13981. delete this._map[key];
  13982. }
  13983. debug$1(`[${this.name}] missed: ${key}`);
  13984. return null;
  13985. }
  13986. set(key, value, ttl) {
  13987. debug$1('[%s] set: %s %d', this.name, key, ttl);
  13988. this._map[key] = new Expirable(value, ttl);
  13989. }
  13990. }
  13991. /**
  13992. * 调试日志控制器
  13993. * @const
  13994. * @memberof module:leancloud-realtime
  13995. * @example
  13996. * debug.enable(); // 启用调试日志
  13997. * debug.disable(); // 关闭调试日志
  13998. */
  13999. const debug$2 = {
  14000. enable: (namespaces = 'LC*') => browser.enable(namespaces),
  14001. disable: browser.disable
  14002. };
  14003. const tryAll = promiseConstructors => {
  14004. const promise = new Promise(promiseConstructors[0]);
  14005. if (promiseConstructors.length === 1) {
  14006. return promise;
  14007. }
  14008. return promise.catch(() => tryAll(promiseConstructors.slice(1)));
  14009. }; // eslint-disable-next-line no-sequences
  14010. const tap = interceptor => value => (interceptor(value), value);
  14011. const finalize = callback => [// eslint-disable-next-line no-sequences
  14012. value => (callback(), value), error => {
  14013. callback();
  14014. throw error;
  14015. }];
  14016. /**
  14017. * 将对象转换为 Date,支持 string、number、ProtoBuf Long 以及 LeanCloud 的 Date 类型,
  14018. * 其他情况下(包括对象为 falsy)返回原值。
  14019. * @private
  14020. */
  14021. const decodeDate = date => {
  14022. if (!date) return date;
  14023. if (typeof date === 'string' || typeof date === 'number') {
  14024. return new Date(date);
  14025. }
  14026. if (date.__type === 'Date' && date.iso) {
  14027. return new Date(date.iso);
  14028. } // Long
  14029. if (typeof date.toNumber === 'function') {
  14030. return new Date(date.toNumber());
  14031. }
  14032. return date;
  14033. };
  14034. /**
  14035. * 获取 Date 的毫秒数,如果不是一个 Date 返回 undefined。
  14036. * @private
  14037. */
  14038. const getTime = date => date && date.getTime ? date.getTime() : undefined;
  14039. /**
  14040. * 解码对象中的 LeanCloud 数据结构。
  14041. * 目前仅会处理 Date 类型。
  14042. * @private
  14043. */
  14044. const decode = value => {
  14045. if (!value) return value;
  14046. if (value.__type === 'Date' && value.iso) {
  14047. return new Date(value.iso);
  14048. }
  14049. if (Array.isArray(value)) {
  14050. return value.map(decode);
  14051. }
  14052. if (isPlainObject_1(value)) {
  14053. return Object.keys(value).reduce((result, key) => ({ ...result,
  14054. [key]: decode(value[key])
  14055. }), {});
  14056. }
  14057. return value;
  14058. };
  14059. /**
  14060. * 将对象中的特殊类型编码为 LeanCloud 数据结构。
  14061. * 目前仅会处理 Date 类型。
  14062. * @private
  14063. */
  14064. const encode = value => {
  14065. if (value instanceof Date) return {
  14066. __type: 'Date',
  14067. iso: value.toJSON()
  14068. };
  14069. if (Array.isArray(value)) {
  14070. return value.map(encode);
  14071. }
  14072. if (isPlainObject_1(value)) {
  14073. return Object.keys(value).reduce((result, key) => ({ ...result,
  14074. [key]: encode(value[key])
  14075. }), {});
  14076. }
  14077. return value;
  14078. };
  14079. const keyRemap = (keymap, obj) => Object.keys(obj).reduce((newObj, key) => {
  14080. const newKey = keymap[key] || key;
  14081. return Object.assign(newObj, {
  14082. [newKey]: obj[key]
  14083. });
  14084. }, {});
  14085. const isIE10 = global$1.navigator && global$1.navigator.userAgent && global$1.navigator.userAgent.indexOf('MSIE 10.') !== -1;
  14086. /* eslint-disable no-proto */
  14087. const getStaticProperty = (klass, property) => klass[property] || (klass.__proto__ ? getStaticProperty(klass.__proto__, property) : undefined);
  14088. /* eslint-enable no-proto */
  14089. const union = (a, b) => Array.from(new Set([...a, ...b]));
  14090. const difference = (a, b) => Array.from((bSet => new Set(a.filter(x => !bSet.has(x))))(new Set(b)));
  14091. const map = new WeakMap(); // protected property helper
  14092. const internal = object => {
  14093. if (!map.has(object)) {
  14094. map.set(object, {});
  14095. }
  14096. return map.get(object);
  14097. };
  14098. const compact = (obj, filter) => {
  14099. if (!isPlainObject_1(obj)) return obj;
  14100. const object = { ...obj
  14101. };
  14102. Object.keys(object).forEach(prop => {
  14103. const value = object[prop];
  14104. if (value === filter) {
  14105. delete object[prop];
  14106. } else {
  14107. object[prop] = compact(value, filter);
  14108. }
  14109. });
  14110. return object;
  14111. }; // debug utility
  14112. const removeNull = obj => compact(obj, null);
  14113. const trim = message => removeNull(JSON.parse(JSON.stringify(message)));
  14114. const ensureArray = target => {
  14115. if (Array.isArray(target)) {
  14116. return target;
  14117. }
  14118. if (target === undefined || target === null) {
  14119. return [];
  14120. }
  14121. return [target];
  14122. };
  14123. const setValue = (target, key, value) => {
  14124. // '.' is not allowed in Class keys, escaping is not in concern now.
  14125. const segs = key.split('.');
  14126. const lastSeg = segs.pop();
  14127. let currentTarget = target;
  14128. segs.forEach(seg => {
  14129. if (currentTarget[seg] === undefined) currentTarget[seg] = {};
  14130. currentTarget = currentTarget[seg];
  14131. });
  14132. currentTarget[lastSeg] = value;
  14133. return target;
  14134. };
  14135. const isWeapp = // eslint-disable-next-line no-undef
  14136. typeof wx === 'object' && typeof wx.connectSocket === 'function'; // throttle decorator
  14137. const throttle = wait => (target, property, descriptor) => {
  14138. const callback = descriptor.value; // very naive, internal use only
  14139. if (callback.length) {
  14140. throw new Error('throttled function should not accept any arguments');
  14141. }
  14142. return { ...descriptor,
  14143. value() {
  14144. let {
  14145. throttleMeta
  14146. } = internal(this);
  14147. if (!throttleMeta) {
  14148. throttleMeta = {};
  14149. internal(this).throttleMeta = throttleMeta;
  14150. }
  14151. let {
  14152. [property]: propertyMeta
  14153. } = throttleMeta;
  14154. if (!propertyMeta) {
  14155. propertyMeta = {};
  14156. throttleMeta[property] = propertyMeta;
  14157. }
  14158. const {
  14159. previouseTimestamp = 0,
  14160. timeout
  14161. } = propertyMeta;
  14162. const now = Date.now();
  14163. const remainingTime = wait - (now - previouseTimestamp);
  14164. if (remainingTime <= 0) {
  14165. throttleMeta[property].previouseTimestamp = now;
  14166. callback.apply(this);
  14167. } else if (!timeout) {
  14168. propertyMeta.timeout = setTimeout(() => {
  14169. propertyMeta.previouseTimestamp = Date.now();
  14170. delete propertyMeta.timeout;
  14171. callback.apply(this);
  14172. }, remainingTime);
  14173. }
  14174. }
  14175. };
  14176. };
  14177. const isCNApp = appId => appId.slice(-9) !== '-MdYXbMMI';
  14178. const equalBuffer = (buffer1, buffer2) => {
  14179. if (!buffer1 || !buffer2) return false;
  14180. if (buffer1.byteLength !== buffer2.byteLength) return false;
  14181. const a = new Uint8Array(buffer1);
  14182. const b = new Uint8Array(buffer2);
  14183. return !a.some((value, index) => value !== b[index]);
  14184. };
  14185. var _class;
  14186. const debug$3 = browser('LC:WebSocketPlus');
  14187. const OPEN = 'open';
  14188. const DISCONNECT = 'disconnect';
  14189. const RECONNECT = 'reconnect';
  14190. const RETRY = 'retry';
  14191. const SCHEDULE = 'schedule';
  14192. const OFFLINE = 'offline';
  14193. const ONLINE = 'online';
  14194. const ERROR = 'error';
  14195. const MESSAGE = 'message';
  14196. const HEARTBEAT_TIME = 180000;
  14197. const TIMEOUT_TIME = 380000;
  14198. const DEFAULT_RETRY_STRATEGY = attempt => Math.min(1000 * 2 ** attempt, 300000);
  14199. const requireConnected = (target, name, descriptor) => ({ ...descriptor,
  14200. value: function requireConnectedWrapper(...args) {
  14201. this.checkConnectionAvailability(name);
  14202. return descriptor.value.call(this, ...args);
  14203. }
  14204. });
  14205. let WebSocketPlus = (_class = class WebSocketPlus extends eventemitter3 {
  14206. get urls() {
  14207. return this._urls;
  14208. }
  14209. set urls(urls) {
  14210. this._urls = ensureArray(urls);
  14211. }
  14212. constructor(getUrls, protocol) {
  14213. super();
  14214. this.init();
  14215. this._protocol = protocol;
  14216. Promise.resolve(typeof getUrls === 'function' ? getUrls() : getUrls).then(ensureArray).then(urls => {
  14217. this._urls = urls;
  14218. return this._open();
  14219. }).then(() => {
  14220. this.__postponeTimeoutTimer = this._postponeTimeoutTimer.bind(this);
  14221. if (global$1.addEventListener) {
  14222. this.__pause = () => {
  14223. if (this.can('pause')) this.pause();
  14224. };
  14225. this.__resume = () => {
  14226. if (this.can('resume')) this.resume();
  14227. };
  14228. global$1.addEventListener('offline', this.__pause);
  14229. global$1.addEventListener('online', this.__resume);
  14230. }
  14231. this.open();
  14232. }).catch(this.throw.bind(this));
  14233. }
  14234. _open() {
  14235. return this._createWs(this._urls, this._protocol).then(ws => {
  14236. const [first, ...reset] = this._urls;
  14237. this._urls = [...reset, first];
  14238. return ws;
  14239. });
  14240. }
  14241. _createWs(urls, protocol) {
  14242. return tryAll(urls.map(url => (resolve, reject) => {
  14243. debug$3(`connect [${url}] ${protocol}`);
  14244. const WebSocket = getAdapter('WebSocket');
  14245. const ws = protocol ? new WebSocket(url, protocol) : new WebSocket(url);
  14246. ws.binaryType = this.binaryType || 'arraybuffer';
  14247. ws.onopen = () => resolve(ws);
  14248. ws.onclose = error => {
  14249. if (error instanceof Error) {
  14250. return reject(error);
  14251. } // in browser, error event is useless
  14252. return reject(new Error(`Failed to connect [${url}]`));
  14253. };
  14254. ws.onerror = ws.onclose;
  14255. })).then(ws => {
  14256. this._ws = ws;
  14257. this._ws.onclose = this._handleClose.bind(this);
  14258. this._ws.onmessage = this._handleMessage.bind(this);
  14259. return ws;
  14260. });
  14261. }
  14262. _destroyWs() {
  14263. const ws = this._ws;
  14264. if (!ws) return;
  14265. ws.onopen = null;
  14266. ws.onclose = null;
  14267. ws.onerror = null;
  14268. ws.onmessage = null;
  14269. this._ws = null;
  14270. ws.close();
  14271. } // eslint-disable-next-line class-methods-use-this
  14272. onbeforeevent(event, from, to, ...payload) {
  14273. debug$3(`${event}: ${from} -> ${to} %o`, payload);
  14274. }
  14275. onopen() {
  14276. this.emit(OPEN);
  14277. }
  14278. onconnected() {
  14279. this._startConnectionKeeper();
  14280. }
  14281. onleaveconnected(event, from, to) {
  14282. this._stopConnectionKeeper();
  14283. this._destroyWs();
  14284. if (to === 'offline' || to === 'disconnected') {
  14285. this.emit(DISCONNECT);
  14286. }
  14287. }
  14288. onpause() {
  14289. this.emit(OFFLINE);
  14290. }
  14291. onbeforeresume() {
  14292. this.emit(ONLINE);
  14293. }
  14294. onreconnect() {
  14295. this.emit(RECONNECT);
  14296. }
  14297. ondisconnected(event, from, to, attempt = 0) {
  14298. const delay = from === OFFLINE ? 0 : DEFAULT_RETRY_STRATEGY.call(null, attempt);
  14299. debug$3(`schedule attempt=${attempt} delay=${delay}`);
  14300. this.emit(SCHEDULE, attempt, delay);
  14301. if (this.__scheduledRetry) {
  14302. clearTimeout(this.__scheduledRetry);
  14303. }
  14304. this.__scheduledRetry = setTimeout(() => {
  14305. if (this.is('disconnected')) {
  14306. this.retry(attempt);
  14307. }
  14308. }, delay);
  14309. }
  14310. onretry(event, from, to, attempt = 0) {
  14311. this.emit(RETRY, attempt);
  14312. this._open().then(() => this.can('reconnect') && this.reconnect(), () => this.can('fail') && this.fail(attempt + 1));
  14313. }
  14314. onerror(event, from, to, error) {
  14315. this.emit(ERROR, error);
  14316. }
  14317. onclose() {
  14318. if (global$1.removeEventListener) {
  14319. if (this.__pause) global$1.removeEventListener('offline', this.__pause);
  14320. if (this.__resume) global$1.removeEventListener('online', this.__resume);
  14321. }
  14322. }
  14323. checkConnectionAvailability(name = 'API') {
  14324. if (!this.is('connected')) {
  14325. const currentState = this.current;
  14326. console.warn(`${name} should not be called when the connection is ${currentState}`);
  14327. if (this.is('disconnected') || this.is('reconnecting')) {
  14328. console.warn('disconnect and reconnect event should be handled to avoid such calls.');
  14329. }
  14330. throw new Error('Connection unavailable');
  14331. }
  14332. } // jsdoc-ignore-start
  14333. // jsdoc-ignore-end
  14334. _ping() {
  14335. debug$3('ping');
  14336. try {
  14337. this.ping();
  14338. } catch (error) {
  14339. console.warn(`websocket ping error: ${error.message}`);
  14340. }
  14341. }
  14342. ping() {
  14343. if (this._ws.ping) {
  14344. this._ws.ping();
  14345. } else {
  14346. console.warn(`The WebSocket implement does not support sending ping frame.
  14347. Override ping method to use application defined ping/pong mechanism.`);
  14348. }
  14349. }
  14350. _postponeTimeoutTimer() {
  14351. debug$3('_postponeTimeoutTimer');
  14352. this._clearTimeoutTimers();
  14353. this._timeoutTimer = setTimeout(() => {
  14354. debug$3('timeout');
  14355. this.disconnect();
  14356. }, TIMEOUT_TIME);
  14357. }
  14358. _clearTimeoutTimers() {
  14359. if (this._timeoutTimer) {
  14360. clearTimeout(this._timeoutTimer);
  14361. }
  14362. }
  14363. _startConnectionKeeper() {
  14364. debug$3('start connection keeper');
  14365. this._heartbeatTimer = setInterval(this._ping.bind(this), HEARTBEAT_TIME);
  14366. const addListener = this._ws.addListener || this._ws.addEventListener;
  14367. if (!addListener) {
  14368. debug$3('connection keeper disabled due to the lack of #addEventListener.');
  14369. return;
  14370. }
  14371. addListener.call(this._ws, 'message', this.__postponeTimeoutTimer);
  14372. addListener.call(this._ws, 'pong', this.__postponeTimeoutTimer);
  14373. this._postponeTimeoutTimer();
  14374. }
  14375. _stopConnectionKeeper() {
  14376. debug$3('stop connection keeper'); // websockets/ws#489
  14377. const removeListener = this._ws.removeListener || this._ws.removeEventListener;
  14378. if (removeListener) {
  14379. removeListener.call(this._ws, 'message', this.__postponeTimeoutTimer);
  14380. removeListener.call(this._ws, 'pong', this.__postponeTimeoutTimer);
  14381. this._clearTimeoutTimers();
  14382. }
  14383. if (this._heartbeatTimer) {
  14384. clearInterval(this._heartbeatTimer);
  14385. }
  14386. }
  14387. _handleClose(event) {
  14388. debug$3(`ws closed [${event.code}] ${event.reason}`); // socket closed manually, ignore close event.
  14389. if (this.isFinished()) return;
  14390. this.handleClose(event);
  14391. }
  14392. handleClose() {
  14393. // reconnect
  14394. this.disconnect();
  14395. } // jsdoc-ignore-start
  14396. // jsdoc-ignore-end
  14397. send(data) {
  14398. debug$3('send', data);
  14399. this._ws.send(data);
  14400. }
  14401. _handleMessage(event) {
  14402. debug$3('message', event.data);
  14403. this.handleMessage(event.data);
  14404. }
  14405. handleMessage(message) {
  14406. this.emit(MESSAGE, message);
  14407. }
  14408. }, (_applyDecoratedDescriptor(_class.prototype, "_ping", [requireConnected], Object.getOwnPropertyDescriptor(_class.prototype, "_ping"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "send", [requireConnected], Object.getOwnPropertyDescriptor(_class.prototype, "send"), _class.prototype)), _class);
  14409. stateMachine.create({
  14410. target: WebSocketPlus.prototype,
  14411. initial: {
  14412. state: 'initialized',
  14413. event: 'init',
  14414. defer: true
  14415. },
  14416. terminal: 'closed',
  14417. events: [{
  14418. name: 'open',
  14419. from: 'initialized',
  14420. to: 'connected'
  14421. }, {
  14422. name: 'disconnect',
  14423. from: 'connected',
  14424. to: 'disconnected'
  14425. }, {
  14426. name: 'retry',
  14427. from: 'disconnected',
  14428. to: 'reconnecting'
  14429. }, {
  14430. name: 'fail',
  14431. from: 'reconnecting',
  14432. to: 'disconnected'
  14433. }, {
  14434. name: 'reconnect',
  14435. from: 'reconnecting',
  14436. to: 'connected'
  14437. }, {
  14438. name: 'pause',
  14439. from: ['connected', 'disconnected', 'reconnecting'],
  14440. to: 'offline'
  14441. }, {}, {
  14442. name: 'resume',
  14443. from: 'offline',
  14444. to: 'disconnected'
  14445. }, {
  14446. name: 'close',
  14447. from: ['connected', 'disconnected', 'reconnecting', 'offline'],
  14448. to: 'closed'
  14449. }, {
  14450. name: 'throw',
  14451. from: '*',
  14452. to: 'error'
  14453. }]
  14454. });
  14455. const error = Object.freeze({
  14456. 1000: {
  14457. name: 'CLOSE_NORMAL'
  14458. },
  14459. 1006: {
  14460. name: 'CLOSE_ABNORMAL'
  14461. },
  14462. 4100: {
  14463. name: 'APP_NOT_AVAILABLE',
  14464. message: 'App not exists or realtime message service is disabled.'
  14465. },
  14466. 4102: {
  14467. name: 'SIGNATURE_FAILED',
  14468. message: 'Login signature mismatch.'
  14469. },
  14470. 4103: {
  14471. name: 'INVALID_LOGIN',
  14472. message: 'Malformed clientId.'
  14473. },
  14474. 4105: {
  14475. name: 'SESSION_REQUIRED',
  14476. message: 'Message sent before session opened.'
  14477. },
  14478. 4107: {
  14479. name: 'READ_TIMEOUT'
  14480. },
  14481. 4108: {
  14482. name: 'LOGIN_TIMEOUT'
  14483. },
  14484. 4109: {
  14485. name: 'FRAME_TOO_LONG'
  14486. },
  14487. 4110: {
  14488. name: 'INVALID_ORIGIN',
  14489. message: 'Access denied by domain whitelist.'
  14490. },
  14491. 4111: {
  14492. name: 'SESSION_CONFLICT'
  14493. },
  14494. 4112: {
  14495. name: 'SESSION_TOKEN_EXPIRED'
  14496. },
  14497. 4113: {
  14498. name: 'APP_QUOTA_EXCEEDED',
  14499. message: 'The daily active users limit exceeded.'
  14500. },
  14501. 4116: {
  14502. name: 'MESSAGE_SENT_QUOTA_EXCEEDED',
  14503. message: 'Command sent too fast.'
  14504. },
  14505. 4200: {
  14506. name: 'INTERNAL_ERROR',
  14507. message: 'Internal error, please contact LeanCloud for support.'
  14508. },
  14509. 4301: {
  14510. name: 'CONVERSATION_API_FAILED',
  14511. message: 'Upstream Conversatoin API failed, see error.detail for details.'
  14512. },
  14513. 4302: {
  14514. name: 'CONVERSATION_SIGNATURE_FAILED',
  14515. message: 'Conversation action signature mismatch.'
  14516. },
  14517. 4303: {
  14518. name: 'CONVERSATION_NOT_FOUND'
  14519. },
  14520. 4304: {
  14521. name: 'CONVERSATION_FULL'
  14522. },
  14523. 4305: {
  14524. name: 'CONVERSATION_REJECTED_BY_APP',
  14525. message: 'Conversation action rejected by hook.'
  14526. },
  14527. 4306: {
  14528. name: 'CONVERSATION_UPDATE_FAILED'
  14529. },
  14530. 4307: {
  14531. name: 'CONVERSATION_READ_ONLY'
  14532. },
  14533. 4308: {
  14534. name: 'CONVERSATION_NOT_ALLOWED'
  14535. },
  14536. 4309: {
  14537. name: 'CONVERSATION_UPDATE_REJECTED',
  14538. message: 'Conversation update rejected because the client is not a member.'
  14539. },
  14540. 4310: {
  14541. name: 'CONVERSATION_QUERY_FAILED',
  14542. message: 'Conversation query failed because it is too expansive.'
  14543. },
  14544. 4311: {
  14545. name: 'CONVERSATION_LOG_FAILED'
  14546. },
  14547. 4312: {
  14548. name: 'CONVERSATION_LOG_REJECTED',
  14549. message: 'Message query rejected because the client is not a member of the conversation.'
  14550. },
  14551. 4313: {
  14552. name: 'SYSTEM_CONVERSATION_REQUIRED'
  14553. },
  14554. 4314: {
  14555. name: 'NORMAL_CONVERSATION_REQUIRED'
  14556. },
  14557. 4315: {
  14558. name: 'CONVERSATION_BLACKLISTED',
  14559. message: 'Blacklisted in the conversation.'
  14560. },
  14561. 4316: {
  14562. name: 'TRANSIENT_CONVERSATION_REQUIRED'
  14563. },
  14564. 4317: {
  14565. name: 'CONVERSATION_MEMBERSHIP_REQUIRED'
  14566. },
  14567. 4318: {
  14568. name: 'CONVERSATION_API_QUOTA_EXCEEDED',
  14569. message: 'LeanCloud API quota exceeded. You may upgrade your plan.'
  14570. },
  14571. 4323: {
  14572. name: 'TEMPORARY_CONVERSATION_EXPIRED',
  14573. message: 'Temporary conversation expired or does not exist.'
  14574. },
  14575. 4401: {
  14576. name: 'INVALID_MESSAGING_TARGET',
  14577. message: 'Conversation does not exist or client is not a member.'
  14578. },
  14579. 4402: {
  14580. name: 'MESSAGE_REJECTED_BY_APP',
  14581. message: 'Message rejected by hook.'
  14582. },
  14583. 4403: {
  14584. name: 'MESSAGE_OWNERSHIP_REQUIRED'
  14585. },
  14586. 4404: {
  14587. name: 'MESSAGE_NOT_FOUND'
  14588. },
  14589. 4405: {
  14590. name: 'MESSAGE_UPDATE_REJECTED_BY_APP',
  14591. message: 'Message update rejected by hook.'
  14592. },
  14593. 4406: {
  14594. name: 'MESSAGE_EDIT_DISABLED'
  14595. },
  14596. 4407: {
  14597. name: 'MESSAGE_RECALL_DISABLED'
  14598. },
  14599. 5130: {
  14600. name: 'OWNER_PROMOTION_NOT_ALLOWED',
  14601. message: "Updating a member's role to owner is not allowed."
  14602. }
  14603. });
  14604. const ErrorCode = Object.freeze(Object.keys(error).reduce((result, code) => Object.assign(result, {
  14605. [error[code].name]: Number(code)
  14606. }), {}));
  14607. const createError = ({
  14608. code,
  14609. reason,
  14610. appCode,
  14611. detail,
  14612. error: errorMessage
  14613. }) => {
  14614. let message = reason || detail || errorMessage;
  14615. let name = reason;
  14616. if (!message && error[code]) {
  14617. ({
  14618. name
  14619. } = error[code]);
  14620. message = error[code].message || name;
  14621. }
  14622. if (!message) {
  14623. message = `Unknow Error: ${code}`;
  14624. }
  14625. const err = new Error(message);
  14626. return Object.assign(err, {
  14627. code,
  14628. appCode,
  14629. detail,
  14630. name
  14631. });
  14632. };
  14633. const debug$4 = browser('LC:Connection');
  14634. const COMMAND_TIMEOUT = 20000;
  14635. const EXPIRE = Symbol('expire');
  14636. const isIdempotentCommand = command => !(command.cmd === CommandType.direct || command.cmd === CommandType.session && command.op === OpType.open || command.cmd === CommandType.conv && (command.op === OpType.start || command.op === OpType.update || command.op === OpType.members));
  14637. class Connection extends WebSocketPlus {
  14638. constructor(getUrl, {
  14639. format,
  14640. version
  14641. }) {
  14642. debug$4('initializing Connection');
  14643. const protocolString = `lc.${format}.${version}`;
  14644. super(getUrl, protocolString);
  14645. this._protocolFormat = format;
  14646. this._commands = {};
  14647. this._serialId = 0;
  14648. }
  14649. async send(command, waitingForRespond = true) {
  14650. let buffer;
  14651. let serialId;
  14652. if (waitingForRespond) {
  14653. if (isIdempotentCommand(command)) {
  14654. buffer = command.toArrayBuffer();
  14655. const duplicatedCommand = values_1(this._commands).find(({
  14656. buffer: targetBuffer,
  14657. command: targetCommand
  14658. }) => targetCommand.cmd === command.cmd && targetCommand.op === command.op && equalBuffer(targetBuffer, buffer));
  14659. if (duplicatedCommand) {
  14660. console.warn(`Duplicated command [cmd:${command.cmd} op:${command.op}] is throttled.`);
  14661. return duplicatedCommand.promise;
  14662. }
  14663. }
  14664. this._serialId += 1;
  14665. serialId = this._serialId;
  14666. command.i = serialId; // eslint-disable-line no-param-reassign
  14667. }
  14668. if (debug$4.enabled) debug$4('↑ %O sent', trim(command));
  14669. let message;
  14670. if (this._protocolFormat === 'proto2base64') {
  14671. message = command.toBase64();
  14672. } else if (command.toArrayBuffer) {
  14673. message = command.toArrayBuffer();
  14674. }
  14675. if (!message) {
  14676. throw new TypeError(`${command} is not a GenericCommand`);
  14677. }
  14678. super.send(message);
  14679. if (!waitingForRespond) return undefined;
  14680. const promise = new Promise((resolve, reject) => {
  14681. this._commands[serialId] = {
  14682. command,
  14683. buffer,
  14684. resolve,
  14685. reject,
  14686. timeout: setTimeout(() => {
  14687. if (this._commands[serialId]) {
  14688. if (debug$4.enabled) debug$4('✗ %O timeout', trim(command));
  14689. reject(createError({
  14690. error: `Command Timeout [cmd:${command.cmd} op:${command.op}]`,
  14691. name: 'COMMAND_TIMEOUT'
  14692. }));
  14693. delete this._commands[serialId];
  14694. }
  14695. }, COMMAND_TIMEOUT)
  14696. };
  14697. });
  14698. this._commands[serialId].promise = promise;
  14699. return promise;
  14700. }
  14701. handleMessage(msg) {
  14702. let message;
  14703. try {
  14704. message = GenericCommand.decode(msg);
  14705. if (debug$4.enabled) debug$4('↓ %O received', trim(message));
  14706. } catch (e) {
  14707. console.warn('Decode message failed:', e.message, msg);
  14708. return;
  14709. }
  14710. const serialId = message.i;
  14711. if (serialId) {
  14712. if (this._commands[serialId]) {
  14713. clearTimeout(this._commands[serialId].timeout);
  14714. if (message.cmd === CommandType.error) {
  14715. this._commands[serialId].reject(createError(message.errorMessage));
  14716. } else {
  14717. this._commands[serialId].resolve(message);
  14718. }
  14719. delete this._commands[serialId];
  14720. } else {
  14721. console.warn(`Unexpected command received with serialId [${serialId}],
  14722. which have timed out or never been requested.`);
  14723. }
  14724. } else {
  14725. switch (message.cmd) {
  14726. case CommandType.error:
  14727. {
  14728. this.emit(ERROR, createError(message.errorMessage));
  14729. return;
  14730. }
  14731. case CommandType.goaway:
  14732. {
  14733. this.emit(EXPIRE);
  14734. return;
  14735. }
  14736. default:
  14737. {
  14738. this.emit(MESSAGE, message);
  14739. }
  14740. }
  14741. }
  14742. }
  14743. ping() {
  14744. return this.send(new GenericCommand({
  14745. cmd: CommandType.echo
  14746. })).catch(error => debug$4('ping failed:', error));
  14747. }
  14748. }
  14749. var promiseTimeout = createCommonjsModule(function (module) {
  14750. /**
  14751. * Local reference to TimeoutError
  14752. * @private
  14753. */
  14754. var TimeoutError;
  14755. /**
  14756. * Rejects a promise with a {@link TimeoutError} if it does not settle within
  14757. * the specified timeout.
  14758. *
  14759. * @param {Promise} promise The promise.
  14760. * @param {number} timeoutMillis Number of milliseconds to wait on settling.
  14761. * @returns {Promise} Either resolves/rejects with `promise`, or rejects with
  14762. * `TimeoutError`, whichever settles first.
  14763. */
  14764. var timeout = module.exports.timeout = function (promise, timeoutMillis) {
  14765. var error = new TimeoutError(),
  14766. timeout;
  14767. return Promise.race([promise, new Promise(function (resolve, reject) {
  14768. timeout = setTimeout(function () {
  14769. reject(error);
  14770. }, timeoutMillis);
  14771. })]).then(function (v) {
  14772. clearTimeout(timeout);
  14773. return v;
  14774. }, function (err) {
  14775. clearTimeout(timeout);
  14776. throw err;
  14777. });
  14778. };
  14779. /**
  14780. * Exception indicating that the timeout expired.
  14781. */
  14782. TimeoutError = module.exports.TimeoutError = function () {
  14783. Error.call(this);
  14784. this.stack = Error().stack;
  14785. this.message = 'Timeout';
  14786. };
  14787. TimeoutError.prototype = Object.create(Error.prototype);
  14788. TimeoutError.prototype.name = "TimeoutError";
  14789. });
  14790. var promiseTimeout_1 = promiseTimeout.timeout;
  14791. var promiseTimeout_2 = promiseTimeout.TimeoutError;
  14792. const debug$5 = browser('LC:request');
  14793. var request = (({
  14794. method = 'GET',
  14795. url: _url,
  14796. query,
  14797. headers,
  14798. data,
  14799. timeout: time
  14800. }) => {
  14801. let url = _url;
  14802. if (query) {
  14803. const queryString = Object.keys(query).map(key => {
  14804. const value = query[key];
  14805. if (value === undefined) return undefined;
  14806. const v = isPlainObject_1(value) ? JSON.stringify(value) : value;
  14807. return `${encodeURIComponent(key)}=${encodeURIComponent(v)}`;
  14808. }).filter(qs => qs).join('&');
  14809. url = `${url}?${queryString}`;
  14810. }
  14811. debug$5('Req: %O %O %O', method, url, {
  14812. headers,
  14813. data
  14814. });
  14815. const request = getAdapter('request');
  14816. const promise = request(url, {
  14817. method,
  14818. headers,
  14819. data
  14820. }).then(response => {
  14821. if (response.ok === false) {
  14822. const error = createError(response.data);
  14823. error.response = response;
  14824. throw error;
  14825. }
  14826. debug$5('Res: %O %O %O', url, response.status, response.data);
  14827. return response.data;
  14828. }).catch(error => {
  14829. if (error.response) {
  14830. debug$5('Error: %O %O %O', url, error.response.status, error.response.data);
  14831. }
  14832. throw error;
  14833. });
  14834. return time ? promiseTimeout_1(promise, time) : promise;
  14835. });
  14836. /* eslint-disable max-len */
  14837. const checkType = middleware => param => {
  14838. const {
  14839. constructor
  14840. } = param;
  14841. return Promise.resolve(param).then(middleware).then(tap(result => {
  14842. if (result === undefined || result === null) {
  14843. // eslint-disable-next-line max-len
  14844. return console.warn(`Middleware[${middleware._pluginName || 'anonymous plugin'}:${middleware.name || 'anonymous middleware'}] param/return types not match. It returns ${result} while a ${param.constructor.name} expected.`);
  14845. }
  14846. if (!(result instanceof constructor)) {
  14847. // eslint-disable-next-line max-len
  14848. return console.warn(`Middleware[${middleware._pluginName || 'anonymous plugin'}:${middleware.name || 'anonymous middleware'}] param/return types not match. It returns a ${result.constructor.name} while a ${param.constructor.name} expected.`);
  14849. }
  14850. return 0;
  14851. }));
  14852. };
  14853. const applyDecorators = (decorators, target) => {
  14854. if (decorators) {
  14855. decorators.forEach(decorator => {
  14856. try {
  14857. decorator(target);
  14858. } catch (error) {
  14859. if (decorator._pluginName) {
  14860. error.message += `[${decorator._pluginName}]`;
  14861. }
  14862. throw error;
  14863. }
  14864. });
  14865. }
  14866. };
  14867. const applyMiddlewares = middlewares => target => ensureArray(middlewares).reduce((previousPromise, middleware) => previousPromise.then(checkType(middleware)).catch(error => {
  14868. if (middleware._pluginName) {
  14869. // eslint-disable-next-line no-param-reassign
  14870. error.message += `[${middleware._pluginName}]`;
  14871. }
  14872. throw error;
  14873. }), Promise.resolve(target));
  14874. const applyDispatcher = (dispatchers, payload) => ensureArray(dispatchers).reduce((resultPromise, dispatcher) => resultPromise.then(shouldDispatch => shouldDispatch === false ? false : dispatcher(...payload)).catch(error => {
  14875. if (dispatcher._pluginName) {
  14876. // eslint-disable-next-line no-param-reassign
  14877. error.message += `[${dispatcher._pluginName}]`;
  14878. }
  14879. throw error;
  14880. }), Promise.resolve(true));
  14881. var version = "5.0.0-rc.7";
  14882. // eslint-disable-next-line max-classes-per-file
  14883. const debug$6 = browser('LC:Realtime');
  14884. const routerCache = new Cache('push-router');
  14885. const initializedApp = {};
  14886. class Realtime extends eventemitter3 {
  14887. /**
  14888. * @extends EventEmitter
  14889. * @param {Object} options
  14890. * @param {String} options.appId
  14891. * @param {String} options.appKey (since 4.0.0)
  14892. * @param {String|Object} [options.server] 指定服务器域名,中国节点应用此参数必填(since 4.0.0)
  14893. * @param {Boolean} [options.noBinary=false] 设置 WebSocket 使用字符串格式收发消息(默认为二进制格式)。
  14894. * 适用于 WebSocket 实现不支持二进制数据格式的情况
  14895. * @param {Boolean} [options.ssl=true] 使用 wss 进行连接
  14896. * @param {String|String[]} [options.RTMServers] 指定私有部署的 RTM 服务器地址(since 4.0.0)
  14897. * @param {Plugin[]} [options.plugins] 加载插件(since 3.1.0)
  14898. */
  14899. constructor({
  14900. plugins,
  14901. ...options
  14902. }) {
  14903. debug$6('initializing Realtime %s %O', version, options);
  14904. super();
  14905. const {
  14906. appId
  14907. } = options;
  14908. if (typeof appId !== 'string') {
  14909. throw new TypeError(`appId [${appId}] is not a string`);
  14910. }
  14911. if (initializedApp[appId]) {
  14912. throw new Error(`App [${appId}] is already initialized.`);
  14913. }
  14914. initializedApp[appId] = true;
  14915. if (typeof options.appKey !== 'string') {
  14916. throw new TypeError(`appKey [${options.appKey}] is not a string`);
  14917. }
  14918. if (isCNApp(appId)) {
  14919. if (!options.server) {
  14920. throw new TypeError(`server option is required for apps from CN region`);
  14921. }
  14922. }
  14923. this._options = {
  14924. appId: undefined,
  14925. appKey: undefined,
  14926. noBinary: false,
  14927. ssl: true,
  14928. RTMServerName: typeof process !== 'undefined' ? process.env.RTM_SERVER_NAME : undefined,
  14929. // undocumented on purpose, internal use only
  14930. ...options
  14931. };
  14932. this._cache = new Cache('endpoints');
  14933. const _this = internal(this);
  14934. _this.clients = new Set();
  14935. _this.pendingClients = new Set();
  14936. const mergedPlugins = [...ensureArray(Realtime.__preRegisteredPlugins), ...ensureArray(plugins)];
  14937. debug$6('Using plugins %o', mergedPlugins.map(plugin => plugin.name));
  14938. this._plugins = mergedPlugins.reduce((result, plugin) => {
  14939. Object.keys(plugin).forEach(hook => {
  14940. if ({}.hasOwnProperty.call(plugin, hook) && hook !== 'name') {
  14941. if (plugin.name) {
  14942. ensureArray(plugin[hook]).forEach(value => {
  14943. // eslint-disable-next-line no-param-reassign
  14944. value._pluginName = plugin.name;
  14945. });
  14946. } // eslint-disable-next-line no-param-reassign
  14947. result[hook] = ensureArray(result[hook]).concat(plugin[hook]);
  14948. }
  14949. });
  14950. return result;
  14951. }, {}); // onRealtimeCreate hook
  14952. applyDecorators(this._plugins.onRealtimeCreate, this);
  14953. }
  14954. async _request({
  14955. method,
  14956. url: _url,
  14957. version = '1.1',
  14958. path,
  14959. query,
  14960. headers,
  14961. data
  14962. }) {
  14963. let url = _url;
  14964. if (!url) {
  14965. const {
  14966. appId,
  14967. server
  14968. } = this._options;
  14969. const {
  14970. api
  14971. } = await this.constructor._getServerUrls({
  14972. appId,
  14973. server
  14974. });
  14975. url = `${api}/${version}${path}`;
  14976. }
  14977. return request({
  14978. url,
  14979. method,
  14980. query,
  14981. headers: {
  14982. 'X-LC-Id': this._options.appId,
  14983. 'X-LC-Key': this._options.appKey,
  14984. ...headers
  14985. },
  14986. data
  14987. });
  14988. }
  14989. _open() {
  14990. if (this._openPromise) return this._openPromise;
  14991. let format = 'protobuf2';
  14992. if (this._options.noBinary) {
  14993. // 不发送 binary data,fallback to base64 string
  14994. format = 'proto2base64';
  14995. }
  14996. const version = 3;
  14997. const protocol = {
  14998. format,
  14999. version
  15000. };
  15001. this._openPromise = new Promise((resolve, reject) => {
  15002. debug$6('No connection established, create a new one.');
  15003. const connection = new Connection(() => this._getRTMServers(this._options), protocol);
  15004. connection.on(OPEN, () => resolve(connection)).on(ERROR, error => {
  15005. delete this._openPromise;
  15006. reject(error);
  15007. }).on(EXPIRE, async () => {
  15008. debug$6('Connection expired. Refresh endpoints.');
  15009. this._cache.set('endpoints', null, 0);
  15010. connection.urls = await this._getRTMServers(this._options);
  15011. connection.disconnect();
  15012. }).on(MESSAGE, this._dispatchCommand.bind(this));
  15013. /**
  15014. * 连接断开。
  15015. * 连接断开可能是因为 SDK 进入了离线状态(see {@link Realtime#event:OFFLINE}),或长时间没有收到服务器心跳。
  15016. * 连接断开后所有的网络操作都会失败,请在连接断开后禁用相关的 UI 元素。
  15017. * @event Realtime#DISCONNECT
  15018. */
  15019. /**
  15020. * 计划在一段时间后尝试重新连接
  15021. * @event Realtime#SCHEDULE
  15022. * @param {Number} attempt 尝试重连的次数
  15023. * @param {Number} delay 延迟的毫秒数
  15024. */
  15025. /**
  15026. * 正在尝试重新连接
  15027. * @event Realtime#RETRY
  15028. * @param {Number} attempt 尝试重连的次数
  15029. */
  15030. /**
  15031. * 连接恢复正常。
  15032. * 请重新启用在 {@link Realtime#event:DISCONNECT} 事件中禁用的相关 UI 元素
  15033. * @event Realtime#RECONNECT
  15034. */
  15035. /**
  15036. * 客户端连接断开
  15037. * @event IMClient#DISCONNECT
  15038. * @see Realtime#event:DISCONNECT
  15039. * @since 3.2.0
  15040. */
  15041. /**
  15042. * 计划在一段时间后尝试重新连接
  15043. * @event IMClient#SCHEDULE
  15044. * @param {Number} attempt 尝试重连的次数
  15045. * @param {Number} delay 延迟的毫秒数
  15046. * @since 3.2.0
  15047. */
  15048. /**
  15049. * 正在尝试重新连接
  15050. * @event IMClient#RETRY
  15051. * @param {Number} attempt 尝试重连的次数
  15052. * @since 3.2.0
  15053. */
  15054. /**
  15055. * 客户端进入离线状态。
  15056. * 这通常意味着网络已断开,或者 {@link Realtime#pause} 被调用
  15057. * @event Realtime#OFFLINE
  15058. * @since 3.4.0
  15059. */
  15060. /**
  15061. * 客户端恢复在线状态
  15062. * 这通常意味着网络已恢复,或者 {@link Realtime#resume} 被调用
  15063. * @event Realtime#ONLINE
  15064. * @since 3.4.0
  15065. */
  15066. /**
  15067. * 进入离线状态。
  15068. * 这通常意味着网络已断开,或者 {@link Realtime#pause} 被调用
  15069. * @event IMClient#OFFLINE
  15070. * @since 3.4.0
  15071. */
  15072. /**
  15073. * 恢复在线状态
  15074. * 这通常意味着网络已恢复,或者 {@link Realtime#resume} 被调用
  15075. * @event IMClient#ONLINE
  15076. * @since 3.4.0
  15077. */
  15078. // event proxy
  15079. [DISCONNECT, RECONNECT, RETRY, SCHEDULE, OFFLINE, ONLINE].forEach(event => connection.on(event, (...payload) => {
  15080. debug$6(`${event} event emitted. %o`, payload);
  15081. this.emit(event, ...payload);
  15082. if (event !== RECONNECT) {
  15083. internal(this).clients.forEach(client => {
  15084. client.emit(event, ...payload);
  15085. });
  15086. }
  15087. })); // override handleClose
  15088. connection.handleClose = function handleClose(event) {
  15089. const isFatal = [ErrorCode.APP_NOT_AVAILABLE, ErrorCode.INVALID_LOGIN, ErrorCode.INVALID_ORIGIN].some(errorCode => errorCode === event.code);
  15090. if (isFatal) {
  15091. // in these cases, SDK should throw.
  15092. this.throw(createError(event));
  15093. } else {
  15094. // reconnect
  15095. this.disconnect();
  15096. }
  15097. };
  15098. internal(this).connection = connection;
  15099. });
  15100. return this._openPromise;
  15101. }
  15102. async _getRTMServers(options) {
  15103. if (options.RTMServers) return shuffle_1(ensureArray(options.RTMServers));
  15104. let info;
  15105. const cachedEndPoints = this._cache.get('endpoints');
  15106. if (cachedEndPoints) {
  15107. info = cachedEndPoints;
  15108. } else {
  15109. info = await this.constructor._fetchRTMServers(options);
  15110. const {
  15111. server,
  15112. secondary,
  15113. ttl
  15114. } = info;
  15115. if (typeof server !== 'string' && typeof secondary !== 'string' && typeof ttl !== 'number') {
  15116. throw new Error(`malformed RTM route response: ${JSON.stringify(info)}`);
  15117. }
  15118. this._cache.set('endpoints', info, info.ttl * 1000);
  15119. }
  15120. debug$6('endpoint info: %O', info);
  15121. return [info.server, info.secondary];
  15122. }
  15123. static async _getServerUrls({
  15124. appId,
  15125. server
  15126. }) {
  15127. debug$6('fetch server urls');
  15128. if (server) {
  15129. if (typeof server !== 'string') return server;
  15130. return {
  15131. RTMRouter: server,
  15132. api: server
  15133. };
  15134. }
  15135. const cachedRouter = routerCache.get(appId);
  15136. if (cachedRouter) return cachedRouter;
  15137. const defaultProtocol = 'https://';
  15138. return request({
  15139. url: 'https://app-router.com/2/route',
  15140. query: {
  15141. appId
  15142. },
  15143. timeout: 20000
  15144. }).then(tap(debug$6)).then(({
  15145. rtm_router_server: RTMRouterServer,
  15146. api_server: APIServer,
  15147. ttl = 3600
  15148. }) => {
  15149. if (!RTMRouterServer) {
  15150. throw new Error('rtm router not exists');
  15151. }
  15152. const serverUrls = {
  15153. RTMRouter: `${defaultProtocol}${RTMRouterServer}`,
  15154. api: `${defaultProtocol}${APIServer}`
  15155. };
  15156. routerCache.set(appId, serverUrls, ttl * 1000);
  15157. return serverUrls;
  15158. }).catch(() => {
  15159. const id = appId.slice(0, 8).toLowerCase();
  15160. const domain = 'lncldglobal.com';
  15161. return {
  15162. RTMRouter: `${defaultProtocol}${id}.rtm.${domain}`,
  15163. api: `${defaultProtocol}${id}.api.${domain}`
  15164. };
  15165. });
  15166. }
  15167. static _fetchRTMServers({
  15168. appId,
  15169. ssl,
  15170. server,
  15171. RTMServerName
  15172. }) {
  15173. debug$6('fetch endpoint info');
  15174. return this._getServerUrls({
  15175. appId,
  15176. server
  15177. }).then(tap(debug$6)).then(({
  15178. RTMRouter
  15179. }) => request({
  15180. url: `${RTMRouter}/v1/route`,
  15181. query: {
  15182. appId,
  15183. secure: ssl,
  15184. features: isWeapp ? 'wechat' : undefined,
  15185. server: RTMServerName,
  15186. _t: Date.now()
  15187. },
  15188. timeout: 20000
  15189. }).then(tap(debug$6)));
  15190. }
  15191. _close() {
  15192. if (this._openPromise) {
  15193. this._openPromise.then(connection => connection.close());
  15194. }
  15195. delete this._openPromise;
  15196. }
  15197. /**
  15198. * 手动进行重连。
  15199. * SDK 在网络出现异常时会自动按照一定的时间间隔尝试重连,调用该方法会立即尝试重连并重置重连尝试计数器。
  15200. * 只能在 `SCHEDULE` 事件之后,`RETRY` 事件之前调用,如果当前网络正常或者正在进行重连,调用该方法会抛异常。
  15201. */
  15202. retry() {
  15203. const {
  15204. connection
  15205. } = internal(this);
  15206. if (!connection) {
  15207. throw new Error('no connection established');
  15208. }
  15209. if (connection.cannot('retry')) {
  15210. throw new Error(`retrying not allowed when not disconnected. the connection is now ${connection.current}`);
  15211. }
  15212. return connection.retry();
  15213. }
  15214. /**
  15215. * 暂停,使 SDK 进入离线状态。
  15216. * 你可以在网络断开、应用进入后台等时刻调用该方法让 SDK 进入离线状态,离线状态下不会尝试重连。
  15217. * 在浏览器中 SDK 会自动监听网络变化,因此无需手动调用该方法。
  15218. *
  15219. * @since 3.4.0
  15220. * @see Realtime#event:OFFLINE
  15221. */
  15222. pause() {
  15223. // 这个方法常常在网络断开、进入后台时被调用,此时 connection 可能没有建立或者已经 close。
  15224. // 因此不像 retry,这个方法应该尽可能 loose
  15225. const {
  15226. connection
  15227. } = internal(this);
  15228. if (!connection) return;
  15229. if (connection.can('pause')) connection.pause();
  15230. }
  15231. /**
  15232. * 恢复在线状态。
  15233. * 你可以在网络恢复、应用回到前台等时刻调用该方法让 SDK 恢复在线状态,恢复在线状态后 SDK 会开始尝试重连。
  15234. *
  15235. * @since 3.4.0
  15236. * @see Realtime#event:ONLINE
  15237. */
  15238. resume() {
  15239. // 与 pause 一样,这个方法应该尽可能 loose
  15240. const {
  15241. connection
  15242. } = internal(this);
  15243. if (!connection) return;
  15244. if (connection.can('resume')) connection.resume();
  15245. }
  15246. _registerPending(value) {
  15247. internal(this).pendingClients.add(value);
  15248. }
  15249. _deregisterPending(client) {
  15250. internal(this).pendingClients.delete(client);
  15251. }
  15252. _register(client) {
  15253. internal(this).clients.add(client);
  15254. }
  15255. _deregister(client) {
  15256. const _this = internal(this);
  15257. _this.clients.delete(client);
  15258. if (_this.clients.size + _this.pendingClients.size === 0) {
  15259. this._close();
  15260. }
  15261. }
  15262. _dispatchCommand(command) {
  15263. return applyDispatcher(this._plugins.beforeCommandDispatch, [command, this]).then(shouldDispatch => {
  15264. // no plugin handled this command
  15265. if (shouldDispatch) return debug$6('[WARN] Unexpected message received: %O', trim(command));
  15266. return false;
  15267. });
  15268. }
  15269. } // For test purpose only
  15270. const polyfilledPromise = Promise;
  15271. var rngBrowser = createCommonjsModule(function (module) {
  15272. // Unique ID creation requires a high quality random # generator. In the
  15273. // browser this is a little complicated due to unknown quality of Math.random()
  15274. // and inconsistent support for the `crypto` API. We do the best we can via
  15275. // feature-detection
  15276. // getRandomValues needs to be invoked in a context where "this" is a Crypto
  15277. // implementation. Also, find the complete implementation of crypto on IE11.
  15278. var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||
  15279. (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));
  15280. if (getRandomValues) {
  15281. // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
  15282. var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef
  15283. module.exports = function whatwgRNG() {
  15284. getRandomValues(rnds8);
  15285. return rnds8;
  15286. };
  15287. } else {
  15288. // Math.random()-based (RNG)
  15289. //
  15290. // If all else fails, use Math.random(). It's fast, but is of unspecified
  15291. // quality.
  15292. var rnds = new Array(16);
  15293. module.exports = function mathRNG() {
  15294. for (var i = 0, r; i < 16; i++) {
  15295. if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
  15296. rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
  15297. }
  15298. return rnds;
  15299. };
  15300. }
  15301. });
  15302. /**
  15303. * Convert array of 16 byte values to UUID string format of the form:
  15304. * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
  15305. */
  15306. var byteToHex = [];
  15307. for (var i = 0; i < 256; ++i) {
  15308. byteToHex[i] = (i + 0x100).toString(16).substr(1);
  15309. }
  15310. function bytesToUuid(buf, offset) {
  15311. var i = offset || 0;
  15312. var bth = byteToHex;
  15313. // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
  15314. return ([bth[buf[i++]], bth[buf[i++]],
  15315. bth[buf[i++]], bth[buf[i++]], '-',
  15316. bth[buf[i++]], bth[buf[i++]], '-',
  15317. bth[buf[i++]], bth[buf[i++]], '-',
  15318. bth[buf[i++]], bth[buf[i++]], '-',
  15319. bth[buf[i++]], bth[buf[i++]],
  15320. bth[buf[i++]], bth[buf[i++]],
  15321. bth[buf[i++]], bth[buf[i++]]]).join('');
  15322. }
  15323. var bytesToUuid_1 = bytesToUuid;
  15324. function v4(options, buf, offset) {
  15325. var i = buf && offset || 0;
  15326. if (typeof(options) == 'string') {
  15327. buf = options === 'binary' ? new Array(16) : null;
  15328. options = null;
  15329. }
  15330. options = options || {};
  15331. var rnds = options.random || (options.rng || rngBrowser)();
  15332. // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
  15333. rnds[6] = (rnds[6] & 0x0f) | 0x40;
  15334. rnds[8] = (rnds[8] & 0x3f) | 0x80;
  15335. // Copy bytes to buffer, if provided
  15336. if (buf) {
  15337. for (var ii = 0; ii < 16; ++ii) {
  15338. buf[i + ii] = rnds[ii];
  15339. }
  15340. }
  15341. return buf || bytesToUuid_1(rnds);
  15342. }
  15343. var v4_1 = v4;
  15344. var base64Arraybuffer = createCommonjsModule(function (module, exports) {
  15345. /*
  15346. * base64-arraybuffer
  15347. * https://github.com/niklasvh/base64-arraybuffer
  15348. *
  15349. * Copyright (c) 2012 Niklas von Hertzen
  15350. * Licensed under the MIT license.
  15351. */
  15352. (function(){
  15353. var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  15354. // Use a lookup table to find the index.
  15355. var lookup = new Uint8Array(256);
  15356. for (var i = 0; i < chars.length; i++) {
  15357. lookup[chars.charCodeAt(i)] = i;
  15358. }
  15359. exports.encode = function(arraybuffer) {
  15360. var bytes = new Uint8Array(arraybuffer),
  15361. i, len = bytes.length, base64 = "";
  15362. for (i = 0; i < len; i+=3) {
  15363. base64 += chars[bytes[i] >> 2];
  15364. base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
  15365. base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
  15366. base64 += chars[bytes[i + 2] & 63];
  15367. }
  15368. if ((len % 3) === 2) {
  15369. base64 = base64.substring(0, base64.length - 1) + "=";
  15370. } else if (len % 3 === 1) {
  15371. base64 = base64.substring(0, base64.length - 2) + "==";
  15372. }
  15373. return base64;
  15374. };
  15375. exports.decode = function(base64) {
  15376. var bufferLength = base64.length * 0.75,
  15377. len = base64.length, i, p = 0,
  15378. encoded1, encoded2, encoded3, encoded4;
  15379. if (base64[base64.length - 1] === "=") {
  15380. bufferLength--;
  15381. if (base64[base64.length - 2] === "=") {
  15382. bufferLength--;
  15383. }
  15384. }
  15385. var arraybuffer = new ArrayBuffer(bufferLength),
  15386. bytes = new Uint8Array(arraybuffer);
  15387. for (i = 0; i < len; i+=4) {
  15388. encoded1 = lookup[base64.charCodeAt(i)];
  15389. encoded2 = lookup[base64.charCodeAt(i+1)];
  15390. encoded3 = lookup[base64.charCodeAt(i+2)];
  15391. encoded4 = lookup[base64.charCodeAt(i+3)];
  15392. bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
  15393. bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
  15394. bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
  15395. }
  15396. return arraybuffer;
  15397. };
  15398. })();
  15399. });
  15400. var base64Arraybuffer_1 = base64Arraybuffer.encode;
  15401. var base64Arraybuffer_2 = base64Arraybuffer.decode;
  15402. /**
  15403. * Removes all key-value entries from the list cache.
  15404. *
  15405. * @private
  15406. * @name clear
  15407. * @memberOf ListCache
  15408. */
  15409. function listCacheClear() {
  15410. this.__data__ = [];
  15411. this.size = 0;
  15412. }
  15413. var _listCacheClear = listCacheClear;
  15414. /**
  15415. * Performs a
  15416. * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  15417. * comparison between two values to determine if they are equivalent.
  15418. *
  15419. * @static
  15420. * @memberOf _
  15421. * @since 4.0.0
  15422. * @category Lang
  15423. * @param {*} value The value to compare.
  15424. * @param {*} other The other value to compare.
  15425. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  15426. * @example
  15427. *
  15428. * var object = { 'a': 1 };
  15429. * var other = { 'a': 1 };
  15430. *
  15431. * _.eq(object, object);
  15432. * // => true
  15433. *
  15434. * _.eq(object, other);
  15435. * // => false
  15436. *
  15437. * _.eq('a', 'a');
  15438. * // => true
  15439. *
  15440. * _.eq('a', Object('a'));
  15441. * // => false
  15442. *
  15443. * _.eq(NaN, NaN);
  15444. * // => true
  15445. */
  15446. function eq(value, other) {
  15447. return value === other || (value !== value && other !== other);
  15448. }
  15449. var eq_1 = eq;
  15450. /**
  15451. * Gets the index at which the `key` is found in `array` of key-value pairs.
  15452. *
  15453. * @private
  15454. * @param {Array} array The array to inspect.
  15455. * @param {*} key The key to search for.
  15456. * @returns {number} Returns the index of the matched value, else `-1`.
  15457. */
  15458. function assocIndexOf(array, key) {
  15459. var length = array.length;
  15460. while (length--) {
  15461. if (eq_1(array[length][0], key)) {
  15462. return length;
  15463. }
  15464. }
  15465. return -1;
  15466. }
  15467. var _assocIndexOf = assocIndexOf;
  15468. /** Used for built-in method references. */
  15469. var arrayProto = Array.prototype;
  15470. /** Built-in value references. */
  15471. var splice = arrayProto.splice;
  15472. /**
  15473. * Removes `key` and its value from the list cache.
  15474. *
  15475. * @private
  15476. * @name delete
  15477. * @memberOf ListCache
  15478. * @param {string} key The key of the value to remove.
  15479. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  15480. */
  15481. function listCacheDelete(key) {
  15482. var data = this.__data__,
  15483. index = _assocIndexOf(data, key);
  15484. if (index < 0) {
  15485. return false;
  15486. }
  15487. var lastIndex = data.length - 1;
  15488. if (index == lastIndex) {
  15489. data.pop();
  15490. } else {
  15491. splice.call(data, index, 1);
  15492. }
  15493. --this.size;
  15494. return true;
  15495. }
  15496. var _listCacheDelete = listCacheDelete;
  15497. /**
  15498. * Gets the list cache value for `key`.
  15499. *
  15500. * @private
  15501. * @name get
  15502. * @memberOf ListCache
  15503. * @param {string} key The key of the value to get.
  15504. * @returns {*} Returns the entry value.
  15505. */
  15506. function listCacheGet(key) {
  15507. var data = this.__data__,
  15508. index = _assocIndexOf(data, key);
  15509. return index < 0 ? undefined : data[index][1];
  15510. }
  15511. var _listCacheGet = listCacheGet;
  15512. /**
  15513. * Checks if a list cache value for `key` exists.
  15514. *
  15515. * @private
  15516. * @name has
  15517. * @memberOf ListCache
  15518. * @param {string} key The key of the entry to check.
  15519. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  15520. */
  15521. function listCacheHas(key) {
  15522. return _assocIndexOf(this.__data__, key) > -1;
  15523. }
  15524. var _listCacheHas = listCacheHas;
  15525. /**
  15526. * Sets the list cache `key` to `value`.
  15527. *
  15528. * @private
  15529. * @name set
  15530. * @memberOf ListCache
  15531. * @param {string} key The key of the value to set.
  15532. * @param {*} value The value to set.
  15533. * @returns {Object} Returns the list cache instance.
  15534. */
  15535. function listCacheSet(key, value) {
  15536. var data = this.__data__,
  15537. index = _assocIndexOf(data, key);
  15538. if (index < 0) {
  15539. ++this.size;
  15540. data.push([key, value]);
  15541. } else {
  15542. data[index][1] = value;
  15543. }
  15544. return this;
  15545. }
  15546. var _listCacheSet = listCacheSet;
  15547. /**
  15548. * Creates an list cache object.
  15549. *
  15550. * @private
  15551. * @constructor
  15552. * @param {Array} [entries] The key-value pairs to cache.
  15553. */
  15554. function ListCache(entries) {
  15555. var index = -1,
  15556. length = entries == null ? 0 : entries.length;
  15557. this.clear();
  15558. while (++index < length) {
  15559. var entry = entries[index];
  15560. this.set(entry[0], entry[1]);
  15561. }
  15562. }
  15563. // Add methods to `ListCache`.
  15564. ListCache.prototype.clear = _listCacheClear;
  15565. ListCache.prototype['delete'] = _listCacheDelete;
  15566. ListCache.prototype.get = _listCacheGet;
  15567. ListCache.prototype.has = _listCacheHas;
  15568. ListCache.prototype.set = _listCacheSet;
  15569. var _ListCache = ListCache;
  15570. /**
  15571. * Removes all key-value entries from the stack.
  15572. *
  15573. * @private
  15574. * @name clear
  15575. * @memberOf Stack
  15576. */
  15577. function stackClear() {
  15578. this.__data__ = new _ListCache;
  15579. this.size = 0;
  15580. }
  15581. var _stackClear = stackClear;
  15582. /**
  15583. * Removes `key` and its value from the stack.
  15584. *
  15585. * @private
  15586. * @name delete
  15587. * @memberOf Stack
  15588. * @param {string} key The key of the value to remove.
  15589. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  15590. */
  15591. function stackDelete(key) {
  15592. var data = this.__data__,
  15593. result = data['delete'](key);
  15594. this.size = data.size;
  15595. return result;
  15596. }
  15597. var _stackDelete = stackDelete;
  15598. /**
  15599. * Gets the stack value for `key`.
  15600. *
  15601. * @private
  15602. * @name get
  15603. * @memberOf Stack
  15604. * @param {string} key The key of the value to get.
  15605. * @returns {*} Returns the entry value.
  15606. */
  15607. function stackGet(key) {
  15608. return this.__data__.get(key);
  15609. }
  15610. var _stackGet = stackGet;
  15611. /**
  15612. * Checks if a stack value for `key` exists.
  15613. *
  15614. * @private
  15615. * @name has
  15616. * @memberOf Stack
  15617. * @param {string} key The key of the entry to check.
  15618. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  15619. */
  15620. function stackHas(key) {
  15621. return this.__data__.has(key);
  15622. }
  15623. var _stackHas = stackHas;
  15624. /** Used to detect overreaching core-js shims. */
  15625. var coreJsData = _root['__core-js_shared__'];
  15626. var _coreJsData = coreJsData;
  15627. /** Used to detect methods masquerading as native. */
  15628. var maskSrcKey = (function() {
  15629. var uid = /[^.]+$/.exec(_coreJsData && _coreJsData.keys && _coreJsData.keys.IE_PROTO || '');
  15630. return uid ? ('Symbol(src)_1.' + uid) : '';
  15631. }());
  15632. /**
  15633. * Checks if `func` has its source masked.
  15634. *
  15635. * @private
  15636. * @param {Function} func The function to check.
  15637. * @returns {boolean} Returns `true` if `func` is masked, else `false`.
  15638. */
  15639. function isMasked(func) {
  15640. return !!maskSrcKey && (maskSrcKey in func);
  15641. }
  15642. var _isMasked = isMasked;
  15643. /** Used for built-in method references. */
  15644. var funcProto$1 = Function.prototype;
  15645. /** Used to resolve the decompiled source of functions. */
  15646. var funcToString$1 = funcProto$1.toString;
  15647. /**
  15648. * Converts `func` to its source code.
  15649. *
  15650. * @private
  15651. * @param {Function} func The function to convert.
  15652. * @returns {string} Returns the source code.
  15653. */
  15654. function toSource(func) {
  15655. if (func != null) {
  15656. try {
  15657. return funcToString$1.call(func);
  15658. } catch (e) {}
  15659. try {
  15660. return (func + '');
  15661. } catch (e) {}
  15662. }
  15663. return '';
  15664. }
  15665. var _toSource = toSource;
  15666. /**
  15667. * Used to match `RegExp`
  15668. * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
  15669. */
  15670. var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
  15671. /** Used to detect host constructors (Safari). */
  15672. var reIsHostCtor = /^\[object .+?Constructor\]$/;
  15673. /** Used for built-in method references. */
  15674. var funcProto$2 = Function.prototype,
  15675. objectProto$7 = Object.prototype;
  15676. /** Used to resolve the decompiled source of functions. */
  15677. var funcToString$2 = funcProto$2.toString;
  15678. /** Used to check objects for own properties. */
  15679. var hasOwnProperty$5 = objectProto$7.hasOwnProperty;
  15680. /** Used to detect if a method is native. */
  15681. var reIsNative = RegExp('^' +
  15682. funcToString$2.call(hasOwnProperty$5).replace(reRegExpChar, '\\$&')
  15683. .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
  15684. );
  15685. /**
  15686. * The base implementation of `_.isNative` without bad shim checks.
  15687. *
  15688. * @private
  15689. * @param {*} value The value to check.
  15690. * @returns {boolean} Returns `true` if `value` is a native function,
  15691. * else `false`.
  15692. */
  15693. function baseIsNative(value) {
  15694. if (!isObject_1$1(value) || _isMasked(value)) {
  15695. return false;
  15696. }
  15697. var pattern = isFunction_1(value) ? reIsNative : reIsHostCtor;
  15698. return pattern.test(_toSource(value));
  15699. }
  15700. var _baseIsNative = baseIsNative;
  15701. /**
  15702. * Gets the value at `key` of `object`.
  15703. *
  15704. * @private
  15705. * @param {Object} [object] The object to query.
  15706. * @param {string} key The key of the property to get.
  15707. * @returns {*} Returns the property value.
  15708. */
  15709. function getValue(object, key) {
  15710. return object == null ? undefined : object[key];
  15711. }
  15712. var _getValue = getValue;
  15713. /**
  15714. * Gets the native function at `key` of `object`.
  15715. *
  15716. * @private
  15717. * @param {Object} object The object to query.
  15718. * @param {string} key The key of the method to get.
  15719. * @returns {*} Returns the function if it's native, else `undefined`.
  15720. */
  15721. function getNative(object, key) {
  15722. var value = _getValue(object, key);
  15723. return _baseIsNative(value) ? value : undefined;
  15724. }
  15725. var _getNative = getNative;
  15726. /* Built-in method references that are verified to be native. */
  15727. var Map = _getNative(_root, 'Map');
  15728. var _Map = Map;
  15729. /* Built-in method references that are verified to be native. */
  15730. var nativeCreate = _getNative(Object, 'create');
  15731. var _nativeCreate = nativeCreate;
  15732. /**
  15733. * Removes all key-value entries from the hash.
  15734. *
  15735. * @private
  15736. * @name clear
  15737. * @memberOf Hash
  15738. */
  15739. function hashClear() {
  15740. this.__data__ = _nativeCreate ? _nativeCreate(null) : {};
  15741. this.size = 0;
  15742. }
  15743. var _hashClear = hashClear;
  15744. /**
  15745. * Removes `key` and its value from the hash.
  15746. *
  15747. * @private
  15748. * @name delete
  15749. * @memberOf Hash
  15750. * @param {Object} hash The hash to modify.
  15751. * @param {string} key The key of the value to remove.
  15752. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  15753. */
  15754. function hashDelete(key) {
  15755. var result = this.has(key) && delete this.__data__[key];
  15756. this.size -= result ? 1 : 0;
  15757. return result;
  15758. }
  15759. var _hashDelete = hashDelete;
  15760. /** Used to stand-in for `undefined` hash values. */
  15761. var HASH_UNDEFINED = '__lodash_hash_undefined__';
  15762. /** Used for built-in method references. */
  15763. var objectProto$8 = Object.prototype;
  15764. /** Used to check objects for own properties. */
  15765. var hasOwnProperty$6 = objectProto$8.hasOwnProperty;
  15766. /**
  15767. * Gets the hash value for `key`.
  15768. *
  15769. * @private
  15770. * @name get
  15771. * @memberOf Hash
  15772. * @param {string} key The key of the value to get.
  15773. * @returns {*} Returns the entry value.
  15774. */
  15775. function hashGet(key) {
  15776. var data = this.__data__;
  15777. if (_nativeCreate) {
  15778. var result = data[key];
  15779. return result === HASH_UNDEFINED ? undefined : result;
  15780. }
  15781. return hasOwnProperty$6.call(data, key) ? data[key] : undefined;
  15782. }
  15783. var _hashGet = hashGet;
  15784. /** Used for built-in method references. */
  15785. var objectProto$9 = Object.prototype;
  15786. /** Used to check objects for own properties. */
  15787. var hasOwnProperty$7 = objectProto$9.hasOwnProperty;
  15788. /**
  15789. * Checks if a hash value for `key` exists.
  15790. *
  15791. * @private
  15792. * @name has
  15793. * @memberOf Hash
  15794. * @param {string} key The key of the entry to check.
  15795. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  15796. */
  15797. function hashHas(key) {
  15798. var data = this.__data__;
  15799. return _nativeCreate ? (data[key] !== undefined) : hasOwnProperty$7.call(data, key);
  15800. }
  15801. var _hashHas = hashHas;
  15802. /** Used to stand-in for `undefined` hash values. */
  15803. var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';
  15804. /**
  15805. * Sets the hash `key` to `value`.
  15806. *
  15807. * @private
  15808. * @name set
  15809. * @memberOf Hash
  15810. * @param {string} key The key of the value to set.
  15811. * @param {*} value The value to set.
  15812. * @returns {Object} Returns the hash instance.
  15813. */
  15814. function hashSet(key, value) {
  15815. var data = this.__data__;
  15816. this.size += this.has(key) ? 0 : 1;
  15817. data[key] = (_nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value;
  15818. return this;
  15819. }
  15820. var _hashSet = hashSet;
  15821. /**
  15822. * Creates a hash object.
  15823. *
  15824. * @private
  15825. * @constructor
  15826. * @param {Array} [entries] The key-value pairs to cache.
  15827. */
  15828. function Hash(entries) {
  15829. var index = -1,
  15830. length = entries == null ? 0 : entries.length;
  15831. this.clear();
  15832. while (++index < length) {
  15833. var entry = entries[index];
  15834. this.set(entry[0], entry[1]);
  15835. }
  15836. }
  15837. // Add methods to `Hash`.
  15838. Hash.prototype.clear = _hashClear;
  15839. Hash.prototype['delete'] = _hashDelete;
  15840. Hash.prototype.get = _hashGet;
  15841. Hash.prototype.has = _hashHas;
  15842. Hash.prototype.set = _hashSet;
  15843. var _Hash = Hash;
  15844. /**
  15845. * Removes all key-value entries from the map.
  15846. *
  15847. * @private
  15848. * @name clear
  15849. * @memberOf MapCache
  15850. */
  15851. function mapCacheClear() {
  15852. this.size = 0;
  15853. this.__data__ = {
  15854. 'hash': new _Hash,
  15855. 'map': new (_Map || _ListCache),
  15856. 'string': new _Hash
  15857. };
  15858. }
  15859. var _mapCacheClear = mapCacheClear;
  15860. /**
  15861. * Checks if `value` is suitable for use as unique object key.
  15862. *
  15863. * @private
  15864. * @param {*} value The value to check.
  15865. * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
  15866. */
  15867. function isKeyable(value) {
  15868. var type = typeof value;
  15869. return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
  15870. ? (value !== '__proto__')
  15871. : (value === null);
  15872. }
  15873. var _isKeyable = isKeyable;
  15874. /**
  15875. * Gets the data for `map`.
  15876. *
  15877. * @private
  15878. * @param {Object} map The map to query.
  15879. * @param {string} key The reference key.
  15880. * @returns {*} Returns the map data.
  15881. */
  15882. function getMapData(map, key) {
  15883. var data = map.__data__;
  15884. return _isKeyable(key)
  15885. ? data[typeof key == 'string' ? 'string' : 'hash']
  15886. : data.map;
  15887. }
  15888. var _getMapData = getMapData;
  15889. /**
  15890. * Removes `key` and its value from the map.
  15891. *
  15892. * @private
  15893. * @name delete
  15894. * @memberOf MapCache
  15895. * @param {string} key The key of the value to remove.
  15896. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  15897. */
  15898. function mapCacheDelete(key) {
  15899. var result = _getMapData(this, key)['delete'](key);
  15900. this.size -= result ? 1 : 0;
  15901. return result;
  15902. }
  15903. var _mapCacheDelete = mapCacheDelete;
  15904. /**
  15905. * Gets the map value for `key`.
  15906. *
  15907. * @private
  15908. * @name get
  15909. * @memberOf MapCache
  15910. * @param {string} key The key of the value to get.
  15911. * @returns {*} Returns the entry value.
  15912. */
  15913. function mapCacheGet(key) {
  15914. return _getMapData(this, key).get(key);
  15915. }
  15916. var _mapCacheGet = mapCacheGet;
  15917. /**
  15918. * Checks if a map value for `key` exists.
  15919. *
  15920. * @private
  15921. * @name has
  15922. * @memberOf MapCache
  15923. * @param {string} key The key of the entry to check.
  15924. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  15925. */
  15926. function mapCacheHas(key) {
  15927. return _getMapData(this, key).has(key);
  15928. }
  15929. var _mapCacheHas = mapCacheHas;
  15930. /**
  15931. * Sets the map `key` to `value`.
  15932. *
  15933. * @private
  15934. * @name set
  15935. * @memberOf MapCache
  15936. * @param {string} key The key of the value to set.
  15937. * @param {*} value The value to set.
  15938. * @returns {Object} Returns the map cache instance.
  15939. */
  15940. function mapCacheSet(key, value) {
  15941. var data = _getMapData(this, key),
  15942. size = data.size;
  15943. data.set(key, value);
  15944. this.size += data.size == size ? 0 : 1;
  15945. return this;
  15946. }
  15947. var _mapCacheSet = mapCacheSet;
  15948. /**
  15949. * Creates a map cache object to store key-value pairs.
  15950. *
  15951. * @private
  15952. * @constructor
  15953. * @param {Array} [entries] The key-value pairs to cache.
  15954. */
  15955. function MapCache(entries) {
  15956. var index = -1,
  15957. length = entries == null ? 0 : entries.length;
  15958. this.clear();
  15959. while (++index < length) {
  15960. var entry = entries[index];
  15961. this.set(entry[0], entry[1]);
  15962. }
  15963. }
  15964. // Add methods to `MapCache`.
  15965. MapCache.prototype.clear = _mapCacheClear;
  15966. MapCache.prototype['delete'] = _mapCacheDelete;
  15967. MapCache.prototype.get = _mapCacheGet;
  15968. MapCache.prototype.has = _mapCacheHas;
  15969. MapCache.prototype.set = _mapCacheSet;
  15970. var _MapCache = MapCache;
  15971. /** Used as the size to enable large array optimizations. */
  15972. var LARGE_ARRAY_SIZE = 200;
  15973. /**
  15974. * Sets the stack `key` to `value`.
  15975. *
  15976. * @private
  15977. * @name set
  15978. * @memberOf Stack
  15979. * @param {string} key The key of the value to set.
  15980. * @param {*} value The value to set.
  15981. * @returns {Object} Returns the stack cache instance.
  15982. */
  15983. function stackSet(key, value) {
  15984. var data = this.__data__;
  15985. if (data instanceof _ListCache) {
  15986. var pairs = data.__data__;
  15987. if (!_Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
  15988. pairs.push([key, value]);
  15989. this.size = ++data.size;
  15990. return this;
  15991. }
  15992. data = this.__data__ = new _MapCache(pairs);
  15993. }
  15994. data.set(key, value);
  15995. this.size = data.size;
  15996. return this;
  15997. }
  15998. var _stackSet = stackSet;
  15999. /**
  16000. * Creates a stack cache object to store key-value pairs.
  16001. *
  16002. * @private
  16003. * @constructor
  16004. * @param {Array} [entries] The key-value pairs to cache.
  16005. */
  16006. function Stack(entries) {
  16007. var data = this.__data__ = new _ListCache(entries);
  16008. this.size = data.size;
  16009. }
  16010. // Add methods to `Stack`.
  16011. Stack.prototype.clear = _stackClear;
  16012. Stack.prototype['delete'] = _stackDelete;
  16013. Stack.prototype.get = _stackGet;
  16014. Stack.prototype.has = _stackHas;
  16015. Stack.prototype.set = _stackSet;
  16016. var _Stack = Stack;
  16017. /** Used to stand-in for `undefined` hash values. */
  16018. var HASH_UNDEFINED$2 = '__lodash_hash_undefined__';
  16019. /**
  16020. * Adds `value` to the array cache.
  16021. *
  16022. * @private
  16023. * @name add
  16024. * @memberOf SetCache
  16025. * @alias push
  16026. * @param {*} value The value to cache.
  16027. * @returns {Object} Returns the cache instance.
  16028. */
  16029. function setCacheAdd(value) {
  16030. this.__data__.set(value, HASH_UNDEFINED$2);
  16031. return this;
  16032. }
  16033. var _setCacheAdd = setCacheAdd;
  16034. /**
  16035. * Checks if `value` is in the array cache.
  16036. *
  16037. * @private
  16038. * @name has
  16039. * @memberOf SetCache
  16040. * @param {*} value The value to search for.
  16041. * @returns {number} Returns `true` if `value` is found, else `false`.
  16042. */
  16043. function setCacheHas(value) {
  16044. return this.__data__.has(value);
  16045. }
  16046. var _setCacheHas = setCacheHas;
  16047. /**
  16048. *
  16049. * Creates an array cache object to store unique values.
  16050. *
  16051. * @private
  16052. * @constructor
  16053. * @param {Array} [values] The values to cache.
  16054. */
  16055. function SetCache(values) {
  16056. var index = -1,
  16057. length = values == null ? 0 : values.length;
  16058. this.__data__ = new _MapCache;
  16059. while (++index < length) {
  16060. this.add(values[index]);
  16061. }
  16062. }
  16063. // Add methods to `SetCache`.
  16064. SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd;
  16065. SetCache.prototype.has = _setCacheHas;
  16066. var _SetCache = SetCache;
  16067. /**
  16068. * A specialized version of `_.some` for arrays without support for iteratee
  16069. * shorthands.
  16070. *
  16071. * @private
  16072. * @param {Array} [array] The array to iterate over.
  16073. * @param {Function} predicate The function invoked per iteration.
  16074. * @returns {boolean} Returns `true` if any element passes the predicate check,
  16075. * else `false`.
  16076. */
  16077. function arraySome(array, predicate) {
  16078. var index = -1,
  16079. length = array == null ? 0 : array.length;
  16080. while (++index < length) {
  16081. if (predicate(array[index], index, array)) {
  16082. return true;
  16083. }
  16084. }
  16085. return false;
  16086. }
  16087. var _arraySome = arraySome;
  16088. /**
  16089. * Checks if a `cache` value for `key` exists.
  16090. *
  16091. * @private
  16092. * @param {Object} cache The cache to query.
  16093. * @param {string} key The key of the entry to check.
  16094. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  16095. */
  16096. function cacheHas(cache, key) {
  16097. return cache.has(key);
  16098. }
  16099. var _cacheHas = cacheHas;
  16100. /** Used to compose bitmasks for value comparisons. */
  16101. var COMPARE_PARTIAL_FLAG = 1,
  16102. COMPARE_UNORDERED_FLAG = 2;
  16103. /**
  16104. * A specialized version of `baseIsEqualDeep` for arrays with support for
  16105. * partial deep comparisons.
  16106. *
  16107. * @private
  16108. * @param {Array} array The array to compare.
  16109. * @param {Array} other The other array to compare.
  16110. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  16111. * @param {Function} customizer The function to customize comparisons.
  16112. * @param {Function} equalFunc The function to determine equivalents of values.
  16113. * @param {Object} stack Tracks traversed `array` and `other` objects.
  16114. * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
  16115. */
  16116. function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
  16117. var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
  16118. arrLength = array.length,
  16119. othLength = other.length;
  16120. if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
  16121. return false;
  16122. }
  16123. // Check that cyclic values are equal.
  16124. var arrStacked = stack.get(array);
  16125. var othStacked = stack.get(other);
  16126. if (arrStacked && othStacked) {
  16127. return arrStacked == other && othStacked == array;
  16128. }
  16129. var index = -1,
  16130. result = true,
  16131. seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache : undefined;
  16132. stack.set(array, other);
  16133. stack.set(other, array);
  16134. // Ignore non-index properties.
  16135. while (++index < arrLength) {
  16136. var arrValue = array[index],
  16137. othValue = other[index];
  16138. if (customizer) {
  16139. var compared = isPartial
  16140. ? customizer(othValue, arrValue, index, other, array, stack)
  16141. : customizer(arrValue, othValue, index, array, other, stack);
  16142. }
  16143. if (compared !== undefined) {
  16144. if (compared) {
  16145. continue;
  16146. }
  16147. result = false;
  16148. break;
  16149. }
  16150. // Recursively compare arrays (susceptible to call stack limits).
  16151. if (seen) {
  16152. if (!_arraySome(other, function(othValue, othIndex) {
  16153. if (!_cacheHas(seen, othIndex) &&
  16154. (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
  16155. return seen.push(othIndex);
  16156. }
  16157. })) {
  16158. result = false;
  16159. break;
  16160. }
  16161. } else if (!(
  16162. arrValue === othValue ||
  16163. equalFunc(arrValue, othValue, bitmask, customizer, stack)
  16164. )) {
  16165. result = false;
  16166. break;
  16167. }
  16168. }
  16169. stack['delete'](array);
  16170. stack['delete'](other);
  16171. return result;
  16172. }
  16173. var _equalArrays = equalArrays;
  16174. /** Built-in value references. */
  16175. var Uint8Array$1 = _root.Uint8Array;
  16176. var _Uint8Array = Uint8Array$1;
  16177. /**
  16178. * Converts `map` to its key-value pairs.
  16179. *
  16180. * @private
  16181. * @param {Object} map The map to convert.
  16182. * @returns {Array} Returns the key-value pairs.
  16183. */
  16184. function mapToArray(map) {
  16185. var index = -1,
  16186. result = Array(map.size);
  16187. map.forEach(function(value, key) {
  16188. result[++index] = [key, value];
  16189. });
  16190. return result;
  16191. }
  16192. var _mapToArray = mapToArray;
  16193. /**
  16194. * Converts `set` to an array of its values.
  16195. *
  16196. * @private
  16197. * @param {Object} set The set to convert.
  16198. * @returns {Array} Returns the values.
  16199. */
  16200. function setToArray(set) {
  16201. var index = -1,
  16202. result = Array(set.size);
  16203. set.forEach(function(value) {
  16204. result[++index] = value;
  16205. });
  16206. return result;
  16207. }
  16208. var _setToArray = setToArray;
  16209. /** Used to compose bitmasks for value comparisons. */
  16210. var COMPARE_PARTIAL_FLAG$1 = 1,
  16211. COMPARE_UNORDERED_FLAG$1 = 2;
  16212. /** `Object#toString` result references. */
  16213. var boolTag$1 = '[object Boolean]',
  16214. dateTag$1 = '[object Date]',
  16215. errorTag$1 = '[object Error]',
  16216. mapTag$1 = '[object Map]',
  16217. numberTag$1 = '[object Number]',
  16218. regexpTag$1 = '[object RegExp]',
  16219. setTag$1 = '[object Set]',
  16220. stringTag$1 = '[object String]',
  16221. symbolTag = '[object Symbol]';
  16222. var arrayBufferTag$1 = '[object ArrayBuffer]',
  16223. dataViewTag$1 = '[object DataView]';
  16224. /** Used to convert symbols to primitives and strings. */
  16225. var symbolProto = _Symbol ? _Symbol.prototype : undefined,
  16226. symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
  16227. /**
  16228. * A specialized version of `baseIsEqualDeep` for comparing objects of
  16229. * the same `toStringTag`.
  16230. *
  16231. * **Note:** This function only supports comparing values with tags of
  16232. * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
  16233. *
  16234. * @private
  16235. * @param {Object} object The object to compare.
  16236. * @param {Object} other The other object to compare.
  16237. * @param {string} tag The `toStringTag` of the objects to compare.
  16238. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  16239. * @param {Function} customizer The function to customize comparisons.
  16240. * @param {Function} equalFunc The function to determine equivalents of values.
  16241. * @param {Object} stack Tracks traversed `object` and `other` objects.
  16242. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  16243. */
  16244. function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
  16245. switch (tag) {
  16246. case dataViewTag$1:
  16247. if ((object.byteLength != other.byteLength) ||
  16248. (object.byteOffset != other.byteOffset)) {
  16249. return false;
  16250. }
  16251. object = object.buffer;
  16252. other = other.buffer;
  16253. case arrayBufferTag$1:
  16254. if ((object.byteLength != other.byteLength) ||
  16255. !equalFunc(new _Uint8Array(object), new _Uint8Array(other))) {
  16256. return false;
  16257. }
  16258. return true;
  16259. case boolTag$1:
  16260. case dateTag$1:
  16261. case numberTag$1:
  16262. // Coerce booleans to `1` or `0` and dates to milliseconds.
  16263. // Invalid dates are coerced to `NaN`.
  16264. return eq_1(+object, +other);
  16265. case errorTag$1:
  16266. return object.name == other.name && object.message == other.message;
  16267. case regexpTag$1:
  16268. case stringTag$1:
  16269. // Coerce regexes to strings and treat strings, primitives and objects,
  16270. // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
  16271. // for more details.
  16272. return object == (other + '');
  16273. case mapTag$1:
  16274. var convert = _mapToArray;
  16275. case setTag$1:
  16276. var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1;
  16277. convert || (convert = _setToArray);
  16278. if (object.size != other.size && !isPartial) {
  16279. return false;
  16280. }
  16281. // Assume cyclic values are equal.
  16282. var stacked = stack.get(object);
  16283. if (stacked) {
  16284. return stacked == other;
  16285. }
  16286. bitmask |= COMPARE_UNORDERED_FLAG$1;
  16287. // Recursively compare objects (susceptible to call stack limits).
  16288. stack.set(object, other);
  16289. var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
  16290. stack['delete'](object);
  16291. return result;
  16292. case symbolTag:
  16293. if (symbolValueOf) {
  16294. return symbolValueOf.call(object) == symbolValueOf.call(other);
  16295. }
  16296. }
  16297. return false;
  16298. }
  16299. var _equalByTag = equalByTag;
  16300. /**
  16301. * Appends the elements of `values` to `array`.
  16302. *
  16303. * @private
  16304. * @param {Array} array The array to modify.
  16305. * @param {Array} values The values to append.
  16306. * @returns {Array} Returns `array`.
  16307. */
  16308. function arrayPush(array, values) {
  16309. var index = -1,
  16310. length = values.length,
  16311. offset = array.length;
  16312. while (++index < length) {
  16313. array[offset + index] = values[index];
  16314. }
  16315. return array;
  16316. }
  16317. var _arrayPush = arrayPush;
  16318. /**
  16319. * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
  16320. * `keysFunc` and `symbolsFunc` to get the enumerable property names and
  16321. * symbols of `object`.
  16322. *
  16323. * @private
  16324. * @param {Object} object The object to query.
  16325. * @param {Function} keysFunc The function to get the keys of `object`.
  16326. * @param {Function} symbolsFunc The function to get the symbols of `object`.
  16327. * @returns {Array} Returns the array of property names and symbols.
  16328. */
  16329. function baseGetAllKeys(object, keysFunc, symbolsFunc) {
  16330. var result = keysFunc(object);
  16331. return isArray_1(object) ? result : _arrayPush(result, symbolsFunc(object));
  16332. }
  16333. var _baseGetAllKeys = baseGetAllKeys;
  16334. /**
  16335. * A specialized version of `_.filter` for arrays without support for
  16336. * iteratee shorthands.
  16337. *
  16338. * @private
  16339. * @param {Array} [array] The array to iterate over.
  16340. * @param {Function} predicate The function invoked per iteration.
  16341. * @returns {Array} Returns the new filtered array.
  16342. */
  16343. function arrayFilter(array, predicate) {
  16344. var index = -1,
  16345. length = array == null ? 0 : array.length,
  16346. resIndex = 0,
  16347. result = [];
  16348. while (++index < length) {
  16349. var value = array[index];
  16350. if (predicate(value, index, array)) {
  16351. result[resIndex++] = value;
  16352. }
  16353. }
  16354. return result;
  16355. }
  16356. var _arrayFilter = arrayFilter;
  16357. /**
  16358. * This method returns a new empty array.
  16359. *
  16360. * @static
  16361. * @memberOf _
  16362. * @since 4.13.0
  16363. * @category Util
  16364. * @returns {Array} Returns the new empty array.
  16365. * @example
  16366. *
  16367. * var arrays = _.times(2, _.stubArray);
  16368. *
  16369. * console.log(arrays);
  16370. * // => [[], []]
  16371. *
  16372. * console.log(arrays[0] === arrays[1]);
  16373. * // => false
  16374. */
  16375. function stubArray() {
  16376. return [];
  16377. }
  16378. var stubArray_1 = stubArray;
  16379. /** Used for built-in method references. */
  16380. var objectProto$a = Object.prototype;
  16381. /** Built-in value references. */
  16382. var propertyIsEnumerable$1 = objectProto$a.propertyIsEnumerable;
  16383. /* Built-in method references for those with the same name as other `lodash` methods. */
  16384. var nativeGetSymbols = Object.getOwnPropertySymbols;
  16385. /**
  16386. * Creates an array of the own enumerable symbols of `object`.
  16387. *
  16388. * @private
  16389. * @param {Object} object The object to query.
  16390. * @returns {Array} Returns the array of symbols.
  16391. */
  16392. var getSymbols = !nativeGetSymbols ? stubArray_1 : function(object) {
  16393. if (object == null) {
  16394. return [];
  16395. }
  16396. object = Object(object);
  16397. return _arrayFilter(nativeGetSymbols(object), function(symbol) {
  16398. return propertyIsEnumerable$1.call(object, symbol);
  16399. });
  16400. };
  16401. var _getSymbols = getSymbols;
  16402. /**
  16403. * Creates an array of own enumerable property names and symbols of `object`.
  16404. *
  16405. * @private
  16406. * @param {Object} object The object to query.
  16407. * @returns {Array} Returns the array of property names and symbols.
  16408. */
  16409. function getAllKeys(object) {
  16410. return _baseGetAllKeys(object, keys_1, _getSymbols);
  16411. }
  16412. var _getAllKeys = getAllKeys;
  16413. /** Used to compose bitmasks for value comparisons. */
  16414. var COMPARE_PARTIAL_FLAG$2 = 1;
  16415. /** Used for built-in method references. */
  16416. var objectProto$b = Object.prototype;
  16417. /** Used to check objects for own properties. */
  16418. var hasOwnProperty$8 = objectProto$b.hasOwnProperty;
  16419. /**
  16420. * A specialized version of `baseIsEqualDeep` for objects with support for
  16421. * partial deep comparisons.
  16422. *
  16423. * @private
  16424. * @param {Object} object The object to compare.
  16425. * @param {Object} other The other object to compare.
  16426. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  16427. * @param {Function} customizer The function to customize comparisons.
  16428. * @param {Function} equalFunc The function to determine equivalents of values.
  16429. * @param {Object} stack Tracks traversed `object` and `other` objects.
  16430. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  16431. */
  16432. function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
  16433. var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2,
  16434. objProps = _getAllKeys(object),
  16435. objLength = objProps.length,
  16436. othProps = _getAllKeys(other),
  16437. othLength = othProps.length;
  16438. if (objLength != othLength && !isPartial) {
  16439. return false;
  16440. }
  16441. var index = objLength;
  16442. while (index--) {
  16443. var key = objProps[index];
  16444. if (!(isPartial ? key in other : hasOwnProperty$8.call(other, key))) {
  16445. return false;
  16446. }
  16447. }
  16448. // Check that cyclic values are equal.
  16449. var objStacked = stack.get(object);
  16450. var othStacked = stack.get(other);
  16451. if (objStacked && othStacked) {
  16452. return objStacked == other && othStacked == object;
  16453. }
  16454. var result = true;
  16455. stack.set(object, other);
  16456. stack.set(other, object);
  16457. var skipCtor = isPartial;
  16458. while (++index < objLength) {
  16459. key = objProps[index];
  16460. var objValue = object[key],
  16461. othValue = other[key];
  16462. if (customizer) {
  16463. var compared = isPartial
  16464. ? customizer(othValue, objValue, key, other, object, stack)
  16465. : customizer(objValue, othValue, key, object, other, stack);
  16466. }
  16467. // Recursively compare objects (susceptible to call stack limits).
  16468. if (!(compared === undefined
  16469. ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
  16470. : compared
  16471. )) {
  16472. result = false;
  16473. break;
  16474. }
  16475. skipCtor || (skipCtor = key == 'constructor');
  16476. }
  16477. if (result && !skipCtor) {
  16478. var objCtor = object.constructor,
  16479. othCtor = other.constructor;
  16480. // Non `Object` object instances with different constructors are not equal.
  16481. if (objCtor != othCtor &&
  16482. ('constructor' in object && 'constructor' in other) &&
  16483. !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
  16484. typeof othCtor == 'function' && othCtor instanceof othCtor)) {
  16485. result = false;
  16486. }
  16487. }
  16488. stack['delete'](object);
  16489. stack['delete'](other);
  16490. return result;
  16491. }
  16492. var _equalObjects = equalObjects;
  16493. /* Built-in method references that are verified to be native. */
  16494. var DataView = _getNative(_root, 'DataView');
  16495. var _DataView = DataView;
  16496. /* Built-in method references that are verified to be native. */
  16497. var Promise$1 = _getNative(_root, 'Promise');
  16498. var _Promise = Promise$1;
  16499. /* Built-in method references that are verified to be native. */
  16500. var Set$1 = _getNative(_root, 'Set');
  16501. var _Set = Set$1;
  16502. /* Built-in method references that are verified to be native. */
  16503. var WeakMap$1 = _getNative(_root, 'WeakMap');
  16504. var _WeakMap = WeakMap$1;
  16505. /** `Object#toString` result references. */
  16506. var mapTag$2 = '[object Map]',
  16507. objectTag$2 = '[object Object]',
  16508. promiseTag = '[object Promise]',
  16509. setTag$2 = '[object Set]',
  16510. weakMapTag$1 = '[object WeakMap]';
  16511. var dataViewTag$2 = '[object DataView]';
  16512. /** Used to detect maps, sets, and weakmaps. */
  16513. var dataViewCtorString = _toSource(_DataView),
  16514. mapCtorString = _toSource(_Map),
  16515. promiseCtorString = _toSource(_Promise),
  16516. setCtorString = _toSource(_Set),
  16517. weakMapCtorString = _toSource(_WeakMap);
  16518. /**
  16519. * Gets the `toStringTag` of `value`.
  16520. *
  16521. * @private
  16522. * @param {*} value The value to query.
  16523. * @returns {string} Returns the `toStringTag`.
  16524. */
  16525. var getTag = _baseGetTag;
  16526. // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
  16527. if ((_DataView && getTag(new _DataView(new ArrayBuffer(1))) != dataViewTag$2) ||
  16528. (_Map && getTag(new _Map) != mapTag$2) ||
  16529. (_Promise && getTag(_Promise.resolve()) != promiseTag) ||
  16530. (_Set && getTag(new _Set) != setTag$2) ||
  16531. (_WeakMap && getTag(new _WeakMap) != weakMapTag$1)) {
  16532. getTag = function(value) {
  16533. var result = _baseGetTag(value),
  16534. Ctor = result == objectTag$2 ? value.constructor : undefined,
  16535. ctorString = Ctor ? _toSource(Ctor) : '';
  16536. if (ctorString) {
  16537. switch (ctorString) {
  16538. case dataViewCtorString: return dataViewTag$2;
  16539. case mapCtorString: return mapTag$2;
  16540. case promiseCtorString: return promiseTag;
  16541. case setCtorString: return setTag$2;
  16542. case weakMapCtorString: return weakMapTag$1;
  16543. }
  16544. }
  16545. return result;
  16546. };
  16547. }
  16548. var _getTag = getTag;
  16549. /** Used to compose bitmasks for value comparisons. */
  16550. var COMPARE_PARTIAL_FLAG$3 = 1;
  16551. /** `Object#toString` result references. */
  16552. var argsTag$2 = '[object Arguments]',
  16553. arrayTag$1 = '[object Array]',
  16554. objectTag$3 = '[object Object]';
  16555. /** Used for built-in method references. */
  16556. var objectProto$c = Object.prototype;
  16557. /** Used to check objects for own properties. */
  16558. var hasOwnProperty$9 = objectProto$c.hasOwnProperty;
  16559. /**
  16560. * A specialized version of `baseIsEqual` for arrays and objects which performs
  16561. * deep comparisons and tracks traversed objects enabling objects with circular
  16562. * references to be compared.
  16563. *
  16564. * @private
  16565. * @param {Object} object The object to compare.
  16566. * @param {Object} other The other object to compare.
  16567. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  16568. * @param {Function} customizer The function to customize comparisons.
  16569. * @param {Function} equalFunc The function to determine equivalents of values.
  16570. * @param {Object} [stack] Tracks traversed `object` and `other` objects.
  16571. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  16572. */
  16573. function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
  16574. var objIsArr = isArray_1(object),
  16575. othIsArr = isArray_1(other),
  16576. objTag = objIsArr ? arrayTag$1 : _getTag(object),
  16577. othTag = othIsArr ? arrayTag$1 : _getTag(other);
  16578. objTag = objTag == argsTag$2 ? objectTag$3 : objTag;
  16579. othTag = othTag == argsTag$2 ? objectTag$3 : othTag;
  16580. var objIsObj = objTag == objectTag$3,
  16581. othIsObj = othTag == objectTag$3,
  16582. isSameTag = objTag == othTag;
  16583. if (isSameTag && isBuffer_1(object)) {
  16584. if (!isBuffer_1(other)) {
  16585. return false;
  16586. }
  16587. objIsArr = true;
  16588. objIsObj = false;
  16589. }
  16590. if (isSameTag && !objIsObj) {
  16591. stack || (stack = new _Stack);
  16592. return (objIsArr || isTypedArray_1(object))
  16593. ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack)
  16594. : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
  16595. }
  16596. if (!(bitmask & COMPARE_PARTIAL_FLAG$3)) {
  16597. var objIsWrapped = objIsObj && hasOwnProperty$9.call(object, '__wrapped__'),
  16598. othIsWrapped = othIsObj && hasOwnProperty$9.call(other, '__wrapped__');
  16599. if (objIsWrapped || othIsWrapped) {
  16600. var objUnwrapped = objIsWrapped ? object.value() : object,
  16601. othUnwrapped = othIsWrapped ? other.value() : other;
  16602. stack || (stack = new _Stack);
  16603. return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
  16604. }
  16605. }
  16606. if (!isSameTag) {
  16607. return false;
  16608. }
  16609. stack || (stack = new _Stack);
  16610. return _equalObjects(object, other, bitmask, customizer, equalFunc, stack);
  16611. }
  16612. var _baseIsEqualDeep = baseIsEqualDeep;
  16613. /**
  16614. * The base implementation of `_.isEqual` which supports partial comparisons
  16615. * and tracks traversed objects.
  16616. *
  16617. * @private
  16618. * @param {*} value The value to compare.
  16619. * @param {*} other The other value to compare.
  16620. * @param {boolean} bitmask The bitmask flags.
  16621. * 1 - Unordered comparison
  16622. * 2 - Partial comparison
  16623. * @param {Function} [customizer] The function to customize comparisons.
  16624. * @param {Object} [stack] Tracks traversed `value` and `other` objects.
  16625. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  16626. */
  16627. function baseIsEqual(value, other, bitmask, customizer, stack) {
  16628. if (value === other) {
  16629. return true;
  16630. }
  16631. if (value == null || other == null || (!isObjectLike_1(value) && !isObjectLike_1(other))) {
  16632. return value !== value && other !== other;
  16633. }
  16634. return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
  16635. }
  16636. var _baseIsEqual = baseIsEqual;
  16637. /** Used to compose bitmasks for value comparisons. */
  16638. var COMPARE_PARTIAL_FLAG$4 = 1,
  16639. COMPARE_UNORDERED_FLAG$2 = 2;
  16640. /**
  16641. * The base implementation of `_.isMatch` without support for iteratee shorthands.
  16642. *
  16643. * @private
  16644. * @param {Object} object The object to inspect.
  16645. * @param {Object} source The object of property values to match.
  16646. * @param {Array} matchData The property names, values, and compare flags to match.
  16647. * @param {Function} [customizer] The function to customize comparisons.
  16648. * @returns {boolean} Returns `true` if `object` is a match, else `false`.
  16649. */
  16650. function baseIsMatch(object, source, matchData, customizer) {
  16651. var index = matchData.length,
  16652. length = index,
  16653. noCustomizer = !customizer;
  16654. if (object == null) {
  16655. return !length;
  16656. }
  16657. object = Object(object);
  16658. while (index--) {
  16659. var data = matchData[index];
  16660. if ((noCustomizer && data[2])
  16661. ? data[1] !== object[data[0]]
  16662. : !(data[0] in object)
  16663. ) {
  16664. return false;
  16665. }
  16666. }
  16667. while (++index < length) {
  16668. data = matchData[index];
  16669. var key = data[0],
  16670. objValue = object[key],
  16671. srcValue = data[1];
  16672. if (noCustomizer && data[2]) {
  16673. if (objValue === undefined && !(key in object)) {
  16674. return false;
  16675. }
  16676. } else {
  16677. var stack = new _Stack;
  16678. if (customizer) {
  16679. var result = customizer(objValue, srcValue, key, object, source, stack);
  16680. }
  16681. if (!(result === undefined
  16682. ? _baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$4 | COMPARE_UNORDERED_FLAG$2, customizer, stack)
  16683. : result
  16684. )) {
  16685. return false;
  16686. }
  16687. }
  16688. }
  16689. return true;
  16690. }
  16691. var _baseIsMatch = baseIsMatch;
  16692. /**
  16693. * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
  16694. *
  16695. * @private
  16696. * @param {*} value The value to check.
  16697. * @returns {boolean} Returns `true` if `value` if suitable for strict
  16698. * equality comparisons, else `false`.
  16699. */
  16700. function isStrictComparable(value) {
  16701. return value === value && !isObject_1$1(value);
  16702. }
  16703. var _isStrictComparable = isStrictComparable;
  16704. /**
  16705. * Gets the property names, values, and compare flags of `object`.
  16706. *
  16707. * @private
  16708. * @param {Object} object The object to query.
  16709. * @returns {Array} Returns the match data of `object`.
  16710. */
  16711. function getMatchData(object) {
  16712. var result = keys_1(object),
  16713. length = result.length;
  16714. while (length--) {
  16715. var key = result[length],
  16716. value = object[key];
  16717. result[length] = [key, value, _isStrictComparable(value)];
  16718. }
  16719. return result;
  16720. }
  16721. var _getMatchData = getMatchData;
  16722. /**
  16723. * A specialized version of `matchesProperty` for source values suitable
  16724. * for strict equality comparisons, i.e. `===`.
  16725. *
  16726. * @private
  16727. * @param {string} key The key of the property to get.
  16728. * @param {*} srcValue The value to match.
  16729. * @returns {Function} Returns the new spec function.
  16730. */
  16731. function matchesStrictComparable(key, srcValue) {
  16732. return function(object) {
  16733. if (object == null) {
  16734. return false;
  16735. }
  16736. return object[key] === srcValue &&
  16737. (srcValue !== undefined || (key in Object(object)));
  16738. };
  16739. }
  16740. var _matchesStrictComparable = matchesStrictComparable;
  16741. /**
  16742. * The base implementation of `_.matches` which doesn't clone `source`.
  16743. *
  16744. * @private
  16745. * @param {Object} source The object of property values to match.
  16746. * @returns {Function} Returns the new spec function.
  16747. */
  16748. function baseMatches(source) {
  16749. var matchData = _getMatchData(source);
  16750. if (matchData.length == 1 && matchData[0][2]) {
  16751. return _matchesStrictComparable(matchData[0][0], matchData[0][1]);
  16752. }
  16753. return function(object) {
  16754. return object === source || _baseIsMatch(object, source, matchData);
  16755. };
  16756. }
  16757. var _baseMatches = baseMatches;
  16758. /** `Object#toString` result references. */
  16759. var symbolTag$1 = '[object Symbol]';
  16760. /**
  16761. * Checks if `value` is classified as a `Symbol` primitive or object.
  16762. *
  16763. * @static
  16764. * @memberOf _
  16765. * @since 4.0.0
  16766. * @category Lang
  16767. * @param {*} value The value to check.
  16768. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
  16769. * @example
  16770. *
  16771. * _.isSymbol(Symbol.iterator);
  16772. * // => true
  16773. *
  16774. * _.isSymbol('abc');
  16775. * // => false
  16776. */
  16777. function isSymbol(value) {
  16778. return typeof value == 'symbol' ||
  16779. (isObjectLike_1(value) && _baseGetTag(value) == symbolTag$1);
  16780. }
  16781. var isSymbol_1 = isSymbol;
  16782. /** Used to match property names within property paths. */
  16783. var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
  16784. reIsPlainProp = /^\w*$/;
  16785. /**
  16786. * Checks if `value` is a property name and not a property path.
  16787. *
  16788. * @private
  16789. * @param {*} value The value to check.
  16790. * @param {Object} [object] The object to query keys on.
  16791. * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
  16792. */
  16793. function isKey(value, object) {
  16794. if (isArray_1(value)) {
  16795. return false;
  16796. }
  16797. var type = typeof value;
  16798. if (type == 'number' || type == 'symbol' || type == 'boolean' ||
  16799. value == null || isSymbol_1(value)) {
  16800. return true;
  16801. }
  16802. return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
  16803. (object != null && value in Object(object));
  16804. }
  16805. var _isKey = isKey;
  16806. /** Error message constants. */
  16807. var FUNC_ERROR_TEXT = 'Expected a function';
  16808. /**
  16809. * Creates a function that memoizes the result of `func`. If `resolver` is
  16810. * provided, it determines the cache key for storing the result based on the
  16811. * arguments provided to the memoized function. By default, the first argument
  16812. * provided to the memoized function is used as the map cache key. The `func`
  16813. * is invoked with the `this` binding of the memoized function.
  16814. *
  16815. * **Note:** The cache is exposed as the `cache` property on the memoized
  16816. * function. Its creation may be customized by replacing the `_.memoize.Cache`
  16817. * constructor with one whose instances implement the
  16818. * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
  16819. * method interface of `clear`, `delete`, `get`, `has`, and `set`.
  16820. *
  16821. * @static
  16822. * @memberOf _
  16823. * @since 0.1.0
  16824. * @category Function
  16825. * @param {Function} func The function to have its output memoized.
  16826. * @param {Function} [resolver] The function to resolve the cache key.
  16827. * @returns {Function} Returns the new memoized function.
  16828. * @example
  16829. *
  16830. * var object = { 'a': 1, 'b': 2 };
  16831. * var other = { 'c': 3, 'd': 4 };
  16832. *
  16833. * var values = _.memoize(_.values);
  16834. * values(object);
  16835. * // => [1, 2]
  16836. *
  16837. * values(other);
  16838. * // => [3, 4]
  16839. *
  16840. * object.a = 2;
  16841. * values(object);
  16842. * // => [1, 2]
  16843. *
  16844. * // Modify the result cache.
  16845. * values.cache.set(object, ['a', 'b']);
  16846. * values(object);
  16847. * // => ['a', 'b']
  16848. *
  16849. * // Replace `_.memoize.Cache`.
  16850. * _.memoize.Cache = WeakMap;
  16851. */
  16852. function memoize(func, resolver) {
  16853. if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
  16854. throw new TypeError(FUNC_ERROR_TEXT);
  16855. }
  16856. var memoized = function() {
  16857. var args = arguments,
  16858. key = resolver ? resolver.apply(this, args) : args[0],
  16859. cache = memoized.cache;
  16860. if (cache.has(key)) {
  16861. return cache.get(key);
  16862. }
  16863. var result = func.apply(this, args);
  16864. memoized.cache = cache.set(key, result) || cache;
  16865. return result;
  16866. };
  16867. memoized.cache = new (memoize.Cache || _MapCache);
  16868. return memoized;
  16869. }
  16870. // Expose `MapCache`.
  16871. memoize.Cache = _MapCache;
  16872. var memoize_1 = memoize;
  16873. /** Used as the maximum memoize cache size. */
  16874. var MAX_MEMOIZE_SIZE = 500;
  16875. /**
  16876. * A specialized version of `_.memoize` which clears the memoized function's
  16877. * cache when it exceeds `MAX_MEMOIZE_SIZE`.
  16878. *
  16879. * @private
  16880. * @param {Function} func The function to have its output memoized.
  16881. * @returns {Function} Returns the new memoized function.
  16882. */
  16883. function memoizeCapped(func) {
  16884. var result = memoize_1(func, function(key) {
  16885. if (cache.size === MAX_MEMOIZE_SIZE) {
  16886. cache.clear();
  16887. }
  16888. return key;
  16889. });
  16890. var cache = result.cache;
  16891. return result;
  16892. }
  16893. var _memoizeCapped = memoizeCapped;
  16894. /** Used to match property names within property paths. */
  16895. var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
  16896. /** Used to match backslashes in property paths. */
  16897. var reEscapeChar = /\\(\\)?/g;
  16898. /**
  16899. * Converts `string` to a property path array.
  16900. *
  16901. * @private
  16902. * @param {string} string The string to convert.
  16903. * @returns {Array} Returns the property path array.
  16904. */
  16905. var stringToPath = _memoizeCapped(function(string) {
  16906. var result = [];
  16907. if (string.charCodeAt(0) === 46 /* . */) {
  16908. result.push('');
  16909. }
  16910. string.replace(rePropName, function(match, number, quote, subString) {
  16911. result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
  16912. });
  16913. return result;
  16914. });
  16915. var _stringToPath = stringToPath;
  16916. /** Used as references for various `Number` constants. */
  16917. var INFINITY = 1 / 0;
  16918. /** Used to convert symbols to primitives and strings. */
  16919. var symbolProto$1 = _Symbol ? _Symbol.prototype : undefined,
  16920. symbolToString = symbolProto$1 ? symbolProto$1.toString : undefined;
  16921. /**
  16922. * The base implementation of `_.toString` which doesn't convert nullish
  16923. * values to empty strings.
  16924. *
  16925. * @private
  16926. * @param {*} value The value to process.
  16927. * @returns {string} Returns the string.
  16928. */
  16929. function baseToString(value) {
  16930. // Exit early for strings to avoid a performance hit in some environments.
  16931. if (typeof value == 'string') {
  16932. return value;
  16933. }
  16934. if (isArray_1(value)) {
  16935. // Recursively convert values (susceptible to call stack limits).
  16936. return _arrayMap(value, baseToString) + '';
  16937. }
  16938. if (isSymbol_1(value)) {
  16939. return symbolToString ? symbolToString.call(value) : '';
  16940. }
  16941. var result = (value + '');
  16942. return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
  16943. }
  16944. var _baseToString = baseToString;
  16945. /**
  16946. * Converts `value` to a string. An empty string is returned for `null`
  16947. * and `undefined` values. The sign of `-0` is preserved.
  16948. *
  16949. * @static
  16950. * @memberOf _
  16951. * @since 4.0.0
  16952. * @category Lang
  16953. * @param {*} value The value to convert.
  16954. * @returns {string} Returns the converted string.
  16955. * @example
  16956. *
  16957. * _.toString(null);
  16958. * // => ''
  16959. *
  16960. * _.toString(-0);
  16961. * // => '-0'
  16962. *
  16963. * _.toString([1, 2, 3]);
  16964. * // => '1,2,3'
  16965. */
  16966. function toString(value) {
  16967. return value == null ? '' : _baseToString(value);
  16968. }
  16969. var toString_1 = toString;
  16970. /**
  16971. * Casts `value` to a path array if it's not one.
  16972. *
  16973. * @private
  16974. * @param {*} value The value to inspect.
  16975. * @param {Object} [object] The object to query keys on.
  16976. * @returns {Array} Returns the cast property path array.
  16977. */
  16978. function castPath(value, object) {
  16979. if (isArray_1(value)) {
  16980. return value;
  16981. }
  16982. return _isKey(value, object) ? [value] : _stringToPath(toString_1(value));
  16983. }
  16984. var _castPath = castPath;
  16985. /** Used as references for various `Number` constants. */
  16986. var INFINITY$1 = 1 / 0;
  16987. /**
  16988. * Converts `value` to a string key if it's not a string or symbol.
  16989. *
  16990. * @private
  16991. * @param {*} value The value to inspect.
  16992. * @returns {string|symbol} Returns the key.
  16993. */
  16994. function toKey(value) {
  16995. if (typeof value == 'string' || isSymbol_1(value)) {
  16996. return value;
  16997. }
  16998. var result = (value + '');
  16999. return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result;
  17000. }
  17001. var _toKey = toKey;
  17002. /**
  17003. * The base implementation of `_.get` without support for default values.
  17004. *
  17005. * @private
  17006. * @param {Object} object The object to query.
  17007. * @param {Array|string} path The path of the property to get.
  17008. * @returns {*} Returns the resolved value.
  17009. */
  17010. function baseGet(object, path) {
  17011. path = _castPath(path, object);
  17012. var index = 0,
  17013. length = path.length;
  17014. while (object != null && index < length) {
  17015. object = object[_toKey(path[index++])];
  17016. }
  17017. return (index && index == length) ? object : undefined;
  17018. }
  17019. var _baseGet = baseGet;
  17020. /**
  17021. * Gets the value at `path` of `object`. If the resolved value is
  17022. * `undefined`, the `defaultValue` is returned in its place.
  17023. *
  17024. * @static
  17025. * @memberOf _
  17026. * @since 3.7.0
  17027. * @category Object
  17028. * @param {Object} object The object to query.
  17029. * @param {Array|string} path The path of the property to get.
  17030. * @param {*} [defaultValue] The value returned for `undefined` resolved values.
  17031. * @returns {*} Returns the resolved value.
  17032. * @example
  17033. *
  17034. * var object = { 'a': [{ 'b': { 'c': 3 } }] };
  17035. *
  17036. * _.get(object, 'a[0].b.c');
  17037. * // => 3
  17038. *
  17039. * _.get(object, ['a', '0', 'b', 'c']);
  17040. * // => 3
  17041. *
  17042. * _.get(object, 'a.b.c', 'default');
  17043. * // => 'default'
  17044. */
  17045. function get(object, path, defaultValue) {
  17046. var result = object == null ? undefined : _baseGet(object, path);
  17047. return result === undefined ? defaultValue : result;
  17048. }
  17049. var get_1 = get;
  17050. /**
  17051. * The base implementation of `_.hasIn` without support for deep paths.
  17052. *
  17053. * @private
  17054. * @param {Object} [object] The object to query.
  17055. * @param {Array|string} key The key to check.
  17056. * @returns {boolean} Returns `true` if `key` exists, else `false`.
  17057. */
  17058. function baseHasIn(object, key) {
  17059. return object != null && key in Object(object);
  17060. }
  17061. var _baseHasIn = baseHasIn;
  17062. /**
  17063. * Checks if `path` exists on `object`.
  17064. *
  17065. * @private
  17066. * @param {Object} object The object to query.
  17067. * @param {Array|string} path The path to check.
  17068. * @param {Function} hasFunc The function to check properties.
  17069. * @returns {boolean} Returns `true` if `path` exists, else `false`.
  17070. */
  17071. function hasPath(object, path, hasFunc) {
  17072. path = _castPath(path, object);
  17073. var index = -1,
  17074. length = path.length,
  17075. result = false;
  17076. while (++index < length) {
  17077. var key = _toKey(path[index]);
  17078. if (!(result = object != null && hasFunc(object, key))) {
  17079. break;
  17080. }
  17081. object = object[key];
  17082. }
  17083. if (result || ++index != length) {
  17084. return result;
  17085. }
  17086. length = object == null ? 0 : object.length;
  17087. return !!length && isLength_1(length) && _isIndex(key, length) &&
  17088. (isArray_1(object) || isArguments_1(object));
  17089. }
  17090. var _hasPath = hasPath;
  17091. /**
  17092. * Checks if `path` is a direct or inherited property of `object`.
  17093. *
  17094. * @static
  17095. * @memberOf _
  17096. * @since 4.0.0
  17097. * @category Object
  17098. * @param {Object} object The object to query.
  17099. * @param {Array|string} path The path to check.
  17100. * @returns {boolean} Returns `true` if `path` exists, else `false`.
  17101. * @example
  17102. *
  17103. * var object = _.create({ 'a': _.create({ 'b': 2 }) });
  17104. *
  17105. * _.hasIn(object, 'a');
  17106. * // => true
  17107. *
  17108. * _.hasIn(object, 'a.b');
  17109. * // => true
  17110. *
  17111. * _.hasIn(object, ['a', 'b']);
  17112. * // => true
  17113. *
  17114. * _.hasIn(object, 'b');
  17115. * // => false
  17116. */
  17117. function hasIn(object, path) {
  17118. return object != null && _hasPath(object, path, _baseHasIn);
  17119. }
  17120. var hasIn_1 = hasIn;
  17121. /** Used to compose bitmasks for value comparisons. */
  17122. var COMPARE_PARTIAL_FLAG$5 = 1,
  17123. COMPARE_UNORDERED_FLAG$3 = 2;
  17124. /**
  17125. * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
  17126. *
  17127. * @private
  17128. * @param {string} path The path of the property to get.
  17129. * @param {*} srcValue The value to match.
  17130. * @returns {Function} Returns the new spec function.
  17131. */
  17132. function baseMatchesProperty(path, srcValue) {
  17133. if (_isKey(path) && _isStrictComparable(srcValue)) {
  17134. return _matchesStrictComparable(_toKey(path), srcValue);
  17135. }
  17136. return function(object) {
  17137. var objValue = get_1(object, path);
  17138. return (objValue === undefined && objValue === srcValue)
  17139. ? hasIn_1(object, path)
  17140. : _baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$5 | COMPARE_UNORDERED_FLAG$3);
  17141. };
  17142. }
  17143. var _baseMatchesProperty = baseMatchesProperty;
  17144. /**
  17145. * This method returns the first argument it receives.
  17146. *
  17147. * @static
  17148. * @since 0.1.0
  17149. * @memberOf _
  17150. * @category Util
  17151. * @param {*} value Any value.
  17152. * @returns {*} Returns `value`.
  17153. * @example
  17154. *
  17155. * var object = { 'a': 1 };
  17156. *
  17157. * console.log(_.identity(object) === object);
  17158. * // => true
  17159. */
  17160. function identity(value) {
  17161. return value;
  17162. }
  17163. var identity_1 = identity;
  17164. /**
  17165. * The base implementation of `_.property` without support for deep paths.
  17166. *
  17167. * @private
  17168. * @param {string} key The key of the property to get.
  17169. * @returns {Function} Returns the new accessor function.
  17170. */
  17171. function baseProperty(key) {
  17172. return function(object) {
  17173. return object == null ? undefined : object[key];
  17174. };
  17175. }
  17176. var _baseProperty = baseProperty;
  17177. /**
  17178. * A specialized version of `baseProperty` which supports deep paths.
  17179. *
  17180. * @private
  17181. * @param {Array|string} path The path of the property to get.
  17182. * @returns {Function} Returns the new accessor function.
  17183. */
  17184. function basePropertyDeep(path) {
  17185. return function(object) {
  17186. return _baseGet(object, path);
  17187. };
  17188. }
  17189. var _basePropertyDeep = basePropertyDeep;
  17190. /**
  17191. * Creates a function that returns the value at `path` of a given object.
  17192. *
  17193. * @static
  17194. * @memberOf _
  17195. * @since 2.4.0
  17196. * @category Util
  17197. * @param {Array|string} path The path of the property to get.
  17198. * @returns {Function} Returns the new accessor function.
  17199. * @example
  17200. *
  17201. * var objects = [
  17202. * { 'a': { 'b': 2 } },
  17203. * { 'a': { 'b': 1 } }
  17204. * ];
  17205. *
  17206. * _.map(objects, _.property('a.b'));
  17207. * // => [2, 1]
  17208. *
  17209. * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
  17210. * // => [1, 2]
  17211. */
  17212. function property(path) {
  17213. return _isKey(path) ? _baseProperty(_toKey(path)) : _basePropertyDeep(path);
  17214. }
  17215. var property_1 = property;
  17216. /**
  17217. * The base implementation of `_.iteratee`.
  17218. *
  17219. * @private
  17220. * @param {*} [value=_.identity] The value to convert to an iteratee.
  17221. * @returns {Function} Returns the iteratee.
  17222. */
  17223. function baseIteratee(value) {
  17224. // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
  17225. // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
  17226. if (typeof value == 'function') {
  17227. return value;
  17228. }
  17229. if (value == null) {
  17230. return identity_1;
  17231. }
  17232. if (typeof value == 'object') {
  17233. return isArray_1(value)
  17234. ? _baseMatchesProperty(value[0], value[1])
  17235. : _baseMatches(value);
  17236. }
  17237. return property_1(value);
  17238. }
  17239. var _baseIteratee = baseIteratee;
  17240. /**
  17241. * Gets the last element of `array`.
  17242. *
  17243. * @static
  17244. * @memberOf _
  17245. * @since 0.1.0
  17246. * @category Array
  17247. * @param {Array} array The array to query.
  17248. * @returns {*} Returns the last element of `array`.
  17249. * @example
  17250. *
  17251. * _.last([1, 2, 3]);
  17252. * // => 3
  17253. */
  17254. function last(array) {
  17255. var length = array == null ? 0 : array.length;
  17256. return length ? array[length - 1] : undefined;
  17257. }
  17258. var last_1 = last;
  17259. /**
  17260. * The base implementation of `_.slice` without an iteratee call guard.
  17261. *
  17262. * @private
  17263. * @param {Array} array The array to slice.
  17264. * @param {number} [start=0] The start position.
  17265. * @param {number} [end=array.length] The end position.
  17266. * @returns {Array} Returns the slice of `array`.
  17267. */
  17268. function baseSlice(array, start, end) {
  17269. var index = -1,
  17270. length = array.length;
  17271. if (start < 0) {
  17272. start = -start > length ? 0 : (length + start);
  17273. }
  17274. end = end > length ? length : end;
  17275. if (end < 0) {
  17276. end += length;
  17277. }
  17278. length = start > end ? 0 : ((end - start) >>> 0);
  17279. start >>>= 0;
  17280. var result = Array(length);
  17281. while (++index < length) {
  17282. result[index] = array[index + start];
  17283. }
  17284. return result;
  17285. }
  17286. var _baseSlice = baseSlice;
  17287. /**
  17288. * Gets the parent value at `path` of `object`.
  17289. *
  17290. * @private
  17291. * @param {Object} object The object to query.
  17292. * @param {Array} path The path to get the parent value of.
  17293. * @returns {*} Returns the parent value.
  17294. */
  17295. function parent(object, path) {
  17296. return path.length < 2 ? object : _baseGet(object, _baseSlice(path, 0, -1));
  17297. }
  17298. var _parent = parent;
  17299. /**
  17300. * The base implementation of `_.unset`.
  17301. *
  17302. * @private
  17303. * @param {Object} object The object to modify.
  17304. * @param {Array|string} path The property path to unset.
  17305. * @returns {boolean} Returns `true` if the property is deleted, else `false`.
  17306. */
  17307. function baseUnset(object, path) {
  17308. path = _castPath(path, object);
  17309. object = _parent(object, path);
  17310. return object == null || delete object[_toKey(last_1(path))];
  17311. }
  17312. var _baseUnset = baseUnset;
  17313. /** Used for built-in method references. */
  17314. var arrayProto$1 = Array.prototype;
  17315. /** Built-in value references. */
  17316. var splice$1 = arrayProto$1.splice;
  17317. /**
  17318. * The base implementation of `_.pullAt` without support for individual
  17319. * indexes or capturing the removed elements.
  17320. *
  17321. * @private
  17322. * @param {Array} array The array to modify.
  17323. * @param {number[]} indexes The indexes of elements to remove.
  17324. * @returns {Array} Returns `array`.
  17325. */
  17326. function basePullAt(array, indexes) {
  17327. var length = array ? indexes.length : 0,
  17328. lastIndex = length - 1;
  17329. while (length--) {
  17330. var index = indexes[length];
  17331. if (length == lastIndex || index !== previous) {
  17332. var previous = index;
  17333. if (_isIndex(index)) {
  17334. splice$1.call(array, index, 1);
  17335. } else {
  17336. _baseUnset(array, index);
  17337. }
  17338. }
  17339. }
  17340. return array;
  17341. }
  17342. var _basePullAt = basePullAt;
  17343. /**
  17344. * Removes all elements from `array` that `predicate` returns truthy for
  17345. * and returns an array of the removed elements. The predicate is invoked
  17346. * with three arguments: (value, index, array).
  17347. *
  17348. * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
  17349. * to pull elements from an array by value.
  17350. *
  17351. * @static
  17352. * @memberOf _
  17353. * @since 2.0.0
  17354. * @category Array
  17355. * @param {Array} array The array to modify.
  17356. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  17357. * @returns {Array} Returns the new array of removed elements.
  17358. * @example
  17359. *
  17360. * var array = [1, 2, 3, 4];
  17361. * var evens = _.remove(array, function(n) {
  17362. * return n % 2 == 0;
  17363. * });
  17364. *
  17365. * console.log(array);
  17366. * // => [1, 3]
  17367. *
  17368. * console.log(evens);
  17369. * // => [2, 4]
  17370. */
  17371. function remove(array, predicate) {
  17372. var result = [];
  17373. if (!(array && array.length)) {
  17374. return result;
  17375. }
  17376. var index = -1,
  17377. indexes = [],
  17378. length = array.length;
  17379. predicate = _baseIteratee(predicate);
  17380. while (++index < length) {
  17381. var value = array[index];
  17382. if (predicate(value, index, array)) {
  17383. result.push(value);
  17384. indexes.push(index);
  17385. }
  17386. }
  17387. _basePullAt(array, indexes);
  17388. return result;
  17389. }
  17390. var remove_1 = remove;
  17391. /** `Object#toString` result references. */
  17392. var mapTag$3 = '[object Map]',
  17393. setTag$3 = '[object Set]';
  17394. /** Used for built-in method references. */
  17395. var objectProto$d = Object.prototype;
  17396. /** Used to check objects for own properties. */
  17397. var hasOwnProperty$a = objectProto$d.hasOwnProperty;
  17398. /**
  17399. * Checks if `value` is an empty object, collection, map, or set.
  17400. *
  17401. * Objects are considered empty if they have no own enumerable string keyed
  17402. * properties.
  17403. *
  17404. * Array-like values such as `arguments` objects, arrays, buffers, strings, or
  17405. * jQuery-like collections are considered empty if they have a `length` of `0`.
  17406. * Similarly, maps and sets are considered empty if they have a `size` of `0`.
  17407. *
  17408. * @static
  17409. * @memberOf _
  17410. * @since 0.1.0
  17411. * @category Lang
  17412. * @param {*} value The value to check.
  17413. * @returns {boolean} Returns `true` if `value` is empty, else `false`.
  17414. * @example
  17415. *
  17416. * _.isEmpty(null);
  17417. * // => true
  17418. *
  17419. * _.isEmpty(true);
  17420. * // => true
  17421. *
  17422. * _.isEmpty(1);
  17423. * // => true
  17424. *
  17425. * _.isEmpty([1, 2, 3]);
  17426. * // => false
  17427. *
  17428. * _.isEmpty({ 'a': 1 });
  17429. * // => false
  17430. */
  17431. function isEmpty(value) {
  17432. if (value == null) {
  17433. return true;
  17434. }
  17435. if (isArrayLike_1(value) &&
  17436. (isArray_1(value) || typeof value == 'string' || typeof value.splice == 'function' ||
  17437. isBuffer_1(value) || isTypedArray_1(value) || isArguments_1(value))) {
  17438. return !value.length;
  17439. }
  17440. var tag = _getTag(value);
  17441. if (tag == mapTag$3 || tag == setTag$3) {
  17442. return !value.size;
  17443. }
  17444. if (_isPrototype(value)) {
  17445. return !_baseKeys(value).length;
  17446. }
  17447. for (var key in value) {
  17448. if (hasOwnProperty$a.call(value, key)) {
  17449. return false;
  17450. }
  17451. }
  17452. return true;
  17453. }
  17454. var isEmpty_1 = isEmpty;
  17455. /**
  17456. * A specialized version of `_.forEach` for arrays without support for
  17457. * iteratee shorthands.
  17458. *
  17459. * @private
  17460. * @param {Array} [array] The array to iterate over.
  17461. * @param {Function} iteratee The function invoked per iteration.
  17462. * @returns {Array} Returns `array`.
  17463. */
  17464. function arrayEach(array, iteratee) {
  17465. var index = -1,
  17466. length = array == null ? 0 : array.length;
  17467. while (++index < length) {
  17468. if (iteratee(array[index], index, array) === false) {
  17469. break;
  17470. }
  17471. }
  17472. return array;
  17473. }
  17474. var _arrayEach = arrayEach;
  17475. var defineProperty = (function() {
  17476. try {
  17477. var func = _getNative(Object, 'defineProperty');
  17478. func({}, '', {});
  17479. return func;
  17480. } catch (e) {}
  17481. }());
  17482. var _defineProperty = defineProperty;
  17483. /**
  17484. * The base implementation of `assignValue` and `assignMergeValue` without
  17485. * value checks.
  17486. *
  17487. * @private
  17488. * @param {Object} object The object to modify.
  17489. * @param {string} key The key of the property to assign.
  17490. * @param {*} value The value to assign.
  17491. */
  17492. function baseAssignValue(object, key, value) {
  17493. if (key == '__proto__' && _defineProperty) {
  17494. _defineProperty(object, key, {
  17495. 'configurable': true,
  17496. 'enumerable': true,
  17497. 'value': value,
  17498. 'writable': true
  17499. });
  17500. } else {
  17501. object[key] = value;
  17502. }
  17503. }
  17504. var _baseAssignValue = baseAssignValue;
  17505. /** Used for built-in method references. */
  17506. var objectProto$e = Object.prototype;
  17507. /** Used to check objects for own properties. */
  17508. var hasOwnProperty$b = objectProto$e.hasOwnProperty;
  17509. /**
  17510. * Assigns `value` to `key` of `object` if the existing value is not equivalent
  17511. * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  17512. * for equality comparisons.
  17513. *
  17514. * @private
  17515. * @param {Object} object The object to modify.
  17516. * @param {string} key The key of the property to assign.
  17517. * @param {*} value The value to assign.
  17518. */
  17519. function assignValue(object, key, value) {
  17520. var objValue = object[key];
  17521. if (!(hasOwnProperty$b.call(object, key) && eq_1(objValue, value)) ||
  17522. (value === undefined && !(key in object))) {
  17523. _baseAssignValue(object, key, value);
  17524. }
  17525. }
  17526. var _assignValue = assignValue;
  17527. /**
  17528. * Copies properties of `source` to `object`.
  17529. *
  17530. * @private
  17531. * @param {Object} source The object to copy properties from.
  17532. * @param {Array} props The property identifiers to copy.
  17533. * @param {Object} [object={}] The object to copy properties to.
  17534. * @param {Function} [customizer] The function to customize copied values.
  17535. * @returns {Object} Returns `object`.
  17536. */
  17537. function copyObject(source, props, object, customizer) {
  17538. var isNew = !object;
  17539. object || (object = {});
  17540. var index = -1,
  17541. length = props.length;
  17542. while (++index < length) {
  17543. var key = props[index];
  17544. var newValue = customizer
  17545. ? customizer(object[key], source[key], key, object, source)
  17546. : undefined;
  17547. if (newValue === undefined) {
  17548. newValue = source[key];
  17549. }
  17550. if (isNew) {
  17551. _baseAssignValue(object, key, newValue);
  17552. } else {
  17553. _assignValue(object, key, newValue);
  17554. }
  17555. }
  17556. return object;
  17557. }
  17558. var _copyObject = copyObject;
  17559. /**
  17560. * The base implementation of `_.assign` without support for multiple sources
  17561. * or `customizer` functions.
  17562. *
  17563. * @private
  17564. * @param {Object} object The destination object.
  17565. * @param {Object} source The source object.
  17566. * @returns {Object} Returns `object`.
  17567. */
  17568. function baseAssign(object, source) {
  17569. return object && _copyObject(source, keys_1(source), object);
  17570. }
  17571. var _baseAssign = baseAssign;
  17572. /**
  17573. * This function is like
  17574. * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
  17575. * except that it includes inherited enumerable properties.
  17576. *
  17577. * @private
  17578. * @param {Object} object The object to query.
  17579. * @returns {Array} Returns the array of property names.
  17580. */
  17581. function nativeKeysIn(object) {
  17582. var result = [];
  17583. if (object != null) {
  17584. for (var key in Object(object)) {
  17585. result.push(key);
  17586. }
  17587. }
  17588. return result;
  17589. }
  17590. var _nativeKeysIn = nativeKeysIn;
  17591. /** Used for built-in method references. */
  17592. var objectProto$f = Object.prototype;
  17593. /** Used to check objects for own properties. */
  17594. var hasOwnProperty$c = objectProto$f.hasOwnProperty;
  17595. /**
  17596. * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
  17597. *
  17598. * @private
  17599. * @param {Object} object The object to query.
  17600. * @returns {Array} Returns the array of property names.
  17601. */
  17602. function baseKeysIn(object) {
  17603. if (!isObject_1$1(object)) {
  17604. return _nativeKeysIn(object);
  17605. }
  17606. var isProto = _isPrototype(object),
  17607. result = [];
  17608. for (var key in object) {
  17609. if (!(key == 'constructor' && (isProto || !hasOwnProperty$c.call(object, key)))) {
  17610. result.push(key);
  17611. }
  17612. }
  17613. return result;
  17614. }
  17615. var _baseKeysIn = baseKeysIn;
  17616. /**
  17617. * Creates an array of the own and inherited enumerable property names of `object`.
  17618. *
  17619. * **Note:** Non-object values are coerced to objects.
  17620. *
  17621. * @static
  17622. * @memberOf _
  17623. * @since 3.0.0
  17624. * @category Object
  17625. * @param {Object} object The object to query.
  17626. * @returns {Array} Returns the array of property names.
  17627. * @example
  17628. *
  17629. * function Foo() {
  17630. * this.a = 1;
  17631. * this.b = 2;
  17632. * }
  17633. *
  17634. * Foo.prototype.c = 3;
  17635. *
  17636. * _.keysIn(new Foo);
  17637. * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
  17638. */
  17639. function keysIn(object) {
  17640. return isArrayLike_1(object) ? _arrayLikeKeys(object, true) : _baseKeysIn(object);
  17641. }
  17642. var keysIn_1 = keysIn;
  17643. /**
  17644. * The base implementation of `_.assignIn` without support for multiple sources
  17645. * or `customizer` functions.
  17646. *
  17647. * @private
  17648. * @param {Object} object The destination object.
  17649. * @param {Object} source The source object.
  17650. * @returns {Object} Returns `object`.
  17651. */
  17652. function baseAssignIn(object, source) {
  17653. return object && _copyObject(source, keysIn_1(source), object);
  17654. }
  17655. var _baseAssignIn = baseAssignIn;
  17656. var _cloneBuffer = createCommonjsModule(function (module, exports) {
  17657. /** Detect free variable `exports`. */
  17658. var freeExports = exports && !exports.nodeType && exports;
  17659. /** Detect free variable `module`. */
  17660. var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
  17661. /** Detect the popular CommonJS extension `module.exports`. */
  17662. var moduleExports = freeModule && freeModule.exports === freeExports;
  17663. /** Built-in value references. */
  17664. var Buffer = moduleExports ? _root.Buffer : undefined,
  17665. allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;
  17666. /**
  17667. * Creates a clone of `buffer`.
  17668. *
  17669. * @private
  17670. * @param {Buffer} buffer The buffer to clone.
  17671. * @param {boolean} [isDeep] Specify a deep clone.
  17672. * @returns {Buffer} Returns the cloned buffer.
  17673. */
  17674. function cloneBuffer(buffer, isDeep) {
  17675. if (isDeep) {
  17676. return buffer.slice();
  17677. }
  17678. var length = buffer.length,
  17679. result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
  17680. buffer.copy(result);
  17681. return result;
  17682. }
  17683. module.exports = cloneBuffer;
  17684. });
  17685. /**
  17686. * Copies own symbols of `source` to `object`.
  17687. *
  17688. * @private
  17689. * @param {Object} source The object to copy symbols from.
  17690. * @param {Object} [object={}] The object to copy symbols to.
  17691. * @returns {Object} Returns `object`.
  17692. */
  17693. function copySymbols(source, object) {
  17694. return _copyObject(source, _getSymbols(source), object);
  17695. }
  17696. var _copySymbols = copySymbols;
  17697. /* Built-in method references for those with the same name as other `lodash` methods. */
  17698. var nativeGetSymbols$1 = Object.getOwnPropertySymbols;
  17699. /**
  17700. * Creates an array of the own and inherited enumerable symbols of `object`.
  17701. *
  17702. * @private
  17703. * @param {Object} object The object to query.
  17704. * @returns {Array} Returns the array of symbols.
  17705. */
  17706. var getSymbolsIn = !nativeGetSymbols$1 ? stubArray_1 : function(object) {
  17707. var result = [];
  17708. while (object) {
  17709. _arrayPush(result, _getSymbols(object));
  17710. object = _getPrototype(object);
  17711. }
  17712. return result;
  17713. };
  17714. var _getSymbolsIn = getSymbolsIn;
  17715. /**
  17716. * Copies own and inherited symbols of `source` to `object`.
  17717. *
  17718. * @private
  17719. * @param {Object} source The object to copy symbols from.
  17720. * @param {Object} [object={}] The object to copy symbols to.
  17721. * @returns {Object} Returns `object`.
  17722. */
  17723. function copySymbolsIn(source, object) {
  17724. return _copyObject(source, _getSymbolsIn(source), object);
  17725. }
  17726. var _copySymbolsIn = copySymbolsIn;
  17727. /**
  17728. * Creates an array of own and inherited enumerable property names and
  17729. * symbols of `object`.
  17730. *
  17731. * @private
  17732. * @param {Object} object The object to query.
  17733. * @returns {Array} Returns the array of property names and symbols.
  17734. */
  17735. function getAllKeysIn(object) {
  17736. return _baseGetAllKeys(object, keysIn_1, _getSymbolsIn);
  17737. }
  17738. var _getAllKeysIn = getAllKeysIn;
  17739. /** Used for built-in method references. */
  17740. var objectProto$g = Object.prototype;
  17741. /** Used to check objects for own properties. */
  17742. var hasOwnProperty$d = objectProto$g.hasOwnProperty;
  17743. /**
  17744. * Initializes an array clone.
  17745. *
  17746. * @private
  17747. * @param {Array} array The array to clone.
  17748. * @returns {Array} Returns the initialized clone.
  17749. */
  17750. function initCloneArray(array) {
  17751. var length = array.length,
  17752. result = new array.constructor(length);
  17753. // Add properties assigned by `RegExp#exec`.
  17754. if (length && typeof array[0] == 'string' && hasOwnProperty$d.call(array, 'index')) {
  17755. result.index = array.index;
  17756. result.input = array.input;
  17757. }
  17758. return result;
  17759. }
  17760. var _initCloneArray = initCloneArray;
  17761. /**
  17762. * Creates a clone of `arrayBuffer`.
  17763. *
  17764. * @private
  17765. * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
  17766. * @returns {ArrayBuffer} Returns the cloned array buffer.
  17767. */
  17768. function cloneArrayBuffer(arrayBuffer) {
  17769. var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
  17770. new _Uint8Array(result).set(new _Uint8Array(arrayBuffer));
  17771. return result;
  17772. }
  17773. var _cloneArrayBuffer = cloneArrayBuffer;
  17774. /**
  17775. * Creates a clone of `dataView`.
  17776. *
  17777. * @private
  17778. * @param {Object} dataView The data view to clone.
  17779. * @param {boolean} [isDeep] Specify a deep clone.
  17780. * @returns {Object} Returns the cloned data view.
  17781. */
  17782. function cloneDataView(dataView, isDeep) {
  17783. var buffer = isDeep ? _cloneArrayBuffer(dataView.buffer) : dataView.buffer;
  17784. return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
  17785. }
  17786. var _cloneDataView = cloneDataView;
  17787. /** Used to match `RegExp` flags from their coerced string values. */
  17788. var reFlags = /\w*$/;
  17789. /**
  17790. * Creates a clone of `regexp`.
  17791. *
  17792. * @private
  17793. * @param {Object} regexp The regexp to clone.
  17794. * @returns {Object} Returns the cloned regexp.
  17795. */
  17796. function cloneRegExp(regexp) {
  17797. var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
  17798. result.lastIndex = regexp.lastIndex;
  17799. return result;
  17800. }
  17801. var _cloneRegExp = cloneRegExp;
  17802. /** Used to convert symbols to primitives and strings. */
  17803. var symbolProto$2 = _Symbol ? _Symbol.prototype : undefined,
  17804. symbolValueOf$1 = symbolProto$2 ? symbolProto$2.valueOf : undefined;
  17805. /**
  17806. * Creates a clone of the `symbol` object.
  17807. *
  17808. * @private
  17809. * @param {Object} symbol The symbol object to clone.
  17810. * @returns {Object} Returns the cloned symbol object.
  17811. */
  17812. function cloneSymbol(symbol) {
  17813. return symbolValueOf$1 ? Object(symbolValueOf$1.call(symbol)) : {};
  17814. }
  17815. var _cloneSymbol = cloneSymbol;
  17816. /**
  17817. * Creates a clone of `typedArray`.
  17818. *
  17819. * @private
  17820. * @param {Object} typedArray The typed array to clone.
  17821. * @param {boolean} [isDeep] Specify a deep clone.
  17822. * @returns {Object} Returns the cloned typed array.
  17823. */
  17824. function cloneTypedArray(typedArray, isDeep) {
  17825. var buffer = isDeep ? _cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
  17826. return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
  17827. }
  17828. var _cloneTypedArray = cloneTypedArray;
  17829. /** `Object#toString` result references. */
  17830. var boolTag$2 = '[object Boolean]',
  17831. dateTag$2 = '[object Date]',
  17832. mapTag$4 = '[object Map]',
  17833. numberTag$2 = '[object Number]',
  17834. regexpTag$2 = '[object RegExp]',
  17835. setTag$4 = '[object Set]',
  17836. stringTag$2 = '[object String]',
  17837. symbolTag$2 = '[object Symbol]';
  17838. var arrayBufferTag$2 = '[object ArrayBuffer]',
  17839. dataViewTag$3 = '[object DataView]',
  17840. float32Tag$1 = '[object Float32Array]',
  17841. float64Tag$1 = '[object Float64Array]',
  17842. int8Tag$1 = '[object Int8Array]',
  17843. int16Tag$1 = '[object Int16Array]',
  17844. int32Tag$1 = '[object Int32Array]',
  17845. uint8Tag$1 = '[object Uint8Array]',
  17846. uint8ClampedTag$1 = '[object Uint8ClampedArray]',
  17847. uint16Tag$1 = '[object Uint16Array]',
  17848. uint32Tag$1 = '[object Uint32Array]';
  17849. /**
  17850. * Initializes an object clone based on its `toStringTag`.
  17851. *
  17852. * **Note:** This function only supports cloning values with tags of
  17853. * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
  17854. *
  17855. * @private
  17856. * @param {Object} object The object to clone.
  17857. * @param {string} tag The `toStringTag` of the object to clone.
  17858. * @param {boolean} [isDeep] Specify a deep clone.
  17859. * @returns {Object} Returns the initialized clone.
  17860. */
  17861. function initCloneByTag(object, tag, isDeep) {
  17862. var Ctor = object.constructor;
  17863. switch (tag) {
  17864. case arrayBufferTag$2:
  17865. return _cloneArrayBuffer(object);
  17866. case boolTag$2:
  17867. case dateTag$2:
  17868. return new Ctor(+object);
  17869. case dataViewTag$3:
  17870. return _cloneDataView(object, isDeep);
  17871. case float32Tag$1: case float64Tag$1:
  17872. case int8Tag$1: case int16Tag$1: case int32Tag$1:
  17873. case uint8Tag$1: case uint8ClampedTag$1: case uint16Tag$1: case uint32Tag$1:
  17874. return _cloneTypedArray(object, isDeep);
  17875. case mapTag$4:
  17876. return new Ctor;
  17877. case numberTag$2:
  17878. case stringTag$2:
  17879. return new Ctor(object);
  17880. case regexpTag$2:
  17881. return _cloneRegExp(object);
  17882. case setTag$4:
  17883. return new Ctor;
  17884. case symbolTag$2:
  17885. return _cloneSymbol(object);
  17886. }
  17887. }
  17888. var _initCloneByTag = initCloneByTag;
  17889. /** Built-in value references. */
  17890. var objectCreate = Object.create;
  17891. /**
  17892. * The base implementation of `_.create` without support for assigning
  17893. * properties to the created object.
  17894. *
  17895. * @private
  17896. * @param {Object} proto The object to inherit from.
  17897. * @returns {Object} Returns the new object.
  17898. */
  17899. var baseCreate = (function() {
  17900. function object() {}
  17901. return function(proto) {
  17902. if (!isObject_1$1(proto)) {
  17903. return {};
  17904. }
  17905. if (objectCreate) {
  17906. return objectCreate(proto);
  17907. }
  17908. object.prototype = proto;
  17909. var result = new object;
  17910. object.prototype = undefined;
  17911. return result;
  17912. };
  17913. }());
  17914. var _baseCreate = baseCreate;
  17915. /**
  17916. * Initializes an object clone.
  17917. *
  17918. * @private
  17919. * @param {Object} object The object to clone.
  17920. * @returns {Object} Returns the initialized clone.
  17921. */
  17922. function initCloneObject(object) {
  17923. return (typeof object.constructor == 'function' && !_isPrototype(object))
  17924. ? _baseCreate(_getPrototype(object))
  17925. : {};
  17926. }
  17927. var _initCloneObject = initCloneObject;
  17928. /** `Object#toString` result references. */
  17929. var mapTag$5 = '[object Map]';
  17930. /**
  17931. * The base implementation of `_.isMap` without Node.js optimizations.
  17932. *
  17933. * @private
  17934. * @param {*} value The value to check.
  17935. * @returns {boolean} Returns `true` if `value` is a map, else `false`.
  17936. */
  17937. function baseIsMap(value) {
  17938. return isObjectLike_1(value) && _getTag(value) == mapTag$5;
  17939. }
  17940. var _baseIsMap = baseIsMap;
  17941. /* Node.js helper references. */
  17942. var nodeIsMap = _nodeUtil && _nodeUtil.isMap;
  17943. /**
  17944. * Checks if `value` is classified as a `Map` object.
  17945. *
  17946. * @static
  17947. * @memberOf _
  17948. * @since 4.3.0
  17949. * @category Lang
  17950. * @param {*} value The value to check.
  17951. * @returns {boolean} Returns `true` if `value` is a map, else `false`.
  17952. * @example
  17953. *
  17954. * _.isMap(new Map);
  17955. * // => true
  17956. *
  17957. * _.isMap(new WeakMap);
  17958. * // => false
  17959. */
  17960. var isMap = nodeIsMap ? _baseUnary(nodeIsMap) : _baseIsMap;
  17961. var isMap_1 = isMap;
  17962. /** `Object#toString` result references. */
  17963. var setTag$5 = '[object Set]';
  17964. /**
  17965. * The base implementation of `_.isSet` without Node.js optimizations.
  17966. *
  17967. * @private
  17968. * @param {*} value The value to check.
  17969. * @returns {boolean} Returns `true` if `value` is a set, else `false`.
  17970. */
  17971. function baseIsSet(value) {
  17972. return isObjectLike_1(value) && _getTag(value) == setTag$5;
  17973. }
  17974. var _baseIsSet = baseIsSet;
  17975. /* Node.js helper references. */
  17976. var nodeIsSet = _nodeUtil && _nodeUtil.isSet;
  17977. /**
  17978. * Checks if `value` is classified as a `Set` object.
  17979. *
  17980. * @static
  17981. * @memberOf _
  17982. * @since 4.3.0
  17983. * @category Lang
  17984. * @param {*} value The value to check.
  17985. * @returns {boolean} Returns `true` if `value` is a set, else `false`.
  17986. * @example
  17987. *
  17988. * _.isSet(new Set);
  17989. * // => true
  17990. *
  17991. * _.isSet(new WeakSet);
  17992. * // => false
  17993. */
  17994. var isSet = nodeIsSet ? _baseUnary(nodeIsSet) : _baseIsSet;
  17995. var isSet_1 = isSet;
  17996. /** Used to compose bitmasks for cloning. */
  17997. var CLONE_DEEP_FLAG = 1,
  17998. CLONE_FLAT_FLAG = 2,
  17999. CLONE_SYMBOLS_FLAG = 4;
  18000. /** `Object#toString` result references. */
  18001. var argsTag$3 = '[object Arguments]',
  18002. arrayTag$2 = '[object Array]',
  18003. boolTag$3 = '[object Boolean]',
  18004. dateTag$3 = '[object Date]',
  18005. errorTag$2 = '[object Error]',
  18006. funcTag$2 = '[object Function]',
  18007. genTag$1 = '[object GeneratorFunction]',
  18008. mapTag$6 = '[object Map]',
  18009. numberTag$3 = '[object Number]',
  18010. objectTag$4 = '[object Object]',
  18011. regexpTag$3 = '[object RegExp]',
  18012. setTag$6 = '[object Set]',
  18013. stringTag$3 = '[object String]',
  18014. symbolTag$3 = '[object Symbol]',
  18015. weakMapTag$2 = '[object WeakMap]';
  18016. var arrayBufferTag$3 = '[object ArrayBuffer]',
  18017. dataViewTag$4 = '[object DataView]',
  18018. float32Tag$2 = '[object Float32Array]',
  18019. float64Tag$2 = '[object Float64Array]',
  18020. int8Tag$2 = '[object Int8Array]',
  18021. int16Tag$2 = '[object Int16Array]',
  18022. int32Tag$2 = '[object Int32Array]',
  18023. uint8Tag$2 = '[object Uint8Array]',
  18024. uint8ClampedTag$2 = '[object Uint8ClampedArray]',
  18025. uint16Tag$2 = '[object Uint16Array]',
  18026. uint32Tag$2 = '[object Uint32Array]';
  18027. /** Used to identify `toStringTag` values supported by `_.clone`. */
  18028. var cloneableTags = {};
  18029. cloneableTags[argsTag$3] = cloneableTags[arrayTag$2] =
  18030. cloneableTags[arrayBufferTag$3] = cloneableTags[dataViewTag$4] =
  18031. cloneableTags[boolTag$3] = cloneableTags[dateTag$3] =
  18032. cloneableTags[float32Tag$2] = cloneableTags[float64Tag$2] =
  18033. cloneableTags[int8Tag$2] = cloneableTags[int16Tag$2] =
  18034. cloneableTags[int32Tag$2] = cloneableTags[mapTag$6] =
  18035. cloneableTags[numberTag$3] = cloneableTags[objectTag$4] =
  18036. cloneableTags[regexpTag$3] = cloneableTags[setTag$6] =
  18037. cloneableTags[stringTag$3] = cloneableTags[symbolTag$3] =
  18038. cloneableTags[uint8Tag$2] = cloneableTags[uint8ClampedTag$2] =
  18039. cloneableTags[uint16Tag$2] = cloneableTags[uint32Tag$2] = true;
  18040. cloneableTags[errorTag$2] = cloneableTags[funcTag$2] =
  18041. cloneableTags[weakMapTag$2] = false;
  18042. /**
  18043. * The base implementation of `_.clone` and `_.cloneDeep` which tracks
  18044. * traversed objects.
  18045. *
  18046. * @private
  18047. * @param {*} value The value to clone.
  18048. * @param {boolean} bitmask The bitmask flags.
  18049. * 1 - Deep clone
  18050. * 2 - Flatten inherited properties
  18051. * 4 - Clone symbols
  18052. * @param {Function} [customizer] The function to customize cloning.
  18053. * @param {string} [key] The key of `value`.
  18054. * @param {Object} [object] The parent object of `value`.
  18055. * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
  18056. * @returns {*} Returns the cloned value.
  18057. */
  18058. function baseClone(value, bitmask, customizer, key, object, stack) {
  18059. var result,
  18060. isDeep = bitmask & CLONE_DEEP_FLAG,
  18061. isFlat = bitmask & CLONE_FLAT_FLAG,
  18062. isFull = bitmask & CLONE_SYMBOLS_FLAG;
  18063. if (customizer) {
  18064. result = object ? customizer(value, key, object, stack) : customizer(value);
  18065. }
  18066. if (result !== undefined) {
  18067. return result;
  18068. }
  18069. if (!isObject_1$1(value)) {
  18070. return value;
  18071. }
  18072. var isArr = isArray_1(value);
  18073. if (isArr) {
  18074. result = _initCloneArray(value);
  18075. if (!isDeep) {
  18076. return _copyArray(value, result);
  18077. }
  18078. } else {
  18079. var tag = _getTag(value),
  18080. isFunc = tag == funcTag$2 || tag == genTag$1;
  18081. if (isBuffer_1(value)) {
  18082. return _cloneBuffer(value, isDeep);
  18083. }
  18084. if (tag == objectTag$4 || tag == argsTag$3 || (isFunc && !object)) {
  18085. result = (isFlat || isFunc) ? {} : _initCloneObject(value);
  18086. if (!isDeep) {
  18087. return isFlat
  18088. ? _copySymbolsIn(value, _baseAssignIn(result, value))
  18089. : _copySymbols(value, _baseAssign(result, value));
  18090. }
  18091. } else {
  18092. if (!cloneableTags[tag]) {
  18093. return object ? value : {};
  18094. }
  18095. result = _initCloneByTag(value, tag, isDeep);
  18096. }
  18097. }
  18098. // Check for circular references and return its corresponding clone.
  18099. stack || (stack = new _Stack);
  18100. var stacked = stack.get(value);
  18101. if (stacked) {
  18102. return stacked;
  18103. }
  18104. stack.set(value, result);
  18105. if (isSet_1(value)) {
  18106. value.forEach(function(subValue) {
  18107. result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
  18108. });
  18109. } else if (isMap_1(value)) {
  18110. value.forEach(function(subValue, key) {
  18111. result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
  18112. });
  18113. }
  18114. var keysFunc = isFull
  18115. ? (isFlat ? _getAllKeysIn : _getAllKeys)
  18116. : (isFlat ? keysIn_1 : keys_1);
  18117. var props = isArr ? undefined : keysFunc(value);
  18118. _arrayEach(props || value, function(subValue, key) {
  18119. if (props) {
  18120. key = subValue;
  18121. subValue = value[key];
  18122. }
  18123. // Recursively populate clone (susceptible to call stack limits).
  18124. _assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
  18125. });
  18126. return result;
  18127. }
  18128. var _baseClone = baseClone;
  18129. /** Used to compose bitmasks for cloning. */
  18130. var CLONE_DEEP_FLAG$1 = 1,
  18131. CLONE_SYMBOLS_FLAG$1 = 4;
  18132. /**
  18133. * This method is like `_.clone` except that it recursively clones `value`.
  18134. *
  18135. * @static
  18136. * @memberOf _
  18137. * @since 1.0.0
  18138. * @category Lang
  18139. * @param {*} value The value to recursively clone.
  18140. * @returns {*} Returns the deep cloned value.
  18141. * @see _.clone
  18142. * @example
  18143. *
  18144. * var objects = [{ 'a': 1 }, { 'b': 2 }];
  18145. *
  18146. * var deep = _.cloneDeep(objects);
  18147. * console.log(deep[0] === objects[0]);
  18148. * // => false
  18149. */
  18150. function cloneDeep(value) {
  18151. return _baseClone(value, CLONE_DEEP_FLAG$1 | CLONE_SYMBOLS_FLAG$1);
  18152. }
  18153. var cloneDeep_1 = cloneDeep;
  18154. /**
  18155. * Creates a `_.find` or `_.findLast` function.
  18156. *
  18157. * @private
  18158. * @param {Function} findIndexFunc The function to find the collection index.
  18159. * @returns {Function} Returns the new find function.
  18160. */
  18161. function createFind(findIndexFunc) {
  18162. return function(collection, predicate, fromIndex) {
  18163. var iterable = Object(collection);
  18164. if (!isArrayLike_1(collection)) {
  18165. var iteratee = _baseIteratee(predicate);
  18166. collection = keys_1(collection);
  18167. predicate = function(key) { return iteratee(iterable[key], key, iterable); };
  18168. }
  18169. var index = findIndexFunc(collection, predicate, fromIndex);
  18170. return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
  18171. };
  18172. }
  18173. var _createFind = createFind;
  18174. /**
  18175. * The base implementation of `_.findIndex` and `_.findLastIndex` without
  18176. * support for iteratee shorthands.
  18177. *
  18178. * @private
  18179. * @param {Array} array The array to inspect.
  18180. * @param {Function} predicate The function invoked per iteration.
  18181. * @param {number} fromIndex The index to search from.
  18182. * @param {boolean} [fromRight] Specify iterating from right to left.
  18183. * @returns {number} Returns the index of the matched value, else `-1`.
  18184. */
  18185. function baseFindIndex(array, predicate, fromIndex, fromRight) {
  18186. var length = array.length,
  18187. index = fromIndex + (fromRight ? 1 : -1);
  18188. while ((fromRight ? index-- : ++index < length)) {
  18189. if (predicate(array[index], index, array)) {
  18190. return index;
  18191. }
  18192. }
  18193. return -1;
  18194. }
  18195. var _baseFindIndex = baseFindIndex;
  18196. /** Used to match a single whitespace character. */
  18197. var reWhitespace = /\s/;
  18198. /**
  18199. * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
  18200. * character of `string`.
  18201. *
  18202. * @private
  18203. * @param {string} string The string to inspect.
  18204. * @returns {number} Returns the index of the last non-whitespace character.
  18205. */
  18206. function trimmedEndIndex(string) {
  18207. var index = string.length;
  18208. while (index-- && reWhitespace.test(string.charAt(index))) {}
  18209. return index;
  18210. }
  18211. var _trimmedEndIndex = trimmedEndIndex;
  18212. /** Used to match leading whitespace. */
  18213. var reTrimStart = /^\s+/;
  18214. /**
  18215. * The base implementation of `_.trim`.
  18216. *
  18217. * @private
  18218. * @param {string} string The string to trim.
  18219. * @returns {string} Returns the trimmed string.
  18220. */
  18221. function baseTrim(string) {
  18222. return string
  18223. ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '')
  18224. : string;
  18225. }
  18226. var _baseTrim = baseTrim;
  18227. /** Used as references for various `Number` constants. */
  18228. var NAN = 0 / 0;
  18229. /** Used to detect bad signed hexadecimal string values. */
  18230. var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
  18231. /** Used to detect binary string values. */
  18232. var reIsBinary = /^0b[01]+$/i;
  18233. /** Used to detect octal string values. */
  18234. var reIsOctal = /^0o[0-7]+$/i;
  18235. /** Built-in method references without a dependency on `root`. */
  18236. var freeParseInt = parseInt;
  18237. /**
  18238. * Converts `value` to a number.
  18239. *
  18240. * @static
  18241. * @memberOf _
  18242. * @since 4.0.0
  18243. * @category Lang
  18244. * @param {*} value The value to process.
  18245. * @returns {number} Returns the number.
  18246. * @example
  18247. *
  18248. * _.toNumber(3.2);
  18249. * // => 3.2
  18250. *
  18251. * _.toNumber(Number.MIN_VALUE);
  18252. * // => 5e-324
  18253. *
  18254. * _.toNumber(Infinity);
  18255. * // => Infinity
  18256. *
  18257. * _.toNumber('3.2');
  18258. * // => 3.2
  18259. */
  18260. function toNumber(value) {
  18261. if (typeof value == 'number') {
  18262. return value;
  18263. }
  18264. if (isSymbol_1(value)) {
  18265. return NAN;
  18266. }
  18267. if (isObject_1$1(value)) {
  18268. var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
  18269. value = isObject_1$1(other) ? (other + '') : other;
  18270. }
  18271. if (typeof value != 'string') {
  18272. return value === 0 ? value : +value;
  18273. }
  18274. value = _baseTrim(value);
  18275. var isBinary = reIsBinary.test(value);
  18276. return (isBinary || reIsOctal.test(value))
  18277. ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
  18278. : (reIsBadHex.test(value) ? NAN : +value);
  18279. }
  18280. var toNumber_1 = toNumber;
  18281. /** Used as references for various `Number` constants. */
  18282. var INFINITY$2 = 1 / 0,
  18283. MAX_INTEGER = 1.7976931348623157e+308;
  18284. /**
  18285. * Converts `value` to a finite number.
  18286. *
  18287. * @static
  18288. * @memberOf _
  18289. * @since 4.12.0
  18290. * @category Lang
  18291. * @param {*} value The value to convert.
  18292. * @returns {number} Returns the converted number.
  18293. * @example
  18294. *
  18295. * _.toFinite(3.2);
  18296. * // => 3.2
  18297. *
  18298. * _.toFinite(Number.MIN_VALUE);
  18299. * // => 5e-324
  18300. *
  18301. * _.toFinite(Infinity);
  18302. * // => 1.7976931348623157e+308
  18303. *
  18304. * _.toFinite('3.2');
  18305. * // => 3.2
  18306. */
  18307. function toFinite(value) {
  18308. if (!value) {
  18309. return value === 0 ? value : 0;
  18310. }
  18311. value = toNumber_1(value);
  18312. if (value === INFINITY$2 || value === -INFINITY$2) {
  18313. var sign = (value < 0 ? -1 : 1);
  18314. return sign * MAX_INTEGER;
  18315. }
  18316. return value === value ? value : 0;
  18317. }
  18318. var toFinite_1 = toFinite;
  18319. /**
  18320. * Converts `value` to an integer.
  18321. *
  18322. * **Note:** This method is loosely based on
  18323. * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
  18324. *
  18325. * @static
  18326. * @memberOf _
  18327. * @since 4.0.0
  18328. * @category Lang
  18329. * @param {*} value The value to convert.
  18330. * @returns {number} Returns the converted integer.
  18331. * @example
  18332. *
  18333. * _.toInteger(3.2);
  18334. * // => 3
  18335. *
  18336. * _.toInteger(Number.MIN_VALUE);
  18337. * // => 0
  18338. *
  18339. * _.toInteger(Infinity);
  18340. * // => 1.7976931348623157e+308
  18341. *
  18342. * _.toInteger('3.2');
  18343. * // => 3
  18344. */
  18345. function toInteger(value) {
  18346. var result = toFinite_1(value),
  18347. remainder = result % 1;
  18348. return result === result ? (remainder ? result - remainder : result) : 0;
  18349. }
  18350. var toInteger_1 = toInteger;
  18351. /* Built-in method references for those with the same name as other `lodash` methods. */
  18352. var nativeMax = Math.max;
  18353. /**
  18354. * This method is like `_.find` except that it returns the index of the first
  18355. * element `predicate` returns truthy for instead of the element itself.
  18356. *
  18357. * @static
  18358. * @memberOf _
  18359. * @since 1.1.0
  18360. * @category Array
  18361. * @param {Array} array The array to inspect.
  18362. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  18363. * @param {number} [fromIndex=0] The index to search from.
  18364. * @returns {number} Returns the index of the found element, else `-1`.
  18365. * @example
  18366. *
  18367. * var users = [
  18368. * { 'user': 'barney', 'active': false },
  18369. * { 'user': 'fred', 'active': false },
  18370. * { 'user': 'pebbles', 'active': true }
  18371. * ];
  18372. *
  18373. * _.findIndex(users, function(o) { return o.user == 'barney'; });
  18374. * // => 0
  18375. *
  18376. * // The `_.matches` iteratee shorthand.
  18377. * _.findIndex(users, { 'user': 'fred', 'active': false });
  18378. * // => 1
  18379. *
  18380. * // The `_.matchesProperty` iteratee shorthand.
  18381. * _.findIndex(users, ['active', false]);
  18382. * // => 0
  18383. *
  18384. * // The `_.property` iteratee shorthand.
  18385. * _.findIndex(users, 'active');
  18386. * // => 2
  18387. */
  18388. function findIndex(array, predicate, fromIndex) {
  18389. var length = array == null ? 0 : array.length;
  18390. if (!length) {
  18391. return -1;
  18392. }
  18393. var index = fromIndex == null ? 0 : toInteger_1(fromIndex);
  18394. if (index < 0) {
  18395. index = nativeMax(length + index, 0);
  18396. }
  18397. return _baseFindIndex(array, _baseIteratee(predicate), index);
  18398. }
  18399. var findIndex_1 = findIndex;
  18400. /**
  18401. * Iterates over elements of `collection`, returning the first element
  18402. * `predicate` returns truthy for. The predicate is invoked with three
  18403. * arguments: (value, index|key, collection).
  18404. *
  18405. * @static
  18406. * @memberOf _
  18407. * @since 0.1.0
  18408. * @category Collection
  18409. * @param {Array|Object} collection The collection to inspect.
  18410. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  18411. * @param {number} [fromIndex=0] The index to search from.
  18412. * @returns {*} Returns the matched element, else `undefined`.
  18413. * @example
  18414. *
  18415. * var users = [
  18416. * { 'user': 'barney', 'age': 36, 'active': true },
  18417. * { 'user': 'fred', 'age': 40, 'active': false },
  18418. * { 'user': 'pebbles', 'age': 1, 'active': true }
  18419. * ];
  18420. *
  18421. * _.find(users, function(o) { return o.age < 40; });
  18422. * // => object for 'barney'
  18423. *
  18424. * // The `_.matches` iteratee shorthand.
  18425. * _.find(users, { 'age': 1, 'active': true });
  18426. * // => object for 'pebbles'
  18427. *
  18428. * // The `_.matchesProperty` iteratee shorthand.
  18429. * _.find(users, ['active', false]);
  18430. * // => object for 'fred'
  18431. *
  18432. * // The `_.property` iteratee shorthand.
  18433. * _.find(users, 'active');
  18434. * // => object for 'barney'
  18435. */
  18436. var find = _createFind(findIndex_1);
  18437. var find_1 = find;
  18438. // IMClient
  18439. const UNREAD_MESSAGES_COUNT_UPDATE = 'unreadmessagescountupdate';
  18440. const CLOSE = 'close';
  18441. const CONFLICT = 'conflict';
  18442. const CONVERSATION_INFO_UPDATED = 'conversationinfoupdated';
  18443. const UNHANDLED_MESSAGE = 'unhandledmessage'; // shared
  18444. const INVITED = 'invited';
  18445. const KICKED = 'kicked';
  18446. const MEMBERS_JOINED = 'membersjoined';
  18447. const MEMBERS_LEFT = 'membersleft';
  18448. const MEMBER_INFO_UPDATED = 'memberinfoupdated';
  18449. const BLOCKED = 'blocked';
  18450. const UNBLOCKED = 'unblocked';
  18451. const MEMBERS_BLOCKED = 'membersblocked';
  18452. const MEMBERS_UNBLOCKED = 'membersunblocked';
  18453. const MUTED = 'muted';
  18454. const UNMUTED = 'unmuted';
  18455. const MEMBERS_MUTED = 'membersmuted';
  18456. const MEMBERS_UNMUTED = 'membersunmuted';
  18457. const MESSAGE$1 = 'message';
  18458. const MESSAGE_RECALL = 'messagerecall';
  18459. const MESSAGE_UPDATE = 'messageupdate'; // Conversation
  18460. const LAST_DELIVERED_AT_UPDATE = 'lastdeliveredatupdate';
  18461. const LAST_READ_AT_UPDATE = 'lastreadatupdate';
  18462. const INFO_UPDATED = 'infoupdated';
  18463. var IMEvent = /*#__PURE__*/Object.freeze({
  18464. __proto__: null,
  18465. UNREAD_MESSAGES_COUNT_UPDATE: UNREAD_MESSAGES_COUNT_UPDATE,
  18466. CLOSE: CLOSE,
  18467. CONFLICT: CONFLICT,
  18468. CONVERSATION_INFO_UPDATED: CONVERSATION_INFO_UPDATED,
  18469. UNHANDLED_MESSAGE: UNHANDLED_MESSAGE,
  18470. INVITED: INVITED,
  18471. KICKED: KICKED,
  18472. MEMBERS_JOINED: MEMBERS_JOINED,
  18473. MEMBERS_LEFT: MEMBERS_LEFT,
  18474. MEMBER_INFO_UPDATED: MEMBER_INFO_UPDATED,
  18475. BLOCKED: BLOCKED,
  18476. UNBLOCKED: UNBLOCKED,
  18477. MEMBERS_BLOCKED: MEMBERS_BLOCKED,
  18478. MEMBERS_UNBLOCKED: MEMBERS_UNBLOCKED,
  18479. MUTED: MUTED,
  18480. UNMUTED: UNMUTED,
  18481. MEMBERS_MUTED: MEMBERS_MUTED,
  18482. MEMBERS_UNMUTED: MEMBERS_UNMUTED,
  18483. MESSAGE: MESSAGE$1,
  18484. MESSAGE_RECALL: MESSAGE_RECALL,
  18485. MESSAGE_UPDATE: MESSAGE_UPDATE,
  18486. LAST_DELIVERED_AT_UPDATE: LAST_DELIVERED_AT_UPDATE,
  18487. LAST_READ_AT_UPDATE: LAST_READ_AT_UPDATE,
  18488. INFO_UPDATED: INFO_UPDATED
  18489. });
  18490. /**
  18491. * 消息状态枚举
  18492. * @enum {Symbol}
  18493. * @since 3.2.0
  18494. * @memberof module:leancloud-realtime
  18495. */
  18496. const MessageStatus = {
  18497. /** 初始状态、未知状态 */
  18498. NONE: Symbol('none'),
  18499. /** 正在发送 */
  18500. SENDING: Symbol('sending'),
  18501. /** 已发送 */
  18502. SENT: Symbol('sent'),
  18503. /** 已送达 */
  18504. DELIVERED: Symbol('delivered'),
  18505. /** 发送失败 */
  18506. FAILED: Symbol('failed')
  18507. };
  18508. Object.freeze(MessageStatus);
  18509. const rMessageStatus = {
  18510. [MessageStatus.NONE]: true,
  18511. [MessageStatus.SENDING]: true,
  18512. [MessageStatus.SENT]: true,
  18513. [MessageStatus.DELIVERED]: true,
  18514. [MessageStatus.READ]: true,
  18515. [MessageStatus.FAILED]: true
  18516. };
  18517. class Message {
  18518. /**
  18519. * @implements AVMessage
  18520. * @param {Object|String|ArrayBuffer} content 消息内容
  18521. */
  18522. constructor(content) {
  18523. Object.assign(this, {
  18524. content
  18525. }, {
  18526. /**
  18527. * @type {String}
  18528. * @memberof Message#
  18529. */
  18530. id: v4_1(),
  18531. /**
  18532. * 消息所在的 conversation id
  18533. * @memberof Message#
  18534. * @type {String?}
  18535. */
  18536. cid: null,
  18537. /**
  18538. * 消息发送时间
  18539. * @memberof Message#
  18540. * @type {Date}
  18541. */
  18542. timestamp: new Date(),
  18543. /**
  18544. * 消息发送者
  18545. * @memberof Message#
  18546. * @type {String}
  18547. */
  18548. from: undefined,
  18549. /**
  18550. * 消息提及的用户
  18551. * @since 4.0.0
  18552. * @memberof Message#
  18553. * @type {String[]}
  18554. */
  18555. mentionList: [],
  18556. /**
  18557. * 消息是否提及了所有人
  18558. * @since 4.0.0
  18559. * @memberof Message#
  18560. * @type {Boolean}
  18561. */
  18562. mentionedAll: false,
  18563. _mentioned: false
  18564. });
  18565. this._setStatus(MessageStatus.NONE);
  18566. }
  18567. /**
  18568. * 将当前消息的内容序列化为 JSON 对象
  18569. * @private
  18570. * @return {Object}
  18571. */
  18572. getPayload() {
  18573. return this.content;
  18574. }
  18575. _toJSON() {
  18576. const {
  18577. id,
  18578. cid,
  18579. from,
  18580. timestamp,
  18581. deliveredAt,
  18582. updatedAt,
  18583. mentionList,
  18584. mentionedAll,
  18585. mentioned
  18586. } = this;
  18587. return {
  18588. id,
  18589. cid,
  18590. from,
  18591. timestamp,
  18592. deliveredAt,
  18593. updatedAt,
  18594. mentionList,
  18595. mentionedAll,
  18596. mentioned
  18597. };
  18598. }
  18599. /**
  18600. * 返回 JSON 格式的消息
  18601. * @return {Object} 返回值是一个 plain Object
  18602. */
  18603. toJSON() {
  18604. return { ...this._toJSON(),
  18605. data: this.content
  18606. };
  18607. }
  18608. /**
  18609. * 返回 JSON 格式的消息,与 toJSON 不同的是,该对象包含了完整的信息,可以通过 {@link IMClient#parseMessage} 反序列化。
  18610. * @return {Object} 返回值是一个 plain Object
  18611. * @since 4.0.0
  18612. */
  18613. toFullJSON() {
  18614. const {
  18615. content,
  18616. id,
  18617. cid,
  18618. from,
  18619. timestamp,
  18620. deliveredAt,
  18621. _updatedAt,
  18622. mentionList,
  18623. mentionedAll
  18624. } = this;
  18625. return {
  18626. data: content,
  18627. id,
  18628. cid,
  18629. from,
  18630. timestamp: getTime(timestamp),
  18631. deliveredAt: getTime(deliveredAt),
  18632. updatedAt: getTime(_updatedAt),
  18633. mentionList,
  18634. mentionedAll
  18635. };
  18636. }
  18637. /**
  18638. * 消息状态,值为 {@link module:leancloud-realtime.MessageStatus} 之一
  18639. * @type {Symbol}
  18640. * @readonly
  18641. * @since 3.2.0
  18642. */
  18643. get status() {
  18644. return this._status;
  18645. }
  18646. _setStatus(status) {
  18647. if (!rMessageStatus[status]) {
  18648. throw new Error('Invalid message status');
  18649. }
  18650. this._status = status;
  18651. }
  18652. get timestamp() {
  18653. return this._timestamp;
  18654. }
  18655. set timestamp(value) {
  18656. this._timestamp = decodeDate(value);
  18657. }
  18658. /**
  18659. * 消息送达时间
  18660. * @type {?Date}
  18661. */
  18662. get deliveredAt() {
  18663. return this._deliveredAt;
  18664. }
  18665. set deliveredAt(value) {
  18666. this._deliveredAt = decodeDate(value);
  18667. }
  18668. /**
  18669. * 消息修改或撤回时间,可以通过比较其与消息的 timestamp 是否相等判断消息是否被修改过或撤回过。
  18670. * @type {Date}
  18671. * @since 3.5.0
  18672. */
  18673. get updatedAt() {
  18674. return this._updatedAt || this.timestamp;
  18675. }
  18676. set updatedAt(value) {
  18677. this._updatedAt = decodeDate(value);
  18678. }
  18679. /**
  18680. * 当前用户是否在该消息中被提及
  18681. * @type {Boolean}
  18682. * @readonly
  18683. * @since 4.0.0
  18684. */
  18685. get mentioned() {
  18686. return this._mentioned;
  18687. }
  18688. _updateMentioned(client) {
  18689. this._mentioned = this.from !== client && (this.mentionedAll || this.mentionList.indexOf(client) > -1);
  18690. }
  18691. /**
  18692. * 获取提及用户列表
  18693. * @since 4.0.0
  18694. * @return {String[]} 提及用户的 id 列表
  18695. */
  18696. getMentionList() {
  18697. return this.mentionList;
  18698. }
  18699. /**
  18700. * 设置提及用户列表
  18701. * @since 4.0.0
  18702. * @param {String[]} clients 提及用户的 id 列表
  18703. * @return {this} self
  18704. */
  18705. setMentionList(clients) {
  18706. this.mentionList = ensureArray(clients);
  18707. return this;
  18708. }
  18709. /**
  18710. * 设置是否提及所有人
  18711. * @since 4.0.0
  18712. * @param {Boolean} [value=true]
  18713. * @return {this} self
  18714. */
  18715. mentionAll(value = true) {
  18716. this.mentionedAll = Boolean(value);
  18717. return this;
  18718. }
  18719. /**
  18720. * 判断给定的内容是否是有效的 Message,
  18721. * 该方法始终返回 true
  18722. * @private
  18723. * @returns {Boolean}
  18724. * @implements AVMessage.validate
  18725. */
  18726. static validate() {
  18727. return true;
  18728. }
  18729. /**
  18730. * 解析处理消息内容
  18731. * <pre>
  18732. * 如果子类提供了 message,返回该 message
  18733. * 如果没有提供,将 json 作为 content 实例化一个 Message
  18734. * @private
  18735. * @param {Object} json json 格式的消息内容
  18736. * @param {Message} message 子类提供的 message
  18737. * @return {Message}
  18738. * @implements AVMessage.parse
  18739. */
  18740. static parse(json, message) {
  18741. return message || new this(json);
  18742. }
  18743. }
  18744. /* eslint-disable no-param-reassign */
  18745. const messageType = type => {
  18746. if (typeof type !== 'number') {
  18747. throw new TypeError(`${type} is not a Number`);
  18748. }
  18749. return target => {
  18750. target.TYPE = type;
  18751. target.validate = json => json._lctype === type;
  18752. target.prototype._getType = () => ({
  18753. _lctype: type
  18754. });
  18755. };
  18756. }; // documented in ../plugin-im.js
  18757. const messageField = fields => {
  18758. if (typeof fields !== 'string') {
  18759. if (!Array.isArray(fields)) {
  18760. throw new TypeError(`${fields} is not an Array`);
  18761. } else if (fields.some(value => typeof value !== 'string')) {
  18762. throw new TypeError('fields contains non-string typed member');
  18763. }
  18764. }
  18765. return target => {
  18766. // IE10 Hack:
  18767. // static properties in IE10 will not be inherited from super
  18768. // search for parse method and assign it manually
  18769. let originalCustomFields = isIE10 ? getStaticProperty(target, '_customFields') : target._customFields;
  18770. originalCustomFields = Array.isArray(originalCustomFields) ? originalCustomFields : [];
  18771. target._customFields = originalCustomFields.concat(fields);
  18772. };
  18773. }; // IE10 Hack:
  18774. // static properties in IE10 will not be inherited from super
  18775. // search for parse method and assign it manually
  18776. const IE10Compatible = target => {
  18777. if (isIE10) {
  18778. target.parse = getStaticProperty(target, 'parse');
  18779. }
  18780. };
  18781. var _dec, _class$1;
  18782. let // jsdoc-ignore-end
  18783. /**
  18784. * 所有内置的富媒体消息均继承自本类
  18785. * @extends Message
  18786. */
  18787. TypedMessage = (_dec = messageField(['_lctext', '_lcattrs']), _dec(_class$1 = class TypedMessage extends Message {
  18788. /**
  18789. * @type {Number}
  18790. * @readonly
  18791. */
  18792. get type() {
  18793. return this.constructor.TYPE;
  18794. }
  18795. /** @type {String} */
  18796. set text(text) {
  18797. return this.setText(text);
  18798. }
  18799. get text() {
  18800. return this.getText();
  18801. }
  18802. /** @type {Object} */
  18803. set attributes(attributes) {
  18804. return this.setAttributes(attributes);
  18805. }
  18806. get attributes() {
  18807. return this.getAttributes();
  18808. }
  18809. /**
  18810. * 在客户端需要以文本形式展示该消息时显示的文案,
  18811. * 如 <code>[红包] 新春快乐</code>。
  18812. * 默认值为消息的 text。
  18813. * @type {String}
  18814. * @readonly
  18815. */
  18816. get summary() {
  18817. return this.text;
  18818. }
  18819. /**
  18820. * @param {String} text
  18821. * @return {this} self
  18822. */
  18823. setText(text) {
  18824. this._lctext = text;
  18825. return this;
  18826. }
  18827. /**
  18828. * @return {String}
  18829. */
  18830. getText() {
  18831. return this._lctext;
  18832. }
  18833. /**
  18834. * @param {Object} attributes
  18835. * @return {this} self
  18836. */
  18837. setAttributes(attributes) {
  18838. this._lcattrs = attributes;
  18839. return this;
  18840. }
  18841. /**
  18842. * @return {Object}
  18843. */
  18844. getAttributes() {
  18845. return this._lcattrs;
  18846. }
  18847. _getCustomFields() {
  18848. const fields = Array.isArray(this.constructor._customFields) ? this.constructor._customFields : [];
  18849. return fields.reduce((result, field) => {
  18850. if (typeof field !== 'string') return result;
  18851. result[field] = this[field]; // eslint-disable-line no-param-reassign
  18852. return result;
  18853. }, {});
  18854. }
  18855. /* eslint-disable class-methods-use-this */
  18856. _getType() {
  18857. throw new Error('not implemented');
  18858. }
  18859. /* eslint-enable class-methods-use-this */
  18860. getPayload() {
  18861. return compact({
  18862. _lctext: this.getText(),
  18863. _lcattrs: this.getAttributes(),
  18864. ...this._getCustomFields(),
  18865. ...this._getType()
  18866. });
  18867. }
  18868. toJSON() {
  18869. const {
  18870. type,
  18871. text,
  18872. attributes,
  18873. summary
  18874. } = this;
  18875. return { ...super._toJSON(),
  18876. type,
  18877. text,
  18878. attributes,
  18879. summary
  18880. };
  18881. }
  18882. toFullJSON() {
  18883. return { ...super.toFullJSON(),
  18884. data: this.getPayload()
  18885. };
  18886. }
  18887. /**
  18888. * 解析处理消息内容
  18889. * <pre>
  18890. * 为给定的 message 设置 text 与 attributes 属性,返回该 message
  18891. * 如果子类没有提供 message,new this()
  18892. * @protected
  18893. * @param {Object} json json 格式的消息内容
  18894. * @param {TypedMessage} message 子类提供的 message
  18895. * @return {TypedMessage}
  18896. * @implements AVMessage.parse
  18897. */
  18898. static parse(json, message = new this()) {
  18899. message.content = json; // eslint-disable-line no-param-reassign
  18900. const customFields = isIE10 ? getStaticProperty(message.constructor, '_customFields') : message.constructor._customFields;
  18901. let fields = Array.isArray(customFields) ? customFields : [];
  18902. fields = fields.reduce((result, field) => {
  18903. if (typeof field !== 'string') return result;
  18904. result[field] = json[field]; // eslint-disable-line no-param-reassign
  18905. return result;
  18906. }, {});
  18907. Object.assign(message, fields);
  18908. return super.parse(json, message);
  18909. }
  18910. }) || _class$1);
  18911. var _dec$1, _class$2;
  18912. let // jsdoc-ignore-end
  18913. /**
  18914. * 已撤回类型消息,当消息被撤回时,SDK 会使用该类型的消息替代原始消息
  18915. * @extends TypedMessage
  18916. */
  18917. RecalledMessage = (_dec$1 = messageType(-127), _dec$1(_class$2 = IE10Compatible(_class$2 = class RecalledMessage extends TypedMessage {
  18918. /**
  18919. * 在客户端需要以文本形式展示该消息时显示的文案,值为 <code>[该消息已撤回]</code>
  18920. * @type {String}
  18921. * @readonly
  18922. */
  18923. // eslint-disable-next-line class-methods-use-this
  18924. get summary() {
  18925. return '[该消息已撤回]';
  18926. }
  18927. }) || _class$2) || _class$2);
  18928. /* eslint class-methods-use-this: ["error", { "exceptMethods": ["_addMembers", "_removeMembers"] }] */
  18929. const debug$7 = browser('LC:Conversation');
  18930. const serializeMessage = message => {
  18931. const content = message.getPayload();
  18932. let msg;
  18933. let binaryMsg;
  18934. if (content instanceof ArrayBuffer) {
  18935. binaryMsg = content;
  18936. } else if (typeof content !== 'string') {
  18937. msg = JSON.stringify(content);
  18938. } else {
  18939. msg = content;
  18940. }
  18941. return {
  18942. msg,
  18943. binaryMsg
  18944. };
  18945. };
  18946. const {
  18947. NEW,
  18948. OLD
  18949. } = LogsCommand.QueryDirection;
  18950. /**
  18951. * 历史消息查询方向枚举
  18952. * @enum {Number}
  18953. * @since 4.0.0
  18954. * @memberof module:leancloud-realtime
  18955. */
  18956. const MessageQueryDirection = {
  18957. /** 从后向前 */
  18958. NEW_TO_OLD: OLD,
  18959. /** 从前向后 */
  18960. OLD_TO_NEW: NEW
  18961. };
  18962. Object.freeze(MessageQueryDirection);
  18963. class ConversationBase extends eventemitter3 {
  18964. /**
  18965. * @extends EventEmitter
  18966. * @private
  18967. * @abstract
  18968. */
  18969. constructor({
  18970. id,
  18971. lastMessageAt,
  18972. lastMessage,
  18973. lastDeliveredAt,
  18974. lastReadAt,
  18975. unreadMessagesCount = 0,
  18976. members = [],
  18977. mentioned = false,
  18978. ...properties
  18979. }, client) {
  18980. super();
  18981. Object.assign(this, {
  18982. /**
  18983. * 对话 id,对应 _Conversation 表中的 objectId
  18984. * @memberof ConversationBase#
  18985. * @type {String}
  18986. */
  18987. id,
  18988. /**
  18989. * 最后一条消息时间
  18990. * @memberof ConversationBase#
  18991. * @type {?Date}
  18992. */
  18993. lastMessageAt,
  18994. /**
  18995. * 最后一条消息
  18996. * @memberof ConversationBase#
  18997. * @type {?Message}
  18998. */
  18999. lastMessage,
  19000. /**
  19001. * 参与该对话的用户列表
  19002. * @memberof ConversationBase#
  19003. * @type {String[]}
  19004. */
  19005. members,
  19006. // other properties provided by subclasses
  19007. ...properties
  19008. });
  19009. this.members = Array.from(new Set(this.members));
  19010. Object.assign(internal(this), {
  19011. messagesWaitingForReceipt: {},
  19012. lastDeliveredAt,
  19013. lastReadAt,
  19014. unreadMessagesCount,
  19015. mentioned
  19016. });
  19017. this._client = client;
  19018. if (debug$7.enabled) {
  19019. values_1(IMEvent).forEach(event => this.on(event, (...payload) => this._debug(`${event} event emitted. %o`, payload)));
  19020. } // onConversationCreate hook
  19021. applyDecorators(this._client._plugins.onConversationCreate, this);
  19022. }
  19023. /**
  19024. * 当前用户是否在该对话的未读消息中被提及
  19025. * @type {Boolean}
  19026. * @since 4.0.0
  19027. */
  19028. get unreadMessagesMentioned() {
  19029. return internal(this).unreadMessagesMentioned;
  19030. }
  19031. _setUnreadMessagesMentioned(value) {
  19032. internal(this).unreadMessagesMentioned = Boolean(value);
  19033. }
  19034. set unreadMessagesCount(value) {
  19035. if (value !== this.unreadMessagesCount) {
  19036. internal(this).unreadMessagesCount = value;
  19037. this._client.emit(UNREAD_MESSAGES_COUNT_UPDATE, [this]);
  19038. }
  19039. }
  19040. /**
  19041. * 当前用户在该对话的未读消息数
  19042. * @type {Number}
  19043. */
  19044. get unreadMessagesCount() {
  19045. return internal(this).unreadMessagesCount;
  19046. }
  19047. set lastMessageAt(value) {
  19048. const time = decodeDate(value);
  19049. if (time <= this._lastMessageAt) return;
  19050. this._lastMessageAt = time;
  19051. }
  19052. get lastMessageAt() {
  19053. return this._lastMessageAt;
  19054. }
  19055. /**
  19056. * 最后消息送达时间,常用来实现消息的「已送达」标记,可通过 {@link Conversation#fetchReceiptTimestamps} 获取或更新该属性
  19057. * @type {?Date}
  19058. * @since 3.4.0
  19059. */
  19060. get lastDeliveredAt() {
  19061. if (this.members.length !== 2) return null;
  19062. return internal(this).lastDeliveredAt;
  19063. }
  19064. _setLastDeliveredAt(value) {
  19065. const date = decodeDate(value);
  19066. if (!(date < internal(this).lastDeliveredAt)) {
  19067. internal(this).lastDeliveredAt = date;
  19068. /**
  19069. * 最后消息送达时间更新
  19070. * @event ConversationBase#LAST_DELIVERED_AT_UPDATE
  19071. * @since 3.4.0
  19072. */
  19073. this.emit(LAST_DELIVERED_AT_UPDATE);
  19074. }
  19075. }
  19076. /**
  19077. * 最后消息被阅读时间,常用来实现发送消息的「已读」标记,可通过 {@link Conversation#fetchReceiptTimestamps} 获取或更新该属性
  19078. * @type {?Date}
  19079. * @since 3.4.0
  19080. */
  19081. get lastReadAt() {
  19082. if (this.members.length !== 2) return null;
  19083. return internal(this).lastReadAt;
  19084. }
  19085. _setLastReadAt(value) {
  19086. const date = decodeDate(value);
  19087. if (!(date < internal(this).lastReadAt)) {
  19088. internal(this).lastReadAt = date;
  19089. /**
  19090. * 最后消息被阅读时间更新
  19091. * @event ConversationBase#LAST_READ_AT_UPDATE
  19092. * @since 3.4.0
  19093. */
  19094. this.emit(LAST_READ_AT_UPDATE);
  19095. }
  19096. }
  19097. /**
  19098. * 返回 JSON 格式的对话,与 toJSON 不同的是,该对象包含了完整的信息,可以通过 {@link IMClient#parseConversation} 反序列化。
  19099. * @return {Object} 返回值是一个 plain Object
  19100. * @since 4.0.0
  19101. */
  19102. toFullJSON() {
  19103. const {
  19104. id,
  19105. members,
  19106. lastMessageAt,
  19107. lastDeliveredAt,
  19108. lastReadAt,
  19109. lastMessage,
  19110. unreadMessagesCount
  19111. } = this;
  19112. return {
  19113. id,
  19114. members,
  19115. lastMessageAt: getTime(lastMessageAt),
  19116. lastDeliveredAt: getTime(lastDeliveredAt),
  19117. lastReadAt: getTime(lastReadAt),
  19118. lastMessage: lastMessage ? lastMessage.toFullJSON() : undefined,
  19119. unreadMessagesCount
  19120. };
  19121. }
  19122. /**
  19123. * 返回 JSON 格式的对话
  19124. * @return {Object} 返回值是一个 plain Object
  19125. * @since 4.0.0
  19126. */
  19127. toJSON() {
  19128. const {
  19129. id,
  19130. members,
  19131. lastMessageAt,
  19132. lastDeliveredAt,
  19133. lastReadAt,
  19134. lastMessage,
  19135. unreadMessagesCount,
  19136. unreadMessagesMentioned
  19137. } = this;
  19138. return {
  19139. id,
  19140. members,
  19141. lastMessageAt,
  19142. lastDeliveredAt,
  19143. lastReadAt,
  19144. lastMessage: lastMessage ? lastMessage.toJSON() : undefined,
  19145. unreadMessagesCount,
  19146. unreadMessagesMentioned
  19147. };
  19148. }
  19149. _debug(...params) {
  19150. debug$7(...params, `[${this.id}]`);
  19151. }
  19152. _send(command, ...args) {
  19153. /* eslint-disable no-param-reassign */
  19154. if (command.cmd === null) {
  19155. command.cmd = 'conv';
  19156. }
  19157. if (command.cmd === 'conv' && command.convMessage === null) {
  19158. command.convMessage = new ConvCommand();
  19159. }
  19160. if (command.convMessage && command.convMessage.cid === null) {
  19161. command.convMessage.cid = this.id;
  19162. }
  19163. /* eslint-enable no-param-reassign */
  19164. return this._client._send(command, ...args);
  19165. }
  19166. /**
  19167. * 发送消息
  19168. * @param {Message} message 消息,Message 及其子类的实例
  19169. * @param {Object} [options] since v3.3.0,发送选项
  19170. * @param {Boolean} [options.transient] since v3.3.1,是否作为暂态消息发送
  19171. * @param {Boolean} [options.receipt] 是否需要回执,仅在普通对话中有效
  19172. * @param {Boolean} [options.will] since v3.4.0,是否指定该消息作为「掉线消息」发送,
  19173. * 「掉线消息」会延迟到当前用户掉线后发送,常用来实现「下线通知」功能
  19174. * @param {MessagePriority} [options.priority] 消息优先级,仅在暂态对话中有效,
  19175. * see: {@link module:leancloud-realtime.MessagePriority MessagePriority}
  19176. * @param {Object} [options.pushData] 消息对应的离线推送内容,如果消息接收方不在线,会推送指定的内容。其结构说明参见: {@link https://url.leanapp.cn/pushData 推送消息内容}
  19177. * @return {Promise.<Message>} 发送的消息
  19178. */
  19179. async send(message, options) {
  19180. this._debug(message, 'send');
  19181. if (!(message instanceof Message)) {
  19182. throw new TypeError(`${message} is not a Message`);
  19183. }
  19184. const {
  19185. transient,
  19186. receipt,
  19187. priority,
  19188. pushData,
  19189. will
  19190. } = { // support Message static property: sendOptions
  19191. ...message.constructor.sendOptions,
  19192. // support Message static property: getSendOptions
  19193. ...(typeof message.constructor.getSendOptions === 'function' ? message.constructor.getSendOptions(message) : {}),
  19194. ...options
  19195. };
  19196. if (receipt) {
  19197. if (this.transient) {
  19198. console.warn('receipt option is ignored as the conversation is transient.');
  19199. } else if (transient) {
  19200. console.warn('receipt option is ignored as the message is sent transiently.');
  19201. } else if (this.members.length > 2) {
  19202. console.warn('receipt option is recommended to be used in one-on-one conversation.'); // eslint-disable-line max-len
  19203. }
  19204. }
  19205. if (priority && !this.transient) {
  19206. console.warn('priority option is ignored as the conversation is not transient.');
  19207. }
  19208. Object.assign(message, {
  19209. cid: this.id,
  19210. from: this._client.id
  19211. });
  19212. message._setStatus(MessageStatus.SENDING);
  19213. const {
  19214. msg,
  19215. binaryMsg
  19216. } = serializeMessage(message);
  19217. const command = new GenericCommand({
  19218. cmd: 'direct',
  19219. directMessage: new DirectCommand({
  19220. msg,
  19221. binaryMsg,
  19222. cid: this.id,
  19223. r: receipt,
  19224. transient,
  19225. dt: message.id,
  19226. pushData: JSON.stringify(pushData),
  19227. will,
  19228. mentionPids: message.mentionList,
  19229. mentionAll: message.mentionedAll
  19230. }),
  19231. priority
  19232. });
  19233. try {
  19234. const resCommand = await this._send(command);
  19235. const {
  19236. ackMessage: {
  19237. uid,
  19238. t,
  19239. code,
  19240. reason,
  19241. appCode
  19242. }
  19243. } = resCommand;
  19244. if (code !== null) {
  19245. throw createError({
  19246. code,
  19247. reason,
  19248. appCode
  19249. });
  19250. }
  19251. Object.assign(message, {
  19252. id: uid,
  19253. timestamp: t
  19254. });
  19255. if (!transient) {
  19256. this.lastMessage = message;
  19257. this.lastMessageAt = message.timestamp;
  19258. }
  19259. message._setStatus(MessageStatus.SENT);
  19260. if (receipt) {
  19261. internal(this).messagesWaitingForReceipt[message.id] = message;
  19262. }
  19263. return message;
  19264. } catch (error) {
  19265. message._setStatus(MessageStatus.FAILED);
  19266. throw error;
  19267. }
  19268. }
  19269. async _update(message, newMessage, recall) {
  19270. this._debug('patch %O %O %O', message, newMessage, recall);
  19271. if (message instanceof Message) {
  19272. if (message.from !== this._client.id) {
  19273. throw new Error('Updating message from others is not allowed');
  19274. }
  19275. if (message.status !== MessageStatus.SENT && message.status !== MessageStatus.DELIVERED) {
  19276. throw new Error('Message is not sent');
  19277. }
  19278. } else if (!(message.id && message.timestamp)) {
  19279. throw new TypeError(`${message} is not a Message`);
  19280. }
  19281. let msg;
  19282. let binaryMsg;
  19283. if (!recall) {
  19284. const content = serializeMessage(newMessage);
  19285. ({
  19286. msg,
  19287. binaryMsg
  19288. } = content);
  19289. }
  19290. await this._send(new GenericCommand({
  19291. cmd: CommandType.patch,
  19292. op: OpType.modify,
  19293. patchMessage: new PatchCommand({
  19294. patches: [new PatchItem({
  19295. cid: this.id,
  19296. mid: message.id,
  19297. timestamp: Number(message.timestamp),
  19298. recall,
  19299. data: msg,
  19300. binaryMsg,
  19301. mentionPids: newMessage.mentionList,
  19302. mentionAll: newMessage.mentionedAll
  19303. })],
  19304. lastPatchTime: this._client._lastPatchTime
  19305. })
  19306. }));
  19307. const {
  19308. id,
  19309. cid,
  19310. timestamp,
  19311. from,
  19312. _status
  19313. } = message;
  19314. Object.assign(newMessage, {
  19315. id,
  19316. cid,
  19317. timestamp,
  19318. from,
  19319. _status
  19320. });
  19321. if (this.lastMessage && this.lastMessage.id === newMessage.id) {
  19322. this.lastMessage = newMessage;
  19323. }
  19324. return newMessage;
  19325. }
  19326. /**
  19327. * 获取对话人数,或暂态对话的在线人数
  19328. * @return {Promise.<Number>}
  19329. */
  19330. async count() {
  19331. this._debug('count');
  19332. const resCommand = await this._send(new GenericCommand({
  19333. op: 'count'
  19334. }));
  19335. return resCommand.convMessage.count;
  19336. }
  19337. /**
  19338. * 应用增加成员的操作,产生副作用
  19339. * @param {string[]} members
  19340. * @abstract
  19341. * @private
  19342. */
  19343. _addMembers() {}
  19344. /**
  19345. * 应用减少成员的操作,产生副作用
  19346. * @param {string[]} members
  19347. * @abstract
  19348. * @private
  19349. */
  19350. _removeMembers() {}
  19351. /**
  19352. * 修改已发送的消息
  19353. * @param {AVMessage} message 要修改的消息,该消息必须是由当前用户发送的。也可以提供一个包含消息 {id, timestamp} 的对象
  19354. * @param {AVMessage} newMessage 新的消息
  19355. * @return {Promise.<AVMessage>} 更新后的消息
  19356. */
  19357. async update(message, newMessage) {
  19358. if (!(newMessage instanceof Message)) {
  19359. throw new TypeError(`${newMessage} is not a Message`);
  19360. }
  19361. return this._update(message, newMessage, false);
  19362. }
  19363. /**
  19364. * 撤回已发送的消息
  19365. * @param {AVMessage} message 要撤回的消息,该消息必须是由当前用户发送的。也可以提供一个包含消息 {id, timestamp} 的对象
  19366. * @return {Promise.<RecalledMessage>} 一条已撤回的消息
  19367. */
  19368. async recall(message) {
  19369. return this._update(message, new RecalledMessage(), true);
  19370. }
  19371. /**
  19372. * 查询消息记录
  19373. * 如果仅需实现消息向前记录翻页查询需求,建议使用 {@link Conversation#createMessagesIterator}。
  19374. * 不论何种方向,获得的消息都是按照时间升序排列的。
  19375. * startClosed 与 endClosed 用于指定查询区间的开闭。
  19376. *
  19377. * @param {Object} [options]
  19378. * @param {Number} [options.limit] 限制查询结果的数量,目前服务端默认为 20
  19379. * @param {Number} [options.type] 指定查询的富媒体消息类型,不指定则查询所有消息。
  19380. * @param {MessageQueryDirection} [options.direction] 查询的方向。
  19381. * 在不指定的情况下如果 startTime 大于 endTime,则为从新到旧查询,可以实现加载聊天记录等场景。
  19382. * 如果 startTime 小于 endTime,则为从旧到新查询,可以实现弹幕等场景。
  19383. * @param {Date} [options.startTime] 从该时间开始查询,不传则从当前时间开始查询
  19384. * @param {String} [options.startMessageId] 从该消息之前开始查询,需要与 startTime 同时使用,为防止某时刻有重复消息
  19385. * @param {Boolean}[options.startClosed] 指定查询范围是否包括开始的时间点,默认不包括
  19386. * @param {Date} [options.endTime] 查询到该时间为止,不传则查询最早消息为止
  19387. * @param {String} [options.endMessageId] 查询到该消息为止,需要与 endTime 同时使用,为防止某时刻有重复消息
  19388. * @param {Boolean}[options.endClosed] 指定查询范围是否包括结束的时间点,默认不包括
  19389. *
  19390. * @param {Date} [options.beforeTime] DEPRECATED: 使用 startTime 代替。限制查询结果为小于该时间之前的消息,不传则为当前时间
  19391. * @param {String} [options.beforeMessageId] DEPRECATED: 使用 startMessageId 代替。
  19392. * 限制查询结果为该消息之前的消息,需要与 beforeTime 同时使用,为防止某时刻有重复消息
  19393. * @param {Date} [options.afterTime] DEPRECATED: 使用 endTime 代替。限制查询结果为大于该时间之前的消息
  19394. * @param {String} [options.afterMessageId] DEPRECATED: 使用 endMessageId 代替。
  19395. * 限制查询结果为该消息之后的消息,需要与 afterTime 同时使用,为防止某时刻有重复消息
  19396. * @return {Promise.<Message[]>} 消息列表
  19397. */
  19398. async queryMessages(options = {}) {
  19399. this._debug('query messages %O', options);
  19400. const {
  19401. beforeTime,
  19402. beforeMessageId,
  19403. afterTime,
  19404. afterMessageId,
  19405. limit,
  19406. direction,
  19407. type,
  19408. startTime,
  19409. startMessageId,
  19410. startClosed,
  19411. endTime,
  19412. endMessageId,
  19413. endClosed
  19414. } = options;
  19415. if (beforeMessageId || beforeTime || afterMessageId || afterTime) {
  19416. console.warn('DEPRECATION: queryMessages options beforeTime, beforeMessageId, afterTime and afterMessageId are deprecated in favor of startTime, startMessageId, endTime and endMessageId.');
  19417. return this.queryMessages({
  19418. startTime: beforeTime,
  19419. startMessageId: beforeMessageId,
  19420. endTime: afterTime,
  19421. endMessageId: afterMessageId,
  19422. limit
  19423. });
  19424. }
  19425. if (startMessageId && !startTime) {
  19426. throw new Error('query option startMessageId must be used with option startTime');
  19427. }
  19428. if (endMessageId && !endTime) {
  19429. throw new Error('query option endMessageId must be used with option endTime');
  19430. }
  19431. const conditions = {
  19432. t: startTime,
  19433. mid: startMessageId,
  19434. tIncluded: startClosed,
  19435. tt: endTime,
  19436. tmid: endMessageId,
  19437. ttIncluded: endClosed,
  19438. l: limit,
  19439. lctype: type
  19440. };
  19441. if (conditions.t instanceof Date) {
  19442. conditions.t = conditions.t.getTime();
  19443. }
  19444. if (conditions.tt instanceof Date) {
  19445. conditions.tt = conditions.tt.getTime();
  19446. }
  19447. if (direction !== undefined) {
  19448. conditions.direction = direction;
  19449. } else if (conditions.tt > conditions.t) {
  19450. conditions.direction = MessageQueryDirection.OLD_TO_NEW;
  19451. }
  19452. const resCommand = await this._send(new GenericCommand({
  19453. cmd: 'logs',
  19454. logsMessage: new LogsCommand(Object.assign(conditions, {
  19455. cid: this.id
  19456. }))
  19457. }));
  19458. return Promise.all(resCommand.logsMessage.logs.map(async ({
  19459. msgId,
  19460. timestamp,
  19461. patchTimestamp,
  19462. from,
  19463. ackAt,
  19464. readAt,
  19465. data,
  19466. mentionAll,
  19467. mentionPids,
  19468. bin
  19469. }) => {
  19470. const messageData = {
  19471. data,
  19472. bin,
  19473. id: msgId,
  19474. cid: this.id,
  19475. timestamp,
  19476. from,
  19477. deliveredAt: ackAt,
  19478. updatedAt: patchTimestamp,
  19479. mentionList: mentionPids,
  19480. mentionedAll: mentionAll
  19481. };
  19482. const message = await this._client.parseMessage(messageData);
  19483. let status = MessageStatus.SENT;
  19484. if (this.members.length === 2) {
  19485. if (ackAt) status = MessageStatus.DELIVERED;
  19486. if (ackAt) this._setLastDeliveredAt(ackAt);
  19487. if (readAt) this._setLastReadAt(readAt);
  19488. }
  19489. message._setStatus(status);
  19490. return message;
  19491. }));
  19492. }
  19493. /**
  19494. * 获取消息翻页迭代器
  19495. * @param {Object} [options]
  19496. * @param {Date} [options.beforeTime] 限制起始查询结果为小于该时间之前的消息,不传则为当前时间
  19497. * @param {String} [options.beforeMessageId] 限制起始查询结果为该消息之前的消息,需要与 beforeTime 同时使用,为防止某时刻有重复消息
  19498. * @param {Number} [options.limit] 限制每页查询结果的数量,目前服务端默认为 20
  19499. * @return {AsyncIterater.<Promise.<IteratorResult<Message[]>>>} [AsyncIterator]{@link https://github.com/tc39/proposal-async-iteration},调用其 next 方法返回获取下一页消息的 Promise
  19500. * @example
  19501. * var messageIterator = conversation.createMessagesIterator({ limit: 10 });
  19502. * messageIterator.next().then(function(result) {
  19503. * // result: {
  19504. * // value: [message1, ..., message10],
  19505. * // done: false,
  19506. * // }
  19507. * });
  19508. * messageIterator.next().then(function(result) {
  19509. * // result: {
  19510. * // value: [message11, ..., message20],
  19511. * // done: false,
  19512. * // }
  19513. * });
  19514. * messageIterator.next().then(function(result) {
  19515. * // No more messages
  19516. * // result: { value: [], done: true }
  19517. * });
  19518. */
  19519. createMessagesIterator({
  19520. beforeTime,
  19521. beforeMessageId,
  19522. limit
  19523. } = {}) {
  19524. let promise;
  19525. return {
  19526. next: () => {
  19527. if (promise === undefined) {
  19528. // first call
  19529. promise = this.queryMessages({
  19530. limit,
  19531. startTime: beforeTime,
  19532. startMessageId: beforeMessageId
  19533. });
  19534. } else {
  19535. promise = promise.then(prevMessages => {
  19536. if (prevMessages.length === 0 || prevMessages.length < limit) {
  19537. // no more messages
  19538. return [];
  19539. }
  19540. return this.queryMessages({
  19541. startTime: prevMessages[0].timestamp,
  19542. startMessageId: prevMessages[0].id,
  19543. limit
  19544. });
  19545. });
  19546. }
  19547. return promise.then(value => ({
  19548. value: Array.from(value),
  19549. done: value.length === 0 || value.length < limit
  19550. }));
  19551. }
  19552. };
  19553. }
  19554. /**
  19555. * 将该会话标记为已读
  19556. * @return {Promise.<this>} self
  19557. */
  19558. async read() {
  19559. this.unreadMessagesCount = 0;
  19560. this._setUnreadMessagesMentioned(false); // 跳过暂态会话
  19561. if (this.transient) return this;
  19562. const client = this._client;
  19563. if (!internal(client).readConversationsBuffer) {
  19564. internal(client).readConversationsBuffer = new Set();
  19565. }
  19566. internal(client).readConversationsBuffer.add(this);
  19567. client._doSendRead();
  19568. return this;
  19569. }
  19570. _handleReceipt({
  19571. messageId,
  19572. timestamp,
  19573. read
  19574. }) {
  19575. if (read) {
  19576. this._setLastReadAt(timestamp);
  19577. } else {
  19578. this._setLastDeliveredAt(timestamp);
  19579. }
  19580. const {
  19581. messagesWaitingForReceipt
  19582. } = internal(this);
  19583. const message = messagesWaitingForReceipt[messageId];
  19584. if (!message) return;
  19585. message._setStatus(MessageStatus.DELIVERED);
  19586. message.deliveredAt = timestamp;
  19587. delete messagesWaitingForReceipt[messageId];
  19588. }
  19589. /**
  19590. * 更新对话的最新回执时间戳(lastDeliveredAt、lastReadAt)
  19591. * @since 3.4.0
  19592. * @return {Promise.<this>} this
  19593. */
  19594. async fetchReceiptTimestamps() {
  19595. // 暂态/系统会话不支持回执
  19596. if (this.transient || this.system) return this;
  19597. const {
  19598. convMessage: {
  19599. maxReadTimestamp,
  19600. maxAckTimestamp
  19601. }
  19602. } = await this._send(new GenericCommand({
  19603. op: 'max_read'
  19604. }));
  19605. this._setLastDeliveredAt(maxAckTimestamp);
  19606. this._setLastReadAt(maxReadTimestamp);
  19607. return this;
  19608. }
  19609. _fetchAllReceiptTimestamps() {
  19610. // 暂态/系统会话不支持回执
  19611. if (this.transient || this.system) return this;
  19612. const convMessage = new ConvCommand({
  19613. queryAllMembers: true
  19614. });
  19615. return this._send(new GenericCommand({
  19616. op: 'max_read',
  19617. convMessage
  19618. })).then(({
  19619. convMessage: {
  19620. maxReadTuples
  19621. }
  19622. }) => maxReadTuples.filter(maxReadTuple => maxReadTuple.maxAckTimestamp || maxReadTuple.maxReadTimestamp).map(({
  19623. pid,
  19624. maxAckTimestamp,
  19625. maxReadTimestamp
  19626. }) => ({
  19627. pid,
  19628. lastDeliveredAt: decodeDate(maxAckTimestamp),
  19629. lastReadAt: decodeDate(maxReadTimestamp)
  19630. })));
  19631. }
  19632. }
  19633. const debug$8 = browser('LC:SignatureFactoryRunner');
  19634. function _validateSignature(signatureResult = {}) {
  19635. const {
  19636. signature,
  19637. timestamp,
  19638. nonce
  19639. } = signatureResult;
  19640. if (typeof signature !== 'string' || typeof timestamp !== 'number' || typeof nonce !== 'string') {
  19641. throw new Error('malformed signature');
  19642. }
  19643. return {
  19644. signature,
  19645. timestamp,
  19646. nonce
  19647. };
  19648. }
  19649. var runSignatureFactory = ((signatureFactory, params) => Promise.resolve().then(() => {
  19650. debug$8('call signatureFactory with %O', params);
  19651. return signatureFactory(...params);
  19652. }).then(tap(signatureResult => debug$8('sign result %O', signatureResult)), error => {
  19653. // eslint-disable-next-line no-param-reassign
  19654. error.message = `sign error: ${error.message}`;
  19655. debug$8(error);
  19656. throw error;
  19657. }).then(_validateSignature));
  19658. /**
  19659. * 部分失败异常
  19660. * @typedef OperationFailureError
  19661. * @type {Error}
  19662. * @property {string} message 异常信息
  19663. * @property {string[]} clientIds 因为该原因失败的 client id 列表
  19664. * @property {number} [code] 错误码
  19665. * @property {string} [detail] 详细信息
  19666. */
  19667. /**
  19668. * 部分成功的结果
  19669. * @typedef PartiallySuccess
  19670. * @type {Object}
  19671. * @property {string[]} successfulClientIds 成功的 client id 列表
  19672. * @property {OperationFailureError[]} failures 失败的异常列表
  19673. */
  19674. /**
  19675. * 分页查询结果
  19676. * @typedef PagedResults
  19677. * @type {Object}
  19678. * @property {T[]} results 查询结果
  19679. * @property {string} [next] 存在表示还有更多结果,在下次查询中带上可实现翻页。
  19680. */
  19681. const createPartiallySuccess = ({
  19682. allowedPids,
  19683. failedPids
  19684. }) => ({
  19685. successfulClientIds: allowedPids,
  19686. failures: failedPids.map(({
  19687. pids,
  19688. ...error
  19689. }) => Object.assign(createError(error), {
  19690. clientIds: pids
  19691. }))
  19692. });
  19693. /**
  19694. * @extends ConversationBase
  19695. * @private
  19696. * @abstract
  19697. */
  19698. class PersistentConversation extends ConversationBase {
  19699. constructor(data, {
  19700. creator,
  19701. createdAt,
  19702. updatedAt,
  19703. transient = false,
  19704. system = false,
  19705. muted = false,
  19706. mutedMembers = [],
  19707. ...attributes
  19708. }, client) {
  19709. super({ ...data,
  19710. /**
  19711. * 对话创建者
  19712. * @memberof PersistentConversation#
  19713. * @type {String}
  19714. */
  19715. creator,
  19716. /**
  19717. * 对话创建时间
  19718. * @memberof PersistentConversation#
  19719. * @type {Date}
  19720. */
  19721. createdAt,
  19722. /**
  19723. * 对话更新时间
  19724. * @memberof PersistentConversation#
  19725. * @type {Date}
  19726. */
  19727. updatedAt,
  19728. /**
  19729. * 对该对话设置了静音的用户列表
  19730. * @memberof PersistentConversation#
  19731. * @type {?String[]}
  19732. */
  19733. mutedMembers,
  19734. /**
  19735. * 暂态对话标记
  19736. * @memberof PersistentConversation#
  19737. * @type {Boolean}
  19738. */
  19739. transient,
  19740. /**
  19741. * 系统对话标记
  19742. * @memberof PersistentConversation#
  19743. * @type {Boolean}
  19744. * @since 3.3.0
  19745. */
  19746. system,
  19747. /**
  19748. * 当前用户静音该对话标记
  19749. * @memberof PersistentConversation#
  19750. * @type {Boolean}
  19751. */
  19752. muted,
  19753. _attributes: attributes
  19754. }, client);
  19755. this._reset();
  19756. }
  19757. set createdAt(value) {
  19758. this._createdAt = decodeDate(value);
  19759. }
  19760. get createdAt() {
  19761. return this._createdAt;
  19762. }
  19763. set updatedAt(value) {
  19764. this._updatedAt = decodeDate(value);
  19765. }
  19766. get updatedAt() {
  19767. return this._updatedAt;
  19768. }
  19769. /**
  19770. * 对话名字,对应 _Conversation 表中的 name
  19771. * @type {String}
  19772. */
  19773. get name() {
  19774. return this.get('name');
  19775. }
  19776. set name(value) {
  19777. this.set('name', value);
  19778. }
  19779. /**
  19780. * 获取对话的自定义属性
  19781. * @since 3.2.0
  19782. * @param {String} key key 属性的键名,'x' 对应 Conversation 表中的 x 列
  19783. * @return {Any} 属性的值
  19784. */
  19785. get(key) {
  19786. return get_1(internal(this).currentAttributes, key);
  19787. }
  19788. /**
  19789. * 设置对话的自定义属性
  19790. * @since 3.2.0
  19791. * @param {String} key 属性的键名,'x' 对应 Conversation 表中的 x 列,支持使用 'x.y.z' 来修改对象的部分字段。
  19792. * @param {Any} value 属性的值
  19793. * @return {this} self
  19794. * @example
  19795. *
  19796. * // 设置对话的 color 属性
  19797. * conversation.set('color', {
  19798. * text: '#000',
  19799. * background: '#DDD',
  19800. * });
  19801. * // 设置对话的 color.text 属性
  19802. * conversation.set('color.text', '#333');
  19803. */
  19804. set(key, value) {
  19805. this._debug(`set [${key}]: ${value}`);
  19806. const {
  19807. pendingAttributes
  19808. } = internal(this);
  19809. const pendingKeys = Object.keys(pendingAttributes); // suppose pendingAttributes = { 'a.b': {} }
  19810. // set 'a' or 'a.b': delete 'a.b'
  19811. const re = new RegExp(`^${key}`);
  19812. const childKeys = pendingKeys.filter(re.test.bind(re));
  19813. childKeys.forEach(k => {
  19814. delete pendingAttributes[k];
  19815. });
  19816. if (childKeys.length) {
  19817. pendingAttributes[key] = value;
  19818. } else {
  19819. // set 'a.c': nothing to do
  19820. // set 'a.b.c.d': assign c: { d: {} } to 'a.b'
  19821. const parentKey = find_1(pendingKeys, k => key.indexOf(k) === 0); // 'a.b'
  19822. if (parentKey) {
  19823. setValue(pendingAttributes[parentKey], key.slice(parentKey.length + 1), value);
  19824. } else {
  19825. pendingAttributes[key] = value;
  19826. }
  19827. }
  19828. this._buildCurrentAttributes();
  19829. return this;
  19830. }
  19831. _buildCurrentAttributes() {
  19832. const {
  19833. pendingAttributes
  19834. } = internal(this);
  19835. internal(this).currentAttributes = Object.keys(pendingAttributes).reduce((target, k) => setValue(target, k, pendingAttributes[k]), cloneDeep_1(this._attributes));
  19836. }
  19837. _updateServerAttributes(attributes) {
  19838. Object.keys(attributes).forEach(key => setValue(this._attributes, key, attributes[key]));
  19839. this._buildCurrentAttributes();
  19840. }
  19841. _reset() {
  19842. Object.assign(internal(this), {
  19843. pendingAttributes: {},
  19844. currentAttributes: this._attributes
  19845. });
  19846. }
  19847. /**
  19848. * 保存当前对话的属性至服务器
  19849. * @return {Promise.<this>} self
  19850. */
  19851. async save() {
  19852. this._debug('save');
  19853. const attr = internal(this).pendingAttributes;
  19854. if (isEmpty_1(attr)) {
  19855. this._debug('nothing touched, resolve with self');
  19856. return this;
  19857. }
  19858. this._debug('attr: %O', attr);
  19859. const convMessage = new ConvCommand({
  19860. attr: new JsonObjectMessage({
  19861. data: JSON.stringify(encode(attr))
  19862. })
  19863. });
  19864. const resCommand = await this._send(new GenericCommand({
  19865. op: 'update',
  19866. convMessage
  19867. }));
  19868. this.updatedAt = resCommand.convMessage.udate;
  19869. this._attributes = internal(this).currentAttributes;
  19870. internal(this).pendingAttributes = {};
  19871. return this;
  19872. }
  19873. /**
  19874. * 从服务器更新对话的属性
  19875. * @return {Promise.<this>} self
  19876. */
  19877. async fetch() {
  19878. const query = this._client.getQuery().equalTo('objectId', this.id);
  19879. await query.find();
  19880. return this;
  19881. }
  19882. /**
  19883. * 静音,客户端拒绝收到服务器端的离线推送通知
  19884. * @return {Promise.<this>} self
  19885. */
  19886. async mute() {
  19887. this._debug('mute');
  19888. await this._send(new GenericCommand({
  19889. op: 'mute'
  19890. }));
  19891. if (!this.transient) {
  19892. this.muted = true;
  19893. this.mutedMembers = union(this.mutedMembers, [this._client.id]);
  19894. }
  19895. return this;
  19896. }
  19897. /**
  19898. * 取消静音
  19899. * @return {Promise.<this>} self
  19900. */
  19901. async unmute() {
  19902. this._debug('unmute');
  19903. await this._send(new GenericCommand({
  19904. op: 'unmute'
  19905. }));
  19906. if (!this.transient) {
  19907. this.muted = false;
  19908. this.mutedMembers = difference(this.mutedMembers, [this._client.id]);
  19909. }
  19910. return this;
  19911. }
  19912. async _appendConversationSignature(command, action, clientIds) {
  19913. if (this._client.options.conversationSignatureFactory) {
  19914. const params = [this.id, this._client.id, clientIds.sort(), action];
  19915. const signatureResult = await runSignatureFactory(this._client.options.conversationSignatureFactory, params);
  19916. Object.assign(command.convMessage, keyRemap({
  19917. signature: 's',
  19918. timestamp: 't',
  19919. nonce: 'n'
  19920. }, signatureResult));
  19921. }
  19922. }
  19923. async _appendBlacklistSignature(command, action, clientIds) {
  19924. if (this._client.options.blacklistSignatureFactory) {
  19925. const params = [this.id, this._client.id, clientIds.sort(), action];
  19926. const signatureResult = await runSignatureFactory(this._client.options.blacklistSignatureFactory, params);
  19927. Object.assign(command.blacklistMessage, keyRemap({
  19928. signature: 's',
  19929. timestamp: 't',
  19930. nonce: 'n'
  19931. }, signatureResult));
  19932. }
  19933. }
  19934. /**
  19935. * 增加成员
  19936. * @param {String|String[]} clientIds 新增成员 client id
  19937. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  19938. */
  19939. async add(clientIds) {
  19940. this._debug('add', clientIds);
  19941. if (typeof clientIds === 'string') {
  19942. clientIds = [clientIds]; // eslint-disable-line no-param-reassign
  19943. }
  19944. const command = new GenericCommand({
  19945. op: 'add',
  19946. convMessage: new ConvCommand({
  19947. m: clientIds
  19948. })
  19949. });
  19950. await this._appendConversationSignature(command, 'invite', clientIds);
  19951. const {
  19952. convMessage,
  19953. convMessage: {
  19954. allowedPids
  19955. }
  19956. } = await this._send(command);
  19957. this._addMembers(allowedPids);
  19958. return createPartiallySuccess(convMessage);
  19959. }
  19960. /**
  19961. * 剔除成员
  19962. * @param {String|String[]} clientIds 成员 client id
  19963. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  19964. */
  19965. async remove(clientIds) {
  19966. this._debug('remove', clientIds);
  19967. if (typeof clientIds === 'string') {
  19968. clientIds = [clientIds]; // eslint-disable-line no-param-reassign
  19969. }
  19970. const command = new GenericCommand({
  19971. op: 'remove',
  19972. convMessage: new ConvCommand({
  19973. m: clientIds
  19974. })
  19975. });
  19976. await this._appendConversationSignature(command, 'kick', clientIds);
  19977. const {
  19978. convMessage,
  19979. convMessage: {
  19980. allowedPids
  19981. }
  19982. } = await this._send(command);
  19983. this._removeMembers(allowedPids);
  19984. return createPartiallySuccess(convMessage);
  19985. }
  19986. /**
  19987. * (当前用户)加入该对话
  19988. * @return {Promise.<this>} self
  19989. */
  19990. async join() {
  19991. this._debug('join');
  19992. return this.add(this._client.id).then(({
  19993. failures
  19994. }) => {
  19995. if (failures[0]) throw failures[0];
  19996. return this;
  19997. });
  19998. }
  19999. /**
  20000. * (当前用户)退出该对话
  20001. * @return {Promise.<this>} self
  20002. */
  20003. async quit() {
  20004. this._debug('quit');
  20005. return this.remove(this._client.id).then(({
  20006. failures
  20007. }) => {
  20008. if (failures[0]) throw failures[0];
  20009. return this;
  20010. });
  20011. }
  20012. /**
  20013. * 在该对话中禁言成员
  20014. * @param {String|String[]} clientIds 成员 client id
  20015. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  20016. */
  20017. async muteMembers(clientIds) {
  20018. this._debug('mute', clientIds);
  20019. clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
  20020. const command = new GenericCommand({
  20021. op: OpType.add_shutup,
  20022. convMessage: new ConvCommand({
  20023. m: clientIds
  20024. })
  20025. });
  20026. const {
  20027. convMessage
  20028. } = await this._send(command);
  20029. return createPartiallySuccess(convMessage);
  20030. }
  20031. /**
  20032. * 在该对话中解除成员禁言
  20033. * @param {String|String[]} clientIds 成员 client id
  20034. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  20035. */
  20036. async unmuteMembers(clientIds) {
  20037. this._debug('unmute', clientIds);
  20038. clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
  20039. const command = new GenericCommand({
  20040. op: OpType.remove_shutup,
  20041. convMessage: new ConvCommand({
  20042. m: clientIds
  20043. })
  20044. });
  20045. const {
  20046. convMessage
  20047. } = await this._send(command);
  20048. return createPartiallySuccess(convMessage);
  20049. }
  20050. /**
  20051. * 查询该对话禁言成员列表
  20052. * @param {Object} [options]
  20053. * @param {Number} [options.limit] 返回的成员数量,服务器默认值 10
  20054. * @param {String} [options.next] 从指定 next 开始查询,与 limit 一起使用可以完成翻页。
  20055. * @return {PagedResults.<string>} 查询结果。其中的 cureser 存在表示还有更多结果。
  20056. */
  20057. async queryMutedMembers({
  20058. limit,
  20059. next
  20060. } = {}) {
  20061. this._debug('query muted: limit %O, next: %O', limit, next);
  20062. const command = new GenericCommand({
  20063. op: OpType.query_shutup,
  20064. convMessage: new ConvCommand({
  20065. limit,
  20066. next
  20067. })
  20068. });
  20069. const {
  20070. convMessage: {
  20071. m,
  20072. next: newNext
  20073. }
  20074. } = await this._send(command);
  20075. return {
  20076. results: m,
  20077. next: newNext
  20078. };
  20079. }
  20080. /**
  20081. * 将用户加入该对话黑名单
  20082. * @param {String|String[]} clientIds 成员 client id
  20083. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  20084. */
  20085. async blockMembers(clientIds) {
  20086. this._debug('block', clientIds);
  20087. clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
  20088. const command = new GenericCommand({
  20089. cmd: 'blacklist',
  20090. op: OpType.block,
  20091. blacklistMessage: new BlacklistCommand({
  20092. srcCid: this.id,
  20093. toPids: clientIds
  20094. })
  20095. });
  20096. await this._appendBlacklistSignature(command, 'conversation-block-clients', clientIds);
  20097. const {
  20098. blacklistMessage
  20099. } = await this._send(command);
  20100. return createPartiallySuccess(blacklistMessage);
  20101. }
  20102. /**
  20103. * 将用户移出该对话黑名单
  20104. * @param {String|String[]} clientIds 成员 client id
  20105. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  20106. */
  20107. async unblockMembers(clientIds) {
  20108. this._debug('unblock', clientIds);
  20109. clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
  20110. const command = new GenericCommand({
  20111. cmd: 'blacklist',
  20112. op: OpType.unblock,
  20113. blacklistMessage: new BlacklistCommand({
  20114. srcCid: this.id,
  20115. toPids: clientIds
  20116. })
  20117. });
  20118. await this._appendBlacklistSignature(command, 'conversation-unblock-clients', clientIds);
  20119. const {
  20120. blacklistMessage
  20121. } = await this._send(command);
  20122. return createPartiallySuccess(blacklistMessage);
  20123. }
  20124. /**
  20125. * 查询该对话黑名单
  20126. * @param {Object} [options]
  20127. * @param {Number} [options.limit] 返回的成员数量,服务器默认值 10
  20128. * @param {String} [options.next] 从指定 next 开始查询,与 limit 一起使用可以完成翻页
  20129. * @return {PagedResults.<string>} 查询结果。其中的 cureser 存在表示还有更多结果。
  20130. */
  20131. async queryBlockedMembers({
  20132. limit,
  20133. next
  20134. } = {}) {
  20135. this._debug('query blocked: limit %O, next: %O', limit, next);
  20136. const command = new GenericCommand({
  20137. cmd: 'blacklist',
  20138. op: OpType.query,
  20139. blacklistMessage: new BlacklistCommand({
  20140. srcCid: this.id,
  20141. limit,
  20142. next
  20143. })
  20144. });
  20145. const {
  20146. blacklistMessage: {
  20147. blockedPids,
  20148. next: newNext
  20149. }
  20150. } = await this._send(command);
  20151. return {
  20152. results: blockedPids,
  20153. next: newNext
  20154. };
  20155. }
  20156. toFullJSON() {
  20157. const {
  20158. creator,
  20159. system,
  20160. transient,
  20161. createdAt,
  20162. updatedAt,
  20163. _attributes
  20164. } = this;
  20165. return { ...super.toFullJSON(),
  20166. creator,
  20167. system,
  20168. transient,
  20169. createdAt: getTime(createdAt),
  20170. updatedAt: getTime(updatedAt),
  20171. ..._attributes
  20172. };
  20173. }
  20174. toJSON() {
  20175. const {
  20176. creator,
  20177. system,
  20178. transient,
  20179. muted,
  20180. mutedMembers,
  20181. createdAt,
  20182. updatedAt,
  20183. _attributes
  20184. } = this;
  20185. return { ...super.toJSON(),
  20186. creator,
  20187. system,
  20188. transient,
  20189. muted,
  20190. mutedMembers,
  20191. createdAt,
  20192. updatedAt,
  20193. ..._attributes
  20194. };
  20195. }
  20196. }
  20197. /**
  20198. * 对话成员角色枚举
  20199. * @enum {String}
  20200. * @since 4.0.0
  20201. * @memberof module:leancloud-realtime
  20202. */
  20203. const ConversationMemberRole = {
  20204. /** 所有者 */
  20205. OWNER: 'Owner',
  20206. /** 管理员 */
  20207. MANAGER: 'Manager',
  20208. /** 成员 */
  20209. MEMBER: 'Member'
  20210. };
  20211. Object.freeze(ConversationMemberRole);
  20212. class ConversationMemberInfo {
  20213. /**
  20214. * 对话成员属性,保存了成员与某个对话相关的属性,对应 _ConversationMemberInfo 表
  20215. * @since 4.0.0
  20216. */
  20217. constructor({
  20218. conversation,
  20219. memberId,
  20220. role
  20221. }) {
  20222. if (!conversation) throw new Error('conversation requried');
  20223. if (!memberId) throw new Error('memberId requried');
  20224. Object.assign(internal(this), {
  20225. conversation,
  20226. memberId,
  20227. role
  20228. });
  20229. }
  20230. /**
  20231. * 对话 Id
  20232. * @type {String}
  20233. * @readonly
  20234. */
  20235. get conversationId() {
  20236. return internal(this).conversation.id;
  20237. }
  20238. /**
  20239. * 成员 Id
  20240. * @type {String}
  20241. * @readonly
  20242. */
  20243. get memberId() {
  20244. return internal(this).memberId;
  20245. }
  20246. /**
  20247. * 角色
  20248. * @type {module:leancloud-realtime.ConversationMemberRole | String}
  20249. * @readonly
  20250. */
  20251. get role() {
  20252. if (this.isOwner) return ConversationMemberRole.OWNER;
  20253. return internal(this).role;
  20254. }
  20255. /**
  20256. * 是否是管理员
  20257. * @type {Boolean}
  20258. * @readonly
  20259. */
  20260. get isOwner() {
  20261. return this.memberId === internal(this).conversation.creator;
  20262. }
  20263. toJSON() {
  20264. const {
  20265. conversationId,
  20266. memberId,
  20267. role,
  20268. isOwner
  20269. } = this;
  20270. return {
  20271. conversationId,
  20272. memberId,
  20273. role,
  20274. isOwner
  20275. };
  20276. }
  20277. }
  20278. /**
  20279. * 普通对话
  20280. *
  20281. * 无法直接实例化,请使用 {@link IMClient#createConversation} 创建新的普通对话。
  20282. * @extends PersistentConversation
  20283. * @public
  20284. */
  20285. class Conversation extends PersistentConversation {
  20286. _addMembers(members) {
  20287. super._addMembers(members);
  20288. this.members = union(this.members, members);
  20289. const {
  20290. memberInfoMap
  20291. } = internal(this);
  20292. if (!memberInfoMap) return;
  20293. members.forEach(memberId => {
  20294. memberInfoMap[memberId] = memberInfoMap[memberId] || new ConversationMemberInfo({
  20295. conversation: this,
  20296. memberId,
  20297. role: ConversationMemberRole.MEMBER
  20298. });
  20299. });
  20300. }
  20301. _removeMembers(members) {
  20302. super._removeMembers(members);
  20303. this.members = difference(this.members, members);
  20304. const {
  20305. memberInfoMap
  20306. } = internal(this);
  20307. if (!memberInfoMap) return;
  20308. members.forEach(memberId => {
  20309. delete memberInfoMap[memberId];
  20310. });
  20311. }
  20312. async _fetchAllMemberInfo() {
  20313. const response = await this._client._requestWithSessionToken({
  20314. method: 'GET',
  20315. path: '/classes/_ConversationMemberInfo',
  20316. query: {
  20317. where: {
  20318. cid: this.id
  20319. }
  20320. }
  20321. });
  20322. const memberInfos = response.results.map(info => new ConversationMemberInfo({
  20323. conversation: this,
  20324. memberId: info.clientId,
  20325. role: info.role
  20326. }));
  20327. const memberInfoMap = {};
  20328. memberInfos.forEach(memberInfo => {
  20329. memberInfoMap[memberInfo.memberId] = memberInfo;
  20330. });
  20331. this.members.forEach(memberId => {
  20332. memberInfoMap[memberId] = memberInfoMap[memberId] || new ConversationMemberInfo({
  20333. conversation: this,
  20334. memberId,
  20335. role: ConversationMemberRole.MEMBER
  20336. });
  20337. });
  20338. internal(this).memberInfoMap = memberInfoMap;
  20339. return memberInfoMap;
  20340. }
  20341. /**
  20342. * 获取所有成员的对话属性
  20343. * @since 4.0.0
  20344. * @return {Promise.<ConversationMemberInfo[]>} 所有成员的对话属性列表
  20345. */
  20346. async getAllMemberInfo({
  20347. noCache = false
  20348. } = {}) {
  20349. let {
  20350. memberInfoMap
  20351. } = internal(this);
  20352. if (!memberInfoMap || noCache) {
  20353. memberInfoMap = await this._fetchAllMemberInfo();
  20354. }
  20355. return this.members.map(memberId => memberInfoMap[memberId]);
  20356. }
  20357. /**
  20358. * 获取指定成员的对话属性
  20359. * @since 4.0.0
  20360. * @param {String} memberId 成员 Id
  20361. * @return {Promise.<ConversationMemberInfo>} 指定成员的对话属性
  20362. */
  20363. async getMemberInfo(memberId) {
  20364. if (this.members.indexOf(memberId) === -1) throw new Error(`${memberId} is not the mumber of conversation[${this.id}]`);
  20365. const {
  20366. memberInfoMap
  20367. } = internal(this);
  20368. if (!(memberInfoMap && memberInfoMap[memberId])) await this.getAllMemberInfo();
  20369. return internal(this).memberInfoMap[memberId];
  20370. }
  20371. /**
  20372. * 更新指定用户的角色
  20373. * @since 4.0.0
  20374. * @param {String} memberId 成员 Id
  20375. * @param {module:leancloud-realtime.ConversationMemberRole | String} role 角色
  20376. * @return {Promise.<this>} self
  20377. */
  20378. async updateMemberRole(memberId, role) {
  20379. this._debug('update member role');
  20380. if (role === ConversationMemberRole.OWNER) throw createError({
  20381. code: ErrorCode.OWNER_PROMOTION_NOT_ALLOWED
  20382. });
  20383. await this._send(new GenericCommand({
  20384. op: OpType.member_info_update,
  20385. convMessage: new ConvCommand({
  20386. targetClientId: memberId,
  20387. info: new ConvMemberInfo({
  20388. pid: memberId,
  20389. role
  20390. })
  20391. })
  20392. }));
  20393. const {
  20394. memberInfos
  20395. } = internal(this);
  20396. if (memberInfos && memberInfos[memberId]) {
  20397. internal(memberInfos[memberId]).role = role;
  20398. }
  20399. return this;
  20400. }
  20401. }
  20402. /**
  20403. * 聊天室。
  20404. *
  20405. * 无法直接实例化,请使用 {@link IMClient#createChatRoom} 创建新的聊天室。
  20406. * @since 4.0.0
  20407. * @extends PersistentConversation
  20408. * @public
  20409. */
  20410. class ChatRoom extends PersistentConversation {}
  20411. /**
  20412. * 服务号。
  20413. *
  20414. * 服务号不支持在客户端创建。
  20415. * @since 4.0.0
  20416. * @extends PersistentConversation
  20417. * @public
  20418. */
  20419. class ServiceConversation extends PersistentConversation {
  20420. /**
  20421. * 订阅该服务号
  20422. * @return {Promise.<this>} self
  20423. */
  20424. async subscribe() {
  20425. return this.join();
  20426. }
  20427. /**
  20428. * 退订该服务号
  20429. * @return {Promise.<this>} self
  20430. */
  20431. async unsubscribe() {
  20432. return this.quit();
  20433. }
  20434. }
  20435. const transformNotFoundError = error => error.code === ErrorCode.CONVERSATION_NOT_FOUND ? createError({
  20436. code: ErrorCode.TEMPORARY_CONVERSATION_EXPIRED
  20437. }) : error;
  20438. /**
  20439. * 临时对话
  20440. * @since 4.0.0
  20441. * @extends ConversationBase
  20442. * @public
  20443. */
  20444. class TemporaryConversation extends ConversationBase {
  20445. /**
  20446. * 无法直接实例化,请使用 {@link IMClient#createTemporaryConversation} 创建新的临时对话。
  20447. */
  20448. constructor(data, {
  20449. expiredAt
  20450. }, client) {
  20451. super({ ...data,
  20452. expiredAt
  20453. }, client);
  20454. }
  20455. /**
  20456. * 对话失效时间
  20457. * @type {Date}
  20458. */
  20459. set expiredAt(value) {
  20460. this._expiredAt = decodeDate(value);
  20461. }
  20462. get expiredAt() {
  20463. return this._expiredAt;
  20464. }
  20465. /**
  20466. * 对话是否已失效
  20467. * @type {Boolean}
  20468. */
  20469. get expired() {
  20470. return this.expiredAt < new Date();
  20471. }
  20472. async _send(...args) {
  20473. if (this.expired) throw createError({
  20474. code: ErrorCode.TEMPORARY_CONVERSATION_EXPIRED
  20475. });
  20476. try {
  20477. return await super._send(...args);
  20478. } catch (error) {
  20479. throw transformNotFoundError(error);
  20480. }
  20481. }
  20482. async send(...args) {
  20483. try {
  20484. return await super.send(...args);
  20485. } catch (error) {
  20486. throw transformNotFoundError(error);
  20487. }
  20488. }
  20489. toFullJSON() {
  20490. const {
  20491. expiredAt
  20492. } = this;
  20493. return { ...super.toFullJSON(),
  20494. expiredAt: getTime(expiredAt)
  20495. };
  20496. }
  20497. toJSON() {
  20498. const {
  20499. expiredAt,
  20500. expired
  20501. } = this;
  20502. return { ...super.toJSON(),
  20503. expiredAt,
  20504. expired
  20505. };
  20506. }
  20507. }
  20508. const debug$9 = browser('LC:ConversationQuery');
  20509. class ConversationQuery {
  20510. static _encode(value) {
  20511. if (value instanceof Date) {
  20512. return {
  20513. __type: 'Date',
  20514. iso: value.toJSON()
  20515. };
  20516. }
  20517. if (value instanceof RegExp) {
  20518. return value.source;
  20519. }
  20520. return value;
  20521. }
  20522. static _quote(s) {
  20523. return `\\Q${s.replace('\\E', '\\E\\\\E\\Q')}\\E`;
  20524. }
  20525. static _calculateFlag(options) {
  20526. return ['withLastMessagesRefreshed', 'compact'].reduce( // eslint-disable-next-line no-bitwise
  20527. (prev, key) => (prev << 1) + Boolean(options[key]), 0);
  20528. }
  20529. /**
  20530. * 构造一个用 AND 连接所有查询的 ConversationQuery
  20531. * @param {...ConversationQuery} queries
  20532. * @return {ConversationQuery}
  20533. */
  20534. static and(...queries) {
  20535. if (queries.length < 2) {
  20536. throw new Error('The queries must contain at least two elements');
  20537. }
  20538. if (!queries.every(q => q instanceof ConversationQuery)) {
  20539. throw new Error('The element of queries must be an instance of ConversationQuery');
  20540. }
  20541. const combined = new ConversationQuery(queries[0]._client);
  20542. combined._where.$and = queries.map(q => q._where);
  20543. return combined;
  20544. }
  20545. /**
  20546. * 构造一个用 OR 连接所有查询的 ConversationQuery
  20547. * @param {...ConversationQuery} queries
  20548. * @return {ConversationQuery}
  20549. */
  20550. static or(...queries) {
  20551. const combined = ConversationQuery.and(...queries);
  20552. combined._where.$or = combined._where.$and;
  20553. delete combined._where.$and;
  20554. return combined;
  20555. }
  20556. /**
  20557. * Create a ConversationQuery
  20558. * @param {IMClient} client
  20559. */
  20560. constructor(client) {
  20561. this._client = client;
  20562. this._where = {};
  20563. this._extraOptions = {};
  20564. }
  20565. _addCondition(key, condition, value) {
  20566. // Check if we already have a condition
  20567. if (!this._where[key]) {
  20568. this._where[key] = {};
  20569. }
  20570. this._where[key][condition] = this.constructor._encode(value);
  20571. return this;
  20572. }
  20573. toJSON() {
  20574. const json = {
  20575. where: this._where,
  20576. flag: this.constructor._calculateFlag(this._extraOptions)
  20577. };
  20578. if (typeof this._skip !== 'undefined') json.skip = this._skip;
  20579. if (typeof this._limit !== 'undefined') json.limit = this._limit;
  20580. if (typeof this._order !== 'undefined') json.sort = this._order;
  20581. debug$9(json);
  20582. return json;
  20583. }
  20584. /**
  20585. * 增加查询条件,指定聊天室的组员包含某些成员即可返回
  20586. * @param {string[]} peerIds - 成员 ID 列表
  20587. * @return {ConversationQuery} self
  20588. */
  20589. containsMembers(peerIds) {
  20590. return this.containsAll('m', peerIds);
  20591. }
  20592. /**
  20593. * 增加查询条件,指定聊天室的组员条件满足条件的才返回
  20594. *
  20595. * @param {string[]} - 成员 ID 列表
  20596. * @param {Boolean} includeSelf - 是否包含自己
  20597. * @return {ConversationQuery} self
  20598. */
  20599. withMembers(peerIds, includeSelf) {
  20600. const peerIdsSet = new Set(peerIds);
  20601. if (includeSelf) {
  20602. peerIdsSet.add(this._client.id);
  20603. }
  20604. this.sizeEqualTo('m', peerIdsSet.size);
  20605. return this.containsMembers(Array.from(peerIdsSet));
  20606. }
  20607. /**
  20608. * 增加查询条件,当 conversation 的属性中对应的字段满足等于条件时即可返回
  20609. *
  20610. * @param {string} key
  20611. * @param value
  20612. * @return {ConversationQuery} self
  20613. */
  20614. equalTo(key, value) {
  20615. this._where[key] = this.constructor._encode(value);
  20616. return this;
  20617. }
  20618. /**
  20619. * 增加查询条件,当 conversation 的属性中对应的字段满足小于条件时即可返回
  20620. * @param {string} key
  20621. * @param value
  20622. * @return {ConversationQuery} self
  20623. */
  20624. lessThan(key, value) {
  20625. return this._addCondition(key, '$lt', value);
  20626. }
  20627. /**
  20628. * 增加查询条件,当 conversation 的属性中对应的字段满足小于等于条件时即可返回
  20629. * @param {string} key
  20630. * @param value
  20631. * @return {ConversationQuery} self
  20632. */
  20633. lessThanOrEqualTo(key, value) {
  20634. return this._addCondition(key, '$lte', value);
  20635. }
  20636. /**
  20637. * 增加查询条件,当 conversation 的属性中对应的字段满足大于条件时即可返回
  20638. *
  20639. * @param {string} key
  20640. * @param value
  20641. * @return {ConversationQuery} self
  20642. */
  20643. greaterThan(key, value) {
  20644. return this._addCondition(key, '$gt', value);
  20645. }
  20646. /**
  20647. * 增加查询条件,当 conversation 的属性中对应的字段满足大于等于条件时即可返回
  20648. *
  20649. * @param {string} key
  20650. * @param value
  20651. * @return {ConversationQuery} self
  20652. */
  20653. greaterThanOrEqualTo(key, value) {
  20654. return this._addCondition(key, '$gte', value);
  20655. }
  20656. /**
  20657. * 增加查询条件,当 conversation 的属性中对应的字段满足不等于条件时即可返回
  20658. *
  20659. * @param {string} key
  20660. * @param value
  20661. * @return {ConversationQuery} self
  20662. */
  20663. notEqualTo(key, value) {
  20664. return this._addCondition(key, '$ne', value);
  20665. }
  20666. /**
  20667. * 增加查询条件,当 conversation 存在指定的字段时即可返回
  20668. *
  20669. * @since 3.5.0
  20670. * @param {string} key
  20671. * @return {ConversationQuery} self
  20672. */
  20673. exists(key) {
  20674. return this._addCondition(key, '$exists', true);
  20675. }
  20676. /**
  20677. * 增加查询条件,当 conversation 不存在指定的字段时即可返回
  20678. *
  20679. * @since 3.5.0
  20680. * @param {string} key
  20681. * @return {ConversationQuery} self
  20682. */
  20683. doesNotExist(key) {
  20684. return this._addCondition(key, '$exists', false);
  20685. }
  20686. /**
  20687. * 增加查询条件,当 conversation 的属性中对应的字段对应的值包含在指定值中时即可返回
  20688. *
  20689. * @param {string} key
  20690. * @param values
  20691. * @return {ConversationQuery} self
  20692. */
  20693. containedIn(key, values) {
  20694. return this._addCondition(key, '$in', values);
  20695. }
  20696. /**
  20697. * 增加查询条件,当 conversation 的属性中对应的字段对应的值不包含在指定值中时即可返回
  20698. *
  20699. * @param {string} key
  20700. * @param values
  20701. * @return {ConversationQuery} self
  20702. */
  20703. notContainsIn(key, values) {
  20704. return this._addCondition(key, '$nin', values);
  20705. }
  20706. /**
  20707. * 增加查询条件,当conversation的属性中对应的字段中的元素包含所有的值才可返回
  20708. *
  20709. * @param {string} key
  20710. * @param values
  20711. * @return {ConversationQuery} self
  20712. */
  20713. containsAll(key, values) {
  20714. return this._addCondition(key, '$all', values);
  20715. }
  20716. /**
  20717. * 增加查询条件,当 conversation 的属性中对应的字段对应的值包含此字符串即可返回
  20718. *
  20719. * @param {string} key
  20720. * @param {string} subString
  20721. * @return {ConversationQuery} self
  20722. */
  20723. contains(key, subString) {
  20724. return this._addCondition(key, '$regex', ConversationQuery._quote(subString));
  20725. }
  20726. /**
  20727. * 增加查询条件,当 conversation 的属性中对应的字段对应的值以此字符串起始即可返回
  20728. *
  20729. * @param {string} key
  20730. * @param {string} prefix
  20731. * @return {ConversationQuery} self
  20732. */
  20733. startsWith(key, prefix) {
  20734. return this._addCondition(key, '$regex', `^${ConversationQuery._quote(prefix)}`);
  20735. }
  20736. /**
  20737. * 增加查询条件,当 conversation 的属性中对应的字段对应的值以此字符串结束即可返回
  20738. *
  20739. * @param {string} key
  20740. * @param {string} suffix
  20741. * @return {ConversationQuery} self
  20742. */
  20743. endsWith(key, suffix) {
  20744. return this._addCondition(key, '$regex', `${ConversationQuery._quote(suffix)}$`);
  20745. }
  20746. /**
  20747. * 增加查询条件,当 conversation 的属性中对应的字段对应的值满足提供的正则表达式即可返回
  20748. *
  20749. * @param {string} key
  20750. * @param {RegExp} regex
  20751. * @return {ConversationQuery} self
  20752. */
  20753. matches(key, regex) {
  20754. this._addCondition(key, '$regex', regex); // Javascript regex options support mig as inline options but store them
  20755. // as properties of the object. We support mi & should migrate them to
  20756. // modifiers
  20757. let _modifiers = '';
  20758. if (regex.ignoreCase) {
  20759. _modifiers += 'i';
  20760. }
  20761. if (regex.multiline) {
  20762. _modifiers += 'm';
  20763. }
  20764. if (_modifiers && _modifiers.length) {
  20765. this._addCondition(key, '$options', _modifiers);
  20766. }
  20767. return this;
  20768. }
  20769. /**
  20770. * 添加查询约束条件,查找 key 类型是数组,该数组的长度匹配提供的数值
  20771. *
  20772. * @param {string} key
  20773. * @param {Number} length
  20774. * @return {ConversationQuery} self
  20775. */
  20776. sizeEqualTo(key, length) {
  20777. return this._addCondition(key, '$size', length);
  20778. }
  20779. /**
  20780. * 设置返回集合的大小上限
  20781. *
  20782. * @param {Number} limit - 上限
  20783. * @return {ConversationQuery} self
  20784. */
  20785. limit(limit) {
  20786. this._limit = limit;
  20787. return this;
  20788. }
  20789. /**
  20790. * 设置返回集合的起始位置,一般用于分页
  20791. *
  20792. * @param {Number} skip - 起始位置跳过几个对象
  20793. * @return {ConversationQuery} self
  20794. */
  20795. skip(skip) {
  20796. this._skip = skip;
  20797. return this;
  20798. }
  20799. /**
  20800. * 设置返回集合按照指定key进行增序排列
  20801. *
  20802. * @param {string} key
  20803. * @return {ConversationQuery} self
  20804. */
  20805. ascending(key) {
  20806. this._order = key;
  20807. return this;
  20808. }
  20809. /**
  20810. * 设置返回集合按照指定key进行增序排列,如果已设置其他排序,原排序的优先级较高
  20811. *
  20812. * @param {string} key
  20813. * @return {ConversationQuery} self
  20814. */
  20815. addAscending(key) {
  20816. if (this._order) {
  20817. this._order += `,${key}`;
  20818. } else {
  20819. this._order = key;
  20820. }
  20821. return this;
  20822. }
  20823. /**
  20824. * 设置返回集合按照指定 key 进行降序排列
  20825. *
  20826. * @param {string} key
  20827. * @return {ConversationQuery} self
  20828. */
  20829. descending(key) {
  20830. this._order = `-${key}`;
  20831. return this;
  20832. }
  20833. /**
  20834. * 设置返回集合按照指定 key 进行降序排列,如果已设置其他排序,原排序的优先级较高
  20835. *
  20836. * @param {string} key
  20837. * @return {ConversationQuery} self
  20838. */
  20839. addDescending(key) {
  20840. if (this._order) {
  20841. this._order += `,-${key}`;
  20842. } else {
  20843. this._order = `-${key}`;
  20844. }
  20845. return this;
  20846. }
  20847. /**
  20848. * 设置返回的 conversations 刷新最后一条消息
  20849. * @param {Boolean} [enabled=true]
  20850. * @return {ConversationQuery} self
  20851. */
  20852. withLastMessagesRefreshed(enabled = true) {
  20853. this._extraOptions.withLastMessagesRefreshed = enabled;
  20854. return this;
  20855. }
  20856. /**
  20857. * 设置返回的 conversations 为精简模式,即不含成员列表
  20858. * @param {Boolean} [enabled=true]
  20859. * @return {ConversationQuery} self
  20860. */
  20861. compact(enabled = true) {
  20862. this._extraOptions.compact = enabled;
  20863. return this;
  20864. }
  20865. /**
  20866. * 执行查询
  20867. * @return {Promise.<ConversationBase[]>}
  20868. */
  20869. async find() {
  20870. return this._client._executeQuery(this);
  20871. }
  20872. /**
  20873. * 返回符合条件的第一个结果
  20874. * @return {Promise.<ConversationBase>}
  20875. */
  20876. async first() {
  20877. return (await this.limit(1).find())[0];
  20878. }
  20879. }
  20880. const debug$a = browser('LC:SessionManager');
  20881. class SessionManager {
  20882. constructor({
  20883. refresh,
  20884. onBeforeGetSessionToken
  20885. } = {}) {
  20886. this.refresh = refresh;
  20887. this._onBeforeGetSessionToken = onBeforeGetSessionToken;
  20888. this.setSessionToken(null, 0);
  20889. }
  20890. setSessionToken(token, ttl) {
  20891. debug$a('set session token', token, ttl);
  20892. const sessionToken = new Expirable(token, ttl * 1000);
  20893. this._sessionToken = sessionToken;
  20894. delete this._pendingSessionTokenPromise;
  20895. return sessionToken;
  20896. }
  20897. async setSessionTokenAsync(promise) {
  20898. const currentSessionToken = this._sessionToken;
  20899. this._pendingSessionTokenPromise = promise.catch(error => {
  20900. // revert, otherwise the following getSessionToken calls
  20901. // will all be rejected
  20902. this._sessionToken = currentSessionToken;
  20903. throw error;
  20904. });
  20905. return this.setSessionToken(...(await this._pendingSessionTokenPromise));
  20906. }
  20907. async getSessionToken({
  20908. autoRefresh = true
  20909. } = {}) {
  20910. debug$a('get session token');
  20911. if (this._onBeforeGetSessionToken) {
  20912. this._onBeforeGetSessionToken(this);
  20913. }
  20914. const {
  20915. value,
  20916. originalValue
  20917. } = this._sessionToken || (await this._pendingSessionTokenPromise);
  20918. if (value === Expirable.EXPIRED && autoRefresh && this.refresh) {
  20919. debug$a('refresh expired session token');
  20920. const {
  20921. value: newValue
  20922. } = await this.setSessionTokenAsync(this.refresh(this, originalValue));
  20923. debug$a('session token', newValue);
  20924. return newValue;
  20925. }
  20926. debug$a('session token', value);
  20927. return value;
  20928. }
  20929. revoke() {
  20930. if (this._sessionToken) this._sessionToken.expiredAt = -1;
  20931. }
  20932. }
  20933. var _dec$2, _dec2, _class$3;
  20934. const debug$b = browser('LC:IMClient');
  20935. const {
  20936. INVITED: INVITED$1,
  20937. KICKED: KICKED$1,
  20938. MEMBERS_JOINED: MEMBERS_JOINED$1,
  20939. MEMBERS_LEFT: MEMBERS_LEFT$1,
  20940. MEMBER_INFO_UPDATED: MEMBER_INFO_UPDATED$1,
  20941. BLOCKED: BLOCKED$1,
  20942. UNBLOCKED: UNBLOCKED$1,
  20943. MEMBERS_BLOCKED: MEMBERS_BLOCKED$1,
  20944. MEMBERS_UNBLOCKED: MEMBERS_UNBLOCKED$1,
  20945. MUTED: MUTED$1,
  20946. UNMUTED: UNMUTED$1,
  20947. MEMBERS_MUTED: MEMBERS_MUTED$1,
  20948. MEMBERS_UNMUTED: MEMBERS_UNMUTED$1,
  20949. MESSAGE: MESSAGE$2,
  20950. UNREAD_MESSAGES_COUNT_UPDATE: UNREAD_MESSAGES_COUNT_UPDATE$1,
  20951. CLOSE: CLOSE$1,
  20952. CONFLICT: CONFLICT$1,
  20953. UNHANDLED_MESSAGE: UNHANDLED_MESSAGE$1,
  20954. CONVERSATION_INFO_UPDATED: CONVERSATION_INFO_UPDATED$1,
  20955. MESSAGE_RECALL: MESSAGE_RECALL$1,
  20956. MESSAGE_UPDATE: MESSAGE_UPDATE$1,
  20957. INFO_UPDATED: INFO_UPDATED$1
  20958. } = IMEvent;
  20959. const isTemporaryConversatrionId = id => /^_tmp:/.test(id);
  20960. /**
  20961. * 1 patch-msg
  20962. * 1 temp-conv-msg
  20963. * 0 auto-bind-deviceid-and-installation
  20964. * 1 transient-msg-ack
  20965. * 1 keep-notification
  20966. * 1 partial-failed-msg
  20967. * 0 group-chat-rcp
  20968. * 1 omit-peer-id
  20969. * @ignore
  20970. */
  20971. const configBitmap = 0b10111011;
  20972. let IMClient = (_dec$2 = throttle(1000), _dec2 = throttle(1000), (_class$3 = class IMClient extends eventemitter3 {
  20973. /**
  20974. * 无法直接实例化,请使用 {@link Realtime#createIMClient} 创建新的 IMClient。
  20975. *
  20976. * @extends EventEmitter
  20977. */
  20978. constructor(id, options = {}, props) {
  20979. if (!(id === undefined || typeof id === 'string')) {
  20980. throw new TypeError(`Client id [${id}] is not a String`);
  20981. }
  20982. super();
  20983. Object.assign(this, {
  20984. /**
  20985. * @var id {String} 客户端 id
  20986. * @memberof IMClient#
  20987. */
  20988. id,
  20989. options
  20990. }, props);
  20991. if (!this._messageParser) {
  20992. throw new Error('IMClient must be initialized with a MessageParser');
  20993. }
  20994. this._conversationCache = new Cache(`client:${this.id}`);
  20995. this._ackMessageBuffer = {};
  20996. internal(this).lastPatchTime = Date.now();
  20997. internal(this).lastNotificationTime = undefined;
  20998. internal(this)._eventemitter = new eventemitter3();
  20999. if (debug$b.enabled) {
  21000. values_1(IMEvent).forEach(event => this.on(event, (...payload) => this._debug(`${event} event emitted. %o`, payload)));
  21001. } // onIMClientCreate hook
  21002. applyDecorators(this._plugins.onIMClientCreate, this);
  21003. }
  21004. _debug(...params) {
  21005. debug$b(...params, `[${this.id}]`);
  21006. }
  21007. /**
  21008. * @override
  21009. * @private
  21010. */
  21011. async _dispatchCommand(command) {
  21012. this._debug(trim(command), 'received');
  21013. if (command.serverTs && command.notificationType === 1) {
  21014. internal(this).lastNotificationTime = getTime(decodeDate(command.serverTs));
  21015. }
  21016. switch (command.cmd) {
  21017. case CommandType.conv:
  21018. return this._dispatchConvMessage(command);
  21019. case CommandType.direct:
  21020. return this._dispatchDirectMessage(command);
  21021. case CommandType.session:
  21022. return this._dispatchSessionMessage(command);
  21023. case CommandType.unread:
  21024. return this._dispatchUnreadMessage(command);
  21025. case CommandType.rcp:
  21026. return this._dispatchRcpMessage(command);
  21027. case CommandType.patch:
  21028. return this._dispatchPatchMessage(command);
  21029. default:
  21030. return this.emit(UNHANDLED_MESSAGE$1, command);
  21031. }
  21032. }
  21033. async _dispatchSessionMessage(message) {
  21034. const {
  21035. sessionMessage: {
  21036. code,
  21037. reason
  21038. }
  21039. } = message;
  21040. switch (message.op) {
  21041. case OpType.closed:
  21042. {
  21043. internal(this)._eventemitter.emit('close');
  21044. if (code === ErrorCode.SESSION_CONFLICT) {
  21045. /**
  21046. * 用户在其他客户端登录,当前客户端被服务端强行下线。详见文档「单点登录」章节。
  21047. * @event IMClient#CONFLICT
  21048. * @param {Object} payload
  21049. * @param {string} payload.reason 原因
  21050. */
  21051. return this.emit(CONFLICT$1, {
  21052. reason
  21053. });
  21054. }
  21055. /**
  21056. * 当前客户端被服务端强行下线
  21057. * @event IMClient#CLOSE
  21058. * @param {Object} payload
  21059. * @param {Number} payload.code 错误码
  21060. * @param {String} payload.reason 原因
  21061. */
  21062. return this.emit(CLOSE$1, {
  21063. code,
  21064. reason
  21065. });
  21066. }
  21067. default:
  21068. this.emit(UNHANDLED_MESSAGE$1, message);
  21069. throw new Error('Unrecognized session command');
  21070. }
  21071. }
  21072. _dispatchUnreadMessage({
  21073. unreadMessage: {
  21074. convs,
  21075. notifTime
  21076. }
  21077. }) {
  21078. internal(this).lastUnreadNotifTime = notifTime; // ensure all converstions are cached
  21079. return this.getConversations(convs.map(conv => conv.cid)).then(() => // update conversations data
  21080. Promise.all(convs.map(({
  21081. cid,
  21082. unread,
  21083. mid,
  21084. timestamp: ts,
  21085. from,
  21086. data,
  21087. binaryMsg,
  21088. patchTimestamp,
  21089. mentioned
  21090. }) => {
  21091. const conversation = this._conversationCache.get(cid); // deleted conversation
  21092. if (!conversation) return null;
  21093. let timestamp;
  21094. if (ts) {
  21095. timestamp = decodeDate(ts);
  21096. conversation.lastMessageAt = timestamp; // eslint-disable-line no-param-reassign
  21097. }
  21098. return (mid ? this._messageParser.parse(binaryMsg || data).then(message => {
  21099. const messageProps = {
  21100. id: mid,
  21101. cid,
  21102. timestamp,
  21103. updatedAt: patchTimestamp,
  21104. from
  21105. };
  21106. Object.assign(message, messageProps);
  21107. conversation.lastMessage = message; // eslint-disable-line no-param-reassign
  21108. }) : Promise.resolve()).then(() => {
  21109. conversation._setUnreadMessagesMentioned(mentioned);
  21110. const countNotUpdated = unread === internal(conversation).unreadMessagesCount;
  21111. if (countNotUpdated) return null; // to be filtered
  21112. // manipulate internal property directly to skip unreadmessagescountupdate event
  21113. internal(conversation).unreadMessagesCount = unread;
  21114. return conversation;
  21115. }); // filter conversations without unread count update
  21116. })).then(conversations => conversations.filter(conversation => conversation))).then(conversations => {
  21117. if (conversations.length) {
  21118. /**
  21119. * 未读消息数目更新
  21120. * @event IMClient#UNREAD_MESSAGES_COUNT_UPDATE
  21121. * @since 3.4.0
  21122. * @param {Conversation[]} conversations 未读消息数目有更新的对话列表
  21123. */
  21124. this.emit(UNREAD_MESSAGES_COUNT_UPDATE$1, conversations);
  21125. }
  21126. });
  21127. }
  21128. async _dispatchRcpMessage(message) {
  21129. const {
  21130. rcpMessage,
  21131. rcpMessage: {
  21132. read
  21133. }
  21134. } = message;
  21135. const conversationId = rcpMessage.cid;
  21136. const messageId = rcpMessage.id;
  21137. const timestamp = decodeDate(rcpMessage.t);
  21138. const conversation = this._conversationCache.get(conversationId); // conversation not cached means the client does not send the message
  21139. // during this session
  21140. if (!conversation) return;
  21141. conversation._handleReceipt({
  21142. messageId,
  21143. timestamp,
  21144. read
  21145. });
  21146. }
  21147. _dispatchPatchMessage({
  21148. patchMessage: {
  21149. patches
  21150. }
  21151. }) {
  21152. // ensure all converstions are cached
  21153. return this.getConversations(patches.map(patch => patch.cid)).then(() => Promise.all(patches.map(({
  21154. cid,
  21155. mid,
  21156. timestamp,
  21157. recall,
  21158. data,
  21159. patchTimestamp,
  21160. from,
  21161. binaryMsg,
  21162. mentionAll,
  21163. mentionPids,
  21164. patchCode,
  21165. patchReason
  21166. }) => {
  21167. const conversation = this._conversationCache.get(cid); // deleted conversation
  21168. if (!conversation) return null;
  21169. return this._messageParser.parse(binaryMsg || data).then(message => {
  21170. const patchTime = getTime(decodeDate(patchTimestamp));
  21171. const messageProps = {
  21172. id: mid,
  21173. cid,
  21174. timestamp,
  21175. updatedAt: patchTime,
  21176. from,
  21177. mentionList: mentionPids,
  21178. mentionedAll: mentionAll
  21179. };
  21180. Object.assign(message, messageProps);
  21181. message._setStatus(MessageStatus.SENT);
  21182. message._updateMentioned(this.id);
  21183. if (internal(this).lastPatchTime < patchTime) {
  21184. internal(this).lastPatchTime = patchTime;
  21185. } // update conversation lastMessage
  21186. if (conversation.lastMessage && conversation.lastMessage.id === mid) {
  21187. conversation.lastMessage = message; // eslint-disable-line no-param-reassign
  21188. }
  21189. let reason;
  21190. if (patchCode) {
  21191. reason = {
  21192. code: patchCode.toNumber(),
  21193. detail: patchReason
  21194. };
  21195. }
  21196. if (recall) {
  21197. /**
  21198. * 消息被撤回
  21199. * @event IMClient#MESSAGE_RECALL
  21200. * @param {AVMessage} message 被撤回的消息
  21201. * @param {ConversationBase} conversation 消息所在的会话
  21202. * @param {PatchReason} [reason] 撤回的原因,不存在代表是发送者主动撤回
  21203. */
  21204. this.emit(MESSAGE_RECALL$1, message, conversation, reason);
  21205. /**
  21206. * 消息被撤回
  21207. * @event ConversationBase#MESSAGE_RECALL
  21208. * @param {AVMessage} message 被撤回的消息
  21209. * @param {PatchReason} [reason] 撤回的原因,不存在代表是发送者主动撤回
  21210. */
  21211. conversation.emit(MESSAGE_RECALL$1, message, reason);
  21212. } else {
  21213. /**
  21214. * 消息被修改
  21215. * @event IMClient#MESSAGE_UPDATE
  21216. * @param {AVMessage} message 被修改的消息
  21217. * @param {ConversationBase} conversation 消息所在的会话
  21218. * @param {PatchReason} [reason] 修改的原因,不存在代表是发送者主动修改
  21219. */
  21220. this.emit(MESSAGE_UPDATE$1, message, conversation, reason);
  21221. /**
  21222. * 消息被修改
  21223. * @event ConversationBase#MESSAGE_UPDATE
  21224. * @param {AVMessage} message 被修改的消息
  21225. * @param {PatchReason} [reason] 修改的原因,不存在代表是发送者主动修改
  21226. */
  21227. conversation.emit(MESSAGE_UPDATE$1, message, reason);
  21228. }
  21229. });
  21230. })));
  21231. }
  21232. async _dispatchConvMessage(message) {
  21233. const {
  21234. convMessage,
  21235. convMessage: {
  21236. initBy,
  21237. m,
  21238. info,
  21239. attr
  21240. }
  21241. } = message;
  21242. const conversation = await this.getConversation(convMessage.cid);
  21243. switch (message.op) {
  21244. case OpType.joined:
  21245. {
  21246. conversation._addMembers([this.id]);
  21247. const payload = {
  21248. invitedBy: initBy
  21249. };
  21250. /**
  21251. * 当前用户被添加至某个对话
  21252. * @event IMClient#INVITED
  21253. * @param {Object} payload
  21254. * @param {String} payload.invitedBy 邀请者 id
  21255. * @param {ConversationBase} conversation
  21256. */
  21257. this.emit(INVITED$1, payload, conversation);
  21258. /**
  21259. * 当前用户被添加至当前对话
  21260. * @event ConversationBase#INVITED
  21261. * @param {Object} payload
  21262. * @param {String} payload.invitedBy 该移除操作的发起者 id
  21263. */
  21264. conversation.emit(INVITED$1, payload);
  21265. return;
  21266. }
  21267. case OpType.left:
  21268. {
  21269. conversation._removeMembers([this.id]);
  21270. const payload = {
  21271. kickedBy: initBy
  21272. };
  21273. /**
  21274. * 当前用户被从某个对话中移除
  21275. * @event IMClient#KICKED
  21276. * @param {Object} payload
  21277. * @param {String} payload.kickedBy 该移除操作的发起者 id
  21278. * @param {ConversationBase} conversation
  21279. */
  21280. this.emit(KICKED$1, payload, conversation);
  21281. /**
  21282. * 当前用户被从当前对话中移除
  21283. * @event ConversationBase#KICKED
  21284. * @param {Object} payload
  21285. * @param {String} payload.kickedBy 该移除操作的发起者 id
  21286. */
  21287. conversation.emit(KICKED$1, payload);
  21288. return;
  21289. }
  21290. case OpType.members_joined:
  21291. {
  21292. conversation._addMembers(m);
  21293. const payload = {
  21294. invitedBy: initBy,
  21295. members: m
  21296. };
  21297. /**
  21298. * 有用户被添加至某个对话
  21299. * @event IMClient#MEMBERS_JOINED
  21300. * @param {Object} payload
  21301. * @param {String[]} payload.members 被添加的用户 id 列表
  21302. * @param {String} payload.invitedBy 邀请者 id
  21303. * @param {ConversationBase} conversation
  21304. */
  21305. this.emit(MEMBERS_JOINED$1, payload, conversation);
  21306. /**
  21307. * 有成员被添加至当前对话
  21308. * @event ConversationBase#MEMBERS_JOINED
  21309. * @param {Object} payload
  21310. * @param {String[]} payload.members 被添加的成员 id 列表
  21311. * @param {String} payload.invitedBy 邀请者 id
  21312. */
  21313. conversation.emit(MEMBERS_JOINED$1, payload);
  21314. return;
  21315. }
  21316. case OpType.members_left:
  21317. {
  21318. conversation._removeMembers(m);
  21319. const payload = {
  21320. kickedBy: initBy,
  21321. members: m
  21322. };
  21323. /**
  21324. * 有成员被从某个对话中移除
  21325. * @event IMClient#MEMBERS_LEFT
  21326. * @param {Object} payload
  21327. * @param {String[]} payload.members 被移除的成员 id 列表
  21328. * @param {String} payload.kickedBy 该移除操作的发起者 id
  21329. * @param {ConversationBase} conversation
  21330. */
  21331. this.emit(MEMBERS_LEFT$1, payload, conversation);
  21332. /**
  21333. * 有成员被从当前对话中移除
  21334. * @event ConversationBase#MEMBERS_LEFT
  21335. * @param {Object} payload
  21336. * @param {String[]} payload.members 被移除的成员 id 列表
  21337. * @param {String} payload.kickedBy 该移除操作的发起者 id
  21338. */
  21339. conversation.emit(MEMBERS_LEFT$1, payload);
  21340. return;
  21341. }
  21342. case OpType.members_blocked:
  21343. {
  21344. const payload = {
  21345. blockedBy: initBy,
  21346. members: m
  21347. };
  21348. /**
  21349. * 有成员被加入某个对话的黑名单
  21350. * @event IMClient#MEMBERS_BLOCKED
  21351. * @param {Object} payload
  21352. * @param {String[]} payload.members 成员 id 列表
  21353. * @param {String} payload.blockedBy 该操作的发起者 id
  21354. * @param {ConversationBase} conversation
  21355. */
  21356. this.emit(MEMBERS_BLOCKED$1, payload, conversation);
  21357. /**
  21358. * 有成员被加入当前对话的黑名单
  21359. * @event ConversationBase#MEMBERS_BLOCKED
  21360. * @param {Object} payload
  21361. * @param {String[]} payload.members 成员 id 列表
  21362. * @param {String} payload.blockedBy 该操作的发起者 id
  21363. */
  21364. conversation.emit(MEMBERS_BLOCKED$1, payload);
  21365. return;
  21366. }
  21367. case OpType.members_unblocked:
  21368. {
  21369. const payload = {
  21370. unblockedBy: initBy,
  21371. members: m
  21372. };
  21373. /**
  21374. * 有成员被移出某个对话的黑名单
  21375. * @event IMClient#MEMBERS_UNBLOCKED
  21376. * @param {Object} payload
  21377. * @param {String[]} payload.members 成员 id 列表
  21378. * @param {String} payload.unblockedBy 该操作的发起者 id
  21379. * @param {ConversationBase} conversation
  21380. */
  21381. this.emit(MEMBERS_UNBLOCKED$1, payload, conversation);
  21382. /**
  21383. * 有成员被移出当前对话的黑名单
  21384. * @event ConversationBase#MEMBERS_UNBLOCKED
  21385. * @param {Object} payload
  21386. * @param {String[]} payload.members 成员 id 列表
  21387. * @param {String} payload.unblockedBy 该操作的发起者 id
  21388. */
  21389. conversation.emit(MEMBERS_UNBLOCKED$1, payload);
  21390. return;
  21391. }
  21392. case OpType.blocked:
  21393. {
  21394. const payload = {
  21395. blockedBy: initBy
  21396. };
  21397. /**
  21398. * 当前用户被加入某个对话的黑名单
  21399. * @event IMClient#BLOCKED
  21400. * @param {Object} payload
  21401. * @param {String} payload.blockedBy 该操作的发起者 id
  21402. * @param {ConversationBase} conversation
  21403. */
  21404. this.emit(BLOCKED$1, payload, conversation);
  21405. /**
  21406. * 当前用户被加入当前对话的黑名单
  21407. * @event ConversationBase#BLOCKED
  21408. * @param {Object} payload
  21409. * @param {String} payload.blockedBy 该操作的发起者 id
  21410. */
  21411. conversation.emit(BLOCKED$1, payload);
  21412. return;
  21413. }
  21414. case OpType.unblocked:
  21415. {
  21416. const payload = {
  21417. unblockedBy: initBy
  21418. };
  21419. /**
  21420. * 当前用户被移出某个对话的黑名单
  21421. * @event IMClient#UNBLOCKED
  21422. * @param {Object} payload
  21423. * @param {String} payload.unblockedBy 该操作的发起者 id
  21424. * @param {ConversationBase} conversation
  21425. */
  21426. this.emit(UNBLOCKED$1, payload, conversation);
  21427. /**
  21428. * 当前用户被移出当前对话的黑名单
  21429. * @event ConversationBase#UNBLOCKED
  21430. * @param {Object} payload
  21431. * @param {String} payload.unblockedBy 该操作的发起者 id
  21432. */
  21433. conversation.emit(UNBLOCKED$1, payload);
  21434. return;
  21435. }
  21436. case OpType.members_shutuped:
  21437. {
  21438. const payload = {
  21439. mutedBy: initBy,
  21440. members: m
  21441. };
  21442. /**
  21443. * 有成员在某个对话中被禁言
  21444. * @event IMClient#MEMBERS_MUTED
  21445. * @param {Object} payload
  21446. * @param {String[]} payload.members 成员 id 列表
  21447. * @param {String} payload.mutedBy 该操作的发起者 id
  21448. * @param {ConversationBase} conversation
  21449. */
  21450. this.emit(MEMBERS_MUTED$1, payload, conversation);
  21451. /**
  21452. * 有成员在当前对话中被禁言
  21453. * @event ConversationBase#MEMBERS_MUTED
  21454. * @param {Object} payload
  21455. * @param {String[]} payload.members 成员 id 列表
  21456. * @param {String} payload.mutedBy 该操作的发起者 id
  21457. */
  21458. conversation.emit(MEMBERS_MUTED$1, payload);
  21459. return;
  21460. }
  21461. case OpType.members_unshutuped:
  21462. {
  21463. const payload = {
  21464. unmutedBy: initBy,
  21465. members: m
  21466. };
  21467. /**
  21468. * 有成员在某个对话中被解除禁言
  21469. * @event IMClient#MEMBERS_UNMUTED
  21470. * @param {Object} payload
  21471. * @param {String[]} payload.members 成员 id 列表
  21472. * @param {String} payload.unmutedBy 该操作的发起者 id
  21473. * @param {ConversationBase} conversation
  21474. */
  21475. this.emit(MEMBERS_UNMUTED$1, payload, conversation);
  21476. /**
  21477. * 有成员在当前对话中被解除禁言
  21478. * @event ConversationBase#MEMBERS_UNMUTED
  21479. * @param {Object} payload
  21480. * @param {String[]} payload.members 成员 id 列表
  21481. * @param {String} payload.unmutedBy 该操作的发起者 id
  21482. */
  21483. conversation.emit(MEMBERS_UNMUTED$1, payload);
  21484. return;
  21485. }
  21486. case OpType.shutuped:
  21487. {
  21488. const payload = {
  21489. mutedBy: initBy
  21490. };
  21491. /**
  21492. * 有成员在某个对话中被禁言
  21493. * @event IMClient#MUTED
  21494. * @param {Object} payload
  21495. * @param {String} payload.mutedBy 该操作的发起者 id
  21496. * @param {ConversationBase} conversation
  21497. */
  21498. this.emit(MUTED$1, payload, conversation);
  21499. /**
  21500. * 有成员在当前对话中被禁言
  21501. * @event ConversationBase#MUTED
  21502. * @param {Object} payload
  21503. * @param {String} payload.mutedBy 该操作的发起者 id
  21504. */
  21505. conversation.emit(MUTED$1, payload);
  21506. return;
  21507. }
  21508. case OpType.unshutuped:
  21509. {
  21510. const payload = {
  21511. unmutedBy: initBy
  21512. };
  21513. /**
  21514. * 有成员在某个对话中被解除禁言
  21515. * @event IMClient#UNMUTED
  21516. * @param {Object} payload
  21517. * @param {String} payload.unmutedBy 该操作的发起者 id
  21518. * @param {ConversationBase} conversation
  21519. */
  21520. this.emit(UNMUTED$1, payload, conversation);
  21521. /**
  21522. * 有成员在当前对话中被解除禁言
  21523. * @event ConversationBase#UNMUTED
  21524. * @param {Object} payload
  21525. * @param {String} payload.unmutedBy 该操作的发起者 id
  21526. */
  21527. conversation.emit(UNMUTED$1, payload);
  21528. return;
  21529. }
  21530. case OpType.member_info_changed:
  21531. {
  21532. const {
  21533. pid,
  21534. role
  21535. } = info;
  21536. const {
  21537. memberInfoMap
  21538. } = internal(conversation); // 如果不存在缓存,且不是 role 的更新,则不通知
  21539. if (!memberInfoMap && !role) return;
  21540. const memberInfo = await conversation.getMemberInfo(pid);
  21541. internal(memberInfo).role = role;
  21542. const payload = {
  21543. member: pid,
  21544. memberInfo,
  21545. updatedBy: initBy
  21546. };
  21547. /**
  21548. * 有成员的对话信息被更新
  21549. * @event IMClient#MEMBER_INFO_UPDATED
  21550. * @param {Object} payload
  21551. * @param {String} payload.member 被更新对话信息的成员 id
  21552. * @param {ConversationMumberInfo} payload.memberInfo 被更新的成员对话信息
  21553. * @param {String} payload.updatedBy 该操作的发起者 id
  21554. * @param {ConversationBase} conversation
  21555. */
  21556. this.emit(MEMBER_INFO_UPDATED$1, payload, conversation);
  21557. /**
  21558. * 有成员的对话信息被更新
  21559. * @event ConversationBase#MEMBER_INFO_UPDATED
  21560. * @param {Object} payload
  21561. * @param {String} payload.member 被更新对话信息的成员 id
  21562. * @param {ConversationMumberInfo} payload.memberInfo 被更新的成员对话信息
  21563. * @param {String} payload.updatedBy 该操作的发起者 id
  21564. */
  21565. conversation.emit(MEMBER_INFO_UPDATED$1, payload);
  21566. return;
  21567. }
  21568. case OpType.updated:
  21569. {
  21570. const attributes = decode(JSON.parse(attr.data));
  21571. conversation._updateServerAttributes(attributes);
  21572. const payload = {
  21573. attributes,
  21574. updatedBy: initBy
  21575. };
  21576. /**
  21577. * 该对话信息被更新
  21578. * @event IMClient#CONVERSATION_INFO_UPDATED
  21579. * @param {Object} payload
  21580. * @param {Object} payload.attributes 被更新的属性
  21581. * @param {String} payload.updatedBy 该操作的发起者 id
  21582. * @param {ConversationBase} conversation
  21583. */
  21584. this.emit(CONVERSATION_INFO_UPDATED$1, payload, conversation);
  21585. /**
  21586. * 有对话信息被更新
  21587. * @event ConversationBase#INFO_UPDATED
  21588. * @param {Object} payload
  21589. * @param {Object} payload.attributes 被更新的属性
  21590. * @param {String} payload.updatedBy 该操作的发起者 id
  21591. */
  21592. conversation.emit(INFO_UPDATED$1, payload);
  21593. return;
  21594. }
  21595. default:
  21596. this.emit(UNHANDLED_MESSAGE$1, message);
  21597. throw new Error('Unrecognized conversation command');
  21598. }
  21599. }
  21600. _dispatchDirectMessage(originalMessage) {
  21601. const {
  21602. directMessage,
  21603. directMessage: {
  21604. id,
  21605. cid,
  21606. fromPeerId,
  21607. timestamp,
  21608. transient,
  21609. patchTimestamp,
  21610. mentionPids,
  21611. mentionAll,
  21612. binaryMsg,
  21613. msg
  21614. }
  21615. } = originalMessage;
  21616. const content = binaryMsg ? binaryMsg.toArrayBuffer() : msg;
  21617. return Promise.all([this.getConversation(directMessage.cid), this._messageParser.parse(content)]).then(([conversation, message]) => {
  21618. // deleted conversation
  21619. if (!conversation) return undefined;
  21620. const messageProps = {
  21621. id,
  21622. cid,
  21623. timestamp,
  21624. updatedAt: patchTimestamp,
  21625. from: fromPeerId,
  21626. mentionList: mentionPids,
  21627. mentionedAll: mentionAll
  21628. };
  21629. Object.assign(message, messageProps);
  21630. message._updateMentioned(this.id);
  21631. message._setStatus(MessageStatus.SENT); // filter outgoing message sent from another device
  21632. if (message.from !== this.id) {
  21633. if (!(transient || conversation.transient)) {
  21634. this._sendAck(message);
  21635. }
  21636. }
  21637. return this._dispatchParsedMessage(message, conversation);
  21638. });
  21639. }
  21640. _dispatchParsedMessage(message, conversation) {
  21641. // beforeMessageDispatch hook
  21642. return applyDispatcher(this._plugins.beforeMessageDispatch, [message, conversation]).then(shouldDispatch => {
  21643. if (shouldDispatch === false) return;
  21644. conversation.lastMessage = message; // eslint-disable-line no-param-reassign
  21645. conversation.lastMessageAt = message.timestamp; // eslint-disable-line no-param-reassign
  21646. // filter outgoing message sent from another device
  21647. if (message.from !== this.id) {
  21648. conversation.unreadMessagesCount += 1; // eslint-disable-line no-param-reassign
  21649. if (message.mentioned) conversation._setUnreadMessagesMentioned(true);
  21650. }
  21651. /**
  21652. * 当前用户收到消息
  21653. * @event IMClient#MESSAGE
  21654. * @param {Message} message
  21655. * @param {ConversationBase} conversation 收到消息的对话
  21656. */
  21657. this.emit(MESSAGE$2, message, conversation);
  21658. /**
  21659. * 当前对话收到消息
  21660. * @event ConversationBase#MESSAGE
  21661. * @param {Message} message
  21662. */
  21663. conversation.emit(MESSAGE$2, message);
  21664. });
  21665. }
  21666. _sendAck(message) {
  21667. this._debug('send ack for %O', message);
  21668. const {
  21669. cid
  21670. } = message;
  21671. if (!cid) {
  21672. throw new Error('missing cid');
  21673. }
  21674. if (!this._ackMessageBuffer[cid]) {
  21675. this._ackMessageBuffer[cid] = [];
  21676. }
  21677. this._ackMessageBuffer[cid].push(message);
  21678. return this._doSendAck();
  21679. } // jsdoc-ignore-start
  21680. // jsdoc-ignore-end
  21681. _doSendAck() {
  21682. // if not connected, just skip everything
  21683. if (!this._connection.is('connected')) return;
  21684. this._debug('do send ack %O', this._ackMessageBuffer);
  21685. Promise.all(Object.keys(this._ackMessageBuffer).map(cid => {
  21686. const convAckMessages = this._ackMessageBuffer[cid];
  21687. const timestamps = convAckMessages.map(message => message.timestamp);
  21688. const command = new GenericCommand({
  21689. cmd: 'ack',
  21690. ackMessage: new AckCommand({
  21691. cid,
  21692. fromts: Math.min.apply(null, timestamps),
  21693. tots: Math.max.apply(null, timestamps)
  21694. })
  21695. });
  21696. delete this._ackMessageBuffer[cid];
  21697. return this._send(command, false).catch(error => {
  21698. this._debug('send ack failed: %O', error);
  21699. this._ackMessageBuffer[cid] = convAckMessages;
  21700. });
  21701. }));
  21702. }
  21703. _omitPeerId(value) {
  21704. internal(this).peerIdOmittable = value;
  21705. }
  21706. _send(cmd, ...args) {
  21707. const command = cmd;
  21708. if (!internal(this).peerIdOmittable && this.id) {
  21709. command.peerId = this.id;
  21710. }
  21711. return this._connection.send(command, ...args);
  21712. }
  21713. async _open(appId, tag, deviceId, isReconnect = false) {
  21714. this._debug('open session');
  21715. const {
  21716. lastUnreadNotifTime,
  21717. lastPatchTime,
  21718. lastNotificationTime
  21719. } = internal(this);
  21720. const command = new GenericCommand({
  21721. cmd: 'session',
  21722. op: 'open',
  21723. appId,
  21724. peerId: this.id,
  21725. sessionMessage: new SessionCommand({
  21726. ua: `js/${version}`,
  21727. r: isReconnect,
  21728. lastUnreadNotifTime,
  21729. lastPatchTime,
  21730. configBitmap
  21731. })
  21732. });
  21733. if (!isReconnect) {
  21734. Object.assign(command.sessionMessage, trim({
  21735. tag,
  21736. deviceId
  21737. }));
  21738. if (this.options.signatureFactory) {
  21739. const signatureResult = await runSignatureFactory(this.options.signatureFactory, [this._identity]);
  21740. Object.assign(command.sessionMessage, keyRemap({
  21741. signature: 's',
  21742. timestamp: 't',
  21743. nonce: 'n'
  21744. }, signatureResult));
  21745. }
  21746. } else {
  21747. const sessionToken = await this._sessionManager.getSessionToken({
  21748. autoRefresh: false
  21749. });
  21750. if (sessionToken && sessionToken !== Expirable.EXPIRED) {
  21751. Object.assign(command.sessionMessage, {
  21752. st: sessionToken
  21753. });
  21754. }
  21755. }
  21756. let resCommand;
  21757. try {
  21758. resCommand = await this._send(command);
  21759. } catch (error) {
  21760. if (error.code === ErrorCode.SESSION_TOKEN_EXPIRED) {
  21761. if (!this._sessionManager) {
  21762. // let it fail if sessoinToken not cached but command rejected as token expired
  21763. // to prevent session openning flood
  21764. throw new Error('Unexpected session expiration');
  21765. }
  21766. debug$b('Session token expired, reopening');
  21767. this._sessionManager.revoke();
  21768. return this._open(appId, tag, deviceId, isReconnect);
  21769. }
  21770. throw error;
  21771. }
  21772. const {
  21773. peerId,
  21774. sessionMessage,
  21775. sessionMessage: {
  21776. st: token,
  21777. stTtl: tokenTTL,
  21778. code
  21779. },
  21780. serverTs
  21781. } = resCommand;
  21782. if (code) {
  21783. throw createError(sessionMessage);
  21784. }
  21785. if (peerId) {
  21786. this.id = peerId;
  21787. if (!this._identity) this._identity = peerId;
  21788. if (token) {
  21789. this._sessionManager = this._sessionManager || this._createSessionManager();
  21790. this._sessionManager.setSessionToken(token, tokenTTL);
  21791. }
  21792. const serverTime = getTime(decodeDate(serverTs));
  21793. if (serverTs) {
  21794. internal(this).lastPatchTime = serverTime;
  21795. }
  21796. if (lastNotificationTime) {
  21797. // Do not await for it as this is failable
  21798. this._syncNotifications(lastNotificationTime).catch(error => console.warn('Syncing notifications failed:', error));
  21799. } else {
  21800. // Set timestamp to now for next reconnection
  21801. internal(this).lastNotificationTime = serverTime;
  21802. }
  21803. } else {
  21804. console.warn('Unexpected session opened without peerId.');
  21805. }
  21806. return undefined;
  21807. }
  21808. async _syncNotifications(timestamp) {
  21809. const {
  21810. hasMore,
  21811. notifications
  21812. } = await this._fetchNotifications(timestamp);
  21813. notifications.forEach(notification => {
  21814. const {
  21815. cmd,
  21816. op,
  21817. serverTs,
  21818. notificationType,
  21819. ...payload
  21820. } = notification;
  21821. this._dispatchCommand({
  21822. cmd: CommandType[cmd],
  21823. op: OpType[op],
  21824. serverTs,
  21825. notificationType,
  21826. [`${cmd}Message`]: payload
  21827. });
  21828. });
  21829. if (hasMore) {
  21830. return this._syncNotifications(internal(this).lastNotificationTime);
  21831. }
  21832. return undefined;
  21833. }
  21834. async _fetchNotifications(timestamp) {
  21835. return this._requestWithSessionToken({
  21836. method: 'GET',
  21837. path: '/rtm/notifications',
  21838. query: {
  21839. start_ts: timestamp,
  21840. notification_type: 'permanent'
  21841. }
  21842. });
  21843. }
  21844. _createSessionManager() {
  21845. debug$b('create SessionManager');
  21846. return new SessionManager({
  21847. onBeforeGetSessionToken: this._connection.checkConnectionAvailability.bind(this._connection),
  21848. refresh: (manager, expiredSessionToken) => manager.setSessionTokenAsync(Promise.resolve(new GenericCommand({
  21849. cmd: 'session',
  21850. op: 'refresh',
  21851. sessionMessage: new SessionCommand({
  21852. ua: `js/${version}`,
  21853. st: expiredSessionToken
  21854. })
  21855. })).then(async command => {
  21856. if (this.options.signatureFactory) {
  21857. const signatureResult = await runSignatureFactory(this.options.signatureFactory, [this._identity]);
  21858. Object.assign(command.sessionMessage, keyRemap({
  21859. signature: 's',
  21860. timestamp: 't',
  21861. nonce: 'n'
  21862. }, signatureResult));
  21863. }
  21864. return command;
  21865. }).then(this._send.bind(this)).then(({
  21866. sessionMessage: {
  21867. st: token,
  21868. stTtl: ttl
  21869. }
  21870. }) => [token, ttl]))
  21871. });
  21872. }
  21873. async _requestWithSessionToken({
  21874. headers,
  21875. query,
  21876. ...params
  21877. }) {
  21878. const sessionToken = await this._sessionManager.getSessionToken();
  21879. return this._request({
  21880. headers: {
  21881. 'X-LC-IM-Session-Token': sessionToken,
  21882. ...headers
  21883. },
  21884. query: {
  21885. client_id: this.id,
  21886. ...query
  21887. },
  21888. ...params
  21889. });
  21890. }
  21891. /**
  21892. * 关闭客户端
  21893. * @return {Promise}
  21894. */
  21895. async close() {
  21896. this._debug('close session');
  21897. const _ee = internal(this)._eventemitter;
  21898. _ee.emit('beforeclose');
  21899. if (this._connection.is('connected')) {
  21900. const command = new GenericCommand({
  21901. cmd: 'session',
  21902. op: 'close'
  21903. });
  21904. await this._send(command);
  21905. }
  21906. _ee.emit('close');
  21907. this.emit(CLOSE$1, {
  21908. code: 0
  21909. });
  21910. }
  21911. /**
  21912. * 获取 client 列表中在线的 client,每次查询最多 20 个 clientId,超出部分会被忽略
  21913. * @param {String[]} clientIds 要查询的 client ids
  21914. * @return {Primse.<String[]>} 在线的 client ids
  21915. */
  21916. async ping(clientIds) {
  21917. this._debug('ping');
  21918. if (!(clientIds instanceof Array)) {
  21919. throw new TypeError(`clientIds ${clientIds} is not an Array`);
  21920. }
  21921. if (!clientIds.length) {
  21922. return Promise.resolve([]);
  21923. }
  21924. const command = new GenericCommand({
  21925. cmd: 'session',
  21926. op: 'query',
  21927. sessionMessage: new SessionCommand({
  21928. sessionPeerIds: clientIds
  21929. })
  21930. });
  21931. const resCommand = await this._send(command);
  21932. return resCommand.sessionMessage.onlineSessionPeerIds;
  21933. }
  21934. /**
  21935. * 获取某个特定的对话
  21936. * @param {String} id 对话 id,对应 _Conversation 表中的 objectId
  21937. * @param {Boolean} [noCache=false] 强制不从缓存中获取
  21938. * @return {Promise.<ConversationBase>} 如果 id 对应的对话不存在则返回 null
  21939. */
  21940. async getConversation(id, noCache = false) {
  21941. if (typeof id !== 'string') {
  21942. throw new TypeError(`${id} is not a String`);
  21943. }
  21944. if (!noCache) {
  21945. const cachedConversation = this._conversationCache.get(id);
  21946. if (cachedConversation) {
  21947. return cachedConversation;
  21948. }
  21949. }
  21950. if (isTemporaryConversatrionId(id)) {
  21951. return (await this._getTemporaryConversations([id]))[0] || null;
  21952. }
  21953. return this.getQuery().equalTo('objectId', id).find().then(conversations => conversations[0] || null);
  21954. }
  21955. /**
  21956. * 通过 id 批量获取某个特定的对话
  21957. * @since 3.4.0
  21958. * @param {String[]} ids 对话 id 列表,对应 _Conversation 表中的 objectId
  21959. * @param {Boolean} [noCache=false] 强制不从缓存中获取
  21960. * @return {Promise.<ConversationBase[]>} 如果 id 对应的对话不存在则返回 null
  21961. */
  21962. async getConversations(ids, noCache = false) {
  21963. const remoteConversationIds = noCache ? ids : ids.filter(id => this._conversationCache.get(id) === null);
  21964. if (remoteConversationIds.length) {
  21965. const remoteTemporaryConversationIds = remove_1(remoteConversationIds, isTemporaryConversatrionId);
  21966. const query = [];
  21967. if (remoteConversationIds.length) {
  21968. query.push(this.getQuery().containedIn('objectId', remoteConversationIds).limit(999).find());
  21969. }
  21970. if (remoteTemporaryConversationIds.length) {
  21971. const remoteTemporaryConversationsPromise = remoteTemporaryConversationIds.map(this._getTemporaryConversations.bind(this));
  21972. query.push(...remoteTemporaryConversationsPromise);
  21973. }
  21974. await Promise.all(query);
  21975. }
  21976. return ids.map(id => this._conversationCache.get(id));
  21977. }
  21978. async _getTemporaryConversations(ids) {
  21979. const command = new GenericCommand({
  21980. cmd: 'conv',
  21981. op: 'query',
  21982. convMessage: new ConvCommand({
  21983. tempConvIds: ids
  21984. })
  21985. });
  21986. const resCommand = await this._send(command);
  21987. return this._handleQueryResults(resCommand);
  21988. }
  21989. /**
  21990. * 构造一个 ConversationQuery 来查询对话
  21991. * @return {ConversationQuery.<PersistentConversation>}
  21992. */
  21993. getQuery() {
  21994. return new ConversationQuery(this);
  21995. }
  21996. /**
  21997. * 构造一个 ConversationQuery 来查询聊天室
  21998. * @return {ConversationQuery.<ChatRoom>}
  21999. */
  22000. getChatRoomQuery() {
  22001. return this.getQuery().equalTo('tr', true);
  22002. }
  22003. /**
  22004. * 构造一个 ConversationQuery 来查询服务号
  22005. * @return {ConversationQuery.<ServiceConversation>}
  22006. */
  22007. getServiceConversationQuery() {
  22008. return this.getQuery().equalTo('sys', true);
  22009. }
  22010. async _executeQuery(query) {
  22011. const queryJSON = query.toJSON();
  22012. queryJSON.where = new JsonObjectMessage({
  22013. data: JSON.stringify(encode(queryJSON.where))
  22014. });
  22015. const command = new GenericCommand({
  22016. cmd: 'conv',
  22017. op: 'query',
  22018. convMessage: new ConvCommand(queryJSON)
  22019. });
  22020. const resCommand = await this._send(command);
  22021. return this._handleQueryResults(resCommand);
  22022. }
  22023. async _handleQueryResults(resCommand) {
  22024. let conversations;
  22025. try {
  22026. conversations = decode(JSON.parse(resCommand.convMessage.results.data));
  22027. } catch (error) {
  22028. const commandString = JSON.stringify(trim(resCommand));
  22029. throw new Error(`Parse query result failed: ${error.message}. Command: ${commandString}`);
  22030. }
  22031. conversations = await Promise.all(conversations.map(this._parseConversationFromRawData.bind(this)));
  22032. return conversations.map(this._upsertConversationToCache.bind(this));
  22033. }
  22034. _upsertConversationToCache(fetchedConversation) {
  22035. let conversation = this._conversationCache.get(fetchedConversation.id);
  22036. if (!conversation) {
  22037. conversation = fetchedConversation;
  22038. this._debug('no match, set cache');
  22039. this._conversationCache.set(fetchedConversation.id, fetchedConversation);
  22040. } else {
  22041. this._debug('update cached conversation');
  22042. ['creator', 'createdAt', 'updatedAt', 'lastMessageAt', 'lastMessage', 'mutedMembers', 'members', '_attributes', 'transient', 'muted'].forEach(key => {
  22043. const value = fetchedConversation[key];
  22044. if (value !== undefined) conversation[key] = value;
  22045. });
  22046. if (conversation._reset) conversation._reset();
  22047. }
  22048. return conversation;
  22049. }
  22050. /**
  22051. * 反序列化消息,与 {@link Message#toFullJSON} 相对。
  22052. * @param {Object}
  22053. * @return {AVMessage} 解析后的消息
  22054. * @since 4.0.0
  22055. */
  22056. async parseMessage({
  22057. data,
  22058. bin = false,
  22059. ...properties
  22060. }) {
  22061. const content = bin ? base64Arraybuffer_2(data) : data;
  22062. const message = await this._messageParser.parse(content);
  22063. Object.assign(message, properties);
  22064. message._updateMentioned(this.id);
  22065. return message;
  22066. }
  22067. /**
  22068. * 反序列化对话,与 {@link Conversation#toFullJSON} 相对。
  22069. * @param {Object}
  22070. * @return {ConversationBase} 解析后的对话
  22071. * @since 4.0.0
  22072. */
  22073. async parseConversation({
  22074. id,
  22075. lastMessageAt,
  22076. lastMessage,
  22077. lastDeliveredAt,
  22078. lastReadAt,
  22079. unreadMessagesCount,
  22080. members,
  22081. mentioned,
  22082. ...properties
  22083. }) {
  22084. const conversationData = {
  22085. id,
  22086. lastMessageAt,
  22087. lastMessage,
  22088. lastDeliveredAt,
  22089. lastReadAt,
  22090. unreadMessagesCount,
  22091. members,
  22092. mentioned
  22093. };
  22094. if (lastMessage) {
  22095. conversationData.lastMessage = await this.parseMessage(lastMessage);
  22096. conversationData.lastMessage._setStatus(MessageStatus.SENT);
  22097. }
  22098. const {
  22099. transient,
  22100. system,
  22101. expiredAt
  22102. } = properties;
  22103. if (transient) return new ChatRoom(conversationData, properties, this);
  22104. if (system) return new ServiceConversation(conversationData, properties, this);
  22105. if (expiredAt || isTemporaryConversatrionId(id)) {
  22106. return new TemporaryConversation(conversationData, {
  22107. expiredAt
  22108. }, this);
  22109. }
  22110. return new Conversation(conversationData, properties, this);
  22111. }
  22112. async _parseConversationFromRawData(rawData) {
  22113. const data = keyRemap({
  22114. objectId: 'id',
  22115. lm: 'lastMessageAt',
  22116. m: 'members',
  22117. tr: 'transient',
  22118. sys: 'system',
  22119. c: 'creator',
  22120. mu: 'mutedMembers'
  22121. }, rawData);
  22122. if (data.msg) {
  22123. data.lastMessage = {
  22124. data: data.msg,
  22125. bin: data.bin,
  22126. from: data.msg_from,
  22127. id: data.msg_mid,
  22128. timestamp: data.msg_timestamp,
  22129. updatedAt: data.patch_timestamp
  22130. };
  22131. delete data.lastMessageFrom;
  22132. delete data.lastMessageId;
  22133. delete data.lastMessageTimestamp;
  22134. delete data.lastMessagePatchTimestamp;
  22135. }
  22136. const {
  22137. ttl
  22138. } = data;
  22139. if (ttl) data.expiredAt = Date.now() + ttl * 1000;
  22140. return this.parseConversation(data);
  22141. }
  22142. /**
  22143. * 创建一个对话
  22144. * @param {Object} options 除了下列字段外的其他字段将被视为对话的自定义属性
  22145. * @param {String[]} options.members 对话的初始成员列表,默认包含当前 client
  22146. * @param {String} [options.name] 对话的名字
  22147. * @param {Boolean} [options.unique=true] 唯一对话,当其为 true 时,如果当前已经有相同成员的对话存在则返回该对话,否则会创建新的对话
  22148. * @return {Promise.<Conversation>}
  22149. */
  22150. async createConversation({
  22151. members: m,
  22152. name,
  22153. transient,
  22154. unique = true,
  22155. _tempConv: tempConv,
  22156. _tempConvTTL: tempConvTTL,
  22157. ...properties
  22158. } = {}) {
  22159. if (!(transient || Array.isArray(m))) {
  22160. throw new TypeError(`conversation members ${m} is not an array`);
  22161. }
  22162. let members = new Set(m);
  22163. members.add(this.id);
  22164. members = Array.from(members).sort();
  22165. let attr = properties || {};
  22166. if (name) {
  22167. if (typeof name !== 'string') {
  22168. throw new TypeError(`conversation name ${name} is not a string`);
  22169. }
  22170. attr.name = name;
  22171. }
  22172. attr = new JsonObjectMessage({
  22173. data: JSON.stringify(encode(attr))
  22174. });
  22175. const startCommandJson = {
  22176. m: members,
  22177. attr,
  22178. transient,
  22179. unique,
  22180. tempConv,
  22181. tempConvTTL
  22182. };
  22183. const command = new GenericCommand({
  22184. cmd: 'conv',
  22185. op: 'start',
  22186. convMessage: new ConvCommand(startCommandJson)
  22187. });
  22188. if (this.options.conversationSignatureFactory) {
  22189. const params = [null, this._identity, members, 'create'];
  22190. const signatureResult = await runSignatureFactory(this.options.conversationSignatureFactory, params);
  22191. Object.assign(command.convMessage, keyRemap({
  22192. signature: 's',
  22193. timestamp: 't',
  22194. nonce: 'n'
  22195. }, signatureResult));
  22196. }
  22197. const {
  22198. convMessage: {
  22199. cid,
  22200. cdate,
  22201. tempConvTTL: ttl
  22202. }
  22203. } = await this._send(command);
  22204. const data = {
  22205. name,
  22206. transient,
  22207. unique,
  22208. id: cid,
  22209. createdAt: cdate,
  22210. updatedAt: cdate,
  22211. lastMessageAt: null,
  22212. creator: this.id,
  22213. members: transient ? [] : members,
  22214. ...properties
  22215. };
  22216. if (ttl) data.expiredAt = Date.now() + ttl * 1000;
  22217. const conversation = await this.parseConversation(data);
  22218. return this._upsertConversationToCache(conversation);
  22219. }
  22220. /**
  22221. * 创建一个聊天室
  22222. * @since 4.0.0
  22223. * @param {Object} options 除了下列字段外的其他字段将被视为对话的自定义属性
  22224. * @param {String} [options.name] 对话的名字
  22225. * @return {Promise.<ChatRoom>}
  22226. */
  22227. async createChatRoom(param) {
  22228. return this.createConversation({ ...param,
  22229. transient: true,
  22230. members: null,
  22231. unique: false,
  22232. _tempConv: false
  22233. });
  22234. }
  22235. /**
  22236. * 创建一个临时对话
  22237. * @since 4.0.0
  22238. * @param {Object} options
  22239. * @param {String[]} options.members 对话的初始成员列表,默认包含当前 client
  22240. * @param {String} [options.ttl] 对话存在时间,单位为秒,最大值与默认值均为 86400(一天),过期后该对话不再可用。
  22241. * @return {Promise.<TemporaryConversation>}
  22242. */
  22243. async createTemporaryConversation({
  22244. ttl: _tempConvTTL,
  22245. ...param
  22246. }) {
  22247. return this.createConversation({ ...param,
  22248. _tempConv: true,
  22249. _tempConvTTL
  22250. });
  22251. } // jsdoc-ignore-start
  22252. // jsdoc-ignore-end
  22253. _doSendRead() {
  22254. // if not connected, just skip everything
  22255. if (!this._connection.is('connected')) return;
  22256. const buffer = internal(this).readConversationsBuffer;
  22257. const conversations = Array.from(buffer);
  22258. if (!conversations.length) return;
  22259. const ids = conversations.map(conversation => {
  22260. if (!(conversation instanceof ConversationBase)) {
  22261. throw new TypeError(`${conversation} is not a Conversation`);
  22262. }
  22263. return conversation.id;
  22264. });
  22265. this._debug(`mark [${ids}] as read`);
  22266. buffer.clear();
  22267. this._sendReadCommand(conversations).catch(error => {
  22268. this._debug('send read failed: %O', error);
  22269. conversations.forEach(buffer.add.bind(buffer));
  22270. });
  22271. }
  22272. _sendReadCommand(conversations) {
  22273. return this._send(new GenericCommand({
  22274. cmd: 'read',
  22275. readMessage: new ReadCommand({
  22276. convs: conversations.map(conversation => new ReadTuple({
  22277. cid: conversation.id,
  22278. mid: conversation.lastMessage && conversation.lastMessage.from !== this.id ? conversation.lastMessage.id : undefined,
  22279. timestamp: (conversation.lastMessageAt || new Date()).getTime()
  22280. }))
  22281. })
  22282. }), false);
  22283. }
  22284. }, (_applyDecoratedDescriptor(_class$3.prototype, "_doSendAck", [_dec$2], Object.getOwnPropertyDescriptor(_class$3.prototype, "_doSendAck"), _class$3.prototype), _applyDecoratedDescriptor(_class$3.prototype, "_doSendRead", [_dec2], Object.getOwnPropertyDescriptor(_class$3.prototype, "_doSendRead"), _class$3.prototype)), _class$3));
  22285. /**
  22286. * 修改、撤回消息的原因
  22287. * @typedef PatchReason
  22288. * @type {Object}
  22289. * @property {number} code 负数为内置 code,正数为开发者在 hook 中自定义的 code。比如因为敏感词过滤被修改的 code 为 -4408。
  22290. * @property {string} [detail] 具体的原因说明。
  22291. */
  22292. const RECONNECT_ERROR = 'reconnecterror';
  22293. var CoreEvent = /*#__PURE__*/Object.freeze({
  22294. __proto__: null,
  22295. RECONNECT_ERROR: RECONNECT_ERROR,
  22296. DISCONNECT: DISCONNECT,
  22297. RECONNECT: RECONNECT,
  22298. RETRY: RETRY,
  22299. SCHEDULE: SCHEDULE,
  22300. OFFLINE: OFFLINE,
  22301. ONLINE: ONLINE
  22302. });
  22303. var _class$4;
  22304. let // jsdoc-ignore-end
  22305. BinaryMessage = IE10Compatible(_class$4 = class BinaryMessage extends Message {
  22306. /**
  22307. * 二进制消息
  22308. * @extends Message
  22309. * @param {ArrayBuffer} buffer
  22310. * @since 4.0.0
  22311. */
  22312. constructor(buffer) {
  22313. if (!(buffer instanceof ArrayBuffer)) {
  22314. throw new TypeError(`${buffer} is not an ArrayBuffer`);
  22315. }
  22316. super(buffer);
  22317. }
  22318. /**
  22319. * @type ArrayBuffer
  22320. */
  22321. get buffer() {
  22322. return this.content;
  22323. }
  22324. set buffer(buffer) {
  22325. this.content = buffer;
  22326. }
  22327. static validate(target) {
  22328. return target instanceof ArrayBuffer;
  22329. }
  22330. toJSON() {
  22331. return { ...super._toJSON(),
  22332. data: base64Arraybuffer_1(this.content)
  22333. };
  22334. }
  22335. toFullJSON() {
  22336. return { ...super.toFullJSON(),
  22337. bin: true,
  22338. data: base64Arraybuffer_1(this.content)
  22339. };
  22340. }
  22341. }) || _class$4;
  22342. var _dec$3, _class$5;
  22343. let // jsdoc-ignore-end
  22344. TextMessage = (_dec$3 = messageType(-1), _dec$3(_class$5 = IE10Compatible(_class$5 = class TextMessage extends TypedMessage {
  22345. /**
  22346. * 文类类型消息
  22347. * @extends TypedMessage
  22348. * @param {String} [text='']
  22349. * @throws {TypeError} text 不是 String 类型
  22350. */
  22351. constructor(text = '') {
  22352. if (typeof text !== 'string') {
  22353. throw new TypeError(`${text} is not a string`);
  22354. }
  22355. super();
  22356. this.setText(text);
  22357. }
  22358. }) || _class$5) || _class$5);
  22359. /**
  22360. * @name TYPE
  22361. * @memberof TextMessage
  22362. * @type Number
  22363. * @static
  22364. * @const
  22365. */
  22366. var _class$6;
  22367. const debug$c = browser('LC:MessageParser');
  22368. const tryParseJson = (target, key, descriptor) => {
  22369. const fn = descriptor.value; // eslint-disable-next-line no-param-reassign
  22370. descriptor.value = function wrapper(param) {
  22371. let content;
  22372. if (typeof param !== 'string') {
  22373. content = param;
  22374. } else {
  22375. try {
  22376. content = JSON.parse(param);
  22377. } catch (error) {
  22378. content = param;
  22379. }
  22380. }
  22381. return fn.call(this, content);
  22382. };
  22383. };
  22384. const applyPlugins = (target, key, descriptor) => {
  22385. const fn = descriptor.value; // eslint-disable-next-line no-param-reassign
  22386. descriptor.value = function wrapper(json) {
  22387. return Promise.resolve(json).then(applyMiddlewares(this._plugins.beforeMessageParse)).then(decoratedJson => fn.call(this, decoratedJson)).then(applyMiddlewares(this._plugins.afterMessageParse));
  22388. };
  22389. };
  22390. let MessageParser = (_class$6 = class MessageParser {
  22391. /**
  22392. * 消息解析器
  22393. * @param {Object} plugins 插件,插件的 messageClasses 会自动被注册,在解析时 beforeMessageParse 与 afterMessageParse Middleware 会被应用。
  22394. */
  22395. constructor(plugins = {}) {
  22396. this._plugins = plugins;
  22397. this._messageClasses = [];
  22398. this.register(plugins.messageClasses);
  22399. }
  22400. /**
  22401. * 注册消息类
  22402. *
  22403. * @param {Function | Function[]} messageClass 消息类,需要实现 {@link AVMessage} 接口,
  22404. * 建议继承自 {@link TypedMessage},也可以传入一个消息类数组。
  22405. * @throws {TypeError} 如果 messageClass 没有实现 {@link AVMessage} 接口则抛出异常
  22406. */
  22407. register(messageClasses) {
  22408. ensureArray(messageClasses).map(klass => this._register(klass));
  22409. }
  22410. _register(messageClass) {
  22411. if (messageClass && messageClass.parse && messageClass.prototype && messageClass.prototype.getPayload) {
  22412. this._messageClasses.unshift(messageClass);
  22413. } else {
  22414. throw new TypeError('Invalid messageClass');
  22415. }
  22416. } // jsdoc-ignore-start
  22417. // jsdoc-ignore-end
  22418. /**
  22419. * 解析消息内容
  22420. * @param {Object | string | any} target 消息内容,如果是字符串会尝试 parse 为 JSON。
  22421. * @return {AVMessage} 解析后的消息
  22422. * @throws {Error} 如果不匹配任何注册的消息则抛出异常
  22423. */
  22424. parse(content) {
  22425. debug$c('parsing message: %O', content); // eslint-disable-next-line
  22426. for (const Klass of this._messageClasses) {
  22427. const contentCopy = isPlainObject_1(content) ? { ...content
  22428. } : content;
  22429. let valid;
  22430. let result;
  22431. try {
  22432. valid = Klass.validate(contentCopy);
  22433. } catch (error) {// eslint-disable-line no-empty
  22434. }
  22435. if (valid) {
  22436. try {
  22437. result = Klass.parse(contentCopy);
  22438. } catch (error) {
  22439. console.warn('parsing a valid message content error', {
  22440. error,
  22441. Klass,
  22442. content: contentCopy
  22443. });
  22444. }
  22445. if (result !== undefined) {
  22446. debug$c('parse result: %O', result);
  22447. return result;
  22448. }
  22449. }
  22450. }
  22451. throw new Error('No Message Class matched');
  22452. }
  22453. }, (_applyDecoratedDescriptor(_class$6.prototype, "parse", [tryParseJson, applyPlugins], Object.getOwnPropertyDescriptor(_class$6.prototype, "parse"), _class$6.prototype)), _class$6);
  22454. /** @module leancloud-realtime */
  22455. const debug$d = browser('LC:IMPlugin');
  22456. /**
  22457. * 消息优先级枚举
  22458. * @enum {Number}
  22459. * @since 3.3.0
  22460. */
  22461. const MessagePriority = {
  22462. /** 高 */
  22463. HIGH: 1,
  22464. /** 普通 */
  22465. NORMAL: 2,
  22466. /** 低 */
  22467. LOW: 3
  22468. };
  22469. Object.freeze(MessagePriority);
  22470. /**
  22471. * 为 Conversation 定义一个新属性
  22472. * @param {String} prop 属性名
  22473. * @param {Object} [descriptor] 属性的描述符,参见 {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor#Description getOwnPropertyDescriptor#Description - MDN},默认为该属性名对应的 Conversation 自定义属性的 getter/setter
  22474. * @returns void
  22475. * @example
  22476. *
  22477. * conversation.get('type');
  22478. * conversation.set('type', 1);
  22479. *
  22480. * // equals to
  22481. * defineConversationProperty('type');
  22482. * conversation.type;
  22483. * conversation.type = 1;
  22484. */
  22485. const defineConversationProperty = (prop, descriptor = {
  22486. get() {
  22487. return this.get(prop);
  22488. },
  22489. set(value) {
  22490. this.set(prop, value);
  22491. }
  22492. }) => {
  22493. Object.defineProperty(Conversation.prototype, prop, descriptor);
  22494. };
  22495. const onRealtimeCreate = realtime => {
  22496. /* eslint-disable no-param-reassign */
  22497. const deviceId = v4_1();
  22498. realtime._IMClients = {};
  22499. realtime._IMClientsCreationCount = 0;
  22500. const messageParser = new MessageParser(realtime._plugins);
  22501. realtime._messageParser = messageParser;
  22502. const signAVUser = async user => realtime._request({
  22503. method: 'POST',
  22504. path: '/rtm/sign',
  22505. data: {
  22506. session_token: user.getSessionToken()
  22507. }
  22508. });
  22509. /**
  22510. * 注册消息类
  22511. *
  22512. * 在接收消息、查询消息时,会按照消息类注册顺序的逆序依次尝试解析消息内容
  22513. *
  22514. * @memberof Realtime
  22515. * @instance
  22516. * @param {Function | Function[]} messageClass 消息类,需要实现 {@link AVMessage} 接口,
  22517. * 建议继承自 {@link TypedMessage}
  22518. * @throws {TypeError} 如果 messageClass 没有实现 {@link AVMessage} 接口则抛出异常
  22519. */
  22520. const register = messageParser.register.bind(messageParser);
  22521. /**
  22522. * 创建一个即时通讯客户端,多次创建相同 id 的客户端会返回同一个实例
  22523. * @memberof Realtime
  22524. * @instance
  22525. * @param {String|AV.User} [identity] 客户端 identity,如果不指定该参数,服务端会随机生成一个字符串作为 identity,
  22526. * 如果传入一个已登录的 AV.User,则会使用该用户的 id 作为客户端 identity 登录。
  22527. * @param {Object} [options]
  22528. * @param {Function} [options.signatureFactory] open session 时的签名方法 // TODO need details
  22529. * @param {Function} [options.conversationSignatureFactory] 对话创建、增减成员操作时的签名方法
  22530. * @param {Function} [options.blacklistSignatureFactory] 黑名单操作时的签名方法
  22531. * @param {String} [options.tag] 客户端类型标记,以支持单点登录功能
  22532. * @param {String} [options.isReconnect=false] 单点登录时标记该次登录是不是应用启动时自动重新登录
  22533. * @return {Promise.<IMClient>}
  22534. */
  22535. const createIMClient = async (identity, {
  22536. tag,
  22537. isReconnect,
  22538. ...clientOptions
  22539. } = {}, lagecyTag) => {
  22540. let id;
  22541. const buildinOptions = {};
  22542. if (identity) {
  22543. if (typeof identity === 'string') {
  22544. id = identity;
  22545. } else if (identity.id && identity.getSessionToken) {
  22546. ({
  22547. id
  22548. } = identity);
  22549. const sessionToken = identity.getSessionToken();
  22550. if (!sessionToken) {
  22551. throw new Error('User must be authenticated');
  22552. }
  22553. buildinOptions.signatureFactory = signAVUser;
  22554. } else {
  22555. throw new TypeError('Identity must be a String or an AV.User');
  22556. }
  22557. if (realtime._IMClients[id] !== undefined) {
  22558. return realtime._IMClients[id];
  22559. }
  22560. }
  22561. if (lagecyTag) {
  22562. console.warn('DEPRECATION createIMClient tag param: Use options.tag instead.');
  22563. }
  22564. const _tag = tag || lagecyTag;
  22565. const promise = realtime._open().then(connection => {
  22566. const client = new IMClient(id, { ...buildinOptions,
  22567. ...clientOptions
  22568. }, {
  22569. _connection: connection,
  22570. _request: realtime._request.bind(realtime),
  22571. _messageParser: messageParser,
  22572. _plugins: realtime._plugins,
  22573. _identity: identity
  22574. });
  22575. connection.on(RECONNECT, () => client._open(realtime._options.appId, _tag, deviceId, true)
  22576. /**
  22577. * 客户端连接恢复正常,该事件通常在 {@link Realtime#event:RECONNECT} 之后发生
  22578. * @event IMClient#RECONNECT
  22579. * @see Realtime#event:RECONNECT
  22580. * @since 3.2.0
  22581. */
  22582. /**
  22583. * 客户端重新登录发生错误(网络连接已恢复,但重新登录错误)
  22584. * @event IMClient#RECONNECT_ERROR
  22585. * @since 3.2.0
  22586. */
  22587. .then(() => client.emit(RECONNECT), error => client.emit(RECONNECT_ERROR, error)));
  22588. internal(client)._eventemitter.on('beforeclose', () => {
  22589. delete realtime._IMClients[client.id];
  22590. if (realtime._firstIMClient === client) {
  22591. delete realtime._firstIMClient;
  22592. }
  22593. }, realtime);
  22594. internal(client)._eventemitter.on('close', () => {
  22595. realtime._deregister(client);
  22596. }, realtime);
  22597. return client._open(realtime._options.appId, _tag, deviceId, isReconnect).then(() => {
  22598. realtime._IMClients[client.id] = client;
  22599. realtime._IMClientsCreationCount += 1;
  22600. if (realtime._IMClientsCreationCount === 1) {
  22601. client._omitPeerId(true);
  22602. realtime._firstIMClient = client;
  22603. } else if (realtime._IMClientsCreationCount > 1 && realtime._firstIMClient) {
  22604. realtime._firstIMClient._omitPeerId(false);
  22605. }
  22606. realtime._register(client);
  22607. return client;
  22608. }).catch(error => {
  22609. delete realtime._IMClients[client.id];
  22610. throw error;
  22611. });
  22612. }).then(...finalize(() => {
  22613. realtime._deregisterPending(promise);
  22614. })).catch(error => {
  22615. delete realtime._IMClients[id];
  22616. throw error;
  22617. });
  22618. if (identity) {
  22619. realtime._IMClients[id] = promise;
  22620. }
  22621. realtime._registerPending(promise);
  22622. return promise;
  22623. };
  22624. Object.assign(realtime, {
  22625. register,
  22626. createIMClient
  22627. });
  22628. /* eslint-enable no-param-reassign */
  22629. };
  22630. const beforeCommandDispatch = (command, realtime) => {
  22631. const isIMCommand = command.service === null || command.service === 2;
  22632. if (!isIMCommand) return true;
  22633. const targetClient = command.peerId ? realtime._IMClients[command.peerId] : realtime._firstIMClient;
  22634. if (targetClient) {
  22635. Promise.resolve(targetClient).then(client => client._dispatchCommand(command)).catch(debug$d);
  22636. } else {
  22637. debug$d('[WARN] Unexpected message received without any live client match: %O', trim(command));
  22638. }
  22639. return false;
  22640. };
  22641. const IMPlugin = {
  22642. name: 'leancloud-realtime-plugin-im',
  22643. onRealtimeCreate,
  22644. beforeCommandDispatch,
  22645. messageClasses: [Message, BinaryMessage, RecalledMessage, TextMessage]
  22646. };
  22647. /** @module leancloud-realtime */
  22648. Realtime.defineConversationProperty = defineConversationProperty;
  22649. Realtime.__preRegisteredPlugins = [IMPlugin];
  22650. const Event = { ...CoreEvent,
  22651. ...IMEvent
  22652. };
  22653. /** core + plugins + platform adapters */
  22654. setAdapters({
  22655. WebSocket: lib_4,
  22656. request: lib_1$1
  22657. });
  22658. exports.BinaryMessage = BinaryMessage;
  22659. exports.ChatRoom = ChatRoom;
  22660. exports.Conversation = Conversation;
  22661. exports.ConversationMemberRole = ConversationMemberRole;
  22662. exports.ConversationQuery = ConversationQuery;
  22663. exports.ErrorCode = ErrorCode;
  22664. exports.Event = Event;
  22665. exports.EventEmitter = eventemitter3;
  22666. exports.IE10Compatible = IE10Compatible;
  22667. exports.IMPlugin = IMPlugin;
  22668. exports.Message = Message;
  22669. exports.MessageParser = MessageParser;
  22670. exports.MessagePriority = MessagePriority;
  22671. exports.MessageQueryDirection = MessageQueryDirection;
  22672. exports.MessageStatus = MessageStatus;
  22673. exports.Promise = polyfilledPromise;
  22674. exports.Protocals = message;
  22675. exports.Protocols = message;
  22676. exports.Realtime = Realtime;
  22677. exports.RecalledMessage = RecalledMessage;
  22678. exports.ServiceConversation = ServiceConversation;
  22679. exports.TemporaryConversation = TemporaryConversation;
  22680. exports.TextMessage = TextMessage;
  22681. exports.TypedMessage = TypedMessage;
  22682. exports.debug = debug$2;
  22683. exports.defineConversationProperty = defineConversationProperty;
  22684. exports.getAdapter = getAdapter;
  22685. exports.messageField = messageField;
  22686. exports.messageType = messageType;
  22687. exports.setAdapters = setAdapters;
  22688. Object.defineProperty(exports, '__esModule', { value: true });
  22689. })));
  22690. //# sourceMappingURL=im-browser.js.map