im.js 737 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173
  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 createCommonjsModule(fn, basedir, module) {
  12. return module = {
  13. path: basedir,
  14. exports: {},
  15. require: function (path, base) {
  16. return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
  17. }
  18. }, fn(module, module.exports), module.exports;
  19. }
  20. function getCjsExportFromNamespace (n) {
  21. return n && n['default'] || n;
  22. }
  23. function commonjsRequire () {
  24. throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
  25. }
  26. var long_1 = createCommonjsModule(function (module) {
  27. /*
  28. Copyright 2013 Daniel Wirtz <dcode@dcode.io>
  29. Copyright 2009 The Closure Library Authors. All Rights Reserved.
  30. Licensed under the Apache License, Version 2.0 (the "License");
  31. you may not use this file except in compliance with the License.
  32. You may obtain a copy of the License at
  33. http://www.apache.org/licenses/LICENSE-2.0
  34. Unless required by applicable law or agreed to in writing, software
  35. distributed under the License is distributed on an "AS-IS" BASIS,
  36. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  37. See the License for the specific language governing permissions and
  38. limitations under the License.
  39. */
  40. /**
  41. * @license long.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
  42. * Released under the Apache License, Version 2.0
  43. * see: https://github.com/dcodeIO/long.js for details
  44. */
  45. (function(global, factory) {
  46. /* AMD */ if (typeof commonjsRequire === 'function' && 'object' === "object" && module && module["exports"])
  47. module["exports"] = factory();
  48. /* Global */ else
  49. (global["dcodeIO"] = global["dcodeIO"] || {})["Long"] = factory();
  50. })(commonjsGlobal, function() {
  51. /**
  52. * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers.
  53. * See the from* functions below for more convenient ways of constructing Longs.
  54. * @exports Long
  55. * @class A Long class for representing a 64 bit two's-complement integer value.
  56. * @param {number} low The low (signed) 32 bits of the long
  57. * @param {number} high The high (signed) 32 bits of the long
  58. * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
  59. * @constructor
  60. */
  61. function Long(low, high, unsigned) {
  62. /**
  63. * The low 32 bits as a signed value.
  64. * @type {number}
  65. */
  66. this.low = low | 0;
  67. /**
  68. * The high 32 bits as a signed value.
  69. * @type {number}
  70. */
  71. this.high = high | 0;
  72. /**
  73. * Whether unsigned or not.
  74. * @type {boolean}
  75. */
  76. this.unsigned = !!unsigned;
  77. }
  78. // The internal representation of a long is the two given signed, 32-bit values.
  79. // We use 32-bit pieces because these are the size of integers on which
  80. // Javascript performs bit-operations. For operations like addition and
  81. // multiplication, we split each number into 16 bit pieces, which can easily be
  82. // multiplied within Javascript's floating-point representation without overflow
  83. // or change in sign.
  84. //
  85. // In the algorithms below, we frequently reduce the negative case to the
  86. // positive case by negating the input(s) and then post-processing the result.
  87. // Note that we must ALWAYS check specially whether those values are MIN_VALUE
  88. // (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
  89. // a positive number, it overflows back into a negative). Not handling this
  90. // case would often result in infinite recursion.
  91. //
  92. // Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from*
  93. // methods on which they depend.
  94. /**
  95. * An indicator used to reliably determine if an object is a Long or not.
  96. * @type {boolean}
  97. * @const
  98. * @private
  99. */
  100. Long.prototype.__isLong__;
  101. Object.defineProperty(Long.prototype, "__isLong__", {
  102. value: true,
  103. enumerable: false,
  104. configurable: false
  105. });
  106. /**
  107. * @function
  108. * @param {*} obj Object
  109. * @returns {boolean}
  110. * @inner
  111. */
  112. function isLong(obj) {
  113. return (obj && obj["__isLong__"]) === true;
  114. }
  115. /**
  116. * Tests if the specified object is a Long.
  117. * @function
  118. * @param {*} obj Object
  119. * @returns {boolean}
  120. */
  121. Long.isLong = isLong;
  122. /**
  123. * A cache of the Long representations of small integer values.
  124. * @type {!Object}
  125. * @inner
  126. */
  127. var INT_CACHE = {};
  128. /**
  129. * A cache of the Long representations of small unsigned integer values.
  130. * @type {!Object}
  131. * @inner
  132. */
  133. var UINT_CACHE = {};
  134. /**
  135. * @param {number} value
  136. * @param {boolean=} unsigned
  137. * @returns {!Long}
  138. * @inner
  139. */
  140. function fromInt(value, unsigned) {
  141. var obj, cachedObj, cache;
  142. if (unsigned) {
  143. value >>>= 0;
  144. if (cache = (0 <= value && value < 256)) {
  145. cachedObj = UINT_CACHE[value];
  146. if (cachedObj)
  147. return cachedObj;
  148. }
  149. obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true);
  150. if (cache)
  151. UINT_CACHE[value] = obj;
  152. return obj;
  153. } else {
  154. value |= 0;
  155. if (cache = (-128 <= value && value < 128)) {
  156. cachedObj = INT_CACHE[value];
  157. if (cachedObj)
  158. return cachedObj;
  159. }
  160. obj = fromBits(value, value < 0 ? -1 : 0, false);
  161. if (cache)
  162. INT_CACHE[value] = obj;
  163. return obj;
  164. }
  165. }
  166. /**
  167. * Returns a Long representing the given 32 bit integer value.
  168. * @function
  169. * @param {number} value The 32 bit integer in question
  170. * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
  171. * @returns {!Long} The corresponding Long value
  172. */
  173. Long.fromInt = fromInt;
  174. /**
  175. * @param {number} value
  176. * @param {boolean=} unsigned
  177. * @returns {!Long}
  178. * @inner
  179. */
  180. function fromNumber(value, unsigned) {
  181. if (isNaN(value) || !isFinite(value))
  182. return unsigned ? UZERO : ZERO;
  183. if (unsigned) {
  184. if (value < 0)
  185. return UZERO;
  186. if (value >= TWO_PWR_64_DBL)
  187. return MAX_UNSIGNED_VALUE;
  188. } else {
  189. if (value <= -TWO_PWR_63_DBL)
  190. return MIN_VALUE;
  191. if (value + 1 >= TWO_PWR_63_DBL)
  192. return MAX_VALUE;
  193. }
  194. if (value < 0)
  195. return fromNumber(-value, unsigned).neg();
  196. return fromBits((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned);
  197. }
  198. /**
  199. * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.
  200. * @function
  201. * @param {number} value The number in question
  202. * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
  203. * @returns {!Long} The corresponding Long value
  204. */
  205. Long.fromNumber = fromNumber;
  206. /**
  207. * @param {number} lowBits
  208. * @param {number} highBits
  209. * @param {boolean=} unsigned
  210. * @returns {!Long}
  211. * @inner
  212. */
  213. function fromBits(lowBits, highBits, unsigned) {
  214. return new Long(lowBits, highBits, unsigned);
  215. }
  216. /**
  217. * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is
  218. * assumed to use 32 bits.
  219. * @function
  220. * @param {number} lowBits The low 32 bits
  221. * @param {number} highBits The high 32 bits
  222. * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
  223. * @returns {!Long} The corresponding Long value
  224. */
  225. Long.fromBits = fromBits;
  226. /**
  227. * @function
  228. * @param {number} base
  229. * @param {number} exponent
  230. * @returns {number}
  231. * @inner
  232. */
  233. var pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4)
  234. /**
  235. * @param {string} str
  236. * @param {(boolean|number)=} unsigned
  237. * @param {number=} radix
  238. * @returns {!Long}
  239. * @inner
  240. */
  241. function fromString(str, unsigned, radix) {
  242. if (str.length === 0)
  243. throw Error('empty string');
  244. if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity")
  245. return ZERO;
  246. if (typeof unsigned === 'number') {
  247. // For goog.math.long compatibility
  248. radix = unsigned,
  249. unsigned = false;
  250. } else {
  251. unsigned = !! unsigned;
  252. }
  253. radix = radix || 10;
  254. if (radix < 2 || 36 < radix)
  255. throw RangeError('radix');
  256. var p;
  257. if ((p = str.indexOf('-')) > 0)
  258. throw Error('interior hyphen');
  259. else if (p === 0) {
  260. return fromString(str.substring(1), unsigned, radix).neg();
  261. }
  262. // Do several (8) digits each time through the loop, so as to
  263. // minimize the calls to the very expensive emulated div.
  264. var radixToPower = fromNumber(pow_dbl(radix, 8));
  265. var result = ZERO;
  266. for (var i = 0; i < str.length; i += 8) {
  267. var size = Math.min(8, str.length - i),
  268. value = parseInt(str.substring(i, i + size), radix);
  269. if (size < 8) {
  270. var power = fromNumber(pow_dbl(radix, size));
  271. result = result.mul(power).add(fromNumber(value));
  272. } else {
  273. result = result.mul(radixToPower);
  274. result = result.add(fromNumber(value));
  275. }
  276. }
  277. result.unsigned = unsigned;
  278. return result;
  279. }
  280. /**
  281. * Returns a Long representation of the given string, written using the specified radix.
  282. * @function
  283. * @param {string} str The textual representation of the Long
  284. * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed
  285. * @param {number=} radix The radix in which the text is written (2-36), defaults to 10
  286. * @returns {!Long} The corresponding Long value
  287. */
  288. Long.fromString = fromString;
  289. /**
  290. * @function
  291. * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val
  292. * @returns {!Long}
  293. * @inner
  294. */
  295. function fromValue(val) {
  296. if (val /* is compatible */ instanceof Long)
  297. return val;
  298. if (typeof val === 'number')
  299. return fromNumber(val);
  300. if (typeof val === 'string')
  301. return fromString(val);
  302. // Throws for non-objects, converts non-instanceof Long:
  303. return fromBits(val.low, val.high, val.unsigned);
  304. }
  305. /**
  306. * Converts the specified value to a Long.
  307. * @function
  308. * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value
  309. * @returns {!Long}
  310. */
  311. Long.fromValue = fromValue;
  312. // NOTE: the compiler should inline these constant values below and then remove these variables, so there should be
  313. // no runtime penalty for these.
  314. /**
  315. * @type {number}
  316. * @const
  317. * @inner
  318. */
  319. var TWO_PWR_16_DBL = 1 << 16;
  320. /**
  321. * @type {number}
  322. * @const
  323. * @inner
  324. */
  325. var TWO_PWR_24_DBL = 1 << 24;
  326. /**
  327. * @type {number}
  328. * @const
  329. * @inner
  330. */
  331. var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;
  332. /**
  333. * @type {number}
  334. * @const
  335. * @inner
  336. */
  337. var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;
  338. /**
  339. * @type {number}
  340. * @const
  341. * @inner
  342. */
  343. var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;
  344. /**
  345. * @type {!Long}
  346. * @const
  347. * @inner
  348. */
  349. var TWO_PWR_24 = fromInt(TWO_PWR_24_DBL);
  350. /**
  351. * @type {!Long}
  352. * @inner
  353. */
  354. var ZERO = fromInt(0);
  355. /**
  356. * Signed zero.
  357. * @type {!Long}
  358. */
  359. Long.ZERO = ZERO;
  360. /**
  361. * @type {!Long}
  362. * @inner
  363. */
  364. var UZERO = fromInt(0, true);
  365. /**
  366. * Unsigned zero.
  367. * @type {!Long}
  368. */
  369. Long.UZERO = UZERO;
  370. /**
  371. * @type {!Long}
  372. * @inner
  373. */
  374. var ONE = fromInt(1);
  375. /**
  376. * Signed one.
  377. * @type {!Long}
  378. */
  379. Long.ONE = ONE;
  380. /**
  381. * @type {!Long}
  382. * @inner
  383. */
  384. var UONE = fromInt(1, true);
  385. /**
  386. * Unsigned one.
  387. * @type {!Long}
  388. */
  389. Long.UONE = UONE;
  390. /**
  391. * @type {!Long}
  392. * @inner
  393. */
  394. var NEG_ONE = fromInt(-1);
  395. /**
  396. * Signed negative one.
  397. * @type {!Long}
  398. */
  399. Long.NEG_ONE = NEG_ONE;
  400. /**
  401. * @type {!Long}
  402. * @inner
  403. */
  404. var MAX_VALUE = fromBits(0xFFFFFFFF|0, 0x7FFFFFFF|0, false);
  405. /**
  406. * Maximum signed value.
  407. * @type {!Long}
  408. */
  409. Long.MAX_VALUE = MAX_VALUE;
  410. /**
  411. * @type {!Long}
  412. * @inner
  413. */
  414. var MAX_UNSIGNED_VALUE = fromBits(0xFFFFFFFF|0, 0xFFFFFFFF|0, true);
  415. /**
  416. * Maximum unsigned value.
  417. * @type {!Long}
  418. */
  419. Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE;
  420. /**
  421. * @type {!Long}
  422. * @inner
  423. */
  424. var MIN_VALUE = fromBits(0, 0x80000000|0, false);
  425. /**
  426. * Minimum signed value.
  427. * @type {!Long}
  428. */
  429. Long.MIN_VALUE = MIN_VALUE;
  430. /**
  431. * @alias Long.prototype
  432. * @inner
  433. */
  434. var LongPrototype = Long.prototype;
  435. /**
  436. * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.
  437. * @returns {number}
  438. */
  439. LongPrototype.toInt = function toInt() {
  440. return this.unsigned ? this.low >>> 0 : this.low;
  441. };
  442. /**
  443. * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).
  444. * @returns {number}
  445. */
  446. LongPrototype.toNumber = function toNumber() {
  447. if (this.unsigned)
  448. return ((this.high >>> 0) * TWO_PWR_32_DBL) + (this.low >>> 0);
  449. return this.high * TWO_PWR_32_DBL + (this.low >>> 0);
  450. };
  451. /**
  452. * Converts the Long to a string written in the specified radix.
  453. * @param {number=} radix Radix (2-36), defaults to 10
  454. * @returns {string}
  455. * @override
  456. * @throws {RangeError} If `radix` is out of range
  457. */
  458. LongPrototype.toString = function toString(radix) {
  459. radix = radix || 10;
  460. if (radix < 2 || 36 < radix)
  461. throw RangeError('radix');
  462. if (this.isZero())
  463. return '0';
  464. if (this.isNegative()) { // Unsigned Longs are never negative
  465. if (this.eq(MIN_VALUE)) {
  466. // We need to change the Long value before it can be negated, so we remove
  467. // the bottom-most digit in this base and then recurse to do the rest.
  468. var radixLong = fromNumber(radix),
  469. div = this.div(radixLong),
  470. rem1 = div.mul(radixLong).sub(this);
  471. return div.toString(radix) + rem1.toInt().toString(radix);
  472. } else
  473. return '-' + this.neg().toString(radix);
  474. }
  475. // Do several (6) digits each time through the loop, so as to
  476. // minimize the calls to the very expensive emulated div.
  477. var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned),
  478. rem = this;
  479. var result = '';
  480. while (true) {
  481. var remDiv = rem.div(radixToPower),
  482. intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0,
  483. digits = intval.toString(radix);
  484. rem = remDiv;
  485. if (rem.isZero())
  486. return digits + result;
  487. else {
  488. while (digits.length < 6)
  489. digits = '0' + digits;
  490. result = '' + digits + result;
  491. }
  492. }
  493. };
  494. /**
  495. * Gets the high 32 bits as a signed integer.
  496. * @returns {number} Signed high bits
  497. */
  498. LongPrototype.getHighBits = function getHighBits() {
  499. return this.high;
  500. };
  501. /**
  502. * Gets the high 32 bits as an unsigned integer.
  503. * @returns {number} Unsigned high bits
  504. */
  505. LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() {
  506. return this.high >>> 0;
  507. };
  508. /**
  509. * Gets the low 32 bits as a signed integer.
  510. * @returns {number} Signed low bits
  511. */
  512. LongPrototype.getLowBits = function getLowBits() {
  513. return this.low;
  514. };
  515. /**
  516. * Gets the low 32 bits as an unsigned integer.
  517. * @returns {number} Unsigned low bits
  518. */
  519. LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() {
  520. return this.low >>> 0;
  521. };
  522. /**
  523. * Gets the number of bits needed to represent the absolute value of this Long.
  524. * @returns {number}
  525. */
  526. LongPrototype.getNumBitsAbs = function getNumBitsAbs() {
  527. if (this.isNegative()) // Unsigned Longs are never negative
  528. return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs();
  529. var val = this.high != 0 ? this.high : this.low;
  530. for (var bit = 31; bit > 0; bit--)
  531. if ((val & (1 << bit)) != 0)
  532. break;
  533. return this.high != 0 ? bit + 33 : bit + 1;
  534. };
  535. /**
  536. * Tests if this Long's value equals zero.
  537. * @returns {boolean}
  538. */
  539. LongPrototype.isZero = function isZero() {
  540. return this.high === 0 && this.low === 0;
  541. };
  542. /**
  543. * Tests if this Long's value is negative.
  544. * @returns {boolean}
  545. */
  546. LongPrototype.isNegative = function isNegative() {
  547. return !this.unsigned && this.high < 0;
  548. };
  549. /**
  550. * Tests if this Long's value is positive.
  551. * @returns {boolean}
  552. */
  553. LongPrototype.isPositive = function isPositive() {
  554. return this.unsigned || this.high >= 0;
  555. };
  556. /**
  557. * Tests if this Long's value is odd.
  558. * @returns {boolean}
  559. */
  560. LongPrototype.isOdd = function isOdd() {
  561. return (this.low & 1) === 1;
  562. };
  563. /**
  564. * Tests if this Long's value is even.
  565. * @returns {boolean}
  566. */
  567. LongPrototype.isEven = function isEven() {
  568. return (this.low & 1) === 0;
  569. };
  570. /**
  571. * Tests if this Long's value equals the specified's.
  572. * @param {!Long|number|string} other Other value
  573. * @returns {boolean}
  574. */
  575. LongPrototype.equals = function equals(other) {
  576. if (!isLong(other))
  577. other = fromValue(other);
  578. if (this.unsigned !== other.unsigned && (this.high >>> 31) === 1 && (other.high >>> 31) === 1)
  579. return false;
  580. return this.high === other.high && this.low === other.low;
  581. };
  582. /**
  583. * Tests if this Long's value equals the specified's. This is an alias of {@link Long#equals}.
  584. * @function
  585. * @param {!Long|number|string} other Other value
  586. * @returns {boolean}
  587. */
  588. LongPrototype.eq = LongPrototype.equals;
  589. /**
  590. * Tests if this Long's value differs from the specified's.
  591. * @param {!Long|number|string} other Other value
  592. * @returns {boolean}
  593. */
  594. LongPrototype.notEquals = function notEquals(other) {
  595. return !this.eq(/* validates */ other);
  596. };
  597. /**
  598. * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}.
  599. * @function
  600. * @param {!Long|number|string} other Other value
  601. * @returns {boolean}
  602. */
  603. LongPrototype.neq = LongPrototype.notEquals;
  604. /**
  605. * Tests if this Long's value is less than the specified's.
  606. * @param {!Long|number|string} other Other value
  607. * @returns {boolean}
  608. */
  609. LongPrototype.lessThan = function lessThan(other) {
  610. return this.comp(/* validates */ other) < 0;
  611. };
  612. /**
  613. * Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}.
  614. * @function
  615. * @param {!Long|number|string} other Other value
  616. * @returns {boolean}
  617. */
  618. LongPrototype.lt = LongPrototype.lessThan;
  619. /**
  620. * Tests if this Long's value is less than or equal the specified's.
  621. * @param {!Long|number|string} other Other value
  622. * @returns {boolean}
  623. */
  624. LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) {
  625. return this.comp(/* validates */ other) <= 0;
  626. };
  627. /**
  628. * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.
  629. * @function
  630. * @param {!Long|number|string} other Other value
  631. * @returns {boolean}
  632. */
  633. LongPrototype.lte = LongPrototype.lessThanOrEqual;
  634. /**
  635. * Tests if this Long's value is greater than the specified's.
  636. * @param {!Long|number|string} other Other value
  637. * @returns {boolean}
  638. */
  639. LongPrototype.greaterThan = function greaterThan(other) {
  640. return this.comp(/* validates */ other) > 0;
  641. };
  642. /**
  643. * Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}.
  644. * @function
  645. * @param {!Long|number|string} other Other value
  646. * @returns {boolean}
  647. */
  648. LongPrototype.gt = LongPrototype.greaterThan;
  649. /**
  650. * Tests if this Long's value is greater than or equal the specified's.
  651. * @param {!Long|number|string} other Other value
  652. * @returns {boolean}
  653. */
  654. LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) {
  655. return this.comp(/* validates */ other) >= 0;
  656. };
  657. /**
  658. * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.
  659. * @function
  660. * @param {!Long|number|string} other Other value
  661. * @returns {boolean}
  662. */
  663. LongPrototype.gte = LongPrototype.greaterThanOrEqual;
  664. /**
  665. * Compares this Long's value with the specified's.
  666. * @param {!Long|number|string} other Other value
  667. * @returns {number} 0 if they are the same, 1 if the this is greater and -1
  668. * if the given one is greater
  669. */
  670. LongPrototype.compare = function compare(other) {
  671. if (!isLong(other))
  672. other = fromValue(other);
  673. if (this.eq(other))
  674. return 0;
  675. var thisNeg = this.isNegative(),
  676. otherNeg = other.isNegative();
  677. if (thisNeg && !otherNeg)
  678. return -1;
  679. if (!thisNeg && otherNeg)
  680. return 1;
  681. // At this point the sign bits are the same
  682. if (!this.unsigned)
  683. return this.sub(other).isNegative() ? -1 : 1;
  684. // Both are positive if at least one is unsigned
  685. return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1;
  686. };
  687. /**
  688. * Compares this Long's value with the specified's. This is an alias of {@link Long#compare}.
  689. * @function
  690. * @param {!Long|number|string} other Other value
  691. * @returns {number} 0 if they are the same, 1 if the this is greater and -1
  692. * if the given one is greater
  693. */
  694. LongPrototype.comp = LongPrototype.compare;
  695. /**
  696. * Negates this Long's value.
  697. * @returns {!Long} Negated Long
  698. */
  699. LongPrototype.negate = function negate() {
  700. if (!this.unsigned && this.eq(MIN_VALUE))
  701. return MIN_VALUE;
  702. return this.not().add(ONE);
  703. };
  704. /**
  705. * Negates this Long's value. This is an alias of {@link Long#negate}.
  706. * @function
  707. * @returns {!Long} Negated Long
  708. */
  709. LongPrototype.neg = LongPrototype.negate;
  710. /**
  711. * Returns the sum of this and the specified Long.
  712. * @param {!Long|number|string} addend Addend
  713. * @returns {!Long} Sum
  714. */
  715. LongPrototype.add = function add(addend) {
  716. if (!isLong(addend))
  717. addend = fromValue(addend);
  718. // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
  719. var a48 = this.high >>> 16;
  720. var a32 = this.high & 0xFFFF;
  721. var a16 = this.low >>> 16;
  722. var a00 = this.low & 0xFFFF;
  723. var b48 = addend.high >>> 16;
  724. var b32 = addend.high & 0xFFFF;
  725. var b16 = addend.low >>> 16;
  726. var b00 = addend.low & 0xFFFF;
  727. var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
  728. c00 += a00 + b00;
  729. c16 += c00 >>> 16;
  730. c00 &= 0xFFFF;
  731. c16 += a16 + b16;
  732. c32 += c16 >>> 16;
  733. c16 &= 0xFFFF;
  734. c32 += a32 + b32;
  735. c48 += c32 >>> 16;
  736. c32 &= 0xFFFF;
  737. c48 += a48 + b48;
  738. c48 &= 0xFFFF;
  739. return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
  740. };
  741. /**
  742. * Returns the difference of this and the specified Long.
  743. * @param {!Long|number|string} subtrahend Subtrahend
  744. * @returns {!Long} Difference
  745. */
  746. LongPrototype.subtract = function subtract(subtrahend) {
  747. if (!isLong(subtrahend))
  748. subtrahend = fromValue(subtrahend);
  749. return this.add(subtrahend.neg());
  750. };
  751. /**
  752. * Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}.
  753. * @function
  754. * @param {!Long|number|string} subtrahend Subtrahend
  755. * @returns {!Long} Difference
  756. */
  757. LongPrototype.sub = LongPrototype.subtract;
  758. /**
  759. * Returns the product of this and the specified Long.
  760. * @param {!Long|number|string} multiplier Multiplier
  761. * @returns {!Long} Product
  762. */
  763. LongPrototype.multiply = function multiply(multiplier) {
  764. if (this.isZero())
  765. return ZERO;
  766. if (!isLong(multiplier))
  767. multiplier = fromValue(multiplier);
  768. if (multiplier.isZero())
  769. return ZERO;
  770. if (this.eq(MIN_VALUE))
  771. return multiplier.isOdd() ? MIN_VALUE : ZERO;
  772. if (multiplier.eq(MIN_VALUE))
  773. return this.isOdd() ? MIN_VALUE : ZERO;
  774. if (this.isNegative()) {
  775. if (multiplier.isNegative())
  776. return this.neg().mul(multiplier.neg());
  777. else
  778. return this.neg().mul(multiplier).neg();
  779. } else if (multiplier.isNegative())
  780. return this.mul(multiplier.neg()).neg();
  781. // If both longs are small, use float multiplication
  782. if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24))
  783. return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned);
  784. // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
  785. // We can skip products that would overflow.
  786. var a48 = this.high >>> 16;
  787. var a32 = this.high & 0xFFFF;
  788. var a16 = this.low >>> 16;
  789. var a00 = this.low & 0xFFFF;
  790. var b48 = multiplier.high >>> 16;
  791. var b32 = multiplier.high & 0xFFFF;
  792. var b16 = multiplier.low >>> 16;
  793. var b00 = multiplier.low & 0xFFFF;
  794. var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
  795. c00 += a00 * b00;
  796. c16 += c00 >>> 16;
  797. c00 &= 0xFFFF;
  798. c16 += a16 * b00;
  799. c32 += c16 >>> 16;
  800. c16 &= 0xFFFF;
  801. c16 += a00 * b16;
  802. c32 += c16 >>> 16;
  803. c16 &= 0xFFFF;
  804. c32 += a32 * b00;
  805. c48 += c32 >>> 16;
  806. c32 &= 0xFFFF;
  807. c32 += a16 * b16;
  808. c48 += c32 >>> 16;
  809. c32 &= 0xFFFF;
  810. c32 += a00 * b32;
  811. c48 += c32 >>> 16;
  812. c32 &= 0xFFFF;
  813. c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
  814. c48 &= 0xFFFF;
  815. return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
  816. };
  817. /**
  818. * Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}.
  819. * @function
  820. * @param {!Long|number|string} multiplier Multiplier
  821. * @returns {!Long} Product
  822. */
  823. LongPrototype.mul = LongPrototype.multiply;
  824. /**
  825. * Returns this Long divided by the specified. The result is signed if this Long is signed or
  826. * unsigned if this Long is unsigned.
  827. * @param {!Long|number|string} divisor Divisor
  828. * @returns {!Long} Quotient
  829. */
  830. LongPrototype.divide = function divide(divisor) {
  831. if (!isLong(divisor))
  832. divisor = fromValue(divisor);
  833. if (divisor.isZero())
  834. throw Error('division by zero');
  835. if (this.isZero())
  836. return this.unsigned ? UZERO : ZERO;
  837. var approx, rem, res;
  838. if (!this.unsigned) {
  839. // This section is only relevant for signed longs and is derived from the
  840. // closure library as a whole.
  841. if (this.eq(MIN_VALUE)) {
  842. if (divisor.eq(ONE) || divisor.eq(NEG_ONE))
  843. return MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE
  844. else if (divisor.eq(MIN_VALUE))
  845. return ONE;
  846. else {
  847. // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
  848. var halfThis = this.shr(1);
  849. approx = halfThis.div(divisor).shl(1);
  850. if (approx.eq(ZERO)) {
  851. return divisor.isNegative() ? ONE : NEG_ONE;
  852. } else {
  853. rem = this.sub(divisor.mul(approx));
  854. res = approx.add(rem.div(divisor));
  855. return res;
  856. }
  857. }
  858. } else if (divisor.eq(MIN_VALUE))
  859. return this.unsigned ? UZERO : ZERO;
  860. if (this.isNegative()) {
  861. if (divisor.isNegative())
  862. return this.neg().div(divisor.neg());
  863. return this.neg().div(divisor).neg();
  864. } else if (divisor.isNegative())
  865. return this.div(divisor.neg()).neg();
  866. res = ZERO;
  867. } else {
  868. // The algorithm below has not been made for unsigned longs. It's therefore
  869. // required to take special care of the MSB prior to running it.
  870. if (!divisor.unsigned)
  871. divisor = divisor.toUnsigned();
  872. if (divisor.gt(this))
  873. return UZERO;
  874. if (divisor.gt(this.shru(1))) // 15 >>> 1 = 7 ; with divisor = 8 ; true
  875. return UONE;
  876. res = UZERO;
  877. }
  878. // Repeat the following until the remainder is less than other: find a
  879. // floating-point that approximates remainder / other *from below*, add this
  880. // into the result, and subtract it from the remainder. It is critical that
  881. // the approximate value is less than or equal to the real value so that the
  882. // remainder never becomes negative.
  883. rem = this;
  884. while (rem.gte(divisor)) {
  885. // Approximate the result of division. This may be a little greater or
  886. // smaller than the actual value.
  887. approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber()));
  888. // We will tweak the approximate result by changing it in the 48-th digit or
  889. // the smallest non-fractional digit, whichever is larger.
  890. var log2 = Math.ceil(Math.log(approx) / Math.LN2),
  891. delta = (log2 <= 48) ? 1 : pow_dbl(2, log2 - 48),
  892. // Decrease the approximation until it is smaller than the remainder. Note
  893. // that if it is too large, the product overflows and is negative.
  894. approxRes = fromNumber(approx),
  895. approxRem = approxRes.mul(divisor);
  896. while (approxRem.isNegative() || approxRem.gt(rem)) {
  897. approx -= delta;
  898. approxRes = fromNumber(approx, this.unsigned);
  899. approxRem = approxRes.mul(divisor);
  900. }
  901. // We know the answer can't be zero... and actually, zero would cause
  902. // infinite recursion since we would make no progress.
  903. if (approxRes.isZero())
  904. approxRes = ONE;
  905. res = res.add(approxRes);
  906. rem = rem.sub(approxRem);
  907. }
  908. return res;
  909. };
  910. /**
  911. * Returns this Long divided by the specified. This is an alias of {@link Long#divide}.
  912. * @function
  913. * @param {!Long|number|string} divisor Divisor
  914. * @returns {!Long} Quotient
  915. */
  916. LongPrototype.div = LongPrototype.divide;
  917. /**
  918. * Returns this Long modulo the specified.
  919. * @param {!Long|number|string} divisor Divisor
  920. * @returns {!Long} Remainder
  921. */
  922. LongPrototype.modulo = function modulo(divisor) {
  923. if (!isLong(divisor))
  924. divisor = fromValue(divisor);
  925. return this.sub(this.div(divisor).mul(divisor));
  926. };
  927. /**
  928. * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.
  929. * @function
  930. * @param {!Long|number|string} divisor Divisor
  931. * @returns {!Long} Remainder
  932. */
  933. LongPrototype.mod = LongPrototype.modulo;
  934. /**
  935. * Returns the bitwise NOT of this Long.
  936. * @returns {!Long}
  937. */
  938. LongPrototype.not = function not() {
  939. return fromBits(~this.low, ~this.high, this.unsigned);
  940. };
  941. /**
  942. * Returns the bitwise AND of this Long and the specified.
  943. * @param {!Long|number|string} other Other Long
  944. * @returns {!Long}
  945. */
  946. LongPrototype.and = function and(other) {
  947. if (!isLong(other))
  948. other = fromValue(other);
  949. return fromBits(this.low & other.low, this.high & other.high, this.unsigned);
  950. };
  951. /**
  952. * Returns the bitwise OR of this Long and the specified.
  953. * @param {!Long|number|string} other Other Long
  954. * @returns {!Long}
  955. */
  956. LongPrototype.or = function or(other) {
  957. if (!isLong(other))
  958. other = fromValue(other);
  959. return fromBits(this.low | other.low, this.high | other.high, this.unsigned);
  960. };
  961. /**
  962. * Returns the bitwise XOR of this Long and the given one.
  963. * @param {!Long|number|string} other Other Long
  964. * @returns {!Long}
  965. */
  966. LongPrototype.xor = function xor(other) {
  967. if (!isLong(other))
  968. other = fromValue(other);
  969. return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned);
  970. };
  971. /**
  972. * Returns this Long with bits shifted to the left by the given amount.
  973. * @param {number|!Long} numBits Number of bits
  974. * @returns {!Long} Shifted Long
  975. */
  976. LongPrototype.shiftLeft = function shiftLeft(numBits) {
  977. if (isLong(numBits))
  978. numBits = numBits.toInt();
  979. if ((numBits &= 63) === 0)
  980. return this;
  981. else if (numBits < 32)
  982. return fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned);
  983. else
  984. return fromBits(0, this.low << (numBits - 32), this.unsigned);
  985. };
  986. /**
  987. * Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}.
  988. * @function
  989. * @param {number|!Long} numBits Number of bits
  990. * @returns {!Long} Shifted Long
  991. */
  992. LongPrototype.shl = LongPrototype.shiftLeft;
  993. /**
  994. * Returns this Long with bits arithmetically shifted to the right by the given amount.
  995. * @param {number|!Long} numBits Number of bits
  996. * @returns {!Long} Shifted Long
  997. */
  998. LongPrototype.shiftRight = function shiftRight(numBits) {
  999. if (isLong(numBits))
  1000. numBits = numBits.toInt();
  1001. if ((numBits &= 63) === 0)
  1002. return this;
  1003. else if (numBits < 32)
  1004. return fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned);
  1005. else
  1006. return fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned);
  1007. };
  1008. /**
  1009. * Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}.
  1010. * @function
  1011. * @param {number|!Long} numBits Number of bits
  1012. * @returns {!Long} Shifted Long
  1013. */
  1014. LongPrototype.shr = LongPrototype.shiftRight;
  1015. /**
  1016. * Returns this Long with bits logically shifted to the right by the given amount.
  1017. * @param {number|!Long} numBits Number of bits
  1018. * @returns {!Long} Shifted Long
  1019. */
  1020. LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) {
  1021. if (isLong(numBits))
  1022. numBits = numBits.toInt();
  1023. numBits &= 63;
  1024. if (numBits === 0)
  1025. return this;
  1026. else {
  1027. var high = this.high;
  1028. if (numBits < 32) {
  1029. var low = this.low;
  1030. return fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned);
  1031. } else if (numBits === 32)
  1032. return fromBits(high, 0, this.unsigned);
  1033. else
  1034. return fromBits(high >>> (numBits - 32), 0, this.unsigned);
  1035. }
  1036. };
  1037. /**
  1038. * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.
  1039. * @function
  1040. * @param {number|!Long} numBits Number of bits
  1041. * @returns {!Long} Shifted Long
  1042. */
  1043. LongPrototype.shru = LongPrototype.shiftRightUnsigned;
  1044. /**
  1045. * Converts this Long to signed.
  1046. * @returns {!Long} Signed long
  1047. */
  1048. LongPrototype.toSigned = function toSigned() {
  1049. if (!this.unsigned)
  1050. return this;
  1051. return fromBits(this.low, this.high, false);
  1052. };
  1053. /**
  1054. * Converts this Long to unsigned.
  1055. * @returns {!Long} Unsigned long
  1056. */
  1057. LongPrototype.toUnsigned = function toUnsigned() {
  1058. if (this.unsigned)
  1059. return this;
  1060. return fromBits(this.low, this.high, true);
  1061. };
  1062. /**
  1063. * Converts this Long to its byte representation.
  1064. * @param {boolean=} le Whether little or big endian, defaults to big endian
  1065. * @returns {!Array.<number>} Byte representation
  1066. */
  1067. LongPrototype.toBytes = function(le) {
  1068. return le ? this.toBytesLE() : this.toBytesBE();
  1069. };
  1070. /**
  1071. * Converts this Long to its little endian byte representation.
  1072. * @returns {!Array.<number>} Little endian byte representation
  1073. */
  1074. LongPrototype.toBytesLE = function() {
  1075. var hi = this.high,
  1076. lo = this.low;
  1077. return [
  1078. lo & 0xff,
  1079. (lo >>> 8) & 0xff,
  1080. (lo >>> 16) & 0xff,
  1081. (lo >>> 24) & 0xff,
  1082. hi & 0xff,
  1083. (hi >>> 8) & 0xff,
  1084. (hi >>> 16) & 0xff,
  1085. (hi >>> 24) & 0xff
  1086. ];
  1087. };
  1088. /**
  1089. * Converts this Long to its big endian byte representation.
  1090. * @returns {!Array.<number>} Big endian byte representation
  1091. */
  1092. LongPrototype.toBytesBE = function() {
  1093. var hi = this.high,
  1094. lo = this.low;
  1095. return [
  1096. (hi >>> 24) & 0xff,
  1097. (hi >>> 16) & 0xff,
  1098. (hi >>> 8) & 0xff,
  1099. hi & 0xff,
  1100. (lo >>> 24) & 0xff,
  1101. (lo >>> 16) & 0xff,
  1102. (lo >>> 8) & 0xff,
  1103. lo & 0xff
  1104. ];
  1105. };
  1106. return Long;
  1107. });
  1108. });
  1109. var bytebuffer = createCommonjsModule(function (module) {
  1110. /*
  1111. Copyright 2013-2014 Daniel Wirtz <dcode@dcode.io>
  1112. Licensed under the Apache License, Version 2.0 (the "License");
  1113. you may not use this file except in compliance with the License.
  1114. You may obtain a copy of the License at
  1115. http://www.apache.org/licenses/LICENSE-2.0
  1116. Unless required by applicable law or agreed to in writing, software
  1117. distributed under the License is distributed on an "AS IS" BASIS,
  1118. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1119. See the License for the specific language governing permissions and
  1120. limitations under the License.
  1121. */
  1122. /**
  1123. * @license bytebuffer.js (c) 2015 Daniel Wirtz <dcode@dcode.io>
  1124. * Backing buffer: ArrayBuffer, Accessor: Uint8Array
  1125. * Released under the Apache License, Version 2.0
  1126. * see: https://github.com/dcodeIO/bytebuffer.js for details
  1127. */
  1128. (function(global, factory) {
  1129. /* AMD */ if (typeof commonjsRequire === 'function' && 'object' === "object" && module && module["exports"])
  1130. module['exports'] = (function() {
  1131. var Long; try { Long = long_1; } catch (e) {}
  1132. return factory(Long);
  1133. })();
  1134. /* Global */ else
  1135. (global["dcodeIO"] = global["dcodeIO"] || {})["ByteBuffer"] = factory(global["dcodeIO"]["Long"]);
  1136. })(commonjsGlobal, function(Long) {
  1137. /**
  1138. * Constructs a new ByteBuffer.
  1139. * @class The swiss army knife for binary data in JavaScript.
  1140. * @exports ByteBuffer
  1141. * @constructor
  1142. * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
  1143. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  1144. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  1145. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  1146. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  1147. * @expose
  1148. */
  1149. var ByteBuffer = function(capacity, littleEndian, noAssert) {
  1150. if (typeof capacity === 'undefined')
  1151. capacity = ByteBuffer.DEFAULT_CAPACITY;
  1152. if (typeof littleEndian === 'undefined')
  1153. littleEndian = ByteBuffer.DEFAULT_ENDIAN;
  1154. if (typeof noAssert === 'undefined')
  1155. noAssert = ByteBuffer.DEFAULT_NOASSERT;
  1156. if (!noAssert) {
  1157. capacity = capacity | 0;
  1158. if (capacity < 0)
  1159. throw RangeError("Illegal capacity");
  1160. littleEndian = !!littleEndian;
  1161. noAssert = !!noAssert;
  1162. }
  1163. /**
  1164. * Backing ArrayBuffer.
  1165. * @type {!ArrayBuffer}
  1166. * @expose
  1167. */
  1168. this.buffer = capacity === 0 ? EMPTY_BUFFER : new ArrayBuffer(capacity);
  1169. /**
  1170. * Uint8Array utilized to manipulate the backing buffer. Becomes `null` if the backing buffer has a capacity of `0`.
  1171. * @type {?Uint8Array}
  1172. * @expose
  1173. */
  1174. this.view = capacity === 0 ? null : new Uint8Array(this.buffer);
  1175. /**
  1176. * Absolute read/write offset.
  1177. * @type {number}
  1178. * @expose
  1179. * @see ByteBuffer#flip
  1180. * @see ByteBuffer#clear
  1181. */
  1182. this.offset = 0;
  1183. /**
  1184. * Marked offset.
  1185. * @type {number}
  1186. * @expose
  1187. * @see ByteBuffer#mark
  1188. * @see ByteBuffer#reset
  1189. */
  1190. this.markedOffset = -1;
  1191. /**
  1192. * Absolute limit of the contained data. Set to the backing buffer's capacity upon allocation.
  1193. * @type {number}
  1194. * @expose
  1195. * @see ByteBuffer#flip
  1196. * @see ByteBuffer#clear
  1197. */
  1198. this.limit = capacity;
  1199. /**
  1200. * Whether to use little endian byte order, defaults to `false` for big endian.
  1201. * @type {boolean}
  1202. * @expose
  1203. */
  1204. this.littleEndian = littleEndian;
  1205. /**
  1206. * Whether to skip assertions of offsets and values, defaults to `false`.
  1207. * @type {boolean}
  1208. * @expose
  1209. */
  1210. this.noAssert = noAssert;
  1211. };
  1212. /**
  1213. * ByteBuffer version.
  1214. * @type {string}
  1215. * @const
  1216. * @expose
  1217. */
  1218. ByteBuffer.VERSION = "5.0.1";
  1219. /**
  1220. * Little endian constant that can be used instead of its boolean value. Evaluates to `true`.
  1221. * @type {boolean}
  1222. * @const
  1223. * @expose
  1224. */
  1225. ByteBuffer.LITTLE_ENDIAN = true;
  1226. /**
  1227. * Big endian constant that can be used instead of its boolean value. Evaluates to `false`.
  1228. * @type {boolean}
  1229. * @const
  1230. * @expose
  1231. */
  1232. ByteBuffer.BIG_ENDIAN = false;
  1233. /**
  1234. * Default initial capacity of `16`.
  1235. * @type {number}
  1236. * @expose
  1237. */
  1238. ByteBuffer.DEFAULT_CAPACITY = 16;
  1239. /**
  1240. * Default endianess of `false` for big endian.
  1241. * @type {boolean}
  1242. * @expose
  1243. */
  1244. ByteBuffer.DEFAULT_ENDIAN = ByteBuffer.BIG_ENDIAN;
  1245. /**
  1246. * Default no assertions flag of `false`.
  1247. * @type {boolean}
  1248. * @expose
  1249. */
  1250. ByteBuffer.DEFAULT_NOASSERT = false;
  1251. /**
  1252. * A `Long` class for representing a 64-bit two's-complement integer value. May be `null` if Long.js has not been loaded
  1253. * and int64 support is not available.
  1254. * @type {?Long}
  1255. * @const
  1256. * @see https://github.com/dcodeIO/long.js
  1257. * @expose
  1258. */
  1259. ByteBuffer.Long = Long || null;
  1260. /**
  1261. * @alias ByteBuffer.prototype
  1262. * @inner
  1263. */
  1264. var ByteBufferPrototype = ByteBuffer.prototype;
  1265. /**
  1266. * An indicator used to reliably determine if an object is a ByteBuffer or not.
  1267. * @type {boolean}
  1268. * @const
  1269. * @expose
  1270. * @private
  1271. */
  1272. ByteBufferPrototype.__isByteBuffer__;
  1273. Object.defineProperty(ByteBufferPrototype, "__isByteBuffer__", {
  1274. value: true,
  1275. enumerable: false,
  1276. configurable: false
  1277. });
  1278. // helpers
  1279. /**
  1280. * @type {!ArrayBuffer}
  1281. * @inner
  1282. */
  1283. var EMPTY_BUFFER = new ArrayBuffer(0);
  1284. /**
  1285. * String.fromCharCode reference for compile-time renaming.
  1286. * @type {function(...number):string}
  1287. * @inner
  1288. */
  1289. var stringFromCharCode = String.fromCharCode;
  1290. /**
  1291. * Creates a source function for a string.
  1292. * @param {string} s String to read from
  1293. * @returns {function():number|null} Source function returning the next char code respectively `null` if there are
  1294. * no more characters left.
  1295. * @throws {TypeError} If the argument is invalid
  1296. * @inner
  1297. */
  1298. function stringSource(s) {
  1299. var i=0; return function() {
  1300. return i < s.length ? s.charCodeAt(i++) : null;
  1301. };
  1302. }
  1303. /**
  1304. * Creates a destination function for a string.
  1305. * @returns {function(number=):undefined|string} Destination function successively called with the next char code.
  1306. * Returns the final string when called without arguments.
  1307. * @inner
  1308. */
  1309. function stringDestination() {
  1310. var cs = [], ps = []; return function() {
  1311. if (arguments.length === 0)
  1312. return ps.join('')+stringFromCharCode.apply(String, cs);
  1313. if (cs.length + arguments.length > 1024)
  1314. ps.push(stringFromCharCode.apply(String, cs)),
  1315. cs.length = 0;
  1316. Array.prototype.push.apply(cs, arguments);
  1317. };
  1318. }
  1319. /**
  1320. * Gets the accessor type.
  1321. * @returns {Function} `Buffer` under node.js, `Uint8Array` respectively `DataView` in the browser (classes)
  1322. * @expose
  1323. */
  1324. ByteBuffer.accessor = function() {
  1325. return Uint8Array;
  1326. };
  1327. /**
  1328. * Allocates a new ByteBuffer backed by a buffer of the specified capacity.
  1329. * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
  1330. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  1331. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  1332. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  1333. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  1334. * @returns {!ByteBuffer}
  1335. * @expose
  1336. */
  1337. ByteBuffer.allocate = function(capacity, littleEndian, noAssert) {
  1338. return new ByteBuffer(capacity, littleEndian, noAssert);
  1339. };
  1340. /**
  1341. * Concatenates multiple ByteBuffers into one.
  1342. * @param {!Array.<!ByteBuffer|!ArrayBuffer|!Uint8Array|string>} buffers Buffers to concatenate
  1343. * @param {(string|boolean)=} encoding String encoding if `buffers` contains a string ("base64", "hex", "binary",
  1344. * defaults to "utf8")
  1345. * @param {boolean=} littleEndian Whether to use little or big endian byte order for the resulting ByteBuffer. Defaults
  1346. * to {@link ByteBuffer.DEFAULT_ENDIAN}.
  1347. * @param {boolean=} noAssert Whether to skip assertions of offsets and values for the resulting ByteBuffer. Defaults to
  1348. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  1349. * @returns {!ByteBuffer} Concatenated ByteBuffer
  1350. * @expose
  1351. */
  1352. ByteBuffer.concat = function(buffers, encoding, littleEndian, noAssert) {
  1353. if (typeof encoding === 'boolean' || typeof encoding !== 'string') {
  1354. noAssert = littleEndian;
  1355. littleEndian = encoding;
  1356. encoding = undefined;
  1357. }
  1358. var capacity = 0;
  1359. for (var i=0, k=buffers.length, length; i<k; ++i) {
  1360. if (!ByteBuffer.isByteBuffer(buffers[i]))
  1361. buffers[i] = ByteBuffer.wrap(buffers[i], encoding);
  1362. length = buffers[i].limit - buffers[i].offset;
  1363. if (length > 0) capacity += length;
  1364. }
  1365. if (capacity === 0)
  1366. return new ByteBuffer(0, littleEndian, noAssert);
  1367. var bb = new ByteBuffer(capacity, littleEndian, noAssert),
  1368. bi;
  1369. i=0; while (i<k) {
  1370. bi = buffers[i++];
  1371. length = bi.limit - bi.offset;
  1372. if (length <= 0) continue;
  1373. bb.view.set(bi.view.subarray(bi.offset, bi.limit), bb.offset);
  1374. bb.offset += length;
  1375. }
  1376. bb.limit = bb.offset;
  1377. bb.offset = 0;
  1378. return bb;
  1379. };
  1380. /**
  1381. * Tests if the specified type is a ByteBuffer.
  1382. * @param {*} bb ByteBuffer to test
  1383. * @returns {boolean} `true` if it is a ByteBuffer, otherwise `false`
  1384. * @expose
  1385. */
  1386. ByteBuffer.isByteBuffer = function(bb) {
  1387. return (bb && bb["__isByteBuffer__"]) === true;
  1388. };
  1389. /**
  1390. * Gets the backing buffer type.
  1391. * @returns {Function} `Buffer` under node.js, `ArrayBuffer` in the browser (classes)
  1392. * @expose
  1393. */
  1394. ByteBuffer.type = function() {
  1395. return ArrayBuffer;
  1396. };
  1397. /**
  1398. * Wraps a buffer or a string. Sets the allocated ByteBuffer's {@link ByteBuffer#offset} to `0` and its
  1399. * {@link ByteBuffer#limit} to the length of the wrapped data.
  1400. * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string|!Array.<number>} buffer Anything that can be wrapped
  1401. * @param {(string|boolean)=} encoding String encoding if `buffer` is a string ("base64", "hex", "binary", defaults to
  1402. * "utf8")
  1403. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  1404. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  1405. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  1406. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  1407. * @returns {!ByteBuffer} A ByteBuffer wrapping `buffer`
  1408. * @expose
  1409. */
  1410. ByteBuffer.wrap = function(buffer, encoding, littleEndian, noAssert) {
  1411. if (typeof encoding !== 'string') {
  1412. noAssert = littleEndian;
  1413. littleEndian = encoding;
  1414. encoding = undefined;
  1415. }
  1416. if (typeof buffer === 'string') {
  1417. if (typeof encoding === 'undefined')
  1418. encoding = "utf8";
  1419. switch (encoding) {
  1420. case "base64":
  1421. return ByteBuffer.fromBase64(buffer, littleEndian);
  1422. case "hex":
  1423. return ByteBuffer.fromHex(buffer, littleEndian);
  1424. case "binary":
  1425. return ByteBuffer.fromBinary(buffer, littleEndian);
  1426. case "utf8":
  1427. return ByteBuffer.fromUTF8(buffer, littleEndian);
  1428. case "debug":
  1429. return ByteBuffer.fromDebug(buffer, littleEndian);
  1430. default:
  1431. throw Error("Unsupported encoding: "+encoding);
  1432. }
  1433. }
  1434. if (buffer === null || typeof buffer !== 'object')
  1435. throw TypeError("Illegal buffer");
  1436. var bb;
  1437. if (ByteBuffer.isByteBuffer(buffer)) {
  1438. bb = ByteBufferPrototype.clone.call(buffer);
  1439. bb.markedOffset = -1;
  1440. return bb;
  1441. }
  1442. if (buffer instanceof Uint8Array) { // Extract ArrayBuffer from Uint8Array
  1443. bb = new ByteBuffer(0, littleEndian, noAssert);
  1444. if (buffer.length > 0) { // Avoid references to more than one EMPTY_BUFFER
  1445. bb.buffer = buffer.buffer;
  1446. bb.offset = buffer.byteOffset;
  1447. bb.limit = buffer.byteOffset + buffer.byteLength;
  1448. bb.view = new Uint8Array(buffer.buffer);
  1449. }
  1450. } else if (buffer instanceof ArrayBuffer) { // Reuse ArrayBuffer
  1451. bb = new ByteBuffer(0, littleEndian, noAssert);
  1452. if (buffer.byteLength > 0) {
  1453. bb.buffer = buffer;
  1454. bb.offset = 0;
  1455. bb.limit = buffer.byteLength;
  1456. bb.view = buffer.byteLength > 0 ? new Uint8Array(buffer) : null;
  1457. }
  1458. } else if (Object.prototype.toString.call(buffer) === "[object Array]") { // Create from octets
  1459. bb = new ByteBuffer(buffer.length, littleEndian, noAssert);
  1460. bb.limit = buffer.length;
  1461. for (var i=0; i<buffer.length; ++i)
  1462. bb.view[i] = buffer[i];
  1463. } else
  1464. throw TypeError("Illegal buffer"); // Otherwise fail
  1465. return bb;
  1466. };
  1467. /**
  1468. * Writes the array as a bitset.
  1469. * @param {Array<boolean>} value Array of booleans to write
  1470. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
  1471. * @returns {!ByteBuffer}
  1472. * @expose
  1473. */
  1474. ByteBufferPrototype.writeBitSet = function(value, offset) {
  1475. var relative = typeof offset === 'undefined';
  1476. if (relative) offset = this.offset;
  1477. if (!this.noAssert) {
  1478. if (!(value instanceof Array))
  1479. throw TypeError("Illegal BitSet: Not an array");
  1480. if (typeof offset !== 'number' || offset % 1 !== 0)
  1481. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  1482. offset >>>= 0;
  1483. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  1484. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  1485. }
  1486. var start = offset,
  1487. bits = value.length,
  1488. bytes = (bits >> 3),
  1489. bit = 0,
  1490. k;
  1491. offset += this.writeVarint32(bits,offset);
  1492. while(bytes--) {
  1493. k = (!!value[bit++] & 1) |
  1494. ((!!value[bit++] & 1) << 1) |
  1495. ((!!value[bit++] & 1) << 2) |
  1496. ((!!value[bit++] & 1) << 3) |
  1497. ((!!value[bit++] & 1) << 4) |
  1498. ((!!value[bit++] & 1) << 5) |
  1499. ((!!value[bit++] & 1) << 6) |
  1500. ((!!value[bit++] & 1) << 7);
  1501. this.writeByte(k,offset++);
  1502. }
  1503. if(bit < bits) {
  1504. var m = 0; k = 0;
  1505. while(bit < bits) k = k | ((!!value[bit++] & 1) << (m++));
  1506. this.writeByte(k,offset++);
  1507. }
  1508. if (relative) {
  1509. this.offset = offset;
  1510. return this;
  1511. }
  1512. return offset - start;
  1513. };
  1514. /**
  1515. * Reads a BitSet as an array of booleans.
  1516. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
  1517. * @returns {Array<boolean>
  1518. * @expose
  1519. */
  1520. ByteBufferPrototype.readBitSet = function(offset) {
  1521. var relative = typeof offset === 'undefined';
  1522. if (relative) offset = this.offset;
  1523. var ret = this.readVarint32(offset),
  1524. bits = ret.value,
  1525. bytes = (bits >> 3),
  1526. bit = 0,
  1527. value = [],
  1528. k;
  1529. offset += ret.length;
  1530. while(bytes--) {
  1531. k = this.readByte(offset++);
  1532. value[bit++] = !!(k & 0x01);
  1533. value[bit++] = !!(k & 0x02);
  1534. value[bit++] = !!(k & 0x04);
  1535. value[bit++] = !!(k & 0x08);
  1536. value[bit++] = !!(k & 0x10);
  1537. value[bit++] = !!(k & 0x20);
  1538. value[bit++] = !!(k & 0x40);
  1539. value[bit++] = !!(k & 0x80);
  1540. }
  1541. if(bit < bits) {
  1542. var m = 0;
  1543. k = this.readByte(offset++);
  1544. while(bit < bits) value[bit++] = !!((k >> (m++)) & 1);
  1545. }
  1546. if (relative) {
  1547. this.offset = offset;
  1548. }
  1549. return value;
  1550. };
  1551. /**
  1552. * Reads the specified number of bytes.
  1553. * @param {number} length Number of bytes to read
  1554. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
  1555. * @returns {!ByteBuffer}
  1556. * @expose
  1557. */
  1558. ByteBufferPrototype.readBytes = function(length, offset) {
  1559. var relative = typeof offset === 'undefined';
  1560. if (relative) offset = this.offset;
  1561. if (!this.noAssert) {
  1562. if (typeof offset !== 'number' || offset % 1 !== 0)
  1563. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  1564. offset >>>= 0;
  1565. if (offset < 0 || offset + length > this.buffer.byteLength)
  1566. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength);
  1567. }
  1568. var slice = this.slice(offset, offset + length);
  1569. if (relative) this.offset += length;
  1570. return slice;
  1571. };
  1572. /**
  1573. * Writes a payload of bytes. This is an alias of {@link ByteBuffer#append}.
  1574. * @function
  1575. * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to write. If `source` is a ByteBuffer, its offsets
  1576. * will be modified according to the performed read operation.
  1577. * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
  1578. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  1579. * written if omitted.
  1580. * @returns {!ByteBuffer} this
  1581. * @expose
  1582. */
  1583. ByteBufferPrototype.writeBytes = ByteBufferPrototype.append;
  1584. // types/ints/int8
  1585. /**
  1586. * Writes an 8bit signed integer.
  1587. * @param {number} value Value to write
  1588. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  1589. * @returns {!ByteBuffer} this
  1590. * @expose
  1591. */
  1592. ByteBufferPrototype.writeInt8 = function(value, offset) {
  1593. var relative = typeof offset === 'undefined';
  1594. if (relative) offset = this.offset;
  1595. if (!this.noAssert) {
  1596. if (typeof value !== 'number' || value % 1 !== 0)
  1597. throw TypeError("Illegal value: "+value+" (not an integer)");
  1598. value |= 0;
  1599. if (typeof offset !== 'number' || offset % 1 !== 0)
  1600. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  1601. offset >>>= 0;
  1602. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  1603. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  1604. }
  1605. offset += 1;
  1606. var capacity0 = this.buffer.byteLength;
  1607. if (offset > capacity0)
  1608. this.resize((capacity0 *= 2) > offset ? capacity0 : offset);
  1609. offset -= 1;
  1610. this.view[offset] = value;
  1611. if (relative) this.offset += 1;
  1612. return this;
  1613. };
  1614. /**
  1615. * Writes an 8bit signed integer. This is an alias of {@link ByteBuffer#writeInt8}.
  1616. * @function
  1617. * @param {number} value Value to write
  1618. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  1619. * @returns {!ByteBuffer} this
  1620. * @expose
  1621. */
  1622. ByteBufferPrototype.writeByte = ByteBufferPrototype.writeInt8;
  1623. /**
  1624. * Reads an 8bit signed integer.
  1625. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  1626. * @returns {number} Value read
  1627. * @expose
  1628. */
  1629. ByteBufferPrototype.readInt8 = function(offset) {
  1630. var relative = typeof offset === 'undefined';
  1631. if (relative) offset = this.offset;
  1632. if (!this.noAssert) {
  1633. if (typeof offset !== 'number' || offset % 1 !== 0)
  1634. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  1635. offset >>>= 0;
  1636. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  1637. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  1638. }
  1639. var value = this.view[offset];
  1640. if ((value & 0x80) === 0x80) value = -(0xFF - value + 1); // Cast to signed
  1641. if (relative) this.offset += 1;
  1642. return value;
  1643. };
  1644. /**
  1645. * Reads an 8bit signed integer. This is an alias of {@link ByteBuffer#readInt8}.
  1646. * @function
  1647. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  1648. * @returns {number} Value read
  1649. * @expose
  1650. */
  1651. ByteBufferPrototype.readByte = ByteBufferPrototype.readInt8;
  1652. /**
  1653. * Writes an 8bit unsigned integer.
  1654. * @param {number} value Value to write
  1655. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  1656. * @returns {!ByteBuffer} this
  1657. * @expose
  1658. */
  1659. ByteBufferPrototype.writeUint8 = function(value, offset) {
  1660. var relative = typeof offset === 'undefined';
  1661. if (relative) offset = this.offset;
  1662. if (!this.noAssert) {
  1663. if (typeof value !== 'number' || value % 1 !== 0)
  1664. throw TypeError("Illegal value: "+value+" (not an integer)");
  1665. value >>>= 0;
  1666. if (typeof offset !== 'number' || offset % 1 !== 0)
  1667. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  1668. offset >>>= 0;
  1669. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  1670. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  1671. }
  1672. offset += 1;
  1673. var capacity1 = this.buffer.byteLength;
  1674. if (offset > capacity1)
  1675. this.resize((capacity1 *= 2) > offset ? capacity1 : offset);
  1676. offset -= 1;
  1677. this.view[offset] = value;
  1678. if (relative) this.offset += 1;
  1679. return this;
  1680. };
  1681. /**
  1682. * Writes an 8bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint8}.
  1683. * @function
  1684. * @param {number} value Value to write
  1685. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  1686. * @returns {!ByteBuffer} this
  1687. * @expose
  1688. */
  1689. ByteBufferPrototype.writeUInt8 = ByteBufferPrototype.writeUint8;
  1690. /**
  1691. * Reads an 8bit unsigned integer.
  1692. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  1693. * @returns {number} Value read
  1694. * @expose
  1695. */
  1696. ByteBufferPrototype.readUint8 = function(offset) {
  1697. var relative = typeof offset === 'undefined';
  1698. if (relative) offset = this.offset;
  1699. if (!this.noAssert) {
  1700. if (typeof offset !== 'number' || offset % 1 !== 0)
  1701. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  1702. offset >>>= 0;
  1703. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  1704. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  1705. }
  1706. var value = this.view[offset];
  1707. if (relative) this.offset += 1;
  1708. return value;
  1709. };
  1710. /**
  1711. * Reads an 8bit unsigned integer. This is an alias of {@link ByteBuffer#readUint8}.
  1712. * @function
  1713. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
  1714. * @returns {number} Value read
  1715. * @expose
  1716. */
  1717. ByteBufferPrototype.readUInt8 = ByteBufferPrototype.readUint8;
  1718. // types/ints/int16
  1719. /**
  1720. * Writes a 16bit signed integer.
  1721. * @param {number} value Value to write
  1722. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  1723. * @throws {TypeError} If `offset` or `value` is not a valid number
  1724. * @throws {RangeError} If `offset` is out of bounds
  1725. * @expose
  1726. */
  1727. ByteBufferPrototype.writeInt16 = function(value, offset) {
  1728. var relative = typeof offset === 'undefined';
  1729. if (relative) offset = this.offset;
  1730. if (!this.noAssert) {
  1731. if (typeof value !== 'number' || value % 1 !== 0)
  1732. throw TypeError("Illegal value: "+value+" (not an integer)");
  1733. value |= 0;
  1734. if (typeof offset !== 'number' || offset % 1 !== 0)
  1735. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  1736. offset >>>= 0;
  1737. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  1738. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  1739. }
  1740. offset += 2;
  1741. var capacity2 = this.buffer.byteLength;
  1742. if (offset > capacity2)
  1743. this.resize((capacity2 *= 2) > offset ? capacity2 : offset);
  1744. offset -= 2;
  1745. if (this.littleEndian) {
  1746. this.view[offset+1] = (value & 0xFF00) >>> 8;
  1747. this.view[offset ] = value & 0x00FF;
  1748. } else {
  1749. this.view[offset] = (value & 0xFF00) >>> 8;
  1750. this.view[offset+1] = value & 0x00FF;
  1751. }
  1752. if (relative) this.offset += 2;
  1753. return this;
  1754. };
  1755. /**
  1756. * Writes a 16bit signed integer. This is an alias of {@link ByteBuffer#writeInt16}.
  1757. * @function
  1758. * @param {number} value Value to write
  1759. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  1760. * @throws {TypeError} If `offset` or `value` is not a valid number
  1761. * @throws {RangeError} If `offset` is out of bounds
  1762. * @expose
  1763. */
  1764. ByteBufferPrototype.writeShort = ByteBufferPrototype.writeInt16;
  1765. /**
  1766. * Reads a 16bit signed integer.
  1767. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  1768. * @returns {number} Value read
  1769. * @throws {TypeError} If `offset` is not a valid number
  1770. * @throws {RangeError} If `offset` is out of bounds
  1771. * @expose
  1772. */
  1773. ByteBufferPrototype.readInt16 = function(offset) {
  1774. var relative = typeof offset === 'undefined';
  1775. if (relative) offset = this.offset;
  1776. if (!this.noAssert) {
  1777. if (typeof offset !== 'number' || offset % 1 !== 0)
  1778. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  1779. offset >>>= 0;
  1780. if (offset < 0 || offset + 2 > this.buffer.byteLength)
  1781. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
  1782. }
  1783. var value = 0;
  1784. if (this.littleEndian) {
  1785. value = this.view[offset ];
  1786. value |= this.view[offset+1] << 8;
  1787. } else {
  1788. value = this.view[offset ] << 8;
  1789. value |= this.view[offset+1];
  1790. }
  1791. if ((value & 0x8000) === 0x8000) value = -(0xFFFF - value + 1); // Cast to signed
  1792. if (relative) this.offset += 2;
  1793. return value;
  1794. };
  1795. /**
  1796. * Reads a 16bit signed integer. This is an alias of {@link ByteBuffer#readInt16}.
  1797. * @function
  1798. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  1799. * @returns {number} Value read
  1800. * @throws {TypeError} If `offset` is not a valid number
  1801. * @throws {RangeError} If `offset` is out of bounds
  1802. * @expose
  1803. */
  1804. ByteBufferPrototype.readShort = ByteBufferPrototype.readInt16;
  1805. /**
  1806. * Writes a 16bit unsigned integer.
  1807. * @param {number} value Value to write
  1808. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  1809. * @throws {TypeError} If `offset` or `value` is not a valid number
  1810. * @throws {RangeError} If `offset` is out of bounds
  1811. * @expose
  1812. */
  1813. ByteBufferPrototype.writeUint16 = function(value, offset) {
  1814. var relative = typeof offset === 'undefined';
  1815. if (relative) offset = this.offset;
  1816. if (!this.noAssert) {
  1817. if (typeof value !== 'number' || value % 1 !== 0)
  1818. throw TypeError("Illegal value: "+value+" (not an integer)");
  1819. value >>>= 0;
  1820. if (typeof offset !== 'number' || offset % 1 !== 0)
  1821. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  1822. offset >>>= 0;
  1823. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  1824. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  1825. }
  1826. offset += 2;
  1827. var capacity3 = this.buffer.byteLength;
  1828. if (offset > capacity3)
  1829. this.resize((capacity3 *= 2) > offset ? capacity3 : offset);
  1830. offset -= 2;
  1831. if (this.littleEndian) {
  1832. this.view[offset+1] = (value & 0xFF00) >>> 8;
  1833. this.view[offset ] = value & 0x00FF;
  1834. } else {
  1835. this.view[offset] = (value & 0xFF00) >>> 8;
  1836. this.view[offset+1] = value & 0x00FF;
  1837. }
  1838. if (relative) this.offset += 2;
  1839. return this;
  1840. };
  1841. /**
  1842. * Writes a 16bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint16}.
  1843. * @function
  1844. * @param {number} value Value to write
  1845. * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  1846. * @throws {TypeError} If `offset` or `value` is not a valid number
  1847. * @throws {RangeError} If `offset` is out of bounds
  1848. * @expose
  1849. */
  1850. ByteBufferPrototype.writeUInt16 = ByteBufferPrototype.writeUint16;
  1851. /**
  1852. * Reads a 16bit unsigned integer.
  1853. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  1854. * @returns {number} Value read
  1855. * @throws {TypeError} If `offset` is not a valid number
  1856. * @throws {RangeError} If `offset` is out of bounds
  1857. * @expose
  1858. */
  1859. ByteBufferPrototype.readUint16 = function(offset) {
  1860. var relative = typeof offset === 'undefined';
  1861. if (relative) offset = this.offset;
  1862. if (!this.noAssert) {
  1863. if (typeof offset !== 'number' || offset % 1 !== 0)
  1864. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  1865. offset >>>= 0;
  1866. if (offset < 0 || offset + 2 > this.buffer.byteLength)
  1867. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
  1868. }
  1869. var value = 0;
  1870. if (this.littleEndian) {
  1871. value = this.view[offset ];
  1872. value |= this.view[offset+1] << 8;
  1873. } else {
  1874. value = this.view[offset ] << 8;
  1875. value |= this.view[offset+1];
  1876. }
  1877. if (relative) this.offset += 2;
  1878. return value;
  1879. };
  1880. /**
  1881. * Reads a 16bit unsigned integer. This is an alias of {@link ByteBuffer#readUint16}.
  1882. * @function
  1883. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
  1884. * @returns {number} Value read
  1885. * @throws {TypeError} If `offset` is not a valid number
  1886. * @throws {RangeError} If `offset` is out of bounds
  1887. * @expose
  1888. */
  1889. ByteBufferPrototype.readUInt16 = ByteBufferPrototype.readUint16;
  1890. // types/ints/int32
  1891. /**
  1892. * Writes a 32bit signed integer.
  1893. * @param {number} value Value to write
  1894. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  1895. * @expose
  1896. */
  1897. ByteBufferPrototype.writeInt32 = function(value, offset) {
  1898. var relative = typeof offset === 'undefined';
  1899. if (relative) offset = this.offset;
  1900. if (!this.noAssert) {
  1901. if (typeof value !== 'number' || value % 1 !== 0)
  1902. throw TypeError("Illegal value: "+value+" (not an integer)");
  1903. value |= 0;
  1904. if (typeof offset !== 'number' || offset % 1 !== 0)
  1905. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  1906. offset >>>= 0;
  1907. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  1908. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  1909. }
  1910. offset += 4;
  1911. var capacity4 = this.buffer.byteLength;
  1912. if (offset > capacity4)
  1913. this.resize((capacity4 *= 2) > offset ? capacity4 : offset);
  1914. offset -= 4;
  1915. if (this.littleEndian) {
  1916. this.view[offset+3] = (value >>> 24) & 0xFF;
  1917. this.view[offset+2] = (value >>> 16) & 0xFF;
  1918. this.view[offset+1] = (value >>> 8) & 0xFF;
  1919. this.view[offset ] = value & 0xFF;
  1920. } else {
  1921. this.view[offset ] = (value >>> 24) & 0xFF;
  1922. this.view[offset+1] = (value >>> 16) & 0xFF;
  1923. this.view[offset+2] = (value >>> 8) & 0xFF;
  1924. this.view[offset+3] = value & 0xFF;
  1925. }
  1926. if (relative) this.offset += 4;
  1927. return this;
  1928. };
  1929. /**
  1930. * Writes a 32bit signed integer. This is an alias of {@link ByteBuffer#writeInt32}.
  1931. * @param {number} value Value to write
  1932. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  1933. * @expose
  1934. */
  1935. ByteBufferPrototype.writeInt = ByteBufferPrototype.writeInt32;
  1936. /**
  1937. * Reads a 32bit signed integer.
  1938. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  1939. * @returns {number} Value read
  1940. * @expose
  1941. */
  1942. ByteBufferPrototype.readInt32 = function(offset) {
  1943. var relative = typeof offset === 'undefined';
  1944. if (relative) offset = this.offset;
  1945. if (!this.noAssert) {
  1946. if (typeof offset !== 'number' || offset % 1 !== 0)
  1947. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  1948. offset >>>= 0;
  1949. if (offset < 0 || offset + 4 > this.buffer.byteLength)
  1950. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
  1951. }
  1952. var value = 0;
  1953. if (this.littleEndian) {
  1954. value = this.view[offset+2] << 16;
  1955. value |= this.view[offset+1] << 8;
  1956. value |= this.view[offset ];
  1957. value += this.view[offset+3] << 24 >>> 0;
  1958. } else {
  1959. value = this.view[offset+1] << 16;
  1960. value |= this.view[offset+2] << 8;
  1961. value |= this.view[offset+3];
  1962. value += this.view[offset ] << 24 >>> 0;
  1963. }
  1964. value |= 0; // Cast to signed
  1965. if (relative) this.offset += 4;
  1966. return value;
  1967. };
  1968. /**
  1969. * Reads a 32bit signed integer. This is an alias of {@link ByteBuffer#readInt32}.
  1970. * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `4` if omitted.
  1971. * @returns {number} Value read
  1972. * @expose
  1973. */
  1974. ByteBufferPrototype.readInt = ByteBufferPrototype.readInt32;
  1975. /**
  1976. * Writes a 32bit unsigned integer.
  1977. * @param {number} value Value to write
  1978. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  1979. * @expose
  1980. */
  1981. ByteBufferPrototype.writeUint32 = function(value, offset) {
  1982. var relative = typeof offset === 'undefined';
  1983. if (relative) offset = this.offset;
  1984. if (!this.noAssert) {
  1985. if (typeof value !== 'number' || value % 1 !== 0)
  1986. throw TypeError("Illegal value: "+value+" (not an integer)");
  1987. value >>>= 0;
  1988. if (typeof offset !== 'number' || offset % 1 !== 0)
  1989. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  1990. offset >>>= 0;
  1991. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  1992. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  1993. }
  1994. offset += 4;
  1995. var capacity5 = this.buffer.byteLength;
  1996. if (offset > capacity5)
  1997. this.resize((capacity5 *= 2) > offset ? capacity5 : offset);
  1998. offset -= 4;
  1999. if (this.littleEndian) {
  2000. this.view[offset+3] = (value >>> 24) & 0xFF;
  2001. this.view[offset+2] = (value >>> 16) & 0xFF;
  2002. this.view[offset+1] = (value >>> 8) & 0xFF;
  2003. this.view[offset ] = value & 0xFF;
  2004. } else {
  2005. this.view[offset ] = (value >>> 24) & 0xFF;
  2006. this.view[offset+1] = (value >>> 16) & 0xFF;
  2007. this.view[offset+2] = (value >>> 8) & 0xFF;
  2008. this.view[offset+3] = value & 0xFF;
  2009. }
  2010. if (relative) this.offset += 4;
  2011. return this;
  2012. };
  2013. /**
  2014. * Writes a 32bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint32}.
  2015. * @function
  2016. * @param {number} value Value to write
  2017. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  2018. * @expose
  2019. */
  2020. ByteBufferPrototype.writeUInt32 = ByteBufferPrototype.writeUint32;
  2021. /**
  2022. * Reads a 32bit unsigned integer.
  2023. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  2024. * @returns {number} Value read
  2025. * @expose
  2026. */
  2027. ByteBufferPrototype.readUint32 = function(offset) {
  2028. var relative = typeof offset === 'undefined';
  2029. if (relative) offset = this.offset;
  2030. if (!this.noAssert) {
  2031. if (typeof offset !== 'number' || offset % 1 !== 0)
  2032. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2033. offset >>>= 0;
  2034. if (offset < 0 || offset + 4 > this.buffer.byteLength)
  2035. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
  2036. }
  2037. var value = 0;
  2038. if (this.littleEndian) {
  2039. value = this.view[offset+2] << 16;
  2040. value |= this.view[offset+1] << 8;
  2041. value |= this.view[offset ];
  2042. value += this.view[offset+3] << 24 >>> 0;
  2043. } else {
  2044. value = this.view[offset+1] << 16;
  2045. value |= this.view[offset+2] << 8;
  2046. value |= this.view[offset+3];
  2047. value += this.view[offset ] << 24 >>> 0;
  2048. }
  2049. if (relative) this.offset += 4;
  2050. return value;
  2051. };
  2052. /**
  2053. * Reads a 32bit unsigned integer. This is an alias of {@link ByteBuffer#readUint32}.
  2054. * @function
  2055. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  2056. * @returns {number} Value read
  2057. * @expose
  2058. */
  2059. ByteBufferPrototype.readUInt32 = ByteBufferPrototype.readUint32;
  2060. // types/ints/int64
  2061. if (Long) {
  2062. /**
  2063. * Writes a 64bit signed integer.
  2064. * @param {number|!Long} value Value to write
  2065. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  2066. * @returns {!ByteBuffer} this
  2067. * @expose
  2068. */
  2069. ByteBufferPrototype.writeInt64 = function(value, offset) {
  2070. var relative = typeof offset === 'undefined';
  2071. if (relative) offset = this.offset;
  2072. if (!this.noAssert) {
  2073. if (typeof value === 'number')
  2074. value = Long.fromNumber(value);
  2075. else if (typeof value === 'string')
  2076. value = Long.fromString(value);
  2077. else if (!(value && value instanceof Long))
  2078. throw TypeError("Illegal value: "+value+" (not an integer or Long)");
  2079. if (typeof offset !== 'number' || offset % 1 !== 0)
  2080. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2081. offset >>>= 0;
  2082. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  2083. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  2084. }
  2085. if (typeof value === 'number')
  2086. value = Long.fromNumber(value);
  2087. else if (typeof value === 'string')
  2088. value = Long.fromString(value);
  2089. offset += 8;
  2090. var capacity6 = this.buffer.byteLength;
  2091. if (offset > capacity6)
  2092. this.resize((capacity6 *= 2) > offset ? capacity6 : offset);
  2093. offset -= 8;
  2094. var lo = value.low,
  2095. hi = value.high;
  2096. if (this.littleEndian) {
  2097. this.view[offset+3] = (lo >>> 24) & 0xFF;
  2098. this.view[offset+2] = (lo >>> 16) & 0xFF;
  2099. this.view[offset+1] = (lo >>> 8) & 0xFF;
  2100. this.view[offset ] = lo & 0xFF;
  2101. offset += 4;
  2102. this.view[offset+3] = (hi >>> 24) & 0xFF;
  2103. this.view[offset+2] = (hi >>> 16) & 0xFF;
  2104. this.view[offset+1] = (hi >>> 8) & 0xFF;
  2105. this.view[offset ] = hi & 0xFF;
  2106. } else {
  2107. this.view[offset ] = (hi >>> 24) & 0xFF;
  2108. this.view[offset+1] = (hi >>> 16) & 0xFF;
  2109. this.view[offset+2] = (hi >>> 8) & 0xFF;
  2110. this.view[offset+3] = hi & 0xFF;
  2111. offset += 4;
  2112. this.view[offset ] = (lo >>> 24) & 0xFF;
  2113. this.view[offset+1] = (lo >>> 16) & 0xFF;
  2114. this.view[offset+2] = (lo >>> 8) & 0xFF;
  2115. this.view[offset+3] = lo & 0xFF;
  2116. }
  2117. if (relative) this.offset += 8;
  2118. return this;
  2119. };
  2120. /**
  2121. * Writes a 64bit signed integer. This is an alias of {@link ByteBuffer#writeInt64}.
  2122. * @param {number|!Long} value Value to write
  2123. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  2124. * @returns {!ByteBuffer} this
  2125. * @expose
  2126. */
  2127. ByteBufferPrototype.writeLong = ByteBufferPrototype.writeInt64;
  2128. /**
  2129. * Reads a 64bit signed integer.
  2130. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  2131. * @returns {!Long}
  2132. * @expose
  2133. */
  2134. ByteBufferPrototype.readInt64 = function(offset) {
  2135. var relative = typeof offset === 'undefined';
  2136. if (relative) offset = this.offset;
  2137. if (!this.noAssert) {
  2138. if (typeof offset !== 'number' || offset % 1 !== 0)
  2139. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2140. offset >>>= 0;
  2141. if (offset < 0 || offset + 8 > this.buffer.byteLength)
  2142. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
  2143. }
  2144. var lo = 0,
  2145. hi = 0;
  2146. if (this.littleEndian) {
  2147. lo = this.view[offset+2] << 16;
  2148. lo |= this.view[offset+1] << 8;
  2149. lo |= this.view[offset ];
  2150. lo += this.view[offset+3] << 24 >>> 0;
  2151. offset += 4;
  2152. hi = this.view[offset+2] << 16;
  2153. hi |= this.view[offset+1] << 8;
  2154. hi |= this.view[offset ];
  2155. hi += this.view[offset+3] << 24 >>> 0;
  2156. } else {
  2157. hi = this.view[offset+1] << 16;
  2158. hi |= this.view[offset+2] << 8;
  2159. hi |= this.view[offset+3];
  2160. hi += this.view[offset ] << 24 >>> 0;
  2161. offset += 4;
  2162. lo = this.view[offset+1] << 16;
  2163. lo |= this.view[offset+2] << 8;
  2164. lo |= this.view[offset+3];
  2165. lo += this.view[offset ] << 24 >>> 0;
  2166. }
  2167. var value = new Long(lo, hi, false);
  2168. if (relative) this.offset += 8;
  2169. return value;
  2170. };
  2171. /**
  2172. * Reads a 64bit signed integer. This is an alias of {@link ByteBuffer#readInt64}.
  2173. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  2174. * @returns {!Long}
  2175. * @expose
  2176. */
  2177. ByteBufferPrototype.readLong = ByteBufferPrototype.readInt64;
  2178. /**
  2179. * Writes a 64bit unsigned integer.
  2180. * @param {number|!Long} value Value to write
  2181. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  2182. * @returns {!ByteBuffer} this
  2183. * @expose
  2184. */
  2185. ByteBufferPrototype.writeUint64 = function(value, offset) {
  2186. var relative = typeof offset === 'undefined';
  2187. if (relative) offset = this.offset;
  2188. if (!this.noAssert) {
  2189. if (typeof value === 'number')
  2190. value = Long.fromNumber(value);
  2191. else if (typeof value === 'string')
  2192. value = Long.fromString(value);
  2193. else if (!(value && value instanceof Long))
  2194. throw TypeError("Illegal value: "+value+" (not an integer or Long)");
  2195. if (typeof offset !== 'number' || offset % 1 !== 0)
  2196. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2197. offset >>>= 0;
  2198. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  2199. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  2200. }
  2201. if (typeof value === 'number')
  2202. value = Long.fromNumber(value);
  2203. else if (typeof value === 'string')
  2204. value = Long.fromString(value);
  2205. offset += 8;
  2206. var capacity7 = this.buffer.byteLength;
  2207. if (offset > capacity7)
  2208. this.resize((capacity7 *= 2) > offset ? capacity7 : offset);
  2209. offset -= 8;
  2210. var lo = value.low,
  2211. hi = value.high;
  2212. if (this.littleEndian) {
  2213. this.view[offset+3] = (lo >>> 24) & 0xFF;
  2214. this.view[offset+2] = (lo >>> 16) & 0xFF;
  2215. this.view[offset+1] = (lo >>> 8) & 0xFF;
  2216. this.view[offset ] = lo & 0xFF;
  2217. offset += 4;
  2218. this.view[offset+3] = (hi >>> 24) & 0xFF;
  2219. this.view[offset+2] = (hi >>> 16) & 0xFF;
  2220. this.view[offset+1] = (hi >>> 8) & 0xFF;
  2221. this.view[offset ] = hi & 0xFF;
  2222. } else {
  2223. this.view[offset ] = (hi >>> 24) & 0xFF;
  2224. this.view[offset+1] = (hi >>> 16) & 0xFF;
  2225. this.view[offset+2] = (hi >>> 8) & 0xFF;
  2226. this.view[offset+3] = hi & 0xFF;
  2227. offset += 4;
  2228. this.view[offset ] = (lo >>> 24) & 0xFF;
  2229. this.view[offset+1] = (lo >>> 16) & 0xFF;
  2230. this.view[offset+2] = (lo >>> 8) & 0xFF;
  2231. this.view[offset+3] = lo & 0xFF;
  2232. }
  2233. if (relative) this.offset += 8;
  2234. return this;
  2235. };
  2236. /**
  2237. * Writes a 64bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint64}.
  2238. * @function
  2239. * @param {number|!Long} value Value to write
  2240. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  2241. * @returns {!ByteBuffer} this
  2242. * @expose
  2243. */
  2244. ByteBufferPrototype.writeUInt64 = ByteBufferPrototype.writeUint64;
  2245. /**
  2246. * Reads a 64bit unsigned integer.
  2247. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  2248. * @returns {!Long}
  2249. * @expose
  2250. */
  2251. ByteBufferPrototype.readUint64 = function(offset) {
  2252. var relative = typeof offset === 'undefined';
  2253. if (relative) offset = this.offset;
  2254. if (!this.noAssert) {
  2255. if (typeof offset !== 'number' || offset % 1 !== 0)
  2256. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2257. offset >>>= 0;
  2258. if (offset < 0 || offset + 8 > this.buffer.byteLength)
  2259. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
  2260. }
  2261. var lo = 0,
  2262. hi = 0;
  2263. if (this.littleEndian) {
  2264. lo = this.view[offset+2] << 16;
  2265. lo |= this.view[offset+1] << 8;
  2266. lo |= this.view[offset ];
  2267. lo += this.view[offset+3] << 24 >>> 0;
  2268. offset += 4;
  2269. hi = this.view[offset+2] << 16;
  2270. hi |= this.view[offset+1] << 8;
  2271. hi |= this.view[offset ];
  2272. hi += this.view[offset+3] << 24 >>> 0;
  2273. } else {
  2274. hi = this.view[offset+1] << 16;
  2275. hi |= this.view[offset+2] << 8;
  2276. hi |= this.view[offset+3];
  2277. hi += this.view[offset ] << 24 >>> 0;
  2278. offset += 4;
  2279. lo = this.view[offset+1] << 16;
  2280. lo |= this.view[offset+2] << 8;
  2281. lo |= this.view[offset+3];
  2282. lo += this.view[offset ] << 24 >>> 0;
  2283. }
  2284. var value = new Long(lo, hi, true);
  2285. if (relative) this.offset += 8;
  2286. return value;
  2287. };
  2288. /**
  2289. * Reads a 64bit unsigned integer. This is an alias of {@link ByteBuffer#readUint64}.
  2290. * @function
  2291. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  2292. * @returns {!Long}
  2293. * @expose
  2294. */
  2295. ByteBufferPrototype.readUInt64 = ByteBufferPrototype.readUint64;
  2296. } // Long
  2297. // types/floats/float32
  2298. /*
  2299. ieee754 - https://github.com/feross/ieee754
  2300. The MIT License (MIT)
  2301. Copyright (c) Feross Aboukhadijeh
  2302. Permission is hereby granted, free of charge, to any person obtaining a copy
  2303. of this software and associated documentation files (the "Software"), to deal
  2304. in the Software without restriction, including without limitation the rights
  2305. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  2306. copies of the Software, and to permit persons to whom the Software is
  2307. furnished to do so, subject to the following conditions:
  2308. The above copyright notice and this permission notice shall be included in
  2309. all copies or substantial portions of the Software.
  2310. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  2311. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  2312. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  2313. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  2314. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  2315. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  2316. THE SOFTWARE.
  2317. */
  2318. /**
  2319. * Reads an IEEE754 float from a byte array.
  2320. * @param {!Array} buffer
  2321. * @param {number} offset
  2322. * @param {boolean} isLE
  2323. * @param {number} mLen
  2324. * @param {number} nBytes
  2325. * @returns {number}
  2326. * @inner
  2327. */
  2328. function ieee754_read(buffer, offset, isLE, mLen, nBytes) {
  2329. var e, m,
  2330. eLen = nBytes * 8 - mLen - 1,
  2331. eMax = (1 << eLen) - 1,
  2332. eBias = eMax >> 1,
  2333. nBits = -7,
  2334. i = isLE ? (nBytes - 1) : 0,
  2335. d = isLE ? -1 : 1,
  2336. s = buffer[offset + i];
  2337. i += d;
  2338. e = s & ((1 << (-nBits)) - 1);
  2339. s >>= (-nBits);
  2340. nBits += eLen;
  2341. for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
  2342. m = e & ((1 << (-nBits)) - 1);
  2343. e >>= (-nBits);
  2344. nBits += mLen;
  2345. for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
  2346. if (e === 0) {
  2347. e = 1 - eBias;
  2348. } else if (e === eMax) {
  2349. return m ? NaN : ((s ? -1 : 1) * Infinity);
  2350. } else {
  2351. m = m + Math.pow(2, mLen);
  2352. e = e - eBias;
  2353. }
  2354. return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
  2355. }
  2356. /**
  2357. * Writes an IEEE754 float to a byte array.
  2358. * @param {!Array} buffer
  2359. * @param {number} value
  2360. * @param {number} offset
  2361. * @param {boolean} isLE
  2362. * @param {number} mLen
  2363. * @param {number} nBytes
  2364. * @inner
  2365. */
  2366. function ieee754_write(buffer, value, offset, isLE, mLen, nBytes) {
  2367. var e, m, c,
  2368. eLen = nBytes * 8 - mLen - 1,
  2369. eMax = (1 << eLen) - 1,
  2370. eBias = eMax >> 1,
  2371. rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
  2372. i = isLE ? 0 : (nBytes - 1),
  2373. d = isLE ? 1 : -1,
  2374. s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
  2375. value = Math.abs(value);
  2376. if (isNaN(value) || value === Infinity) {
  2377. m = isNaN(value) ? 1 : 0;
  2378. e = eMax;
  2379. } else {
  2380. e = Math.floor(Math.log(value) / Math.LN2);
  2381. if (value * (c = Math.pow(2, -e)) < 1) {
  2382. e--;
  2383. c *= 2;
  2384. }
  2385. if (e + eBias >= 1) {
  2386. value += rt / c;
  2387. } else {
  2388. value += rt * Math.pow(2, 1 - eBias);
  2389. }
  2390. if (value * c >= 2) {
  2391. e++;
  2392. c /= 2;
  2393. }
  2394. if (e + eBias >= eMax) {
  2395. m = 0;
  2396. e = eMax;
  2397. } else if (e + eBias >= 1) {
  2398. m = (value * c - 1) * Math.pow(2, mLen);
  2399. e = e + eBias;
  2400. } else {
  2401. m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
  2402. e = 0;
  2403. }
  2404. }
  2405. for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
  2406. e = (e << mLen) | m;
  2407. eLen += mLen;
  2408. for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
  2409. buffer[offset + i - d] |= s * 128;
  2410. }
  2411. /**
  2412. * Writes a 32bit float.
  2413. * @param {number} value Value to write
  2414. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  2415. * @returns {!ByteBuffer} this
  2416. * @expose
  2417. */
  2418. ByteBufferPrototype.writeFloat32 = function(value, offset) {
  2419. var relative = typeof offset === 'undefined';
  2420. if (relative) offset = this.offset;
  2421. if (!this.noAssert) {
  2422. if (typeof value !== 'number')
  2423. throw TypeError("Illegal value: "+value+" (not a number)");
  2424. if (typeof offset !== 'number' || offset % 1 !== 0)
  2425. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2426. offset >>>= 0;
  2427. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  2428. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  2429. }
  2430. offset += 4;
  2431. var capacity8 = this.buffer.byteLength;
  2432. if (offset > capacity8)
  2433. this.resize((capacity8 *= 2) > offset ? capacity8 : offset);
  2434. offset -= 4;
  2435. ieee754_write(this.view, value, offset, this.littleEndian, 23, 4);
  2436. if (relative) this.offset += 4;
  2437. return this;
  2438. };
  2439. /**
  2440. * Writes a 32bit float. This is an alias of {@link ByteBuffer#writeFloat32}.
  2441. * @function
  2442. * @param {number} value Value to write
  2443. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  2444. * @returns {!ByteBuffer} this
  2445. * @expose
  2446. */
  2447. ByteBufferPrototype.writeFloat = ByteBufferPrototype.writeFloat32;
  2448. /**
  2449. * Reads a 32bit float.
  2450. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  2451. * @returns {number}
  2452. * @expose
  2453. */
  2454. ByteBufferPrototype.readFloat32 = function(offset) {
  2455. var relative = typeof offset === 'undefined';
  2456. if (relative) offset = this.offset;
  2457. if (!this.noAssert) {
  2458. if (typeof offset !== 'number' || offset % 1 !== 0)
  2459. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2460. offset >>>= 0;
  2461. if (offset < 0 || offset + 4 > this.buffer.byteLength)
  2462. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
  2463. }
  2464. var value = ieee754_read(this.view, offset, this.littleEndian, 23, 4);
  2465. if (relative) this.offset += 4;
  2466. return value;
  2467. };
  2468. /**
  2469. * Reads a 32bit float. This is an alias of {@link ByteBuffer#readFloat32}.
  2470. * @function
  2471. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
  2472. * @returns {number}
  2473. * @expose
  2474. */
  2475. ByteBufferPrototype.readFloat = ByteBufferPrototype.readFloat32;
  2476. // types/floats/float64
  2477. /**
  2478. * Writes a 64bit float.
  2479. * @param {number} value Value to write
  2480. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  2481. * @returns {!ByteBuffer} this
  2482. * @expose
  2483. */
  2484. ByteBufferPrototype.writeFloat64 = function(value, offset) {
  2485. var relative = typeof offset === 'undefined';
  2486. if (relative) offset = this.offset;
  2487. if (!this.noAssert) {
  2488. if (typeof value !== 'number')
  2489. throw TypeError("Illegal value: "+value+" (not a number)");
  2490. if (typeof offset !== 'number' || offset % 1 !== 0)
  2491. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2492. offset >>>= 0;
  2493. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  2494. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  2495. }
  2496. offset += 8;
  2497. var capacity9 = this.buffer.byteLength;
  2498. if (offset > capacity9)
  2499. this.resize((capacity9 *= 2) > offset ? capacity9 : offset);
  2500. offset -= 8;
  2501. ieee754_write(this.view, value, offset, this.littleEndian, 52, 8);
  2502. if (relative) this.offset += 8;
  2503. return this;
  2504. };
  2505. /**
  2506. * Writes a 64bit float. This is an alias of {@link ByteBuffer#writeFloat64}.
  2507. * @function
  2508. * @param {number} value Value to write
  2509. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  2510. * @returns {!ByteBuffer} this
  2511. * @expose
  2512. */
  2513. ByteBufferPrototype.writeDouble = ByteBufferPrototype.writeFloat64;
  2514. /**
  2515. * Reads a 64bit float.
  2516. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  2517. * @returns {number}
  2518. * @expose
  2519. */
  2520. ByteBufferPrototype.readFloat64 = function(offset) {
  2521. var relative = typeof offset === 'undefined';
  2522. if (relative) offset = this.offset;
  2523. if (!this.noAssert) {
  2524. if (typeof offset !== 'number' || offset % 1 !== 0)
  2525. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2526. offset >>>= 0;
  2527. if (offset < 0 || offset + 8 > this.buffer.byteLength)
  2528. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
  2529. }
  2530. var value = ieee754_read(this.view, offset, this.littleEndian, 52, 8);
  2531. if (relative) this.offset += 8;
  2532. return value;
  2533. };
  2534. /**
  2535. * Reads a 64bit float. This is an alias of {@link ByteBuffer#readFloat64}.
  2536. * @function
  2537. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
  2538. * @returns {number}
  2539. * @expose
  2540. */
  2541. ByteBufferPrototype.readDouble = ByteBufferPrototype.readFloat64;
  2542. // types/varints/varint32
  2543. /**
  2544. * Maximum number of bytes required to store a 32bit base 128 variable-length integer.
  2545. * @type {number}
  2546. * @const
  2547. * @expose
  2548. */
  2549. ByteBuffer.MAX_VARINT32_BYTES = 5;
  2550. /**
  2551. * Calculates the actual number of bytes required to store a 32bit base 128 variable-length integer.
  2552. * @param {number} value Value to encode
  2553. * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT32_BYTES}
  2554. * @expose
  2555. */
  2556. ByteBuffer.calculateVarint32 = function(value) {
  2557. // ref: src/google/protobuf/io/coded_stream.cc
  2558. value = value >>> 0;
  2559. if (value < 1 << 7 ) return 1;
  2560. else if (value < 1 << 14) return 2;
  2561. else if (value < 1 << 21) return 3;
  2562. else if (value < 1 << 28) return 4;
  2563. else return 5;
  2564. };
  2565. /**
  2566. * Zigzag encodes a signed 32bit integer so that it can be effectively used with varint encoding.
  2567. * @param {number} n Signed 32bit integer
  2568. * @returns {number} Unsigned zigzag encoded 32bit integer
  2569. * @expose
  2570. */
  2571. ByteBuffer.zigZagEncode32 = function(n) {
  2572. return (((n |= 0) << 1) ^ (n >> 31)) >>> 0; // ref: src/google/protobuf/wire_format_lite.h
  2573. };
  2574. /**
  2575. * Decodes a zigzag encoded signed 32bit integer.
  2576. * @param {number} n Unsigned zigzag encoded 32bit integer
  2577. * @returns {number} Signed 32bit integer
  2578. * @expose
  2579. */
  2580. ByteBuffer.zigZagDecode32 = function(n) {
  2581. return ((n >>> 1) ^ -(n & 1)) | 0; // // ref: src/google/protobuf/wire_format_lite.h
  2582. };
  2583. /**
  2584. * Writes a 32bit base 128 variable-length integer.
  2585. * @param {number} value Value to write
  2586. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  2587. * written if omitted.
  2588. * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written
  2589. * @expose
  2590. */
  2591. ByteBufferPrototype.writeVarint32 = function(value, offset) {
  2592. var relative = typeof offset === 'undefined';
  2593. if (relative) offset = this.offset;
  2594. if (!this.noAssert) {
  2595. if (typeof value !== 'number' || value % 1 !== 0)
  2596. throw TypeError("Illegal value: "+value+" (not an integer)");
  2597. value |= 0;
  2598. if (typeof offset !== 'number' || offset % 1 !== 0)
  2599. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2600. offset >>>= 0;
  2601. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  2602. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  2603. }
  2604. var size = ByteBuffer.calculateVarint32(value),
  2605. b;
  2606. offset += size;
  2607. var capacity10 = this.buffer.byteLength;
  2608. if (offset > capacity10)
  2609. this.resize((capacity10 *= 2) > offset ? capacity10 : offset);
  2610. offset -= size;
  2611. value >>>= 0;
  2612. while (value >= 0x80) {
  2613. b = (value & 0x7f) | 0x80;
  2614. this.view[offset++] = b;
  2615. value >>>= 7;
  2616. }
  2617. this.view[offset++] = value;
  2618. if (relative) {
  2619. this.offset = offset;
  2620. return this;
  2621. }
  2622. return size;
  2623. };
  2624. /**
  2625. * Writes a zig-zag encoded (signed) 32bit base 128 variable-length integer.
  2626. * @param {number} value Value to write
  2627. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  2628. * written if omitted.
  2629. * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written
  2630. * @expose
  2631. */
  2632. ByteBufferPrototype.writeVarint32ZigZag = function(value, offset) {
  2633. return this.writeVarint32(ByteBuffer.zigZagEncode32(value), offset);
  2634. };
  2635. /**
  2636. * Reads a 32bit base 128 variable-length integer.
  2637. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  2638. * written if omitted.
  2639. * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read
  2640. * and the actual number of bytes read.
  2641. * @throws {Error} If it's not a valid varint. Has a property `truncated = true` if there is not enough data available
  2642. * to fully decode the varint.
  2643. * @expose
  2644. */
  2645. ByteBufferPrototype.readVarint32 = function(offset) {
  2646. var relative = typeof offset === 'undefined';
  2647. if (relative) offset = this.offset;
  2648. if (!this.noAssert) {
  2649. if (typeof offset !== 'number' || offset % 1 !== 0)
  2650. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2651. offset >>>= 0;
  2652. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  2653. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  2654. }
  2655. var c = 0,
  2656. value = 0 >>> 0,
  2657. b;
  2658. do {
  2659. if (!this.noAssert && offset > this.limit) {
  2660. var err = Error("Truncated");
  2661. err['truncated'] = true;
  2662. throw err;
  2663. }
  2664. b = this.view[offset++];
  2665. if (c < 5)
  2666. value |= (b & 0x7f) << (7*c);
  2667. ++c;
  2668. } while ((b & 0x80) !== 0);
  2669. value |= 0;
  2670. if (relative) {
  2671. this.offset = offset;
  2672. return value;
  2673. }
  2674. return {
  2675. "value": value,
  2676. "length": c
  2677. };
  2678. };
  2679. /**
  2680. * Reads a zig-zag encoded (signed) 32bit base 128 variable-length integer.
  2681. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  2682. * written if omitted.
  2683. * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read
  2684. * and the actual number of bytes read.
  2685. * @throws {Error} If it's not a valid varint
  2686. * @expose
  2687. */
  2688. ByteBufferPrototype.readVarint32ZigZag = function(offset) {
  2689. var val = this.readVarint32(offset);
  2690. if (typeof val === 'object')
  2691. val["value"] = ByteBuffer.zigZagDecode32(val["value"]);
  2692. else
  2693. val = ByteBuffer.zigZagDecode32(val);
  2694. return val;
  2695. };
  2696. // types/varints/varint64
  2697. if (Long) {
  2698. /**
  2699. * Maximum number of bytes required to store a 64bit base 128 variable-length integer.
  2700. * @type {number}
  2701. * @const
  2702. * @expose
  2703. */
  2704. ByteBuffer.MAX_VARINT64_BYTES = 10;
  2705. /**
  2706. * Calculates the actual number of bytes required to store a 64bit base 128 variable-length integer.
  2707. * @param {number|!Long} value Value to encode
  2708. * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT64_BYTES}
  2709. * @expose
  2710. */
  2711. ByteBuffer.calculateVarint64 = function(value) {
  2712. if (typeof value === 'number')
  2713. value = Long.fromNumber(value);
  2714. else if (typeof value === 'string')
  2715. value = Long.fromString(value);
  2716. // ref: src/google/protobuf/io/coded_stream.cc
  2717. var part0 = value.toInt() >>> 0,
  2718. part1 = value.shiftRightUnsigned(28).toInt() >>> 0,
  2719. part2 = value.shiftRightUnsigned(56).toInt() >>> 0;
  2720. if (part2 == 0) {
  2721. if (part1 == 0) {
  2722. if (part0 < 1 << 14)
  2723. return part0 < 1 << 7 ? 1 : 2;
  2724. else
  2725. return part0 < 1 << 21 ? 3 : 4;
  2726. } else {
  2727. if (part1 < 1 << 14)
  2728. return part1 < 1 << 7 ? 5 : 6;
  2729. else
  2730. return part1 < 1 << 21 ? 7 : 8;
  2731. }
  2732. } else
  2733. return part2 < 1 << 7 ? 9 : 10;
  2734. };
  2735. /**
  2736. * Zigzag encodes a signed 64bit integer so that it can be effectively used with varint encoding.
  2737. * @param {number|!Long} value Signed long
  2738. * @returns {!Long} Unsigned zigzag encoded long
  2739. * @expose
  2740. */
  2741. ByteBuffer.zigZagEncode64 = function(value) {
  2742. if (typeof value === 'number')
  2743. value = Long.fromNumber(value, false);
  2744. else if (typeof value === 'string')
  2745. value = Long.fromString(value, false);
  2746. else if (value.unsigned !== false) value = value.toSigned();
  2747. // ref: src/google/protobuf/wire_format_lite.h
  2748. return value.shiftLeft(1).xor(value.shiftRight(63)).toUnsigned();
  2749. };
  2750. /**
  2751. * Decodes a zigzag encoded signed 64bit integer.
  2752. * @param {!Long|number} value Unsigned zigzag encoded long or JavaScript number
  2753. * @returns {!Long} Signed long
  2754. * @expose
  2755. */
  2756. ByteBuffer.zigZagDecode64 = function(value) {
  2757. if (typeof value === 'number')
  2758. value = Long.fromNumber(value, false);
  2759. else if (typeof value === 'string')
  2760. value = Long.fromString(value, false);
  2761. else if (value.unsigned !== false) value = value.toSigned();
  2762. // ref: src/google/protobuf/wire_format_lite.h
  2763. return value.shiftRightUnsigned(1).xor(value.and(Long.ONE).toSigned().negate()).toSigned();
  2764. };
  2765. /**
  2766. * Writes a 64bit base 128 variable-length integer.
  2767. * @param {number|Long} value Value to write
  2768. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  2769. * written if omitted.
  2770. * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written.
  2771. * @expose
  2772. */
  2773. ByteBufferPrototype.writeVarint64 = function(value, offset) {
  2774. var relative = typeof offset === 'undefined';
  2775. if (relative) offset = this.offset;
  2776. if (!this.noAssert) {
  2777. if (typeof value === 'number')
  2778. value = Long.fromNumber(value);
  2779. else if (typeof value === 'string')
  2780. value = Long.fromString(value);
  2781. else if (!(value && value instanceof Long))
  2782. throw TypeError("Illegal value: "+value+" (not an integer or Long)");
  2783. if (typeof offset !== 'number' || offset % 1 !== 0)
  2784. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2785. offset >>>= 0;
  2786. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  2787. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  2788. }
  2789. if (typeof value === 'number')
  2790. value = Long.fromNumber(value, false);
  2791. else if (typeof value === 'string')
  2792. value = Long.fromString(value, false);
  2793. else if (value.unsigned !== false) value = value.toSigned();
  2794. var size = ByteBuffer.calculateVarint64(value),
  2795. part0 = value.toInt() >>> 0,
  2796. part1 = value.shiftRightUnsigned(28).toInt() >>> 0,
  2797. part2 = value.shiftRightUnsigned(56).toInt() >>> 0;
  2798. offset += size;
  2799. var capacity11 = this.buffer.byteLength;
  2800. if (offset > capacity11)
  2801. this.resize((capacity11 *= 2) > offset ? capacity11 : offset);
  2802. offset -= size;
  2803. switch (size) {
  2804. case 10: this.view[offset+9] = (part2 >>> 7) & 0x01;
  2805. case 9 : this.view[offset+8] = size !== 9 ? (part2 ) | 0x80 : (part2 ) & 0x7F;
  2806. case 8 : this.view[offset+7] = size !== 8 ? (part1 >>> 21) | 0x80 : (part1 >>> 21) & 0x7F;
  2807. case 7 : this.view[offset+6] = size !== 7 ? (part1 >>> 14) | 0x80 : (part1 >>> 14) & 0x7F;
  2808. case 6 : this.view[offset+5] = size !== 6 ? (part1 >>> 7) | 0x80 : (part1 >>> 7) & 0x7F;
  2809. case 5 : this.view[offset+4] = size !== 5 ? (part1 ) | 0x80 : (part1 ) & 0x7F;
  2810. case 4 : this.view[offset+3] = size !== 4 ? (part0 >>> 21) | 0x80 : (part0 >>> 21) & 0x7F;
  2811. case 3 : this.view[offset+2] = size !== 3 ? (part0 >>> 14) | 0x80 : (part0 >>> 14) & 0x7F;
  2812. case 2 : this.view[offset+1] = size !== 2 ? (part0 >>> 7) | 0x80 : (part0 >>> 7) & 0x7F;
  2813. case 1 : this.view[offset ] = size !== 1 ? (part0 ) | 0x80 : (part0 ) & 0x7F;
  2814. }
  2815. if (relative) {
  2816. this.offset += size;
  2817. return this;
  2818. } else {
  2819. return size;
  2820. }
  2821. };
  2822. /**
  2823. * Writes a zig-zag encoded 64bit base 128 variable-length integer.
  2824. * @param {number|Long} value Value to write
  2825. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  2826. * written if omitted.
  2827. * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written.
  2828. * @expose
  2829. */
  2830. ByteBufferPrototype.writeVarint64ZigZag = function(value, offset) {
  2831. return this.writeVarint64(ByteBuffer.zigZagEncode64(value), offset);
  2832. };
  2833. /**
  2834. * Reads a 64bit base 128 variable-length integer. Requires Long.js.
  2835. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  2836. * read if omitted.
  2837. * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and
  2838. * the actual number of bytes read.
  2839. * @throws {Error} If it's not a valid varint
  2840. * @expose
  2841. */
  2842. ByteBufferPrototype.readVarint64 = function(offset) {
  2843. var relative = typeof offset === 'undefined';
  2844. if (relative) offset = this.offset;
  2845. if (!this.noAssert) {
  2846. if (typeof offset !== 'number' || offset % 1 !== 0)
  2847. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2848. offset >>>= 0;
  2849. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  2850. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  2851. }
  2852. // ref: src/google/protobuf/io/coded_stream.cc
  2853. var start = offset,
  2854. part0 = 0,
  2855. part1 = 0,
  2856. part2 = 0,
  2857. b = 0;
  2858. b = this.view[offset++]; part0 = (b & 0x7F) ; if ( b & 0x80 ) {
  2859. b = this.view[offset++]; part0 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  2860. b = this.view[offset++]; part0 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  2861. b = this.view[offset++]; part0 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  2862. b = this.view[offset++]; part1 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  2863. b = this.view[offset++]; part1 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  2864. b = this.view[offset++]; part1 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  2865. b = this.view[offset++]; part1 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  2866. b = this.view[offset++]; part2 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  2867. b = this.view[offset++]; part2 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
  2868. throw Error("Buffer overrun"); }}}}}}}}}}
  2869. var value = Long.fromBits(part0 | (part1 << 28), (part1 >>> 4) | (part2) << 24, false);
  2870. if (relative) {
  2871. this.offset = offset;
  2872. return value;
  2873. } else {
  2874. return {
  2875. 'value': value,
  2876. 'length': offset-start
  2877. };
  2878. }
  2879. };
  2880. /**
  2881. * Reads a zig-zag encoded 64bit base 128 variable-length integer. Requires Long.js.
  2882. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  2883. * read if omitted.
  2884. * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and
  2885. * the actual number of bytes read.
  2886. * @throws {Error} If it's not a valid varint
  2887. * @expose
  2888. */
  2889. ByteBufferPrototype.readVarint64ZigZag = function(offset) {
  2890. var val = this.readVarint64(offset);
  2891. if (val && val['value'] instanceof Long)
  2892. val["value"] = ByteBuffer.zigZagDecode64(val["value"]);
  2893. else
  2894. val = ByteBuffer.zigZagDecode64(val);
  2895. return val;
  2896. };
  2897. } // Long
  2898. // types/strings/cstring
  2899. /**
  2900. * Writes a NULL-terminated UTF8 encoded string. For this to work the specified string must not contain any NULL
  2901. * characters itself.
  2902. * @param {string} str String to write
  2903. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  2904. * contained in `str` + 1 if omitted.
  2905. * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written
  2906. * @expose
  2907. */
  2908. ByteBufferPrototype.writeCString = function(str, offset) {
  2909. var relative = typeof offset === 'undefined';
  2910. if (relative) offset = this.offset;
  2911. var i,
  2912. k = str.length;
  2913. if (!this.noAssert) {
  2914. if (typeof str !== 'string')
  2915. throw TypeError("Illegal str: Not a string");
  2916. for (i=0; i<k; ++i) {
  2917. if (str.charCodeAt(i) === 0)
  2918. throw RangeError("Illegal str: Contains NULL-characters");
  2919. }
  2920. if (typeof offset !== 'number' || offset % 1 !== 0)
  2921. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2922. offset >>>= 0;
  2923. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  2924. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  2925. }
  2926. // UTF8 strings do not contain zero bytes in between except for the zero character, so:
  2927. k = utfx.calculateUTF16asUTF8(stringSource(str))[1];
  2928. offset += k+1;
  2929. var capacity12 = this.buffer.byteLength;
  2930. if (offset > capacity12)
  2931. this.resize((capacity12 *= 2) > offset ? capacity12 : offset);
  2932. offset -= k+1;
  2933. utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
  2934. this.view[offset++] = b;
  2935. }.bind(this));
  2936. this.view[offset++] = 0;
  2937. if (relative) {
  2938. this.offset = offset;
  2939. return this;
  2940. }
  2941. return k;
  2942. };
  2943. /**
  2944. * Reads a NULL-terminated UTF8 encoded string. For this to work the string read must not contain any NULL characters
  2945. * itself.
  2946. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  2947. * read if omitted.
  2948. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
  2949. * read and the actual number of bytes read.
  2950. * @expose
  2951. */
  2952. ByteBufferPrototype.readCString = function(offset) {
  2953. var relative = typeof offset === 'undefined';
  2954. if (relative) offset = this.offset;
  2955. if (!this.noAssert) {
  2956. if (typeof offset !== 'number' || offset % 1 !== 0)
  2957. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  2958. offset >>>= 0;
  2959. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  2960. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  2961. }
  2962. var start = offset;
  2963. // UTF8 strings do not contain zero bytes in between except for the zero character itself, so:
  2964. var sd, b = -1;
  2965. utfx.decodeUTF8toUTF16(function() {
  2966. if (b === 0) return null;
  2967. if (offset >= this.limit)
  2968. throw RangeError("Illegal range: Truncated data, "+offset+" < "+this.limit);
  2969. b = this.view[offset++];
  2970. return b === 0 ? null : b;
  2971. }.bind(this), sd = stringDestination(), true);
  2972. if (relative) {
  2973. this.offset = offset;
  2974. return sd();
  2975. } else {
  2976. return {
  2977. "string": sd(),
  2978. "length": offset - start
  2979. };
  2980. }
  2981. };
  2982. // types/strings/istring
  2983. /**
  2984. * Writes a length as uint32 prefixed UTF8 encoded string.
  2985. * @param {string} str String to write
  2986. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  2987. * written if omitted.
  2988. * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written
  2989. * @expose
  2990. * @see ByteBuffer#writeVarint32
  2991. */
  2992. ByteBufferPrototype.writeIString = function(str, offset) {
  2993. var relative = typeof offset === 'undefined';
  2994. if (relative) offset = this.offset;
  2995. if (!this.noAssert) {
  2996. if (typeof str !== 'string')
  2997. throw TypeError("Illegal str: Not a string");
  2998. if (typeof offset !== 'number' || offset % 1 !== 0)
  2999. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3000. offset >>>= 0;
  3001. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3002. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3003. }
  3004. var start = offset,
  3005. k;
  3006. k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1];
  3007. offset += 4+k;
  3008. var capacity13 = this.buffer.byteLength;
  3009. if (offset > capacity13)
  3010. this.resize((capacity13 *= 2) > offset ? capacity13 : offset);
  3011. offset -= 4+k;
  3012. if (this.littleEndian) {
  3013. this.view[offset+3] = (k >>> 24) & 0xFF;
  3014. this.view[offset+2] = (k >>> 16) & 0xFF;
  3015. this.view[offset+1] = (k >>> 8) & 0xFF;
  3016. this.view[offset ] = k & 0xFF;
  3017. } else {
  3018. this.view[offset ] = (k >>> 24) & 0xFF;
  3019. this.view[offset+1] = (k >>> 16) & 0xFF;
  3020. this.view[offset+2] = (k >>> 8) & 0xFF;
  3021. this.view[offset+3] = k & 0xFF;
  3022. }
  3023. offset += 4;
  3024. utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
  3025. this.view[offset++] = b;
  3026. }.bind(this));
  3027. if (offset !== start + 4 + k)
  3028. throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+4+k));
  3029. if (relative) {
  3030. this.offset = offset;
  3031. return this;
  3032. }
  3033. return offset - start;
  3034. };
  3035. /**
  3036. * Reads a length as uint32 prefixed UTF8 encoded string.
  3037. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  3038. * read if omitted.
  3039. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
  3040. * read and the actual number of bytes read.
  3041. * @expose
  3042. * @see ByteBuffer#readVarint32
  3043. */
  3044. ByteBufferPrototype.readIString = function(offset) {
  3045. var relative = typeof offset === 'undefined';
  3046. if (relative) offset = this.offset;
  3047. if (!this.noAssert) {
  3048. if (typeof offset !== 'number' || offset % 1 !== 0)
  3049. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3050. offset >>>= 0;
  3051. if (offset < 0 || offset + 4 > this.buffer.byteLength)
  3052. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
  3053. }
  3054. var start = offset;
  3055. var len = this.readUint32(offset);
  3056. var str = this.readUTF8String(len, ByteBuffer.METRICS_BYTES, offset += 4);
  3057. offset += str['length'];
  3058. if (relative) {
  3059. this.offset = offset;
  3060. return str['string'];
  3061. } else {
  3062. return {
  3063. 'string': str['string'],
  3064. 'length': offset - start
  3065. };
  3066. }
  3067. };
  3068. // types/strings/utf8string
  3069. /**
  3070. * Metrics representing number of UTF8 characters. Evaluates to `c`.
  3071. * @type {string}
  3072. * @const
  3073. * @expose
  3074. */
  3075. ByteBuffer.METRICS_CHARS = 'c';
  3076. /**
  3077. * Metrics representing number of bytes. Evaluates to `b`.
  3078. * @type {string}
  3079. * @const
  3080. * @expose
  3081. */
  3082. ByteBuffer.METRICS_BYTES = 'b';
  3083. /**
  3084. * Writes an UTF8 encoded string.
  3085. * @param {string} str String to write
  3086. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted.
  3087. * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written.
  3088. * @expose
  3089. */
  3090. ByteBufferPrototype.writeUTF8String = function(str, offset) {
  3091. var relative = typeof offset === 'undefined';
  3092. if (relative) offset = this.offset;
  3093. if (!this.noAssert) {
  3094. if (typeof offset !== 'number' || offset % 1 !== 0)
  3095. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3096. offset >>>= 0;
  3097. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3098. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3099. }
  3100. var k;
  3101. var start = offset;
  3102. k = utfx.calculateUTF16asUTF8(stringSource(str))[1];
  3103. offset += k;
  3104. var capacity14 = this.buffer.byteLength;
  3105. if (offset > capacity14)
  3106. this.resize((capacity14 *= 2) > offset ? capacity14 : offset);
  3107. offset -= k;
  3108. utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
  3109. this.view[offset++] = b;
  3110. }.bind(this));
  3111. if (relative) {
  3112. this.offset = offset;
  3113. return this;
  3114. }
  3115. return offset - start;
  3116. };
  3117. /**
  3118. * Writes an UTF8 encoded string. This is an alias of {@link ByteBuffer#writeUTF8String}.
  3119. * @function
  3120. * @param {string} str String to write
  3121. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted.
  3122. * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written.
  3123. * @expose
  3124. */
  3125. ByteBufferPrototype.writeString = ByteBufferPrototype.writeUTF8String;
  3126. /**
  3127. * Calculates the number of UTF8 characters of a string. JavaScript itself uses UTF-16, so that a string's
  3128. * `length` property does not reflect its actual UTF8 size if it contains code points larger than 0xFFFF.
  3129. * @param {string} str String to calculate
  3130. * @returns {number} Number of UTF8 characters
  3131. * @expose
  3132. */
  3133. ByteBuffer.calculateUTF8Chars = function(str) {
  3134. return utfx.calculateUTF16asUTF8(stringSource(str))[0];
  3135. };
  3136. /**
  3137. * Calculates the number of UTF8 bytes of a string.
  3138. * @param {string} str String to calculate
  3139. * @returns {number} Number of UTF8 bytes
  3140. * @expose
  3141. */
  3142. ByteBuffer.calculateUTF8Bytes = function(str) {
  3143. return utfx.calculateUTF16asUTF8(stringSource(str))[1];
  3144. };
  3145. /**
  3146. * Calculates the number of UTF8 bytes of a string. This is an alias of {@link ByteBuffer.calculateUTF8Bytes}.
  3147. * @function
  3148. * @param {string} str String to calculate
  3149. * @returns {number} Number of UTF8 bytes
  3150. * @expose
  3151. */
  3152. ByteBuffer.calculateString = ByteBuffer.calculateUTF8Bytes;
  3153. /**
  3154. * Reads an UTF8 encoded string.
  3155. * @param {number} length Number of characters or bytes to read.
  3156. * @param {string=} metrics Metrics specifying what `length` is meant to count. Defaults to
  3157. * {@link ByteBuffer.METRICS_CHARS}.
  3158. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  3159. * read if omitted.
  3160. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
  3161. * read and the actual number of bytes read.
  3162. * @expose
  3163. */
  3164. ByteBufferPrototype.readUTF8String = function(length, metrics, offset) {
  3165. if (typeof metrics === 'number') {
  3166. offset = metrics;
  3167. metrics = undefined;
  3168. }
  3169. var relative = typeof offset === 'undefined';
  3170. if (relative) offset = this.offset;
  3171. if (typeof metrics === 'undefined') metrics = ByteBuffer.METRICS_CHARS;
  3172. if (!this.noAssert) {
  3173. if (typeof length !== 'number' || length % 1 !== 0)
  3174. throw TypeError("Illegal length: "+length+" (not an integer)");
  3175. length |= 0;
  3176. if (typeof offset !== 'number' || offset % 1 !== 0)
  3177. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3178. offset >>>= 0;
  3179. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3180. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3181. }
  3182. var i = 0,
  3183. start = offset,
  3184. sd;
  3185. if (metrics === ByteBuffer.METRICS_CHARS) { // The same for node and the browser
  3186. sd = stringDestination();
  3187. utfx.decodeUTF8(function() {
  3188. return i < length && offset < this.limit ? this.view[offset++] : null;
  3189. }.bind(this), function(cp) {
  3190. ++i; utfx.UTF8toUTF16(cp, sd);
  3191. });
  3192. if (i !== length)
  3193. throw RangeError("Illegal range: Truncated data, "+i+" == "+length);
  3194. if (relative) {
  3195. this.offset = offset;
  3196. return sd();
  3197. } else {
  3198. return {
  3199. "string": sd(),
  3200. "length": offset - start
  3201. };
  3202. }
  3203. } else if (metrics === ByteBuffer.METRICS_BYTES) {
  3204. if (!this.noAssert) {
  3205. if (typeof offset !== 'number' || offset % 1 !== 0)
  3206. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3207. offset >>>= 0;
  3208. if (offset < 0 || offset + length > this.buffer.byteLength)
  3209. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength);
  3210. }
  3211. var k = offset + length;
  3212. utfx.decodeUTF8toUTF16(function() {
  3213. return offset < k ? this.view[offset++] : null;
  3214. }.bind(this), sd = stringDestination(), this.noAssert);
  3215. if (offset !== k)
  3216. throw RangeError("Illegal range: Truncated data, "+offset+" == "+k);
  3217. if (relative) {
  3218. this.offset = offset;
  3219. return sd();
  3220. } else {
  3221. return {
  3222. 'string': sd(),
  3223. 'length': offset - start
  3224. };
  3225. }
  3226. } else
  3227. throw TypeError("Unsupported metrics: "+metrics);
  3228. };
  3229. /**
  3230. * Reads an UTF8 encoded string. This is an alias of {@link ByteBuffer#readUTF8String}.
  3231. * @function
  3232. * @param {number} length Number of characters or bytes to read
  3233. * @param {number=} metrics Metrics specifying what `n` is meant to count. Defaults to
  3234. * {@link ByteBuffer.METRICS_CHARS}.
  3235. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  3236. * read if omitted.
  3237. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
  3238. * read and the actual number of bytes read.
  3239. * @expose
  3240. */
  3241. ByteBufferPrototype.readString = ByteBufferPrototype.readUTF8String;
  3242. // types/strings/vstring
  3243. /**
  3244. * Writes a length as varint32 prefixed UTF8 encoded string.
  3245. * @param {string} str String to write
  3246. * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  3247. * written if omitted.
  3248. * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written
  3249. * @expose
  3250. * @see ByteBuffer#writeVarint32
  3251. */
  3252. ByteBufferPrototype.writeVString = function(str, offset) {
  3253. var relative = typeof offset === 'undefined';
  3254. if (relative) offset = this.offset;
  3255. if (!this.noAssert) {
  3256. if (typeof str !== 'string')
  3257. throw TypeError("Illegal str: Not a string");
  3258. if (typeof offset !== 'number' || offset % 1 !== 0)
  3259. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3260. offset >>>= 0;
  3261. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3262. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3263. }
  3264. var start = offset,
  3265. k, l;
  3266. k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1];
  3267. l = ByteBuffer.calculateVarint32(k);
  3268. offset += l+k;
  3269. var capacity15 = this.buffer.byteLength;
  3270. if (offset > capacity15)
  3271. this.resize((capacity15 *= 2) > offset ? capacity15 : offset);
  3272. offset -= l+k;
  3273. offset += this.writeVarint32(k, offset);
  3274. utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
  3275. this.view[offset++] = b;
  3276. }.bind(this));
  3277. if (offset !== start+k+l)
  3278. throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+k+l));
  3279. if (relative) {
  3280. this.offset = offset;
  3281. return this;
  3282. }
  3283. return offset - start;
  3284. };
  3285. /**
  3286. * Reads a length as varint32 prefixed UTF8 encoded string.
  3287. * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  3288. * read if omitted.
  3289. * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
  3290. * read and the actual number of bytes read.
  3291. * @expose
  3292. * @see ByteBuffer#readVarint32
  3293. */
  3294. ByteBufferPrototype.readVString = function(offset) {
  3295. var relative = typeof offset === 'undefined';
  3296. if (relative) offset = this.offset;
  3297. if (!this.noAssert) {
  3298. if (typeof offset !== 'number' || offset % 1 !== 0)
  3299. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3300. offset >>>= 0;
  3301. if (offset < 0 || offset + 1 > this.buffer.byteLength)
  3302. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
  3303. }
  3304. var start = offset;
  3305. var len = this.readVarint32(offset);
  3306. var str = this.readUTF8String(len['value'], ByteBuffer.METRICS_BYTES, offset += len['length']);
  3307. offset += str['length'];
  3308. if (relative) {
  3309. this.offset = offset;
  3310. return str['string'];
  3311. } else {
  3312. return {
  3313. 'string': str['string'],
  3314. 'length': offset - start
  3315. };
  3316. }
  3317. };
  3318. /**
  3319. * Appends some data to this ByteBuffer. This will overwrite any contents behind the specified offset up to the appended
  3320. * data's length.
  3321. * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to append. If `source` is a ByteBuffer, its offsets
  3322. * will be modified according to the performed read operation.
  3323. * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
  3324. * @param {number=} offset Offset to append at. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  3325. * written if omitted.
  3326. * @returns {!ByteBuffer} this
  3327. * @expose
  3328. * @example A relative `<01 02>03.append(<04 05>)` will result in `<01 02 04 05>, 04 05|`
  3329. * @example An absolute `<01 02>03.append(04 05>, 1)` will result in `<01 04>05, 04 05|`
  3330. */
  3331. ByteBufferPrototype.append = function(source, encoding, offset) {
  3332. if (typeof encoding === 'number' || typeof encoding !== 'string') {
  3333. offset = encoding;
  3334. encoding = undefined;
  3335. }
  3336. var relative = typeof offset === 'undefined';
  3337. if (relative) offset = this.offset;
  3338. if (!this.noAssert) {
  3339. if (typeof offset !== 'number' || offset % 1 !== 0)
  3340. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3341. offset >>>= 0;
  3342. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3343. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3344. }
  3345. if (!(source instanceof ByteBuffer))
  3346. source = ByteBuffer.wrap(source, encoding);
  3347. var length = source.limit - source.offset;
  3348. if (length <= 0) return this; // Nothing to append
  3349. offset += length;
  3350. var capacity16 = this.buffer.byteLength;
  3351. if (offset > capacity16)
  3352. this.resize((capacity16 *= 2) > offset ? capacity16 : offset);
  3353. offset -= length;
  3354. this.view.set(source.view.subarray(source.offset, source.limit), offset);
  3355. source.offset += length;
  3356. if (relative) this.offset += length;
  3357. return this;
  3358. };
  3359. /**
  3360. * Appends this ByteBuffer's contents to another ByteBuffer. This will overwrite any contents at and after the
  3361. specified offset up to the length of this ByteBuffer's data.
  3362. * @param {!ByteBuffer} target Target ByteBuffer
  3363. * @param {number=} offset Offset to append to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  3364. * read if omitted.
  3365. * @returns {!ByteBuffer} this
  3366. * @expose
  3367. * @see ByteBuffer#append
  3368. */
  3369. ByteBufferPrototype.appendTo = function(target, offset) {
  3370. target.append(this, offset);
  3371. return this;
  3372. };
  3373. /**
  3374. * Enables or disables assertions of argument types and offsets. Assertions are enabled by default but you can opt to
  3375. * disable them if your code already makes sure that everything is valid.
  3376. * @param {boolean} assert `true` to enable assertions, otherwise `false`
  3377. * @returns {!ByteBuffer} this
  3378. * @expose
  3379. */
  3380. ByteBufferPrototype.assert = function(assert) {
  3381. this.noAssert = !assert;
  3382. return this;
  3383. };
  3384. /**
  3385. * Gets the capacity of this ByteBuffer's backing buffer.
  3386. * @returns {number} Capacity of the backing buffer
  3387. * @expose
  3388. */
  3389. ByteBufferPrototype.capacity = function() {
  3390. return this.buffer.byteLength;
  3391. };
  3392. /**
  3393. * Clears this ByteBuffer's offsets by setting {@link ByteBuffer#offset} to `0` and {@link ByteBuffer#limit} to the
  3394. * backing buffer's capacity. Discards {@link ByteBuffer#markedOffset}.
  3395. * @returns {!ByteBuffer} this
  3396. * @expose
  3397. */
  3398. ByteBufferPrototype.clear = function() {
  3399. this.offset = 0;
  3400. this.limit = this.buffer.byteLength;
  3401. this.markedOffset = -1;
  3402. return this;
  3403. };
  3404. /**
  3405. * Creates a cloned instance of this ByteBuffer, preset with this ByteBuffer's values for {@link ByteBuffer#offset},
  3406. * {@link ByteBuffer#markedOffset} and {@link ByteBuffer#limit}.
  3407. * @param {boolean=} copy Whether to copy the backing buffer or to return another view on the same, defaults to `false`
  3408. * @returns {!ByteBuffer} Cloned instance
  3409. * @expose
  3410. */
  3411. ByteBufferPrototype.clone = function(copy) {
  3412. var bb = new ByteBuffer(0, this.littleEndian, this.noAssert);
  3413. if (copy) {
  3414. bb.buffer = new ArrayBuffer(this.buffer.byteLength);
  3415. bb.view = new Uint8Array(bb.buffer);
  3416. } else {
  3417. bb.buffer = this.buffer;
  3418. bb.view = this.view;
  3419. }
  3420. bb.offset = this.offset;
  3421. bb.markedOffset = this.markedOffset;
  3422. bb.limit = this.limit;
  3423. return bb;
  3424. };
  3425. /**
  3426. * Compacts this ByteBuffer to be backed by a {@link ByteBuffer#buffer} of its contents' length. Contents are the bytes
  3427. * between {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. Will set `offset = 0` and `limit = capacity` and
  3428. * adapt {@link ByteBuffer#markedOffset} to the same relative position if set.
  3429. * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
  3430. * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
  3431. * @returns {!ByteBuffer} this
  3432. * @expose
  3433. */
  3434. ByteBufferPrototype.compact = function(begin, end) {
  3435. if (typeof begin === 'undefined') begin = this.offset;
  3436. if (typeof end === 'undefined') end = this.limit;
  3437. if (!this.noAssert) {
  3438. if (typeof begin !== 'number' || begin % 1 !== 0)
  3439. throw TypeError("Illegal begin: Not an integer");
  3440. begin >>>= 0;
  3441. if (typeof end !== 'number' || end % 1 !== 0)
  3442. throw TypeError("Illegal end: Not an integer");
  3443. end >>>= 0;
  3444. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  3445. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  3446. }
  3447. if (begin === 0 && end === this.buffer.byteLength)
  3448. return this; // Already compacted
  3449. var len = end - begin;
  3450. if (len === 0) {
  3451. this.buffer = EMPTY_BUFFER;
  3452. this.view = null;
  3453. if (this.markedOffset >= 0) this.markedOffset -= begin;
  3454. this.offset = 0;
  3455. this.limit = 0;
  3456. return this;
  3457. }
  3458. var buffer = new ArrayBuffer(len);
  3459. var view = new Uint8Array(buffer);
  3460. view.set(this.view.subarray(begin, end));
  3461. this.buffer = buffer;
  3462. this.view = view;
  3463. if (this.markedOffset >= 0) this.markedOffset -= begin;
  3464. this.offset = 0;
  3465. this.limit = len;
  3466. return this;
  3467. };
  3468. /**
  3469. * Creates a copy of this ByteBuffer's contents. Contents are the bytes between {@link ByteBuffer#offset} and
  3470. * {@link ByteBuffer#limit}.
  3471. * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
  3472. * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
  3473. * @returns {!ByteBuffer} Copy
  3474. * @expose
  3475. */
  3476. ByteBufferPrototype.copy = function(begin, end) {
  3477. if (typeof begin === 'undefined') begin = this.offset;
  3478. if (typeof end === 'undefined') end = this.limit;
  3479. if (!this.noAssert) {
  3480. if (typeof begin !== 'number' || begin % 1 !== 0)
  3481. throw TypeError("Illegal begin: Not an integer");
  3482. begin >>>= 0;
  3483. if (typeof end !== 'number' || end % 1 !== 0)
  3484. throw TypeError("Illegal end: Not an integer");
  3485. end >>>= 0;
  3486. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  3487. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  3488. }
  3489. if (begin === end)
  3490. return new ByteBuffer(0, this.littleEndian, this.noAssert);
  3491. var capacity = end - begin,
  3492. bb = new ByteBuffer(capacity, this.littleEndian, this.noAssert);
  3493. bb.offset = 0;
  3494. bb.limit = capacity;
  3495. if (bb.markedOffset >= 0) bb.markedOffset -= begin;
  3496. this.copyTo(bb, 0, begin, end);
  3497. return bb;
  3498. };
  3499. /**
  3500. * Copies this ByteBuffer's contents to another ByteBuffer. Contents are the bytes between {@link ByteBuffer#offset} and
  3501. * {@link ByteBuffer#limit}.
  3502. * @param {!ByteBuffer} target Target ByteBuffer
  3503. * @param {number=} targetOffset Offset to copy to. Will use and increase the target's {@link ByteBuffer#offset}
  3504. * by the number of bytes copied if omitted.
  3505. * @param {number=} sourceOffset Offset to start copying from. Will use and increase {@link ByteBuffer#offset} by the
  3506. * number of bytes copied if omitted.
  3507. * @param {number=} sourceLimit Offset to end copying from, defaults to {@link ByteBuffer#limit}
  3508. * @returns {!ByteBuffer} this
  3509. * @expose
  3510. */
  3511. ByteBufferPrototype.copyTo = function(target, targetOffset, sourceOffset, sourceLimit) {
  3512. var relative,
  3513. targetRelative;
  3514. if (!this.noAssert) {
  3515. if (!ByteBuffer.isByteBuffer(target))
  3516. throw TypeError("Illegal target: Not a ByteBuffer");
  3517. }
  3518. targetOffset = (targetRelative = typeof targetOffset === 'undefined') ? target.offset : targetOffset | 0;
  3519. sourceOffset = (relative = typeof sourceOffset === 'undefined') ? this.offset : sourceOffset | 0;
  3520. sourceLimit = typeof sourceLimit === 'undefined' ? this.limit : sourceLimit | 0;
  3521. if (targetOffset < 0 || targetOffset > target.buffer.byteLength)
  3522. throw RangeError("Illegal target range: 0 <= "+targetOffset+" <= "+target.buffer.byteLength);
  3523. if (sourceOffset < 0 || sourceLimit > this.buffer.byteLength)
  3524. throw RangeError("Illegal source range: 0 <= "+sourceOffset+" <= "+this.buffer.byteLength);
  3525. var len = sourceLimit - sourceOffset;
  3526. if (len === 0)
  3527. return target; // Nothing to copy
  3528. target.ensureCapacity(targetOffset + len);
  3529. target.view.set(this.view.subarray(sourceOffset, sourceLimit), targetOffset);
  3530. if (relative) this.offset += len;
  3531. if (targetRelative) target.offset += len;
  3532. return this;
  3533. };
  3534. /**
  3535. * Makes sure that this ByteBuffer is backed by a {@link ByteBuffer#buffer} of at least the specified capacity. If the
  3536. * current capacity is exceeded, it will be doubled. If double the current capacity is less than the required capacity,
  3537. * the required capacity will be used instead.
  3538. * @param {number} capacity Required capacity
  3539. * @returns {!ByteBuffer} this
  3540. * @expose
  3541. */
  3542. ByteBufferPrototype.ensureCapacity = function(capacity) {
  3543. var current = this.buffer.byteLength;
  3544. if (current < capacity)
  3545. return this.resize((current *= 2) > capacity ? current : capacity);
  3546. return this;
  3547. };
  3548. /**
  3549. * Overwrites this ByteBuffer's contents with the specified value. Contents are the bytes between
  3550. * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
  3551. * @param {number|string} value Byte value to fill with. If given as a string, the first character is used.
  3552. * @param {number=} begin Begin offset. Will use and increase {@link ByteBuffer#offset} by the number of bytes
  3553. * written if omitted. defaults to {@link ByteBuffer#offset}.
  3554. * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
  3555. * @returns {!ByteBuffer} this
  3556. * @expose
  3557. * @example `someByteBuffer.clear().fill(0)` fills the entire backing buffer with zeroes
  3558. */
  3559. ByteBufferPrototype.fill = function(value, begin, end) {
  3560. var relative = typeof begin === 'undefined';
  3561. if (relative) begin = this.offset;
  3562. if (typeof value === 'string' && value.length > 0)
  3563. value = value.charCodeAt(0);
  3564. if (typeof begin === 'undefined') begin = this.offset;
  3565. if (typeof end === 'undefined') end = this.limit;
  3566. if (!this.noAssert) {
  3567. if (typeof value !== 'number' || value % 1 !== 0)
  3568. throw TypeError("Illegal value: "+value+" (not an integer)");
  3569. value |= 0;
  3570. if (typeof begin !== 'number' || begin % 1 !== 0)
  3571. throw TypeError("Illegal begin: Not an integer");
  3572. begin >>>= 0;
  3573. if (typeof end !== 'number' || end % 1 !== 0)
  3574. throw TypeError("Illegal end: Not an integer");
  3575. end >>>= 0;
  3576. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  3577. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  3578. }
  3579. if (begin >= end)
  3580. return this; // Nothing to fill
  3581. while (begin < end) this.view[begin++] = value;
  3582. if (relative) this.offset = begin;
  3583. return this;
  3584. };
  3585. /**
  3586. * Makes this ByteBuffer ready for a new sequence of write or relative read operations. Sets `limit = offset` and
  3587. * `offset = 0`. Make sure always to flip a ByteBuffer when all relative read or write operations are complete.
  3588. * @returns {!ByteBuffer} this
  3589. * @expose
  3590. */
  3591. ByteBufferPrototype.flip = function() {
  3592. this.limit = this.offset;
  3593. this.offset = 0;
  3594. return this;
  3595. };
  3596. /**
  3597. * Marks an offset on this ByteBuffer to be used later.
  3598. * @param {number=} offset Offset to mark. Defaults to {@link ByteBuffer#offset}.
  3599. * @returns {!ByteBuffer} this
  3600. * @throws {TypeError} If `offset` is not a valid number
  3601. * @throws {RangeError} If `offset` is out of bounds
  3602. * @see ByteBuffer#reset
  3603. * @expose
  3604. */
  3605. ByteBufferPrototype.mark = function(offset) {
  3606. offset = typeof offset === 'undefined' ? this.offset : offset;
  3607. if (!this.noAssert) {
  3608. if (typeof offset !== 'number' || offset % 1 !== 0)
  3609. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3610. offset >>>= 0;
  3611. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3612. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3613. }
  3614. this.markedOffset = offset;
  3615. return this;
  3616. };
  3617. /**
  3618. * Sets the byte order.
  3619. * @param {boolean} littleEndian `true` for little endian byte order, `false` for big endian
  3620. * @returns {!ByteBuffer} this
  3621. * @expose
  3622. */
  3623. ByteBufferPrototype.order = function(littleEndian) {
  3624. if (!this.noAssert) {
  3625. if (typeof littleEndian !== 'boolean')
  3626. throw TypeError("Illegal littleEndian: Not a boolean");
  3627. }
  3628. this.littleEndian = !!littleEndian;
  3629. return this;
  3630. };
  3631. /**
  3632. * Switches (to) little endian byte order.
  3633. * @param {boolean=} littleEndian Defaults to `true`, otherwise uses big endian
  3634. * @returns {!ByteBuffer} this
  3635. * @expose
  3636. */
  3637. ByteBufferPrototype.LE = function(littleEndian) {
  3638. this.littleEndian = typeof littleEndian !== 'undefined' ? !!littleEndian : true;
  3639. return this;
  3640. };
  3641. /**
  3642. * Switches (to) big endian byte order.
  3643. * @param {boolean=} bigEndian Defaults to `true`, otherwise uses little endian
  3644. * @returns {!ByteBuffer} this
  3645. * @expose
  3646. */
  3647. ByteBufferPrototype.BE = function(bigEndian) {
  3648. this.littleEndian = typeof bigEndian !== 'undefined' ? !bigEndian : false;
  3649. return this;
  3650. };
  3651. /**
  3652. * Prepends some data to this ByteBuffer. This will overwrite any contents before the specified offset up to the
  3653. * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
  3654. * will be resized and its contents moved accordingly.
  3655. * @param {!ByteBuffer|string|!ArrayBuffer} source Data to prepend. If `source` is a ByteBuffer, its offset will be
  3656. * modified according to the performed read operation.
  3657. * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
  3658. * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
  3659. * prepended if omitted.
  3660. * @returns {!ByteBuffer} this
  3661. * @expose
  3662. * @example A relative `00<01 02 03>.prepend(<04 05>)` results in `<04 05 01 02 03>, 04 05|`
  3663. * @example An absolute `00<01 02 03>.prepend(<04 05>, 2)` results in `04<05 02 03>, 04 05|`
  3664. */
  3665. ByteBufferPrototype.prepend = function(source, encoding, offset) {
  3666. if (typeof encoding === 'number' || typeof encoding !== 'string') {
  3667. offset = encoding;
  3668. encoding = undefined;
  3669. }
  3670. var relative = typeof offset === 'undefined';
  3671. if (relative) offset = this.offset;
  3672. if (!this.noAssert) {
  3673. if (typeof offset !== 'number' || offset % 1 !== 0)
  3674. throw TypeError("Illegal offset: "+offset+" (not an integer)");
  3675. offset >>>= 0;
  3676. if (offset < 0 || offset + 0 > this.buffer.byteLength)
  3677. throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
  3678. }
  3679. if (!(source instanceof ByteBuffer))
  3680. source = ByteBuffer.wrap(source, encoding);
  3681. var len = source.limit - source.offset;
  3682. if (len <= 0) return this; // Nothing to prepend
  3683. var diff = len - offset;
  3684. if (diff > 0) { // Not enough space before offset, so resize + move
  3685. var buffer = new ArrayBuffer(this.buffer.byteLength + diff);
  3686. var view = new Uint8Array(buffer);
  3687. view.set(this.view.subarray(offset, this.buffer.byteLength), len);
  3688. this.buffer = buffer;
  3689. this.view = view;
  3690. this.offset += diff;
  3691. if (this.markedOffset >= 0) this.markedOffset += diff;
  3692. this.limit += diff;
  3693. offset += diff;
  3694. } else {
  3695. var arrayView = new Uint8Array(this.buffer);
  3696. }
  3697. this.view.set(source.view.subarray(source.offset, source.limit), offset - len);
  3698. source.offset = source.limit;
  3699. if (relative)
  3700. this.offset -= len;
  3701. return this;
  3702. };
  3703. /**
  3704. * Prepends this ByteBuffer to another ByteBuffer. This will overwrite any contents before the specified offset up to the
  3705. * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
  3706. * will be resized and its contents moved accordingly.
  3707. * @param {!ByteBuffer} target Target ByteBuffer
  3708. * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
  3709. * prepended if omitted.
  3710. * @returns {!ByteBuffer} this
  3711. * @expose
  3712. * @see ByteBuffer#prepend
  3713. */
  3714. ByteBufferPrototype.prependTo = function(target, offset) {
  3715. target.prepend(this, offset);
  3716. return this;
  3717. };
  3718. /**
  3719. * Prints debug information about this ByteBuffer's contents.
  3720. * @param {function(string)=} out Output function to call, defaults to console.log
  3721. * @expose
  3722. */
  3723. ByteBufferPrototype.printDebug = function(out) {
  3724. if (typeof out !== 'function') out = console.log.bind(console);
  3725. out(
  3726. this.toString()+"\n"+
  3727. "-------------------------------------------------------------------\n"+
  3728. this.toDebug(/* columns */ true)
  3729. );
  3730. };
  3731. /**
  3732. * Gets the number of remaining readable bytes. Contents are the bytes between {@link ByteBuffer#offset} and
  3733. * {@link ByteBuffer#limit}, so this returns `limit - offset`.
  3734. * @returns {number} Remaining readable bytes. May be negative if `offset > limit`.
  3735. * @expose
  3736. */
  3737. ByteBufferPrototype.remaining = function() {
  3738. return this.limit - this.offset;
  3739. };
  3740. /**
  3741. * Resets this ByteBuffer's {@link ByteBuffer#offset}. If an offset has been marked through {@link ByteBuffer#mark}
  3742. * before, `offset` will be set to {@link ByteBuffer#markedOffset}, which will then be discarded. If no offset has been
  3743. * marked, sets `offset = 0`.
  3744. * @returns {!ByteBuffer} this
  3745. * @see ByteBuffer#mark
  3746. * @expose
  3747. */
  3748. ByteBufferPrototype.reset = function() {
  3749. if (this.markedOffset >= 0) {
  3750. this.offset = this.markedOffset;
  3751. this.markedOffset = -1;
  3752. } else {
  3753. this.offset = 0;
  3754. }
  3755. return this;
  3756. };
  3757. /**
  3758. * Resizes this ByteBuffer to be backed by a buffer of at least the given capacity. Will do nothing if already that
  3759. * large or larger.
  3760. * @param {number} capacity Capacity required
  3761. * @returns {!ByteBuffer} this
  3762. * @throws {TypeError} If `capacity` is not a number
  3763. * @throws {RangeError} If `capacity < 0`
  3764. * @expose
  3765. */
  3766. ByteBufferPrototype.resize = function(capacity) {
  3767. if (!this.noAssert) {
  3768. if (typeof capacity !== 'number' || capacity % 1 !== 0)
  3769. throw TypeError("Illegal capacity: "+capacity+" (not an integer)");
  3770. capacity |= 0;
  3771. if (capacity < 0)
  3772. throw RangeError("Illegal capacity: 0 <= "+capacity);
  3773. }
  3774. if (this.buffer.byteLength < capacity) {
  3775. var buffer = new ArrayBuffer(capacity);
  3776. var view = new Uint8Array(buffer);
  3777. view.set(this.view);
  3778. this.buffer = buffer;
  3779. this.view = view;
  3780. }
  3781. return this;
  3782. };
  3783. /**
  3784. * Reverses this ByteBuffer's contents.
  3785. * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
  3786. * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
  3787. * @returns {!ByteBuffer} this
  3788. * @expose
  3789. */
  3790. ByteBufferPrototype.reverse = function(begin, end) {
  3791. if (typeof begin === 'undefined') begin = this.offset;
  3792. if (typeof end === 'undefined') end = this.limit;
  3793. if (!this.noAssert) {
  3794. if (typeof begin !== 'number' || begin % 1 !== 0)
  3795. throw TypeError("Illegal begin: Not an integer");
  3796. begin >>>= 0;
  3797. if (typeof end !== 'number' || end % 1 !== 0)
  3798. throw TypeError("Illegal end: Not an integer");
  3799. end >>>= 0;
  3800. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  3801. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  3802. }
  3803. if (begin === end)
  3804. return this; // Nothing to reverse
  3805. Array.prototype.reverse.call(this.view.subarray(begin, end));
  3806. return this;
  3807. };
  3808. /**
  3809. * Skips the next `length` bytes. This will just advance
  3810. * @param {number} length Number of bytes to skip. May also be negative to move the offset back.
  3811. * @returns {!ByteBuffer} this
  3812. * @expose
  3813. */
  3814. ByteBufferPrototype.skip = function(length) {
  3815. if (!this.noAssert) {
  3816. if (typeof length !== 'number' || length % 1 !== 0)
  3817. throw TypeError("Illegal length: "+length+" (not an integer)");
  3818. length |= 0;
  3819. }
  3820. var offset = this.offset + length;
  3821. if (!this.noAssert) {
  3822. if (offset < 0 || offset > this.buffer.byteLength)
  3823. throw RangeError("Illegal length: 0 <= "+this.offset+" + "+length+" <= "+this.buffer.byteLength);
  3824. }
  3825. this.offset = offset;
  3826. return this;
  3827. };
  3828. /**
  3829. * Slices this ByteBuffer by creating a cloned instance with `offset = begin` and `limit = end`.
  3830. * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
  3831. * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
  3832. * @returns {!ByteBuffer} Clone of this ByteBuffer with slicing applied, backed by the same {@link ByteBuffer#buffer}
  3833. * @expose
  3834. */
  3835. ByteBufferPrototype.slice = function(begin, end) {
  3836. if (typeof begin === 'undefined') begin = this.offset;
  3837. if (typeof end === 'undefined') end = this.limit;
  3838. if (!this.noAssert) {
  3839. if (typeof begin !== 'number' || begin % 1 !== 0)
  3840. throw TypeError("Illegal begin: Not an integer");
  3841. begin >>>= 0;
  3842. if (typeof end !== 'number' || end % 1 !== 0)
  3843. throw TypeError("Illegal end: Not an integer");
  3844. end >>>= 0;
  3845. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  3846. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  3847. }
  3848. var bb = this.clone();
  3849. bb.offset = begin;
  3850. bb.limit = end;
  3851. return bb;
  3852. };
  3853. /**
  3854. * Returns a copy of the backing buffer that contains this ByteBuffer's contents. Contents are the bytes between
  3855. * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
  3856. * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory if
  3857. * possible. Defaults to `false`
  3858. * @returns {!ArrayBuffer} Contents as an ArrayBuffer
  3859. * @expose
  3860. */
  3861. ByteBufferPrototype.toBuffer = function(forceCopy) {
  3862. var offset = this.offset,
  3863. limit = this.limit;
  3864. if (!this.noAssert) {
  3865. if (typeof offset !== 'number' || offset % 1 !== 0)
  3866. throw TypeError("Illegal offset: Not an integer");
  3867. offset >>>= 0;
  3868. if (typeof limit !== 'number' || limit % 1 !== 0)
  3869. throw TypeError("Illegal limit: Not an integer");
  3870. limit >>>= 0;
  3871. if (offset < 0 || offset > limit || limit > this.buffer.byteLength)
  3872. throw RangeError("Illegal range: 0 <= "+offset+" <= "+limit+" <= "+this.buffer.byteLength);
  3873. }
  3874. // NOTE: It's not possible to have another ArrayBuffer reference the same memory as the backing buffer. This is
  3875. // possible with Uint8Array#subarray only, but we have to return an ArrayBuffer by contract. So:
  3876. if (!forceCopy && offset === 0 && limit === this.buffer.byteLength)
  3877. return this.buffer;
  3878. if (offset === limit)
  3879. return EMPTY_BUFFER;
  3880. var buffer = new ArrayBuffer(limit - offset);
  3881. new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(offset, limit), 0);
  3882. return buffer;
  3883. };
  3884. /**
  3885. * Returns a raw buffer compacted to contain this ByteBuffer's contents. Contents are the bytes between
  3886. * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. This is an alias of {@link ByteBuffer#toBuffer}.
  3887. * @function
  3888. * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory.
  3889. * Defaults to `false`
  3890. * @returns {!ArrayBuffer} Contents as an ArrayBuffer
  3891. * @expose
  3892. */
  3893. ByteBufferPrototype.toArrayBuffer = ByteBufferPrototype.toBuffer;
  3894. /**
  3895. * Converts the ByteBuffer's contents to a string.
  3896. * @param {string=} encoding Output encoding. Returns an informative string representation if omitted but also allows
  3897. * direct conversion to "utf8", "hex", "base64" and "binary" encoding. "debug" returns a hex representation with
  3898. * highlighted offsets.
  3899. * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}
  3900. * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
  3901. * @returns {string} String representation
  3902. * @throws {Error} If `encoding` is invalid
  3903. * @expose
  3904. */
  3905. ByteBufferPrototype.toString = function(encoding, begin, end) {
  3906. if (typeof encoding === 'undefined')
  3907. return "ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")";
  3908. if (typeof encoding === 'number')
  3909. encoding = "utf8",
  3910. begin = encoding,
  3911. end = begin;
  3912. switch (encoding) {
  3913. case "utf8":
  3914. return this.toUTF8(begin, end);
  3915. case "base64":
  3916. return this.toBase64(begin, end);
  3917. case "hex":
  3918. return this.toHex(begin, end);
  3919. case "binary":
  3920. return this.toBinary(begin, end);
  3921. case "debug":
  3922. return this.toDebug();
  3923. case "columns":
  3924. return this.toColumns();
  3925. default:
  3926. throw Error("Unsupported encoding: "+encoding);
  3927. }
  3928. };
  3929. // lxiv-embeddable
  3930. /**
  3931. * lxiv-embeddable (c) 2014 Daniel Wirtz <dcode@dcode.io>
  3932. * Released under the Apache License, Version 2.0
  3933. * see: https://github.com/dcodeIO/lxiv for details
  3934. */
  3935. var lxiv = function() {
  3936. /**
  3937. * lxiv namespace.
  3938. * @type {!Object.<string,*>}
  3939. * @exports lxiv
  3940. */
  3941. var lxiv = {};
  3942. /**
  3943. * Character codes for output.
  3944. * @type {!Array.<number>}
  3945. * @inner
  3946. */
  3947. var aout = [
  3948. 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
  3949. 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102,
  3950. 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
  3951. 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47
  3952. ];
  3953. /**
  3954. * Character codes for input.
  3955. * @type {!Array.<number>}
  3956. * @inner
  3957. */
  3958. var ain = [];
  3959. for (var i=0, k=aout.length; i<k; ++i)
  3960. ain[aout[i]] = i;
  3961. /**
  3962. * Encodes bytes to base64 char codes.
  3963. * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if
  3964. * there are no more bytes left.
  3965. * @param {!function(number)} dst Characters destination as a function successively called with each encoded char
  3966. * code.
  3967. */
  3968. lxiv.encode = function(src, dst) {
  3969. var b, t;
  3970. while ((b = src()) !== null) {
  3971. dst(aout[(b>>2)&0x3f]);
  3972. t = (b&0x3)<<4;
  3973. if ((b = src()) !== null) {
  3974. t |= (b>>4)&0xf;
  3975. dst(aout[(t|((b>>4)&0xf))&0x3f]);
  3976. t = (b&0xf)<<2;
  3977. if ((b = src()) !== null)
  3978. dst(aout[(t|((b>>6)&0x3))&0x3f]),
  3979. dst(aout[b&0x3f]);
  3980. else
  3981. dst(aout[t&0x3f]),
  3982. dst(61);
  3983. } else
  3984. dst(aout[t&0x3f]),
  3985. dst(61),
  3986. dst(61);
  3987. }
  3988. };
  3989. /**
  3990. * Decodes base64 char codes to bytes.
  3991. * @param {!function():number|null} src Characters source as a function returning the next char code respectively
  3992. * `null` if there are no more characters left.
  3993. * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
  3994. * @throws {Error} If a character code is invalid
  3995. */
  3996. lxiv.decode = function(src, dst) {
  3997. var c, t1, t2;
  3998. function fail(c) {
  3999. throw Error("Illegal character code: "+c);
  4000. }
  4001. while ((c = src()) !== null) {
  4002. t1 = ain[c];
  4003. if (typeof t1 === 'undefined') fail(c);
  4004. if ((c = src()) !== null) {
  4005. t2 = ain[c];
  4006. if (typeof t2 === 'undefined') fail(c);
  4007. dst((t1<<2)>>>0|(t2&0x30)>>4);
  4008. if ((c = src()) !== null) {
  4009. t1 = ain[c];
  4010. if (typeof t1 === 'undefined')
  4011. if (c === 61) break; else fail(c);
  4012. dst(((t2&0xf)<<4)>>>0|(t1&0x3c)>>2);
  4013. if ((c = src()) !== null) {
  4014. t2 = ain[c];
  4015. if (typeof t2 === 'undefined')
  4016. if (c === 61) break; else fail(c);
  4017. dst(((t1&0x3)<<6)>>>0|t2);
  4018. }
  4019. }
  4020. }
  4021. }
  4022. };
  4023. /**
  4024. * Tests if a string is valid base64.
  4025. * @param {string} str String to test
  4026. * @returns {boolean} `true` if valid, otherwise `false`
  4027. */
  4028. lxiv.test = function(str) {
  4029. return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(str);
  4030. };
  4031. return lxiv;
  4032. }();
  4033. // encodings/base64
  4034. /**
  4035. * Encodes this ByteBuffer's contents to a base64 encoded string.
  4036. * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}.
  4037. * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}.
  4038. * @returns {string} Base64 encoded string
  4039. * @throws {RangeError} If `begin` or `end` is out of bounds
  4040. * @expose
  4041. */
  4042. ByteBufferPrototype.toBase64 = function(begin, end) {
  4043. if (typeof begin === 'undefined')
  4044. begin = this.offset;
  4045. if (typeof end === 'undefined')
  4046. end = this.limit;
  4047. begin = begin | 0; end = end | 0;
  4048. if (begin < 0 || end > this.capacity || begin > end)
  4049. throw RangeError("begin, end");
  4050. var sd; lxiv.encode(function() {
  4051. return begin < end ? this.view[begin++] : null;
  4052. }.bind(this), sd = stringDestination());
  4053. return sd();
  4054. };
  4055. /**
  4056. * Decodes a base64 encoded string to a ByteBuffer.
  4057. * @param {string} str String to decode
  4058. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  4059. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  4060. * @returns {!ByteBuffer} ByteBuffer
  4061. * @expose
  4062. */
  4063. ByteBuffer.fromBase64 = function(str, littleEndian) {
  4064. if (typeof str !== 'string')
  4065. throw TypeError("str");
  4066. var bb = new ByteBuffer(str.length/4*3, littleEndian),
  4067. i = 0;
  4068. lxiv.decode(stringSource(str), function(b) {
  4069. bb.view[i++] = b;
  4070. });
  4071. bb.limit = i;
  4072. return bb;
  4073. };
  4074. /**
  4075. * Encodes a binary string to base64 like `window.btoa` does.
  4076. * @param {string} str Binary string
  4077. * @returns {string} Base64 encoded string
  4078. * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.btoa
  4079. * @expose
  4080. */
  4081. ByteBuffer.btoa = function(str) {
  4082. return ByteBuffer.fromBinary(str).toBase64();
  4083. };
  4084. /**
  4085. * Decodes a base64 encoded string to binary like `window.atob` does.
  4086. * @param {string} b64 Base64 encoded string
  4087. * @returns {string} Binary string
  4088. * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.atob
  4089. * @expose
  4090. */
  4091. ByteBuffer.atob = function(b64) {
  4092. return ByteBuffer.fromBase64(b64).toBinary();
  4093. };
  4094. // encodings/binary
  4095. /**
  4096. * Encodes this ByteBuffer to a binary encoded string, that is using only characters 0x00-0xFF as bytes.
  4097. * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}.
  4098. * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}.
  4099. * @returns {string} Binary encoded string
  4100. * @throws {RangeError} If `offset > limit`
  4101. * @expose
  4102. */
  4103. ByteBufferPrototype.toBinary = function(begin, end) {
  4104. if (typeof begin === 'undefined')
  4105. begin = this.offset;
  4106. if (typeof end === 'undefined')
  4107. end = this.limit;
  4108. begin |= 0; end |= 0;
  4109. if (begin < 0 || end > this.capacity() || begin > end)
  4110. throw RangeError("begin, end");
  4111. if (begin === end)
  4112. return "";
  4113. var chars = [],
  4114. parts = [];
  4115. while (begin < end) {
  4116. chars.push(this.view[begin++]);
  4117. if (chars.length >= 1024)
  4118. parts.push(String.fromCharCode.apply(String, chars)),
  4119. chars = [];
  4120. }
  4121. return parts.join('') + String.fromCharCode.apply(String, chars);
  4122. };
  4123. /**
  4124. * Decodes a binary encoded string, that is using only characters 0x00-0xFF as bytes, to a ByteBuffer.
  4125. * @param {string} str String to decode
  4126. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  4127. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  4128. * @returns {!ByteBuffer} ByteBuffer
  4129. * @expose
  4130. */
  4131. ByteBuffer.fromBinary = function(str, littleEndian) {
  4132. if (typeof str !== 'string')
  4133. throw TypeError("str");
  4134. var i = 0,
  4135. k = str.length,
  4136. charCode,
  4137. bb = new ByteBuffer(k, littleEndian);
  4138. while (i<k) {
  4139. charCode = str.charCodeAt(i);
  4140. if (charCode > 0xff)
  4141. throw RangeError("illegal char code: "+charCode);
  4142. bb.view[i++] = charCode;
  4143. }
  4144. bb.limit = k;
  4145. return bb;
  4146. };
  4147. // encodings/debug
  4148. /**
  4149. * Encodes this ByteBuffer to a hex encoded string with marked offsets. Offset symbols are:
  4150. * * `<` : offset,
  4151. * * `'` : markedOffset,
  4152. * * `>` : limit,
  4153. * * `|` : offset and limit,
  4154. * * `[` : offset and markedOffset,
  4155. * * `]` : markedOffset and limit,
  4156. * * `!` : offset, markedOffset and limit
  4157. * @param {boolean=} columns If `true` returns two columns hex + ascii, defaults to `false`
  4158. * @returns {string|!Array.<string>} Debug string or array of lines if `asArray = true`
  4159. * @expose
  4160. * @example `>00'01 02<03` contains four bytes with `limit=0, markedOffset=1, offset=3`
  4161. * @example `00[01 02 03>` contains four bytes with `offset=markedOffset=1, limit=4`
  4162. * @example `00|01 02 03` contains four bytes with `offset=limit=1, markedOffset=-1`
  4163. * @example `|` contains zero bytes with `offset=limit=0, markedOffset=-1`
  4164. */
  4165. ByteBufferPrototype.toDebug = function(columns) {
  4166. var i = -1,
  4167. k = this.buffer.byteLength,
  4168. b,
  4169. hex = "",
  4170. asc = "",
  4171. out = "";
  4172. while (i<k) {
  4173. if (i !== -1) {
  4174. b = this.view[i];
  4175. if (b < 0x10) hex += "0"+b.toString(16).toUpperCase();
  4176. else hex += b.toString(16).toUpperCase();
  4177. if (columns)
  4178. asc += b > 32 && b < 127 ? String.fromCharCode(b) : '.';
  4179. }
  4180. ++i;
  4181. if (columns) {
  4182. if (i > 0 && i % 16 === 0 && i !== k) {
  4183. while (hex.length < 3*16+3) hex += " ";
  4184. out += hex+asc+"\n";
  4185. hex = asc = "";
  4186. }
  4187. }
  4188. if (i === this.offset && i === this.limit)
  4189. hex += i === this.markedOffset ? "!" : "|";
  4190. else if (i === this.offset)
  4191. hex += i === this.markedOffset ? "[" : "<";
  4192. else if (i === this.limit)
  4193. hex += i === this.markedOffset ? "]" : ">";
  4194. else
  4195. hex += i === this.markedOffset ? "'" : (columns || (i !== 0 && i !== k) ? " " : "");
  4196. }
  4197. if (columns && hex !== " ") {
  4198. while (hex.length < 3*16+3)
  4199. hex += " ";
  4200. out += hex + asc + "\n";
  4201. }
  4202. return columns ? out : hex;
  4203. };
  4204. /**
  4205. * Decodes a hex encoded string with marked offsets to a ByteBuffer.
  4206. * @param {string} str Debug string to decode (not be generated with `columns = true`)
  4207. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  4208. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  4209. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  4210. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  4211. * @returns {!ByteBuffer} ByteBuffer
  4212. * @expose
  4213. * @see ByteBuffer#toDebug
  4214. */
  4215. ByteBuffer.fromDebug = function(str, littleEndian, noAssert) {
  4216. var k = str.length,
  4217. bb = new ByteBuffer(((k+1)/3)|0, littleEndian, noAssert);
  4218. var i = 0, j = 0, ch, b,
  4219. rs = false, // Require symbol next
  4220. ho = false, hm = false, hl = false, // Already has offset (ho), markedOffset (hm), limit (hl)?
  4221. fail = false;
  4222. while (i<k) {
  4223. switch (ch = str.charAt(i++)) {
  4224. case '!':
  4225. if (!noAssert) {
  4226. if (ho || hm || hl) {
  4227. fail = true;
  4228. break;
  4229. }
  4230. ho = hm = hl = true;
  4231. }
  4232. bb.offset = bb.markedOffset = bb.limit = j;
  4233. rs = false;
  4234. break;
  4235. case '|':
  4236. if (!noAssert) {
  4237. if (ho || hl) {
  4238. fail = true;
  4239. break;
  4240. }
  4241. ho = hl = true;
  4242. }
  4243. bb.offset = bb.limit = j;
  4244. rs = false;
  4245. break;
  4246. case '[':
  4247. if (!noAssert) {
  4248. if (ho || hm) {
  4249. fail = true;
  4250. break;
  4251. }
  4252. ho = hm = true;
  4253. }
  4254. bb.offset = bb.markedOffset = j;
  4255. rs = false;
  4256. break;
  4257. case '<':
  4258. if (!noAssert) {
  4259. if (ho) {
  4260. fail = true;
  4261. break;
  4262. }
  4263. ho = true;
  4264. }
  4265. bb.offset = j;
  4266. rs = false;
  4267. break;
  4268. case ']':
  4269. if (!noAssert) {
  4270. if (hl || hm) {
  4271. fail = true;
  4272. break;
  4273. }
  4274. hl = hm = true;
  4275. }
  4276. bb.limit = bb.markedOffset = j;
  4277. rs = false;
  4278. break;
  4279. case '>':
  4280. if (!noAssert) {
  4281. if (hl) {
  4282. fail = true;
  4283. break;
  4284. }
  4285. hl = true;
  4286. }
  4287. bb.limit = j;
  4288. rs = false;
  4289. break;
  4290. case "'":
  4291. if (!noAssert) {
  4292. if (hm) {
  4293. fail = true;
  4294. break;
  4295. }
  4296. hm = true;
  4297. }
  4298. bb.markedOffset = j;
  4299. rs = false;
  4300. break;
  4301. case ' ':
  4302. rs = false;
  4303. break;
  4304. default:
  4305. if (!noAssert) {
  4306. if (rs) {
  4307. fail = true;
  4308. break;
  4309. }
  4310. }
  4311. b = parseInt(ch+str.charAt(i++), 16);
  4312. if (!noAssert) {
  4313. if (isNaN(b) || b < 0 || b > 255)
  4314. throw TypeError("Illegal str: Not a debug encoded string");
  4315. }
  4316. bb.view[j++] = b;
  4317. rs = true;
  4318. }
  4319. if (fail)
  4320. throw TypeError("Illegal str: Invalid symbol at "+i);
  4321. }
  4322. if (!noAssert) {
  4323. if (!ho || !hl)
  4324. throw TypeError("Illegal str: Missing offset or limit");
  4325. if (j<bb.buffer.byteLength)
  4326. throw TypeError("Illegal str: Not a debug encoded string (is it hex?) "+j+" < "+k);
  4327. }
  4328. return bb;
  4329. };
  4330. // encodings/hex
  4331. /**
  4332. * Encodes this ByteBuffer's contents to a hex encoded string.
  4333. * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}.
  4334. * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}.
  4335. * @returns {string} Hex encoded string
  4336. * @expose
  4337. */
  4338. ByteBufferPrototype.toHex = function(begin, end) {
  4339. begin = typeof begin === 'undefined' ? this.offset : begin;
  4340. end = typeof end === 'undefined' ? this.limit : end;
  4341. if (!this.noAssert) {
  4342. if (typeof begin !== 'number' || begin % 1 !== 0)
  4343. throw TypeError("Illegal begin: Not an integer");
  4344. begin >>>= 0;
  4345. if (typeof end !== 'number' || end % 1 !== 0)
  4346. throw TypeError("Illegal end: Not an integer");
  4347. end >>>= 0;
  4348. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  4349. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  4350. }
  4351. var out = new Array(end - begin),
  4352. b;
  4353. while (begin < end) {
  4354. b = this.view[begin++];
  4355. if (b < 0x10)
  4356. out.push("0", b.toString(16));
  4357. else out.push(b.toString(16));
  4358. }
  4359. return out.join('');
  4360. };
  4361. /**
  4362. * Decodes a hex encoded string to a ByteBuffer.
  4363. * @param {string} str String to decode
  4364. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  4365. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  4366. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  4367. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  4368. * @returns {!ByteBuffer} ByteBuffer
  4369. * @expose
  4370. */
  4371. ByteBuffer.fromHex = function(str, littleEndian, noAssert) {
  4372. if (!noAssert) {
  4373. if (typeof str !== 'string')
  4374. throw TypeError("Illegal str: Not a string");
  4375. if (str.length % 2 !== 0)
  4376. throw TypeError("Illegal str: Length not a multiple of 2");
  4377. }
  4378. var k = str.length,
  4379. bb = new ByteBuffer((k / 2) | 0, littleEndian),
  4380. b;
  4381. for (var i=0, j=0; i<k; i+=2) {
  4382. b = parseInt(str.substring(i, i+2), 16);
  4383. if (!noAssert)
  4384. if (!isFinite(b) || b < 0 || b > 255)
  4385. throw TypeError("Illegal str: Contains non-hex characters");
  4386. bb.view[j++] = b;
  4387. }
  4388. bb.limit = j;
  4389. return bb;
  4390. };
  4391. // utfx-embeddable
  4392. /**
  4393. * utfx-embeddable (c) 2014 Daniel Wirtz <dcode@dcode.io>
  4394. * Released under the Apache License, Version 2.0
  4395. * see: https://github.com/dcodeIO/utfx for details
  4396. */
  4397. var utfx = function() {
  4398. /**
  4399. * utfx namespace.
  4400. * @inner
  4401. * @type {!Object.<string,*>}
  4402. */
  4403. var utfx = {};
  4404. /**
  4405. * Maximum valid code point.
  4406. * @type {number}
  4407. * @const
  4408. */
  4409. utfx.MAX_CODEPOINT = 0x10FFFF;
  4410. /**
  4411. * Encodes UTF8 code points to UTF8 bytes.
  4412. * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
  4413. * respectively `null` if there are no more code points left or a single numeric code point.
  4414. * @param {!function(number)} dst Bytes destination as a function successively called with the next byte
  4415. */
  4416. utfx.encodeUTF8 = function(src, dst) {
  4417. var cp = null;
  4418. if (typeof src === 'number')
  4419. cp = src,
  4420. src = function() { return null; };
  4421. while (cp !== null || (cp = src()) !== null) {
  4422. if (cp < 0x80)
  4423. dst(cp&0x7F);
  4424. else if (cp < 0x800)
  4425. dst(((cp>>6)&0x1F)|0xC0),
  4426. dst((cp&0x3F)|0x80);
  4427. else if (cp < 0x10000)
  4428. dst(((cp>>12)&0x0F)|0xE0),
  4429. dst(((cp>>6)&0x3F)|0x80),
  4430. dst((cp&0x3F)|0x80);
  4431. else
  4432. dst(((cp>>18)&0x07)|0xF0),
  4433. dst(((cp>>12)&0x3F)|0x80),
  4434. dst(((cp>>6)&0x3F)|0x80),
  4435. dst((cp&0x3F)|0x80);
  4436. cp = null;
  4437. }
  4438. };
  4439. /**
  4440. * Decodes UTF8 bytes to UTF8 code points.
  4441. * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
  4442. * are no more bytes left.
  4443. * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point.
  4444. * @throws {RangeError} If a starting byte is invalid in UTF8
  4445. * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the
  4446. * remaining bytes.
  4447. */
  4448. utfx.decodeUTF8 = function(src, dst) {
  4449. var a, b, c, d, fail = function(b) {
  4450. b = b.slice(0, b.indexOf(null));
  4451. var err = Error(b.toString());
  4452. err.name = "TruncatedError";
  4453. err['bytes'] = b;
  4454. throw err;
  4455. };
  4456. while ((a = src()) !== null) {
  4457. if ((a&0x80) === 0)
  4458. dst(a);
  4459. else if ((a&0xE0) === 0xC0)
  4460. ((b = src()) === null) && fail([a, b]),
  4461. dst(((a&0x1F)<<6) | (b&0x3F));
  4462. else if ((a&0xF0) === 0xE0)
  4463. ((b=src()) === null || (c=src()) === null) && fail([a, b, c]),
  4464. dst(((a&0x0F)<<12) | ((b&0x3F)<<6) | (c&0x3F));
  4465. else if ((a&0xF8) === 0xF0)
  4466. ((b=src()) === null || (c=src()) === null || (d=src()) === null) && fail([a, b, c ,d]),
  4467. dst(((a&0x07)<<18) | ((b&0x3F)<<12) | ((c&0x3F)<<6) | (d&0x3F));
  4468. else throw RangeError("Illegal starting byte: "+a);
  4469. }
  4470. };
  4471. /**
  4472. * Converts UTF16 characters to UTF8 code points.
  4473. * @param {!function():number|null} src Characters source as a function returning the next char code respectively
  4474. * `null` if there are no more characters left.
  4475. * @param {!function(number)} dst Code points destination as a function successively called with each converted code
  4476. * point.
  4477. */
  4478. utfx.UTF16toUTF8 = function(src, dst) {
  4479. var c1, c2 = null;
  4480. while (true) {
  4481. if ((c1 = c2 !== null ? c2 : src()) === null)
  4482. break;
  4483. if (c1 >= 0xD800 && c1 <= 0xDFFF) {
  4484. if ((c2 = src()) !== null) {
  4485. if (c2 >= 0xDC00 && c2 <= 0xDFFF) {
  4486. dst((c1-0xD800)*0x400+c2-0xDC00+0x10000);
  4487. c2 = null; continue;
  4488. }
  4489. }
  4490. }
  4491. dst(c1);
  4492. }
  4493. if (c2 !== null) dst(c2);
  4494. };
  4495. /**
  4496. * Converts UTF8 code points to UTF16 characters.
  4497. * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
  4498. * respectively `null` if there are no more code points left or a single numeric code point.
  4499. * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
  4500. * @throws {RangeError} If a code point is out of range
  4501. */
  4502. utfx.UTF8toUTF16 = function(src, dst) {
  4503. var cp = null;
  4504. if (typeof src === 'number')
  4505. cp = src, src = function() { return null; };
  4506. while (cp !== null || (cp = src()) !== null) {
  4507. if (cp <= 0xFFFF)
  4508. dst(cp);
  4509. else
  4510. cp -= 0x10000,
  4511. dst((cp>>10)+0xD800),
  4512. dst((cp%0x400)+0xDC00);
  4513. cp = null;
  4514. }
  4515. };
  4516. /**
  4517. * Converts and encodes UTF16 characters to UTF8 bytes.
  4518. * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null`
  4519. * if there are no more characters left.
  4520. * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
  4521. */
  4522. utfx.encodeUTF16toUTF8 = function(src, dst) {
  4523. utfx.UTF16toUTF8(src, function(cp) {
  4524. utfx.encodeUTF8(cp, dst);
  4525. });
  4526. };
  4527. /**
  4528. * Decodes and converts UTF8 bytes to UTF16 characters.
  4529. * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
  4530. * are no more bytes left.
  4531. * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
  4532. * @throws {RangeError} If a starting byte is invalid in UTF8
  4533. * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes.
  4534. */
  4535. utfx.decodeUTF8toUTF16 = function(src, dst) {
  4536. utfx.decodeUTF8(src, function(cp) {
  4537. utfx.UTF8toUTF16(cp, dst);
  4538. });
  4539. };
  4540. /**
  4541. * Calculates the byte length of an UTF8 code point.
  4542. * @param {number} cp UTF8 code point
  4543. * @returns {number} Byte length
  4544. */
  4545. utfx.calculateCodePoint = function(cp) {
  4546. return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
  4547. };
  4548. /**
  4549. * Calculates the number of UTF8 bytes required to store UTF8 code points.
  4550. * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively
  4551. * `null` if there are no more code points left.
  4552. * @returns {number} The number of UTF8 bytes required
  4553. */
  4554. utfx.calculateUTF8 = function(src) {
  4555. var cp, l=0;
  4556. while ((cp = src()) !== null)
  4557. l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
  4558. return l;
  4559. };
  4560. /**
  4561. * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes.
  4562. * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively
  4563. * `null` if there are no more characters left.
  4564. * @returns {!Array.<number>} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1.
  4565. */
  4566. utfx.calculateUTF16asUTF8 = function(src) {
  4567. var n=0, l=0;
  4568. utfx.UTF16toUTF8(src, function(cp) {
  4569. ++n; l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
  4570. });
  4571. return [n,l];
  4572. };
  4573. return utfx;
  4574. }();
  4575. // encodings/utf8
  4576. /**
  4577. * Encodes this ByteBuffer's contents between {@link ByteBuffer#offset} and {@link ByteBuffer#limit} to an UTF8 encoded
  4578. * string.
  4579. * @returns {string} Hex encoded string
  4580. * @throws {RangeError} If `offset > limit`
  4581. * @expose
  4582. */
  4583. ByteBufferPrototype.toUTF8 = function(begin, end) {
  4584. if (typeof begin === 'undefined') begin = this.offset;
  4585. if (typeof end === 'undefined') end = this.limit;
  4586. if (!this.noAssert) {
  4587. if (typeof begin !== 'number' || begin % 1 !== 0)
  4588. throw TypeError("Illegal begin: Not an integer");
  4589. begin >>>= 0;
  4590. if (typeof end !== 'number' || end % 1 !== 0)
  4591. throw TypeError("Illegal end: Not an integer");
  4592. end >>>= 0;
  4593. if (begin < 0 || begin > end || end > this.buffer.byteLength)
  4594. throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
  4595. }
  4596. var sd; try {
  4597. utfx.decodeUTF8toUTF16(function() {
  4598. return begin < end ? this.view[begin++] : null;
  4599. }.bind(this), sd = stringDestination());
  4600. } catch (e) {
  4601. if (begin !== end)
  4602. throw RangeError("Illegal range: Truncated data, "+begin+" != "+end);
  4603. }
  4604. return sd();
  4605. };
  4606. /**
  4607. * Decodes an UTF8 encoded string to a ByteBuffer.
  4608. * @param {string} str String to decode
  4609. * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
  4610. * {@link ByteBuffer.DEFAULT_ENDIAN}.
  4611. * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
  4612. * {@link ByteBuffer.DEFAULT_NOASSERT}.
  4613. * @returns {!ByteBuffer} ByteBuffer
  4614. * @expose
  4615. */
  4616. ByteBuffer.fromUTF8 = function(str, littleEndian, noAssert) {
  4617. if (!noAssert)
  4618. if (typeof str !== 'string')
  4619. throw TypeError("Illegal str: Not a string");
  4620. var bb = new ByteBuffer(utfx.calculateUTF16asUTF8(stringSource(str), true)[1], littleEndian, noAssert),
  4621. i = 0;
  4622. utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
  4623. bb.view[i++] = b;
  4624. });
  4625. bb.limit = i;
  4626. return bb;
  4627. };
  4628. return ByteBuffer;
  4629. });
  4630. });
  4631. var _nodeResolve_empty = {};
  4632. var _nodeResolve_empty$1 = /*#__PURE__*/Object.freeze({
  4633. __proto__: null,
  4634. 'default': _nodeResolve_empty
  4635. });
  4636. var require$$2 = getCjsExportFromNamespace(_nodeResolve_empty$1);
  4637. var protobufLight = createCommonjsModule(function (module) {
  4638. /*
  4639. Copyright 2013 Daniel Wirtz <dcode@dcode.io>
  4640. Licensed under the Apache License, Version 2.0 (the "License");
  4641. you may not use this file except in compliance with the License.
  4642. You may obtain a copy of the License at
  4643. http://www.apache.org/licenses/LICENSE-2.0
  4644. Unless required by applicable law or agreed to in writing, software
  4645. distributed under the License is distributed on an "AS IS" BASIS,
  4646. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  4647. See the License for the specific language governing permissions and
  4648. limitations under the License.
  4649. */
  4650. /**
  4651. * @license protobuf.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
  4652. * Released under the Apache License, Version 2.0
  4653. * see: https://github.com/dcodeIO/protobuf.js for details
  4654. */
  4655. (function(global, factory) {
  4656. /* AMD */ if (typeof commonjsRequire === "function" && 'object' === "object" && module && module["exports"])
  4657. module["exports"] = factory(bytebuffer, true);
  4658. /* Global */ else
  4659. (global["dcodeIO"] = global["dcodeIO"] || {})["ProtoBuf"] = factory(global["dcodeIO"]["ByteBuffer"]);
  4660. })(commonjsGlobal, function(ByteBuffer, isCommonJS) {
  4661. /**
  4662. * The ProtoBuf namespace.
  4663. * @exports ProtoBuf
  4664. * @namespace
  4665. * @expose
  4666. */
  4667. var ProtoBuf = {};
  4668. /**
  4669. * @type {!function(new: ByteBuffer, ...[*])}
  4670. * @expose
  4671. */
  4672. ProtoBuf.ByteBuffer = ByteBuffer;
  4673. /**
  4674. * @type {?function(new: Long, ...[*])}
  4675. * @expose
  4676. */
  4677. ProtoBuf.Long = ByteBuffer.Long || null;
  4678. /**
  4679. * ProtoBuf.js version.
  4680. * @type {string}
  4681. * @const
  4682. * @expose
  4683. */
  4684. ProtoBuf.VERSION = "5.0.3";
  4685. /**
  4686. * Wire types.
  4687. * @type {Object.<string,number>}
  4688. * @const
  4689. * @expose
  4690. */
  4691. ProtoBuf.WIRE_TYPES = {};
  4692. /**
  4693. * Varint wire type.
  4694. * @type {number}
  4695. * @expose
  4696. */
  4697. ProtoBuf.WIRE_TYPES.VARINT = 0;
  4698. /**
  4699. * Fixed 64 bits wire type.
  4700. * @type {number}
  4701. * @const
  4702. * @expose
  4703. */
  4704. ProtoBuf.WIRE_TYPES.BITS64 = 1;
  4705. /**
  4706. * Length delimited wire type.
  4707. * @type {number}
  4708. * @const
  4709. * @expose
  4710. */
  4711. ProtoBuf.WIRE_TYPES.LDELIM = 2;
  4712. /**
  4713. * Start group wire type.
  4714. * @type {number}
  4715. * @const
  4716. * @expose
  4717. */
  4718. ProtoBuf.WIRE_TYPES.STARTGROUP = 3;
  4719. /**
  4720. * End group wire type.
  4721. * @type {number}
  4722. * @const
  4723. * @expose
  4724. */
  4725. ProtoBuf.WIRE_TYPES.ENDGROUP = 4;
  4726. /**
  4727. * Fixed 32 bits wire type.
  4728. * @type {number}
  4729. * @const
  4730. * @expose
  4731. */
  4732. ProtoBuf.WIRE_TYPES.BITS32 = 5;
  4733. /**
  4734. * Packable wire types.
  4735. * @type {!Array.<number>}
  4736. * @const
  4737. * @expose
  4738. */
  4739. ProtoBuf.PACKABLE_WIRE_TYPES = [
  4740. ProtoBuf.WIRE_TYPES.VARINT,
  4741. ProtoBuf.WIRE_TYPES.BITS64,
  4742. ProtoBuf.WIRE_TYPES.BITS32
  4743. ];
  4744. /**
  4745. * Types.
  4746. * @dict
  4747. * @type {!Object.<string,{name: string, wireType: number, defaultValue: *}>}
  4748. * @const
  4749. * @expose
  4750. */
  4751. ProtoBuf.TYPES = {
  4752. // According to the protobuf spec.
  4753. "int32": {
  4754. name: "int32",
  4755. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  4756. defaultValue: 0
  4757. },
  4758. "uint32": {
  4759. name: "uint32",
  4760. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  4761. defaultValue: 0
  4762. },
  4763. "sint32": {
  4764. name: "sint32",
  4765. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  4766. defaultValue: 0
  4767. },
  4768. "int64": {
  4769. name: "int64",
  4770. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  4771. defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined
  4772. },
  4773. "uint64": {
  4774. name: "uint64",
  4775. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  4776. defaultValue: ProtoBuf.Long ? ProtoBuf.Long.UZERO : undefined
  4777. },
  4778. "sint64": {
  4779. name: "sint64",
  4780. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  4781. defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined
  4782. },
  4783. "bool": {
  4784. name: "bool",
  4785. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  4786. defaultValue: false
  4787. },
  4788. "double": {
  4789. name: "double",
  4790. wireType: ProtoBuf.WIRE_TYPES.BITS64,
  4791. defaultValue: 0
  4792. },
  4793. "string": {
  4794. name: "string",
  4795. wireType: ProtoBuf.WIRE_TYPES.LDELIM,
  4796. defaultValue: ""
  4797. },
  4798. "bytes": {
  4799. name: "bytes",
  4800. wireType: ProtoBuf.WIRE_TYPES.LDELIM,
  4801. defaultValue: null // overridden in the code, must be a unique instance
  4802. },
  4803. "fixed32": {
  4804. name: "fixed32",
  4805. wireType: ProtoBuf.WIRE_TYPES.BITS32,
  4806. defaultValue: 0
  4807. },
  4808. "sfixed32": {
  4809. name: "sfixed32",
  4810. wireType: ProtoBuf.WIRE_TYPES.BITS32,
  4811. defaultValue: 0
  4812. },
  4813. "fixed64": {
  4814. name: "fixed64",
  4815. wireType: ProtoBuf.WIRE_TYPES.BITS64,
  4816. defaultValue: ProtoBuf.Long ? ProtoBuf.Long.UZERO : undefined
  4817. },
  4818. "sfixed64": {
  4819. name: "sfixed64",
  4820. wireType: ProtoBuf.WIRE_TYPES.BITS64,
  4821. defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined
  4822. },
  4823. "float": {
  4824. name: "float",
  4825. wireType: ProtoBuf.WIRE_TYPES.BITS32,
  4826. defaultValue: 0
  4827. },
  4828. "enum": {
  4829. name: "enum",
  4830. wireType: ProtoBuf.WIRE_TYPES.VARINT,
  4831. defaultValue: 0
  4832. },
  4833. "message": {
  4834. name: "message",
  4835. wireType: ProtoBuf.WIRE_TYPES.LDELIM,
  4836. defaultValue: null
  4837. },
  4838. "group": {
  4839. name: "group",
  4840. wireType: ProtoBuf.WIRE_TYPES.STARTGROUP,
  4841. defaultValue: null
  4842. }
  4843. };
  4844. /**
  4845. * Valid map key types.
  4846. * @type {!Array.<!Object.<string,{name: string, wireType: number, defaultValue: *}>>}
  4847. * @const
  4848. * @expose
  4849. */
  4850. ProtoBuf.MAP_KEY_TYPES = [
  4851. ProtoBuf.TYPES["int32"],
  4852. ProtoBuf.TYPES["sint32"],
  4853. ProtoBuf.TYPES["sfixed32"],
  4854. ProtoBuf.TYPES["uint32"],
  4855. ProtoBuf.TYPES["fixed32"],
  4856. ProtoBuf.TYPES["int64"],
  4857. ProtoBuf.TYPES["sint64"],
  4858. ProtoBuf.TYPES["sfixed64"],
  4859. ProtoBuf.TYPES["uint64"],
  4860. ProtoBuf.TYPES["fixed64"],
  4861. ProtoBuf.TYPES["bool"],
  4862. ProtoBuf.TYPES["string"],
  4863. ProtoBuf.TYPES["bytes"]
  4864. ];
  4865. /**
  4866. * Minimum field id.
  4867. * @type {number}
  4868. * @const
  4869. * @expose
  4870. */
  4871. ProtoBuf.ID_MIN = 1;
  4872. /**
  4873. * Maximum field id.
  4874. * @type {number}
  4875. * @const
  4876. * @expose
  4877. */
  4878. ProtoBuf.ID_MAX = 0x1FFFFFFF;
  4879. /**
  4880. * If set to `true`, field names will be converted from underscore notation to camel case. Defaults to `false`.
  4881. * Must be set prior to parsing.
  4882. * @type {boolean}
  4883. * @expose
  4884. */
  4885. ProtoBuf.convertFieldsToCamelCase = false;
  4886. /**
  4887. * By default, messages are populated with (setX, set_x) accessors for each field. This can be disabled by
  4888. * setting this to `false` prior to building messages.
  4889. * @type {boolean}
  4890. * @expose
  4891. */
  4892. ProtoBuf.populateAccessors = true;
  4893. /**
  4894. * By default, messages are populated with default values if a field is not present on the wire. To disable
  4895. * this behavior, set this setting to `false`.
  4896. * @type {boolean}
  4897. * @expose
  4898. */
  4899. ProtoBuf.populateDefaults = true;
  4900. /**
  4901. * @alias ProtoBuf.Util
  4902. * @expose
  4903. */
  4904. ProtoBuf.Util = (function() {
  4905. /**
  4906. * ProtoBuf utilities.
  4907. * @exports ProtoBuf.Util
  4908. * @namespace
  4909. */
  4910. var Util = {};
  4911. /**
  4912. * Flag if running in node or not.
  4913. * @type {boolean}
  4914. * @const
  4915. * @expose
  4916. */
  4917. Util.IS_NODE = !!(
  4918. typeof process === 'object' && process+'' === '[object process]' && !process['browser']
  4919. );
  4920. /**
  4921. * Constructs a XMLHttpRequest object.
  4922. * @return {XMLHttpRequest}
  4923. * @throws {Error} If XMLHttpRequest is not supported
  4924. * @expose
  4925. */
  4926. Util.XHR = function() {
  4927. // No dependencies please, ref: http://www.quirksmode.org/js/xmlhttp.html
  4928. var XMLHttpFactories = [
  4929. function () {return new XMLHttpRequest()},
  4930. function () {return new ActiveXObject("Msxml2.XMLHTTP")},
  4931. function () {return new ActiveXObject("Msxml3.XMLHTTP")},
  4932. function () {return new ActiveXObject("Microsoft.XMLHTTP")}
  4933. ];
  4934. /** @type {?XMLHttpRequest} */
  4935. var xhr = null;
  4936. for (var i=0;i<XMLHttpFactories.length;i++) {
  4937. try { xhr = XMLHttpFactories[i](); }
  4938. catch (e) { continue; }
  4939. break;
  4940. }
  4941. if (!xhr)
  4942. throw Error("XMLHttpRequest is not supported");
  4943. return xhr;
  4944. };
  4945. /**
  4946. * Fetches a resource.
  4947. * @param {string} path Resource path
  4948. * @param {function(?string)=} callback Callback receiving the resource's contents. If omitted the resource will
  4949. * be fetched synchronously. If the request failed, contents will be null.
  4950. * @return {?string|undefined} Resource contents if callback is omitted (null if the request failed), else undefined.
  4951. * @expose
  4952. */
  4953. Util.fetch = function(path, callback) {
  4954. if (callback && typeof callback != 'function')
  4955. callback = null;
  4956. if (Util.IS_NODE) {
  4957. var fs = require$$2;
  4958. if (callback) {
  4959. fs.readFile(path, function(err, data) {
  4960. if (err)
  4961. callback(null);
  4962. else
  4963. callback(""+data);
  4964. });
  4965. } else
  4966. try {
  4967. return fs.readFileSync(path);
  4968. } catch (e) {
  4969. return null;
  4970. }
  4971. } else {
  4972. var xhr = Util.XHR();
  4973. xhr.open('GET', path, callback ? true : false);
  4974. // xhr.setRequestHeader('User-Agent', 'XMLHTTP/1.0');
  4975. xhr.setRequestHeader('Accept', 'text/plain');
  4976. if (typeof xhr.overrideMimeType === 'function') xhr.overrideMimeType('text/plain');
  4977. if (callback) {
  4978. xhr.onreadystatechange = function() {
  4979. if (xhr.readyState != 4) return;
  4980. if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
  4981. callback(xhr.responseText);
  4982. else
  4983. callback(null);
  4984. };
  4985. if (xhr.readyState == 4)
  4986. return;
  4987. xhr.send(null);
  4988. } else {
  4989. xhr.send(null);
  4990. if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
  4991. return xhr.responseText;
  4992. return null;
  4993. }
  4994. }
  4995. };
  4996. /**
  4997. * Converts a string to camel case.
  4998. * @param {string} str
  4999. * @returns {string}
  5000. * @expose
  5001. */
  5002. Util.toCamelCase = function(str) {
  5003. return str.replace(/_([a-zA-Z])/g, function ($0, $1) {
  5004. return $1.toUpperCase();
  5005. });
  5006. };
  5007. return Util;
  5008. })();
  5009. /**
  5010. * Language expressions.
  5011. * @type {!Object.<string,!RegExp>}
  5012. * @expose
  5013. */
  5014. ProtoBuf.Lang = {
  5015. // Characters always ending a statement
  5016. DELIM: /[\s\{\}=;:\[\],'"\(\)<>]/g,
  5017. // Field rules
  5018. RULE: /^(?:required|optional|repeated|map)$/,
  5019. // Field types
  5020. TYPE: /^(?:double|float|int32|uint32|sint32|int64|uint64|sint64|fixed32|sfixed32|fixed64|sfixed64|bool|string|bytes)$/,
  5021. // Names
  5022. NAME: /^[a-zA-Z_][a-zA-Z_0-9]*$/,
  5023. // Type definitions
  5024. TYPEDEF: /^[a-zA-Z][a-zA-Z_0-9]*$/,
  5025. // Type references
  5026. TYPEREF: /^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/,
  5027. // Fully qualified type references
  5028. FQTYPEREF: /^(?:\.[a-zA-Z_][a-zA-Z_0-9]*)+$/,
  5029. // All numbers
  5030. NUMBER: /^-?(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+|([0-9]*(\.[0-9]*)?([Ee][+-]?[0-9]+)?)|inf|nan)$/,
  5031. // Decimal numbers
  5032. NUMBER_DEC: /^(?:[1-9][0-9]*|0)$/,
  5033. // Hexadecimal numbers
  5034. NUMBER_HEX: /^0[xX][0-9a-fA-F]+$/,
  5035. // Octal numbers
  5036. NUMBER_OCT: /^0[0-7]+$/,
  5037. // Floating point numbers
  5038. NUMBER_FLT: /^([0-9]*(\.[0-9]*)?([Ee][+-]?[0-9]+)?|inf|nan)$/,
  5039. // Booleans
  5040. BOOL: /^(?:true|false)$/i,
  5041. // Id numbers
  5042. ID: /^(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+)$/,
  5043. // Negative id numbers (enum values)
  5044. NEGID: /^\-?(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+)$/,
  5045. // Whitespaces
  5046. WHITESPACE: /\s/,
  5047. // All strings
  5048. STRING: /(?:"([^"\\]*(?:\\.[^"\\]*)*)")|(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g,
  5049. // Double quoted strings
  5050. STRING_DQ: /(?:"([^"\\]*(?:\\.[^"\\]*)*)")/g,
  5051. // Single quoted strings
  5052. STRING_SQ: /(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g
  5053. };
  5054. /**
  5055. * @alias ProtoBuf.Reflect
  5056. * @expose
  5057. */
  5058. ProtoBuf.Reflect = (function(ProtoBuf) {
  5059. /**
  5060. * Reflection types.
  5061. * @exports ProtoBuf.Reflect
  5062. * @namespace
  5063. */
  5064. var Reflect = {};
  5065. /**
  5066. * Constructs a Reflect base class.
  5067. * @exports ProtoBuf.Reflect.T
  5068. * @constructor
  5069. * @abstract
  5070. * @param {!ProtoBuf.Builder} builder Builder reference
  5071. * @param {?ProtoBuf.Reflect.T} parent Parent object
  5072. * @param {string} name Object name
  5073. */
  5074. var T = function(builder, parent, name) {
  5075. /**
  5076. * Builder reference.
  5077. * @type {!ProtoBuf.Builder}
  5078. * @expose
  5079. */
  5080. this.builder = builder;
  5081. /**
  5082. * Parent object.
  5083. * @type {?ProtoBuf.Reflect.T}
  5084. * @expose
  5085. */
  5086. this.parent = parent;
  5087. /**
  5088. * Object name in namespace.
  5089. * @type {string}
  5090. * @expose
  5091. */
  5092. this.name = name;
  5093. /**
  5094. * Fully qualified class name
  5095. * @type {string}
  5096. * @expose
  5097. */
  5098. this.className;
  5099. };
  5100. /**
  5101. * @alias ProtoBuf.Reflect.T.prototype
  5102. * @inner
  5103. */
  5104. var TPrototype = T.prototype;
  5105. /**
  5106. * Returns the fully qualified name of this object.
  5107. * @returns {string} Fully qualified name as of ".PATH.TO.THIS"
  5108. * @expose
  5109. */
  5110. TPrototype.fqn = function() {
  5111. var name = this.name,
  5112. ptr = this;
  5113. do {
  5114. ptr = ptr.parent;
  5115. if (ptr == null)
  5116. break;
  5117. name = ptr.name+"."+name;
  5118. } while (true);
  5119. return name;
  5120. };
  5121. /**
  5122. * Returns a string representation of this Reflect object (its fully qualified name).
  5123. * @param {boolean=} includeClass Set to true to include the class name. Defaults to false.
  5124. * @return String representation
  5125. * @expose
  5126. */
  5127. TPrototype.toString = function(includeClass) {
  5128. return (includeClass ? this.className + " " : "") + this.fqn();
  5129. };
  5130. /**
  5131. * Builds this type.
  5132. * @throws {Error} If this type cannot be built directly
  5133. * @expose
  5134. */
  5135. TPrototype.build = function() {
  5136. throw Error(this.toString(true)+" cannot be built directly");
  5137. };
  5138. /**
  5139. * @alias ProtoBuf.Reflect.T
  5140. * @expose
  5141. */
  5142. Reflect.T = T;
  5143. /**
  5144. * Constructs a new Namespace.
  5145. * @exports ProtoBuf.Reflect.Namespace
  5146. * @param {!ProtoBuf.Builder} builder Builder reference
  5147. * @param {?ProtoBuf.Reflect.Namespace} parent Namespace parent
  5148. * @param {string} name Namespace name
  5149. * @param {Object.<string,*>=} options Namespace options
  5150. * @param {string?} syntax The syntax level of this definition (e.g., proto3)
  5151. * @constructor
  5152. * @extends ProtoBuf.Reflect.T
  5153. */
  5154. var Namespace = function(builder, parent, name, options, syntax) {
  5155. T.call(this, builder, parent, name);
  5156. /**
  5157. * @override
  5158. */
  5159. this.className = "Namespace";
  5160. /**
  5161. * Children inside the namespace.
  5162. * @type {!Array.<ProtoBuf.Reflect.T>}
  5163. */
  5164. this.children = [];
  5165. /**
  5166. * Options.
  5167. * @type {!Object.<string, *>}
  5168. */
  5169. this.options = options || {};
  5170. /**
  5171. * Syntax level (e.g., proto2 or proto3).
  5172. * @type {!string}
  5173. */
  5174. this.syntax = syntax || "proto2";
  5175. };
  5176. /**
  5177. * @alias ProtoBuf.Reflect.Namespace.prototype
  5178. * @inner
  5179. */
  5180. var NamespacePrototype = Namespace.prototype = Object.create(T.prototype);
  5181. /**
  5182. * Returns an array of the namespace's children.
  5183. * @param {ProtoBuf.Reflect.T=} type Filter type (returns instances of this type only). Defaults to null (all children).
  5184. * @return {Array.<ProtoBuf.Reflect.T>}
  5185. * @expose
  5186. */
  5187. NamespacePrototype.getChildren = function(type) {
  5188. type = type || null;
  5189. if (type == null)
  5190. return this.children.slice();
  5191. var children = [];
  5192. for (var i=0, k=this.children.length; i<k; ++i)
  5193. if (this.children[i] instanceof type)
  5194. children.push(this.children[i]);
  5195. return children;
  5196. };
  5197. /**
  5198. * Adds a child to the namespace.
  5199. * @param {ProtoBuf.Reflect.T} child Child
  5200. * @throws {Error} If the child cannot be added (duplicate)
  5201. * @expose
  5202. */
  5203. NamespacePrototype.addChild = function(child) {
  5204. var other;
  5205. if (other = this.getChild(child.name)) {
  5206. // Try to revert camelcase transformation on collision
  5207. if (other instanceof Message.Field && other.name !== other.originalName && this.getChild(other.originalName) === null)
  5208. other.name = other.originalName; // Revert previous first (effectively keeps both originals)
  5209. else if (child instanceof Message.Field && child.name !== child.originalName && this.getChild(child.originalName) === null)
  5210. child.name = child.originalName;
  5211. else
  5212. throw Error("Duplicate name in namespace "+this.toString(true)+": "+child.name);
  5213. }
  5214. this.children.push(child);
  5215. };
  5216. /**
  5217. * Gets a child by its name or id.
  5218. * @param {string|number} nameOrId Child name or id
  5219. * @return {?ProtoBuf.Reflect.T} The child or null if not found
  5220. * @expose
  5221. */
  5222. NamespacePrototype.getChild = function(nameOrId) {
  5223. var key = typeof nameOrId === 'number' ? 'id' : 'name';
  5224. for (var i=0, k=this.children.length; i<k; ++i)
  5225. if (this.children[i][key] === nameOrId)
  5226. return this.children[i];
  5227. return null;
  5228. };
  5229. /**
  5230. * Resolves a reflect object inside of this namespace.
  5231. * @param {string|!Array.<string>} qn Qualified name to resolve
  5232. * @param {boolean=} excludeNonNamespace Excludes non-namespace types, defaults to `false`
  5233. * @return {?ProtoBuf.Reflect.Namespace} The resolved type or null if not found
  5234. * @expose
  5235. */
  5236. NamespacePrototype.resolve = function(qn, excludeNonNamespace) {
  5237. var part = typeof qn === 'string' ? qn.split(".") : qn,
  5238. ptr = this,
  5239. i = 0;
  5240. if (part[i] === "") { // Fully qualified name, e.g. ".My.Message'
  5241. while (ptr.parent !== null)
  5242. ptr = ptr.parent;
  5243. i++;
  5244. }
  5245. var child;
  5246. do {
  5247. do {
  5248. if (!(ptr instanceof Reflect.Namespace)) {
  5249. ptr = null;
  5250. break;
  5251. }
  5252. child = ptr.getChild(part[i]);
  5253. if (!child || !(child instanceof Reflect.T) || (excludeNonNamespace && !(child instanceof Reflect.Namespace))) {
  5254. ptr = null;
  5255. break;
  5256. }
  5257. ptr = child; i++;
  5258. } while (i < part.length);
  5259. if (ptr != null)
  5260. break; // Found
  5261. // Else search the parent
  5262. if (this.parent !== null)
  5263. return this.parent.resolve(qn, excludeNonNamespace);
  5264. } while (ptr != null);
  5265. return ptr;
  5266. };
  5267. /**
  5268. * Determines the shortest qualified name of the specified type, if any, relative to this namespace.
  5269. * @param {!ProtoBuf.Reflect.T} t Reflection type
  5270. * @returns {string} The shortest qualified name or, if there is none, the fqn
  5271. * @expose
  5272. */
  5273. NamespacePrototype.qn = function(t) {
  5274. var part = [], ptr = t;
  5275. do {
  5276. part.unshift(ptr.name);
  5277. ptr = ptr.parent;
  5278. } while (ptr !== null);
  5279. for (var len=1; len <= part.length; len++) {
  5280. var qn = part.slice(part.length-len);
  5281. if (t === this.resolve(qn, t instanceof Reflect.Namespace))
  5282. return qn.join(".");
  5283. }
  5284. return t.fqn();
  5285. };
  5286. /**
  5287. * Builds the namespace and returns the runtime counterpart.
  5288. * @return {Object.<string,Function|Object>} Runtime namespace
  5289. * @expose
  5290. */
  5291. NamespacePrototype.build = function() {
  5292. /** @dict */
  5293. var ns = {};
  5294. var children = this.children;
  5295. for (var i=0, k=children.length, child; i<k; ++i) {
  5296. child = children[i];
  5297. if (child instanceof Namespace)
  5298. ns[child.name] = child.build();
  5299. }
  5300. if (Object.defineProperty)
  5301. Object.defineProperty(ns, "$options", { "value": this.buildOpt() });
  5302. return ns;
  5303. };
  5304. /**
  5305. * Builds the namespace's '$options' property.
  5306. * @return {Object.<string,*>}
  5307. */
  5308. NamespacePrototype.buildOpt = function() {
  5309. var opt = {},
  5310. keys = Object.keys(this.options);
  5311. for (var i=0, k=keys.length; i<k; ++i) {
  5312. var key = keys[i],
  5313. val = this.options[keys[i]];
  5314. // TODO: Options are not resolved, yet.
  5315. // if (val instanceof Namespace) {
  5316. // opt[key] = val.build();
  5317. // } else {
  5318. opt[key] = val;
  5319. // }
  5320. }
  5321. return opt;
  5322. };
  5323. /**
  5324. * Gets the value assigned to the option with the specified name.
  5325. * @param {string=} name Returns the option value if specified, otherwise all options are returned.
  5326. * @return {*|Object.<string,*>}null} Option value or NULL if there is no such option
  5327. */
  5328. NamespacePrototype.getOption = function(name) {
  5329. if (typeof name === 'undefined')
  5330. return this.options;
  5331. return typeof this.options[name] !== 'undefined' ? this.options[name] : null;
  5332. };
  5333. /**
  5334. * @alias ProtoBuf.Reflect.Namespace
  5335. * @expose
  5336. */
  5337. Reflect.Namespace = Namespace;
  5338. /**
  5339. * Constructs a new Element implementation that checks and converts values for a
  5340. * particular field type, as appropriate.
  5341. *
  5342. * An Element represents a single value: either the value of a singular field,
  5343. * or a value contained in one entry of a repeated field or map field. This
  5344. * class does not implement these higher-level concepts; it only encapsulates
  5345. * the low-level typechecking and conversion.
  5346. *
  5347. * @exports ProtoBuf.Reflect.Element
  5348. * @param {{name: string, wireType: number}} type Resolved data type
  5349. * @param {ProtoBuf.Reflect.T|null} resolvedType Resolved type, if relevant
  5350. * (e.g. submessage field).
  5351. * @param {boolean} isMapKey Is this element a Map key? The value will be
  5352. * converted to string form if so.
  5353. * @param {string} syntax Syntax level of defining message type, e.g.,
  5354. * proto2 or proto3.
  5355. * @param {string} name Name of the field containing this element (for error
  5356. * messages)
  5357. * @constructor
  5358. */
  5359. var Element = function(type, resolvedType, isMapKey, syntax, name) {
  5360. /**
  5361. * Element type, as a string (e.g., int32).
  5362. * @type {{name: string, wireType: number}}
  5363. */
  5364. this.type = type;
  5365. /**
  5366. * Element type reference to submessage or enum definition, if needed.
  5367. * @type {ProtoBuf.Reflect.T|null}
  5368. */
  5369. this.resolvedType = resolvedType;
  5370. /**
  5371. * Element is a map key.
  5372. * @type {boolean}
  5373. */
  5374. this.isMapKey = isMapKey;
  5375. /**
  5376. * Syntax level of defining message type, e.g., proto2 or proto3.
  5377. * @type {string}
  5378. */
  5379. this.syntax = syntax;
  5380. /**
  5381. * Name of the field containing this element (for error messages)
  5382. * @type {string}
  5383. */
  5384. this.name = name;
  5385. if (isMapKey && ProtoBuf.MAP_KEY_TYPES.indexOf(type) < 0)
  5386. throw Error("Invalid map key type: " + type.name);
  5387. };
  5388. var ElementPrototype = Element.prototype;
  5389. /**
  5390. * Obtains a (new) default value for the specified type.
  5391. * @param type {string|{name: string, wireType: number}} Field type
  5392. * @returns {*} Default value
  5393. * @inner
  5394. */
  5395. function mkDefault(type) {
  5396. if (typeof type === 'string')
  5397. type = ProtoBuf.TYPES[type];
  5398. if (typeof type.defaultValue === 'undefined')
  5399. throw Error("default value for type "+type.name+" is not supported");
  5400. if (type == ProtoBuf.TYPES["bytes"])
  5401. return new ByteBuffer(0);
  5402. return type.defaultValue;
  5403. }
  5404. /**
  5405. * Returns the default value for this field in proto3.
  5406. * @function
  5407. * @param type {string|{name: string, wireType: number}} the field type
  5408. * @returns {*} Default value
  5409. */
  5410. Element.defaultFieldValue = mkDefault;
  5411. /**
  5412. * Makes a Long from a value.
  5413. * @param {{low: number, high: number, unsigned: boolean}|string|number} value Value
  5414. * @param {boolean=} unsigned Whether unsigned or not, defaults to reuse it from Long-like objects or to signed for
  5415. * strings and numbers
  5416. * @returns {!Long}
  5417. * @throws {Error} If the value cannot be converted to a Long
  5418. * @inner
  5419. */
  5420. function mkLong(value, unsigned) {
  5421. if (value && typeof value.low === 'number' && typeof value.high === 'number' && typeof value.unsigned === 'boolean'
  5422. && value.low === value.low && value.high === value.high)
  5423. return new ProtoBuf.Long(value.low, value.high, typeof unsigned === 'undefined' ? value.unsigned : unsigned);
  5424. if (typeof value === 'string')
  5425. return ProtoBuf.Long.fromString(value, unsigned || false, 10);
  5426. if (typeof value === 'number')
  5427. return ProtoBuf.Long.fromNumber(value, unsigned || false);
  5428. throw Error("not convertible to Long");
  5429. }
  5430. ElementPrototype.toString = function() {
  5431. return (this.name || '') + (this.isMapKey ? 'map' : 'value') + ' element';
  5432. };
  5433. /**
  5434. * Checks if the given value can be set for an element of this type (singular
  5435. * field or one element of a repeated field or map).
  5436. * @param {*} value Value to check
  5437. * @return {*} Verified, maybe adjusted, value
  5438. * @throws {Error} If the value cannot be verified for this element slot
  5439. * @expose
  5440. */
  5441. ElementPrototype.verifyValue = function(value) {
  5442. var self = this;
  5443. function fail(val, msg) {
  5444. throw Error("Illegal value for "+self.toString(true)+" of type "+self.type.name+": "+val+" ("+msg+")");
  5445. }
  5446. switch (this.type) {
  5447. // Signed 32bit
  5448. case ProtoBuf.TYPES["int32"]:
  5449. case ProtoBuf.TYPES["sint32"]:
  5450. case ProtoBuf.TYPES["sfixed32"]:
  5451. // Account for !NaN: value === value
  5452. if (typeof value !== 'number' || (value === value && value % 1 !== 0))
  5453. fail(typeof value, "not an integer");
  5454. return value > 4294967295 ? value | 0 : value;
  5455. // Unsigned 32bit
  5456. case ProtoBuf.TYPES["uint32"]:
  5457. case ProtoBuf.TYPES["fixed32"]:
  5458. if (typeof value !== 'number' || (value === value && value % 1 !== 0))
  5459. fail(typeof value, "not an integer");
  5460. return value < 0 ? value >>> 0 : value;
  5461. // Signed 64bit
  5462. case ProtoBuf.TYPES["int64"]:
  5463. case ProtoBuf.TYPES["sint64"]:
  5464. case ProtoBuf.TYPES["sfixed64"]: {
  5465. if (ProtoBuf.Long)
  5466. try {
  5467. return mkLong(value, false);
  5468. } catch (e) {
  5469. fail(typeof value, e.message);
  5470. }
  5471. else
  5472. fail(typeof value, "requires Long.js");
  5473. }
  5474. // Unsigned 64bit
  5475. case ProtoBuf.TYPES["uint64"]:
  5476. case ProtoBuf.TYPES["fixed64"]: {
  5477. if (ProtoBuf.Long)
  5478. try {
  5479. return mkLong(value, true);
  5480. } catch (e) {
  5481. fail(typeof value, e.message);
  5482. }
  5483. else
  5484. fail(typeof value, "requires Long.js");
  5485. }
  5486. // Bool
  5487. case ProtoBuf.TYPES["bool"]:
  5488. if (typeof value !== 'boolean')
  5489. fail(typeof value, "not a boolean");
  5490. return value;
  5491. // Float
  5492. case ProtoBuf.TYPES["float"]:
  5493. case ProtoBuf.TYPES["double"]:
  5494. if (typeof value !== 'number')
  5495. fail(typeof value, "not a number");
  5496. return value;
  5497. // Length-delimited string
  5498. case ProtoBuf.TYPES["string"]:
  5499. if (typeof value !== 'string' && !(value && value instanceof String))
  5500. fail(typeof value, "not a string");
  5501. return ""+value; // Convert String object to string
  5502. // Length-delimited bytes
  5503. case ProtoBuf.TYPES["bytes"]:
  5504. if (ByteBuffer.isByteBuffer(value))
  5505. return value;
  5506. return ByteBuffer.wrap(value, "base64");
  5507. // Constant enum value
  5508. case ProtoBuf.TYPES["enum"]: {
  5509. var values = this.resolvedType.getChildren(ProtoBuf.Reflect.Enum.Value);
  5510. for (i=0; i<values.length; i++)
  5511. if (values[i].name == value)
  5512. return values[i].id;
  5513. else if (values[i].id == value)
  5514. return values[i].id;
  5515. if (this.syntax === 'proto3') {
  5516. // proto3: just make sure it's an integer.
  5517. if (typeof value !== 'number' || (value === value && value % 1 !== 0))
  5518. fail(typeof value, "not an integer");
  5519. if (value > 4294967295 || value < 0)
  5520. fail(typeof value, "not in range for uint32");
  5521. return value;
  5522. } else {
  5523. // proto2 requires enum values to be valid.
  5524. fail(value, "not a valid enum value");
  5525. }
  5526. }
  5527. // Embedded message
  5528. case ProtoBuf.TYPES["group"]:
  5529. case ProtoBuf.TYPES["message"]: {
  5530. if (!value || typeof value !== 'object')
  5531. fail(typeof value, "object expected");
  5532. if (value instanceof this.resolvedType.clazz)
  5533. return value;
  5534. if (value instanceof ProtoBuf.Builder.Message) {
  5535. // Mismatched type: Convert to object (see: https://github.com/dcodeIO/ProtoBuf.js/issues/180)
  5536. var obj = {};
  5537. for (var i in value)
  5538. if (value.hasOwnProperty(i))
  5539. obj[i] = value[i];
  5540. value = obj;
  5541. }
  5542. // Else let's try to construct one from a key-value object
  5543. return new (this.resolvedType.clazz)(value); // May throw for a hundred of reasons
  5544. }
  5545. }
  5546. // We should never end here
  5547. throw Error("[INTERNAL] Illegal value for "+this.toString(true)+": "+value+" (undefined type "+this.type+")");
  5548. };
  5549. /**
  5550. * Calculates the byte length of an element on the wire.
  5551. * @param {number} id Field number
  5552. * @param {*} value Field value
  5553. * @returns {number} Byte length
  5554. * @throws {Error} If the value cannot be calculated
  5555. * @expose
  5556. */
  5557. ElementPrototype.calculateLength = function(id, value) {
  5558. if (value === null) return 0; // Nothing to encode
  5559. // Tag has already been written
  5560. var n;
  5561. switch (this.type) {
  5562. case ProtoBuf.TYPES["int32"]:
  5563. return value < 0 ? ByteBuffer.calculateVarint64(value) : ByteBuffer.calculateVarint32(value);
  5564. case ProtoBuf.TYPES["uint32"]:
  5565. return ByteBuffer.calculateVarint32(value);
  5566. case ProtoBuf.TYPES["sint32"]:
  5567. return ByteBuffer.calculateVarint32(ByteBuffer.zigZagEncode32(value));
  5568. case ProtoBuf.TYPES["fixed32"]:
  5569. case ProtoBuf.TYPES["sfixed32"]:
  5570. case ProtoBuf.TYPES["float"]:
  5571. return 4;
  5572. case ProtoBuf.TYPES["int64"]:
  5573. case ProtoBuf.TYPES["uint64"]:
  5574. return ByteBuffer.calculateVarint64(value);
  5575. case ProtoBuf.TYPES["sint64"]:
  5576. return ByteBuffer.calculateVarint64(ByteBuffer.zigZagEncode64(value));
  5577. case ProtoBuf.TYPES["fixed64"]:
  5578. case ProtoBuf.TYPES["sfixed64"]:
  5579. return 8;
  5580. case ProtoBuf.TYPES["bool"]:
  5581. return 1;
  5582. case ProtoBuf.TYPES["enum"]:
  5583. return ByteBuffer.calculateVarint32(value);
  5584. case ProtoBuf.TYPES["double"]:
  5585. return 8;
  5586. case ProtoBuf.TYPES["string"]:
  5587. n = ByteBuffer.calculateUTF8Bytes(value);
  5588. return ByteBuffer.calculateVarint32(n) + n;
  5589. case ProtoBuf.TYPES["bytes"]:
  5590. if (value.remaining() < 0)
  5591. throw Error("Illegal value for "+this.toString(true)+": "+value.remaining()+" bytes remaining");
  5592. return ByteBuffer.calculateVarint32(value.remaining()) + value.remaining();
  5593. case ProtoBuf.TYPES["message"]:
  5594. n = this.resolvedType.calculate(value);
  5595. return ByteBuffer.calculateVarint32(n) + n;
  5596. case ProtoBuf.TYPES["group"]:
  5597. n = this.resolvedType.calculate(value);
  5598. return n + ByteBuffer.calculateVarint32((id << 3) | ProtoBuf.WIRE_TYPES.ENDGROUP);
  5599. }
  5600. // We should never end here
  5601. throw Error("[INTERNAL] Illegal value to encode in "+this.toString(true)+": "+value+" (unknown type)");
  5602. };
  5603. /**
  5604. * Encodes a value to the specified buffer. Does not encode the key.
  5605. * @param {number} id Field number
  5606. * @param {*} value Field value
  5607. * @param {ByteBuffer} buffer ByteBuffer to encode to
  5608. * @return {ByteBuffer} The ByteBuffer for chaining
  5609. * @throws {Error} If the value cannot be encoded
  5610. * @expose
  5611. */
  5612. ElementPrototype.encodeValue = function(id, value, buffer) {
  5613. if (value === null) return buffer; // Nothing to encode
  5614. // Tag has already been written
  5615. switch (this.type) {
  5616. // 32bit signed varint
  5617. case ProtoBuf.TYPES["int32"]:
  5618. // "If you use int32 or int64 as the type for a negative number, the resulting varint is always ten bytes
  5619. // long – it is, effectively, treated like a very large unsigned integer." (see #122)
  5620. if (value < 0)
  5621. buffer.writeVarint64(value);
  5622. else
  5623. buffer.writeVarint32(value);
  5624. break;
  5625. // 32bit unsigned varint
  5626. case ProtoBuf.TYPES["uint32"]:
  5627. buffer.writeVarint32(value);
  5628. break;
  5629. // 32bit varint zig-zag
  5630. case ProtoBuf.TYPES["sint32"]:
  5631. buffer.writeVarint32ZigZag(value);
  5632. break;
  5633. // Fixed unsigned 32bit
  5634. case ProtoBuf.TYPES["fixed32"]:
  5635. buffer.writeUint32(value);
  5636. break;
  5637. // Fixed signed 32bit
  5638. case ProtoBuf.TYPES["sfixed32"]:
  5639. buffer.writeInt32(value);
  5640. break;
  5641. // 64bit varint as-is
  5642. case ProtoBuf.TYPES["int64"]:
  5643. case ProtoBuf.TYPES["uint64"]:
  5644. buffer.writeVarint64(value); // throws
  5645. break;
  5646. // 64bit varint zig-zag
  5647. case ProtoBuf.TYPES["sint64"]:
  5648. buffer.writeVarint64ZigZag(value); // throws
  5649. break;
  5650. // Fixed unsigned 64bit
  5651. case ProtoBuf.TYPES["fixed64"]:
  5652. buffer.writeUint64(value); // throws
  5653. break;
  5654. // Fixed signed 64bit
  5655. case ProtoBuf.TYPES["sfixed64"]:
  5656. buffer.writeInt64(value); // throws
  5657. break;
  5658. // Bool
  5659. case ProtoBuf.TYPES["bool"]:
  5660. if (typeof value === 'string')
  5661. buffer.writeVarint32(value.toLowerCase() === 'false' ? 0 : !!value);
  5662. else
  5663. buffer.writeVarint32(value ? 1 : 0);
  5664. break;
  5665. // Constant enum value
  5666. case ProtoBuf.TYPES["enum"]:
  5667. buffer.writeVarint32(value);
  5668. break;
  5669. // 32bit float
  5670. case ProtoBuf.TYPES["float"]:
  5671. buffer.writeFloat32(value);
  5672. break;
  5673. // 64bit float
  5674. case ProtoBuf.TYPES["double"]:
  5675. buffer.writeFloat64(value);
  5676. break;
  5677. // Length-delimited string
  5678. case ProtoBuf.TYPES["string"]:
  5679. buffer.writeVString(value);
  5680. break;
  5681. // Length-delimited bytes
  5682. case ProtoBuf.TYPES["bytes"]:
  5683. if (value.remaining() < 0)
  5684. throw Error("Illegal value for "+this.toString(true)+": "+value.remaining()+" bytes remaining");
  5685. var prevOffset = value.offset;
  5686. buffer.writeVarint32(value.remaining());
  5687. buffer.append(value);
  5688. value.offset = prevOffset;
  5689. break;
  5690. // Embedded message
  5691. case ProtoBuf.TYPES["message"]:
  5692. var bb = new ByteBuffer().LE();
  5693. this.resolvedType.encode(value, bb);
  5694. buffer.writeVarint32(bb.offset);
  5695. buffer.append(bb.flip());
  5696. break;
  5697. // Legacy group
  5698. case ProtoBuf.TYPES["group"]:
  5699. this.resolvedType.encode(value, buffer);
  5700. buffer.writeVarint32((id << 3) | ProtoBuf.WIRE_TYPES.ENDGROUP);
  5701. break;
  5702. default:
  5703. // We should never end here
  5704. throw Error("[INTERNAL] Illegal value to encode in "+this.toString(true)+": "+value+" (unknown type)");
  5705. }
  5706. return buffer;
  5707. };
  5708. /**
  5709. * Decode one element value from the specified buffer.
  5710. * @param {ByteBuffer} buffer ByteBuffer to decode from
  5711. * @param {number} wireType The field wire type
  5712. * @param {number} id The field number
  5713. * @return {*} Decoded value
  5714. * @throws {Error} If the field cannot be decoded
  5715. * @expose
  5716. */
  5717. ElementPrototype.decode = function(buffer, wireType, id) {
  5718. if (wireType != this.type.wireType)
  5719. throw Error("Unexpected wire type for element");
  5720. var value, nBytes;
  5721. switch (this.type) {
  5722. // 32bit signed varint
  5723. case ProtoBuf.TYPES["int32"]:
  5724. return buffer.readVarint32() | 0;
  5725. // 32bit unsigned varint
  5726. case ProtoBuf.TYPES["uint32"]:
  5727. return buffer.readVarint32() >>> 0;
  5728. // 32bit signed varint zig-zag
  5729. case ProtoBuf.TYPES["sint32"]:
  5730. return buffer.readVarint32ZigZag() | 0;
  5731. // Fixed 32bit unsigned
  5732. case ProtoBuf.TYPES["fixed32"]:
  5733. return buffer.readUint32() >>> 0;
  5734. case ProtoBuf.TYPES["sfixed32"]:
  5735. return buffer.readInt32() | 0;
  5736. // 64bit signed varint
  5737. case ProtoBuf.TYPES["int64"]:
  5738. return buffer.readVarint64();
  5739. // 64bit unsigned varint
  5740. case ProtoBuf.TYPES["uint64"]:
  5741. return buffer.readVarint64().toUnsigned();
  5742. // 64bit signed varint zig-zag
  5743. case ProtoBuf.TYPES["sint64"]:
  5744. return buffer.readVarint64ZigZag();
  5745. // Fixed 64bit unsigned
  5746. case ProtoBuf.TYPES["fixed64"]:
  5747. return buffer.readUint64();
  5748. // Fixed 64bit signed
  5749. case ProtoBuf.TYPES["sfixed64"]:
  5750. return buffer.readInt64();
  5751. // Bool varint
  5752. case ProtoBuf.TYPES["bool"]:
  5753. return !!buffer.readVarint32();
  5754. // Constant enum value (varint)
  5755. case ProtoBuf.TYPES["enum"]:
  5756. // The following Builder.Message#set will already throw
  5757. return buffer.readVarint32();
  5758. // 32bit float
  5759. case ProtoBuf.TYPES["float"]:
  5760. return buffer.readFloat();
  5761. // 64bit float
  5762. case ProtoBuf.TYPES["double"]:
  5763. return buffer.readDouble();
  5764. // Length-delimited string
  5765. case ProtoBuf.TYPES["string"]:
  5766. return buffer.readVString();
  5767. // Length-delimited bytes
  5768. case ProtoBuf.TYPES["bytes"]: {
  5769. nBytes = buffer.readVarint32();
  5770. if (buffer.remaining() < nBytes)
  5771. throw Error("Illegal number of bytes for "+this.toString(true)+": "+nBytes+" required but got only "+buffer.remaining());
  5772. value = buffer.clone(); // Offset already set
  5773. value.limit = value.offset+nBytes;
  5774. buffer.offset += nBytes;
  5775. return value;
  5776. }
  5777. // Length-delimited embedded message
  5778. case ProtoBuf.TYPES["message"]: {
  5779. nBytes = buffer.readVarint32();
  5780. return this.resolvedType.decode(buffer, nBytes);
  5781. }
  5782. // Legacy group
  5783. case ProtoBuf.TYPES["group"]:
  5784. return this.resolvedType.decode(buffer, -1, id);
  5785. }
  5786. // We should never end here
  5787. throw Error("[INTERNAL] Illegal decode type");
  5788. };
  5789. /**
  5790. * Converts a value from a string to the canonical element type.
  5791. *
  5792. * Legal only when isMapKey is true.
  5793. *
  5794. * @param {string} str The string value
  5795. * @returns {*} The value
  5796. */
  5797. ElementPrototype.valueFromString = function(str) {
  5798. if (!this.isMapKey) {
  5799. throw Error("valueFromString() called on non-map-key element");
  5800. }
  5801. switch (this.type) {
  5802. case ProtoBuf.TYPES["int32"]:
  5803. case ProtoBuf.TYPES["sint32"]:
  5804. case ProtoBuf.TYPES["sfixed32"]:
  5805. case ProtoBuf.TYPES["uint32"]:
  5806. case ProtoBuf.TYPES["fixed32"]:
  5807. return this.verifyValue(parseInt(str));
  5808. case ProtoBuf.TYPES["int64"]:
  5809. case ProtoBuf.TYPES["sint64"]:
  5810. case ProtoBuf.TYPES["sfixed64"]:
  5811. case ProtoBuf.TYPES["uint64"]:
  5812. case ProtoBuf.TYPES["fixed64"]:
  5813. // Long-based fields support conversions from string already.
  5814. return this.verifyValue(str);
  5815. case ProtoBuf.TYPES["bool"]:
  5816. return str === "true";
  5817. case ProtoBuf.TYPES["string"]:
  5818. return this.verifyValue(str);
  5819. case ProtoBuf.TYPES["bytes"]:
  5820. return ByteBuffer.fromBinary(str);
  5821. }
  5822. };
  5823. /**
  5824. * Converts a value from the canonical element type to a string.
  5825. *
  5826. * It should be the case that `valueFromString(valueToString(val))` returns
  5827. * a value equivalent to `verifyValue(val)` for every legal value of `val`
  5828. * according to this element type.
  5829. *
  5830. * This may be used when the element must be stored or used as a string,
  5831. * e.g., as a map key on an Object.
  5832. *
  5833. * Legal only when isMapKey is true.
  5834. *
  5835. * @param {*} val The value
  5836. * @returns {string} The string form of the value.
  5837. */
  5838. ElementPrototype.valueToString = function(value) {
  5839. if (!this.isMapKey) {
  5840. throw Error("valueToString() called on non-map-key element");
  5841. }
  5842. if (this.type === ProtoBuf.TYPES["bytes"]) {
  5843. return value.toString("binary");
  5844. } else {
  5845. return value.toString();
  5846. }
  5847. };
  5848. /**
  5849. * @alias ProtoBuf.Reflect.Element
  5850. * @expose
  5851. */
  5852. Reflect.Element = Element;
  5853. /**
  5854. * Constructs a new Message.
  5855. * @exports ProtoBuf.Reflect.Message
  5856. * @param {!ProtoBuf.Builder} builder Builder reference
  5857. * @param {!ProtoBuf.Reflect.Namespace} parent Parent message or namespace
  5858. * @param {string} name Message name
  5859. * @param {Object.<string,*>=} options Message options
  5860. * @param {boolean=} isGroup `true` if this is a legacy group
  5861. * @param {string?} syntax The syntax level of this definition (e.g., proto3)
  5862. * @constructor
  5863. * @extends ProtoBuf.Reflect.Namespace
  5864. */
  5865. var Message = function(builder, parent, name, options, isGroup, syntax) {
  5866. Namespace.call(this, builder, parent, name, options, syntax);
  5867. /**
  5868. * @override
  5869. */
  5870. this.className = "Message";
  5871. /**
  5872. * Extensions range.
  5873. * @type {!Array.<number>|undefined}
  5874. * @expose
  5875. */
  5876. this.extensions = undefined;
  5877. /**
  5878. * Runtime message class.
  5879. * @type {?function(new:ProtoBuf.Builder.Message)}
  5880. * @expose
  5881. */
  5882. this.clazz = null;
  5883. /**
  5884. * Whether this is a legacy group or not.
  5885. * @type {boolean}
  5886. * @expose
  5887. */
  5888. this.isGroup = !!isGroup;
  5889. // The following cached collections are used to efficiently iterate over or look up fields when decoding.
  5890. /**
  5891. * Cached fields.
  5892. * @type {?Array.<!ProtoBuf.Reflect.Message.Field>}
  5893. * @private
  5894. */
  5895. this._fields = null;
  5896. /**
  5897. * Cached fields by id.
  5898. * @type {?Object.<number,!ProtoBuf.Reflect.Message.Field>}
  5899. * @private
  5900. */
  5901. this._fieldsById = null;
  5902. /**
  5903. * Cached fields by name.
  5904. * @type {?Object.<string,!ProtoBuf.Reflect.Message.Field>}
  5905. * @private
  5906. */
  5907. this._fieldsByName = null;
  5908. };
  5909. /**
  5910. * @alias ProtoBuf.Reflect.Message.prototype
  5911. * @inner
  5912. */
  5913. var MessagePrototype = Message.prototype = Object.create(Namespace.prototype);
  5914. /**
  5915. * Builds the message and returns the runtime counterpart, which is a fully functional class.
  5916. * @see ProtoBuf.Builder.Message
  5917. * @param {boolean=} rebuild Whether to rebuild or not, defaults to false
  5918. * @return {ProtoBuf.Reflect.Message} Message class
  5919. * @throws {Error} If the message cannot be built
  5920. * @expose
  5921. */
  5922. MessagePrototype.build = function(rebuild) {
  5923. if (this.clazz && !rebuild)
  5924. return this.clazz;
  5925. // Create the runtime Message class in its own scope
  5926. var clazz = (function(ProtoBuf, T) {
  5927. var fields = T.getChildren(ProtoBuf.Reflect.Message.Field),
  5928. oneofs = T.getChildren(ProtoBuf.Reflect.Message.OneOf);
  5929. /**
  5930. * Constructs a new runtime Message.
  5931. * @name ProtoBuf.Builder.Message
  5932. * @class Barebone of all runtime messages.
  5933. * @param {!Object.<string,*>|string} values Preset values
  5934. * @param {...string} var_args
  5935. * @constructor
  5936. * @throws {Error} If the message cannot be created
  5937. */
  5938. var Message = function(values, var_args) {
  5939. ProtoBuf.Builder.Message.call(this);
  5940. // Create virtual oneof properties
  5941. for (var i=0, k=oneofs.length; i<k; ++i)
  5942. this[oneofs[i].name] = null;
  5943. // Create fields and set default values
  5944. for (i=0, k=fields.length; i<k; ++i) {
  5945. var field = fields[i];
  5946. this[field.name] =
  5947. field.repeated ? [] :
  5948. (field.map ? new ProtoBuf.Map(field) : null);
  5949. if ((field.required || T.syntax === 'proto3') &&
  5950. field.defaultValue !== null)
  5951. this[field.name] = field.defaultValue;
  5952. }
  5953. if (arguments.length > 0) {
  5954. var value;
  5955. // Set field values from a values object
  5956. if (arguments.length === 1 && values !== null && typeof values === 'object' &&
  5957. /* not _another_ Message */ (typeof values.encode !== 'function' || values instanceof Message) &&
  5958. /* not a repeated field */ !Array.isArray(values) &&
  5959. /* not a Map */ !(values instanceof ProtoBuf.Map) &&
  5960. /* not a ByteBuffer */ !ByteBuffer.isByteBuffer(values) &&
  5961. /* not an ArrayBuffer */ !(values instanceof ArrayBuffer) &&
  5962. /* not a Long */ !(ProtoBuf.Long && values instanceof ProtoBuf.Long)) {
  5963. this.$set(values);
  5964. } else // Set field values from arguments, in declaration order
  5965. for (i=0, k=arguments.length; i<k; ++i)
  5966. if (typeof (value = arguments[i]) !== 'undefined')
  5967. this.$set(fields[i].name, value); // May throw
  5968. }
  5969. };
  5970. /**
  5971. * @alias ProtoBuf.Builder.Message.prototype
  5972. * @inner
  5973. */
  5974. var MessagePrototype = Message.prototype = Object.create(ProtoBuf.Builder.Message.prototype);
  5975. /**
  5976. * Adds a value to a repeated field.
  5977. * @name ProtoBuf.Builder.Message#add
  5978. * @function
  5979. * @param {string} key Field name
  5980. * @param {*} value Value to add
  5981. * @param {boolean=} noAssert Whether to assert the value or not (asserts by default)
  5982. * @returns {!ProtoBuf.Builder.Message} this
  5983. * @throws {Error} If the value cannot be added
  5984. * @expose
  5985. */
  5986. MessagePrototype.add = function(key, value, noAssert) {
  5987. var field = T._fieldsByName[key];
  5988. if (!noAssert) {
  5989. if (!field)
  5990. throw Error(this+"#"+key+" is undefined");
  5991. if (!(field instanceof ProtoBuf.Reflect.Message.Field))
  5992. throw Error(this+"#"+key+" is not a field: "+field.toString(true)); // May throw if it's an enum or embedded message
  5993. if (!field.repeated)
  5994. throw Error(this+"#"+key+" is not a repeated field");
  5995. value = field.verifyValue(value, true);
  5996. }
  5997. if (this[key] === null)
  5998. this[key] = [];
  5999. this[key].push(value);
  6000. return this;
  6001. };
  6002. /**
  6003. * Adds a value to a repeated field. This is an alias for {@link ProtoBuf.Builder.Message#add}.
  6004. * @name ProtoBuf.Builder.Message#$add
  6005. * @function
  6006. * @param {string} key Field name
  6007. * @param {*} value Value to add
  6008. * @param {boolean=} noAssert Whether to assert the value or not (asserts by default)
  6009. * @returns {!ProtoBuf.Builder.Message} this
  6010. * @throws {Error} If the value cannot be added
  6011. * @expose
  6012. */
  6013. MessagePrototype.$add = MessagePrototype.add;
  6014. /**
  6015. * Sets a field's value.
  6016. * @name ProtoBuf.Builder.Message#set
  6017. * @function
  6018. * @param {string|!Object.<string,*>} keyOrObj String key or plain object holding multiple values
  6019. * @param {(*|boolean)=} value Value to set if key is a string, otherwise omitted
  6020. * @param {boolean=} noAssert Whether to not assert for an actual field / proper value type, defaults to `false`
  6021. * @returns {!ProtoBuf.Builder.Message} this
  6022. * @throws {Error} If the value cannot be set
  6023. * @expose
  6024. */
  6025. MessagePrototype.set = function(keyOrObj, value, noAssert) {
  6026. if (keyOrObj && typeof keyOrObj === 'object') {
  6027. noAssert = value;
  6028. for (var ikey in keyOrObj) {
  6029. // Check if virtual oneof field - don't set these
  6030. if (keyOrObj.hasOwnProperty(ikey) && typeof (value = keyOrObj[ikey]) !== 'undefined' && T._oneofsByName[ikey] === undefined)
  6031. this.$set(ikey, value, noAssert);
  6032. }
  6033. return this;
  6034. }
  6035. var field = T._fieldsByName[keyOrObj];
  6036. if (!noAssert) {
  6037. if (!field)
  6038. throw Error(this+"#"+keyOrObj+" is not a field: undefined");
  6039. if (!(field instanceof ProtoBuf.Reflect.Message.Field))
  6040. throw Error(this+"#"+keyOrObj+" is not a field: "+field.toString(true));
  6041. this[field.name] = (value = field.verifyValue(value)); // May throw
  6042. } else
  6043. this[keyOrObj] = value;
  6044. if (field && field.oneof) { // Field is part of an OneOf (not a virtual OneOf field)
  6045. var currentField = this[field.oneof.name]; // Virtual field references currently set field
  6046. if (value !== null) {
  6047. if (currentField !== null && currentField !== field.name)
  6048. this[currentField] = null; // Clear currently set field
  6049. this[field.oneof.name] = field.name; // Point virtual field at this field
  6050. } else if (/* value === null && */currentField === keyOrObj)
  6051. this[field.oneof.name] = null; // Clear virtual field (current field explicitly cleared)
  6052. }
  6053. return this;
  6054. };
  6055. /**
  6056. * Sets a field's value. This is an alias for [@link ProtoBuf.Builder.Message#set}.
  6057. * @name ProtoBuf.Builder.Message#$set
  6058. * @function
  6059. * @param {string|!Object.<string,*>} keyOrObj String key or plain object holding multiple values
  6060. * @param {(*|boolean)=} value Value to set if key is a string, otherwise omitted
  6061. * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
  6062. * @throws {Error} If the value cannot be set
  6063. * @expose
  6064. */
  6065. MessagePrototype.$set = MessagePrototype.set;
  6066. /**
  6067. * Gets a field's value.
  6068. * @name ProtoBuf.Builder.Message#get
  6069. * @function
  6070. * @param {string} key Key
  6071. * @param {boolean=} noAssert Whether to not assert for an actual field, defaults to `false`
  6072. * @return {*} Value
  6073. * @throws {Error} If there is no such field
  6074. * @expose
  6075. */
  6076. MessagePrototype.get = function(key, noAssert) {
  6077. if (noAssert)
  6078. return this[key];
  6079. var field = T._fieldsByName[key];
  6080. if (!field || !(field instanceof ProtoBuf.Reflect.Message.Field))
  6081. throw Error(this+"#"+key+" is not a field: undefined");
  6082. if (!(field instanceof ProtoBuf.Reflect.Message.Field))
  6083. throw Error(this+"#"+key+" is not a field: "+field.toString(true));
  6084. return this[field.name];
  6085. };
  6086. /**
  6087. * Gets a field's value. This is an alias for {@link ProtoBuf.Builder.Message#$get}.
  6088. * @name ProtoBuf.Builder.Message#$get
  6089. * @function
  6090. * @param {string} key Key
  6091. * @return {*} Value
  6092. * @throws {Error} If there is no such field
  6093. * @expose
  6094. */
  6095. MessagePrototype.$get = MessagePrototype.get;
  6096. // Getters and setters
  6097. for (var i=0; i<fields.length; i++) {
  6098. var field = fields[i];
  6099. // no setters for extension fields as these are named by their fqn
  6100. if (field instanceof ProtoBuf.Reflect.Message.ExtensionField)
  6101. continue;
  6102. if (T.builder.options['populateAccessors'])
  6103. (function(field) {
  6104. // set/get[SomeValue]
  6105. var Name = field.originalName.replace(/(_[a-zA-Z])/g, function(match) {
  6106. return match.toUpperCase().replace('_','');
  6107. });
  6108. Name = Name.substring(0,1).toUpperCase() + Name.substring(1);
  6109. // set/get_[some_value] FIXME: Do we really need these?
  6110. var name = field.originalName.replace(/([A-Z])/g, function(match) {
  6111. return "_"+match;
  6112. });
  6113. /**
  6114. * The current field's unbound setter function.
  6115. * @function
  6116. * @param {*} value
  6117. * @param {boolean=} noAssert
  6118. * @returns {!ProtoBuf.Builder.Message}
  6119. * @inner
  6120. */
  6121. var setter = function(value, noAssert) {
  6122. this[field.name] = noAssert ? value : field.verifyValue(value);
  6123. return this;
  6124. };
  6125. /**
  6126. * The current field's unbound getter function.
  6127. * @function
  6128. * @returns {*}
  6129. * @inner
  6130. */
  6131. var getter = function() {
  6132. return this[field.name];
  6133. };
  6134. if (T.getChild("set"+Name) === null)
  6135. /**
  6136. * Sets a value. This method is present for each field, but only if there is no name conflict with
  6137. * another field.
  6138. * @name ProtoBuf.Builder.Message#set[SomeField]
  6139. * @function
  6140. * @param {*} value Value to set
  6141. * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
  6142. * @returns {!ProtoBuf.Builder.Message} this
  6143. * @abstract
  6144. * @throws {Error} If the value cannot be set
  6145. */
  6146. MessagePrototype["set"+Name] = setter;
  6147. if (T.getChild("set_"+name) === null)
  6148. /**
  6149. * Sets a value. This method is present for each field, but only if there is no name conflict with
  6150. * another field.
  6151. * @name ProtoBuf.Builder.Message#set_[some_field]
  6152. * @function
  6153. * @param {*} value Value to set
  6154. * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
  6155. * @returns {!ProtoBuf.Builder.Message} this
  6156. * @abstract
  6157. * @throws {Error} If the value cannot be set
  6158. */
  6159. MessagePrototype["set_"+name] = setter;
  6160. if (T.getChild("get"+Name) === null)
  6161. /**
  6162. * Gets a value. This method is present for each field, but only if there is no name conflict with
  6163. * another field.
  6164. * @name ProtoBuf.Builder.Message#get[SomeField]
  6165. * @function
  6166. * @abstract
  6167. * @return {*} The value
  6168. */
  6169. MessagePrototype["get"+Name] = getter;
  6170. if (T.getChild("get_"+name) === null)
  6171. /**
  6172. * Gets a value. This method is present for each field, but only if there is no name conflict with
  6173. * another field.
  6174. * @name ProtoBuf.Builder.Message#get_[some_field]
  6175. * @function
  6176. * @return {*} The value
  6177. * @abstract
  6178. */
  6179. MessagePrototype["get_"+name] = getter;
  6180. })(field);
  6181. }
  6182. // En-/decoding
  6183. /**
  6184. * Encodes the message.
  6185. * @name ProtoBuf.Builder.Message#$encode
  6186. * @function
  6187. * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.
  6188. * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
  6189. * @return {!ByteBuffer} Encoded message as a ByteBuffer
  6190. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  6191. * returns the encoded ByteBuffer in the `encoded` property on the error.
  6192. * @expose
  6193. * @see ProtoBuf.Builder.Message#encode64
  6194. * @see ProtoBuf.Builder.Message#encodeHex
  6195. * @see ProtoBuf.Builder.Message#encodeAB
  6196. */
  6197. MessagePrototype.encode = function(buffer, noVerify) {
  6198. if (typeof buffer === 'boolean')
  6199. noVerify = buffer,
  6200. buffer = undefined;
  6201. var isNew = false;
  6202. if (!buffer)
  6203. buffer = new ByteBuffer(),
  6204. isNew = true;
  6205. var le = buffer.littleEndian;
  6206. try {
  6207. T.encode(this, buffer.LE(), noVerify);
  6208. return (isNew ? buffer.flip() : buffer).LE(le);
  6209. } catch (e) {
  6210. buffer.LE(le);
  6211. throw(e);
  6212. }
  6213. };
  6214. /**
  6215. * Encodes a message using the specified data payload.
  6216. * @param {!Object.<string,*>} data Data payload
  6217. * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.
  6218. * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
  6219. * @return {!ByteBuffer} Encoded message as a ByteBuffer
  6220. * @expose
  6221. */
  6222. Message.encode = function(data, buffer, noVerify) {
  6223. return new Message(data).encode(buffer, noVerify);
  6224. };
  6225. /**
  6226. * Calculates the byte length of the message.
  6227. * @name ProtoBuf.Builder.Message#calculate
  6228. * @function
  6229. * @returns {number} Byte length
  6230. * @throws {Error} If the message cannot be calculated or if required fields are missing.
  6231. * @expose
  6232. */
  6233. MessagePrototype.calculate = function() {
  6234. return T.calculate(this);
  6235. };
  6236. /**
  6237. * Encodes the varint32 length-delimited message.
  6238. * @name ProtoBuf.Builder.Message#encodeDelimited
  6239. * @function
  6240. * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.
  6241. * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
  6242. * @return {!ByteBuffer} Encoded message as a ByteBuffer
  6243. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  6244. * returns the encoded ByteBuffer in the `encoded` property on the error.
  6245. * @expose
  6246. */
  6247. MessagePrototype.encodeDelimited = function(buffer, noVerify) {
  6248. var isNew = false;
  6249. if (!buffer)
  6250. buffer = new ByteBuffer(),
  6251. isNew = true;
  6252. var enc = new ByteBuffer().LE();
  6253. T.encode(this, enc, noVerify).flip();
  6254. buffer.writeVarint32(enc.remaining());
  6255. buffer.append(enc);
  6256. return isNew ? buffer.flip() : buffer;
  6257. };
  6258. /**
  6259. * Directly encodes the message to an ArrayBuffer.
  6260. * @name ProtoBuf.Builder.Message#encodeAB
  6261. * @function
  6262. * @return {ArrayBuffer} Encoded message as ArrayBuffer
  6263. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  6264. * returns the encoded ArrayBuffer in the `encoded` property on the error.
  6265. * @expose
  6266. */
  6267. MessagePrototype.encodeAB = function() {
  6268. try {
  6269. return this.encode().toArrayBuffer();
  6270. } catch (e) {
  6271. if (e["encoded"]) e["encoded"] = e["encoded"].toArrayBuffer();
  6272. throw(e);
  6273. }
  6274. };
  6275. /**
  6276. * Returns the message as an ArrayBuffer. This is an alias for {@link ProtoBuf.Builder.Message#encodeAB}.
  6277. * @name ProtoBuf.Builder.Message#toArrayBuffer
  6278. * @function
  6279. * @return {ArrayBuffer} Encoded message as ArrayBuffer
  6280. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  6281. * returns the encoded ArrayBuffer in the `encoded` property on the error.
  6282. * @expose
  6283. */
  6284. MessagePrototype.toArrayBuffer = MessagePrototype.encodeAB;
  6285. /**
  6286. * Directly encodes the message to a node Buffer.
  6287. * @name ProtoBuf.Builder.Message#encodeNB
  6288. * @function
  6289. * @return {!Buffer}
  6290. * @throws {Error} If the message cannot be encoded, not running under node.js or if required fields are
  6291. * missing. The later still returns the encoded node Buffer in the `encoded` property on the error.
  6292. * @expose
  6293. */
  6294. MessagePrototype.encodeNB = function() {
  6295. try {
  6296. return this.encode().toBuffer();
  6297. } catch (e) {
  6298. if (e["encoded"]) e["encoded"] = e["encoded"].toBuffer();
  6299. throw(e);
  6300. }
  6301. };
  6302. /**
  6303. * Returns the message as a node Buffer. This is an alias for {@link ProtoBuf.Builder.Message#encodeNB}.
  6304. * @name ProtoBuf.Builder.Message#toBuffer
  6305. * @function
  6306. * @return {!Buffer}
  6307. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  6308. * returns the encoded node Buffer in the `encoded` property on the error.
  6309. * @expose
  6310. */
  6311. MessagePrototype.toBuffer = MessagePrototype.encodeNB;
  6312. /**
  6313. * Directly encodes the message to a base64 encoded string.
  6314. * @name ProtoBuf.Builder.Message#encode64
  6315. * @function
  6316. * @return {string} Base64 encoded string
  6317. * @throws {Error} If the underlying buffer cannot be encoded or if required fields are missing. The later
  6318. * still returns the encoded base64 string in the `encoded` property on the error.
  6319. * @expose
  6320. */
  6321. MessagePrototype.encode64 = function() {
  6322. try {
  6323. return this.encode().toBase64();
  6324. } catch (e) {
  6325. if (e["encoded"]) e["encoded"] = e["encoded"].toBase64();
  6326. throw(e);
  6327. }
  6328. };
  6329. /**
  6330. * Returns the message as a base64 encoded string. This is an alias for {@link ProtoBuf.Builder.Message#encode64}.
  6331. * @name ProtoBuf.Builder.Message#toBase64
  6332. * @function
  6333. * @return {string} Base64 encoded string
  6334. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  6335. * returns the encoded base64 string in the `encoded` property on the error.
  6336. * @expose
  6337. */
  6338. MessagePrototype.toBase64 = MessagePrototype.encode64;
  6339. /**
  6340. * Directly encodes the message to a hex encoded string.
  6341. * @name ProtoBuf.Builder.Message#encodeHex
  6342. * @function
  6343. * @return {string} Hex encoded string
  6344. * @throws {Error} If the underlying buffer cannot be encoded or if required fields are missing. The later
  6345. * still returns the encoded hex string in the `encoded` property on the error.
  6346. * @expose
  6347. */
  6348. MessagePrototype.encodeHex = function() {
  6349. try {
  6350. return this.encode().toHex();
  6351. } catch (e) {
  6352. if (e["encoded"]) e["encoded"] = e["encoded"].toHex();
  6353. throw(e);
  6354. }
  6355. };
  6356. /**
  6357. * Returns the message as a hex encoded string. This is an alias for {@link ProtoBuf.Builder.Message#encodeHex}.
  6358. * @name ProtoBuf.Builder.Message#toHex
  6359. * @function
  6360. * @return {string} Hex encoded string
  6361. * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
  6362. * returns the encoded hex string in the `encoded` property on the error.
  6363. * @expose
  6364. */
  6365. MessagePrototype.toHex = MessagePrototype.encodeHex;
  6366. /**
  6367. * Clones a message object or field value to a raw object.
  6368. * @param {*} obj Object to clone
  6369. * @param {boolean} binaryAsBase64 Whether to include binary data as base64 strings or as a buffer otherwise
  6370. * @param {boolean} longsAsStrings Whether to encode longs as strings
  6371. * @param {!ProtoBuf.Reflect.T=} resolvedType The resolved field type if a field
  6372. * @returns {*} Cloned object
  6373. * @inner
  6374. */
  6375. function cloneRaw(obj, binaryAsBase64, longsAsStrings, resolvedType) {
  6376. if (obj === null || typeof obj !== 'object') {
  6377. // Convert enum values to their respective names
  6378. if (resolvedType && resolvedType instanceof ProtoBuf.Reflect.Enum) {
  6379. var name = ProtoBuf.Reflect.Enum.getName(resolvedType.object, obj);
  6380. if (name !== null)
  6381. return name;
  6382. }
  6383. // Pass-through string, number, boolean, null...
  6384. return obj;
  6385. }
  6386. // Convert ByteBuffers to raw buffer or strings
  6387. if (ByteBuffer.isByteBuffer(obj))
  6388. return binaryAsBase64 ? obj.toBase64() : obj.toBuffer();
  6389. // Convert Longs to proper objects or strings
  6390. if (ProtoBuf.Long.isLong(obj))
  6391. return longsAsStrings ? obj.toString() : ProtoBuf.Long.fromValue(obj);
  6392. var clone;
  6393. // Clone arrays
  6394. if (Array.isArray(obj)) {
  6395. clone = [];
  6396. obj.forEach(function(v, k) {
  6397. clone[k] = cloneRaw(v, binaryAsBase64, longsAsStrings, resolvedType);
  6398. });
  6399. return clone;
  6400. }
  6401. clone = {};
  6402. // Convert maps to objects
  6403. if (obj instanceof ProtoBuf.Map) {
  6404. var it = obj.entries();
  6405. for (var e = it.next(); !e.done; e = it.next())
  6406. clone[obj.keyElem.valueToString(e.value[0])] = cloneRaw(e.value[1], binaryAsBase64, longsAsStrings, obj.valueElem.resolvedType);
  6407. return clone;
  6408. }
  6409. // Everything else is a non-null object
  6410. var type = obj.$type,
  6411. field = undefined;
  6412. for (var i in obj)
  6413. if (obj.hasOwnProperty(i)) {
  6414. if (type && (field = type.getChild(i)))
  6415. clone[i] = cloneRaw(obj[i], binaryAsBase64, longsAsStrings, field.resolvedType);
  6416. else
  6417. clone[i] = cloneRaw(obj[i], binaryAsBase64, longsAsStrings);
  6418. }
  6419. return clone;
  6420. }
  6421. /**
  6422. * Returns the message's raw payload.
  6423. * @param {boolean=} binaryAsBase64 Whether to include binary data as base64 strings instead of Buffers, defaults to `false`
  6424. * @param {boolean} longsAsStrings Whether to encode longs as strings
  6425. * @returns {Object.<string,*>} Raw payload
  6426. * @expose
  6427. */
  6428. MessagePrototype.toRaw = function(binaryAsBase64, longsAsStrings) {
  6429. return cloneRaw(this, !!binaryAsBase64, !!longsAsStrings, this.$type);
  6430. };
  6431. /**
  6432. * Encodes a message to JSON.
  6433. * @returns {string} JSON string
  6434. * @expose
  6435. */
  6436. MessagePrototype.encodeJSON = function() {
  6437. return JSON.stringify(
  6438. cloneRaw(this,
  6439. /* binary-as-base64 */ true,
  6440. /* longs-as-strings */ true,
  6441. this.$type
  6442. )
  6443. );
  6444. };
  6445. /**
  6446. * Decodes a message from the specified buffer or string.
  6447. * @name ProtoBuf.Builder.Message.decode
  6448. * @function
  6449. * @param {!ByteBuffer|!ArrayBuffer|!Buffer|string} buffer Buffer to decode from
  6450. * @param {(number|string)=} length Message length. Defaults to decode all the remainig data.
  6451. * @param {string=} enc Encoding if buffer is a string: hex, utf8 (not recommended), defaults to base64
  6452. * @return {!ProtoBuf.Builder.Message} Decoded message
  6453. * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
  6454. * returns the decoded message with missing fields in the `decoded` property on the error.
  6455. * @expose
  6456. * @see ProtoBuf.Builder.Message.decode64
  6457. * @see ProtoBuf.Builder.Message.decodeHex
  6458. */
  6459. Message.decode = function(buffer, length, enc) {
  6460. if (typeof length === 'string')
  6461. enc = length,
  6462. length = -1;
  6463. if (typeof buffer === 'string')
  6464. buffer = ByteBuffer.wrap(buffer, enc ? enc : "base64");
  6465. else if (!ByteBuffer.isByteBuffer(buffer))
  6466. buffer = ByteBuffer.wrap(buffer); // May throw
  6467. var le = buffer.littleEndian;
  6468. try {
  6469. var msg = T.decode(buffer.LE(), length);
  6470. buffer.LE(le);
  6471. return msg;
  6472. } catch (e) {
  6473. buffer.LE(le);
  6474. throw(e);
  6475. }
  6476. };
  6477. /**
  6478. * Decodes a varint32 length-delimited message from the specified buffer or string.
  6479. * @name ProtoBuf.Builder.Message.decodeDelimited
  6480. * @function
  6481. * @param {!ByteBuffer|!ArrayBuffer|!Buffer|string} buffer Buffer to decode from
  6482. * @param {string=} enc Encoding if buffer is a string: hex, utf8 (not recommended), defaults to base64
  6483. * @return {ProtoBuf.Builder.Message} Decoded message or `null` if not enough bytes are available yet
  6484. * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
  6485. * returns the decoded message with missing fields in the `decoded` property on the error.
  6486. * @expose
  6487. */
  6488. Message.decodeDelimited = function(buffer, enc) {
  6489. if (typeof buffer === 'string')
  6490. buffer = ByteBuffer.wrap(buffer, enc ? enc : "base64");
  6491. else if (!ByteBuffer.isByteBuffer(buffer))
  6492. buffer = ByteBuffer.wrap(buffer); // May throw
  6493. if (buffer.remaining() < 1)
  6494. return null;
  6495. var off = buffer.offset,
  6496. len = buffer.readVarint32();
  6497. if (buffer.remaining() < len) {
  6498. buffer.offset = off;
  6499. return null;
  6500. }
  6501. try {
  6502. var msg = T.decode(buffer.slice(buffer.offset, buffer.offset + len).LE());
  6503. buffer.offset += len;
  6504. return msg;
  6505. } catch (err) {
  6506. buffer.offset += len;
  6507. throw err;
  6508. }
  6509. };
  6510. /**
  6511. * Decodes the message from the specified base64 encoded string.
  6512. * @name ProtoBuf.Builder.Message.decode64
  6513. * @function
  6514. * @param {string} str String to decode from
  6515. * @return {!ProtoBuf.Builder.Message} Decoded message
  6516. * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
  6517. * returns the decoded message with missing fields in the `decoded` property on the error.
  6518. * @expose
  6519. */
  6520. Message.decode64 = function(str) {
  6521. return Message.decode(str, "base64");
  6522. };
  6523. /**
  6524. * Decodes the message from the specified hex encoded string.
  6525. * @name ProtoBuf.Builder.Message.decodeHex
  6526. * @function
  6527. * @param {string} str String to decode from
  6528. * @return {!ProtoBuf.Builder.Message} Decoded message
  6529. * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
  6530. * returns the decoded message with missing fields in the `decoded` property on the error.
  6531. * @expose
  6532. */
  6533. Message.decodeHex = function(str) {
  6534. return Message.decode(str, "hex");
  6535. };
  6536. /**
  6537. * Decodes the message from a JSON string.
  6538. * @name ProtoBuf.Builder.Message.decodeJSON
  6539. * @function
  6540. * @param {string} str String to decode from
  6541. * @return {!ProtoBuf.Builder.Message} Decoded message
  6542. * @throws {Error} If the message cannot be decoded or if required fields are
  6543. * missing.
  6544. * @expose
  6545. */
  6546. Message.decodeJSON = function(str) {
  6547. return new Message(JSON.parse(str));
  6548. };
  6549. // Utility
  6550. /**
  6551. * Returns a string representation of this Message.
  6552. * @name ProtoBuf.Builder.Message#toString
  6553. * @function
  6554. * @return {string} String representation as of ".Fully.Qualified.MessageName"
  6555. * @expose
  6556. */
  6557. MessagePrototype.toString = function() {
  6558. return T.toString();
  6559. };
  6560. if (Object.defineProperty)
  6561. Object.defineProperty(Message, '$options', { "value": T.buildOpt() }),
  6562. Object.defineProperty(MessagePrototype, "$options", { "value": Message["$options"] }),
  6563. Object.defineProperty(Message, "$type", { "value": T }),
  6564. Object.defineProperty(MessagePrototype, "$type", { "value": T });
  6565. return Message;
  6566. })(ProtoBuf, this);
  6567. // Static enums and prototyped sub-messages / cached collections
  6568. this._fields = [];
  6569. this._fieldsById = {};
  6570. this._fieldsByName = {};
  6571. this._oneofsByName = {};
  6572. for (var i=0, k=this.children.length, child; i<k; i++) {
  6573. child = this.children[i];
  6574. if (child instanceof Enum || child instanceof Message || child instanceof Service) {
  6575. if (clazz.hasOwnProperty(child.name))
  6576. throw Error("Illegal reflect child of "+this.toString(true)+": "+child.toString(true)+" cannot override static property '"+child.name+"'");
  6577. clazz[child.name] = child.build();
  6578. } else if (child instanceof Message.Field)
  6579. child.build(),
  6580. this._fields.push(child),
  6581. this._fieldsById[child.id] = child,
  6582. this._fieldsByName[child.name] = child;
  6583. else if (child instanceof Message.OneOf) {
  6584. this._oneofsByName[child.name] = child;
  6585. }
  6586. else if (!(child instanceof Message.OneOf) && !(child instanceof Extension)) // Not built
  6587. throw Error("Illegal reflect child of "+this.toString(true)+": "+this.children[i].toString(true));
  6588. }
  6589. return this.clazz = clazz;
  6590. };
  6591. /**
  6592. * Encodes a runtime message's contents to the specified buffer.
  6593. * @param {!ProtoBuf.Builder.Message} message Runtime message to encode
  6594. * @param {ByteBuffer} buffer ByteBuffer to write to
  6595. * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
  6596. * @return {ByteBuffer} The ByteBuffer for chaining
  6597. * @throws {Error} If required fields are missing or the message cannot be encoded for another reason
  6598. * @expose
  6599. */
  6600. MessagePrototype.encode = function(message, buffer, noVerify) {
  6601. var fieldMissing = null,
  6602. field;
  6603. for (var i=0, k=this._fields.length, val; i<k; ++i) {
  6604. field = this._fields[i];
  6605. val = message[field.name];
  6606. if (field.required && val === null) {
  6607. if (fieldMissing === null)
  6608. fieldMissing = field;
  6609. } else
  6610. field.encode(noVerify ? val : field.verifyValue(val), buffer, message);
  6611. }
  6612. if (fieldMissing !== null) {
  6613. var err = Error("Missing at least one required field for "+this.toString(true)+": "+fieldMissing);
  6614. err["encoded"] = buffer; // Still expose what we got
  6615. throw(err);
  6616. }
  6617. return buffer;
  6618. };
  6619. /**
  6620. * Calculates a runtime message's byte length.
  6621. * @param {!ProtoBuf.Builder.Message} message Runtime message to encode
  6622. * @returns {number} Byte length
  6623. * @throws {Error} If required fields are missing or the message cannot be calculated for another reason
  6624. * @expose
  6625. */
  6626. MessagePrototype.calculate = function(message) {
  6627. for (var n=0, i=0, k=this._fields.length, field, val; i<k; ++i) {
  6628. field = this._fields[i];
  6629. val = message[field.name];
  6630. if (field.required && val === null)
  6631. throw Error("Missing at least one required field for "+this.toString(true)+": "+field);
  6632. else
  6633. n += field.calculate(val, message);
  6634. }
  6635. return n;
  6636. };
  6637. /**
  6638. * Skips all data until the end of the specified group has been reached.
  6639. * @param {number} expectedId Expected GROUPEND id
  6640. * @param {!ByteBuffer} buf ByteBuffer
  6641. * @returns {boolean} `true` if a value as been skipped, `false` if the end has been reached
  6642. * @throws {Error} If it wasn't possible to find the end of the group (buffer overrun or end tag mismatch)
  6643. * @inner
  6644. */
  6645. function skipTillGroupEnd(expectedId, buf) {
  6646. var tag = buf.readVarint32(), // Throws on OOB
  6647. wireType = tag & 0x07,
  6648. id = tag >>> 3;
  6649. switch (wireType) {
  6650. case ProtoBuf.WIRE_TYPES.VARINT:
  6651. do tag = buf.readUint8();
  6652. while ((tag & 0x80) === 0x80);
  6653. break;
  6654. case ProtoBuf.WIRE_TYPES.BITS64:
  6655. buf.offset += 8;
  6656. break;
  6657. case ProtoBuf.WIRE_TYPES.LDELIM:
  6658. tag = buf.readVarint32(); // reads the varint
  6659. buf.offset += tag; // skips n bytes
  6660. break;
  6661. case ProtoBuf.WIRE_TYPES.STARTGROUP:
  6662. skipTillGroupEnd(id, buf);
  6663. break;
  6664. case ProtoBuf.WIRE_TYPES.ENDGROUP:
  6665. if (id === expectedId)
  6666. return false;
  6667. else
  6668. throw Error("Illegal GROUPEND after unknown group: "+id+" ("+expectedId+" expected)");
  6669. case ProtoBuf.WIRE_TYPES.BITS32:
  6670. buf.offset += 4;
  6671. break;
  6672. default:
  6673. throw Error("Illegal wire type in unknown group "+expectedId+": "+wireType);
  6674. }
  6675. return true;
  6676. }
  6677. /**
  6678. * Decodes an encoded message and returns the decoded message.
  6679. * @param {ByteBuffer} buffer ByteBuffer to decode from
  6680. * @param {number=} length Message length. Defaults to decode all remaining data.
  6681. * @param {number=} expectedGroupEndId Expected GROUPEND id if this is a legacy group
  6682. * @return {ProtoBuf.Builder.Message} Decoded message
  6683. * @throws {Error} If the message cannot be decoded
  6684. * @expose
  6685. */
  6686. MessagePrototype.decode = function(buffer, length, expectedGroupEndId) {
  6687. if (typeof length !== 'number')
  6688. length = -1;
  6689. var start = buffer.offset,
  6690. msg = new (this.clazz)(),
  6691. tag, wireType, id, field;
  6692. while (buffer.offset < start+length || (length === -1 && buffer.remaining() > 0)) {
  6693. tag = buffer.readVarint32();
  6694. wireType = tag & 0x07;
  6695. id = tag >>> 3;
  6696. if (wireType === ProtoBuf.WIRE_TYPES.ENDGROUP) {
  6697. if (id !== expectedGroupEndId)
  6698. throw Error("Illegal group end indicator for "+this.toString(true)+": "+id+" ("+(expectedGroupEndId ? expectedGroupEndId+" expected" : "not a group")+")");
  6699. break;
  6700. }
  6701. if (!(field = this._fieldsById[id])) {
  6702. // "messages created by your new code can be parsed by your old code: old binaries simply ignore the new field when parsing."
  6703. switch (wireType) {
  6704. case ProtoBuf.WIRE_TYPES.VARINT:
  6705. buffer.readVarint32();
  6706. break;
  6707. case ProtoBuf.WIRE_TYPES.BITS32:
  6708. buffer.offset += 4;
  6709. break;
  6710. case ProtoBuf.WIRE_TYPES.BITS64:
  6711. buffer.offset += 8;
  6712. break;
  6713. case ProtoBuf.WIRE_TYPES.LDELIM:
  6714. var len = buffer.readVarint32();
  6715. buffer.offset += len;
  6716. break;
  6717. case ProtoBuf.WIRE_TYPES.STARTGROUP:
  6718. while (skipTillGroupEnd(id, buffer)) {}
  6719. break;
  6720. default:
  6721. throw Error("Illegal wire type for unknown field "+id+" in "+this.toString(true)+"#decode: "+wireType);
  6722. }
  6723. continue;
  6724. }
  6725. if (field.repeated && !field.options["packed"]) {
  6726. msg[field.name].push(field.decode(wireType, buffer));
  6727. } else if (field.map) {
  6728. var keyval = field.decode(wireType, buffer);
  6729. msg[field.name].set(keyval[0], keyval[1]);
  6730. } else {
  6731. msg[field.name] = field.decode(wireType, buffer);
  6732. if (field.oneof) { // Field is part of an OneOf (not a virtual OneOf field)
  6733. var currentField = msg[field.oneof.name]; // Virtual field references currently set field
  6734. if (currentField !== null && currentField !== field.name)
  6735. msg[currentField] = null; // Clear currently set field
  6736. msg[field.oneof.name] = field.name; // Point virtual field at this field
  6737. }
  6738. }
  6739. }
  6740. // Check if all required fields are present and set default values for optional fields that are not
  6741. for (var i=0, k=this._fields.length; i<k; ++i) {
  6742. field = this._fields[i];
  6743. if (msg[field.name] === null) {
  6744. if (this.syntax === "proto3") { // Proto3 sets default values by specification
  6745. msg[field.name] = field.defaultValue;
  6746. } else if (field.required) {
  6747. var err = Error("Missing at least one required field for " + this.toString(true) + ": " + field.name);
  6748. err["decoded"] = msg; // Still expose what we got
  6749. throw(err);
  6750. } else if (ProtoBuf.populateDefaults && field.defaultValue !== null)
  6751. msg[field.name] = field.defaultValue;
  6752. }
  6753. }
  6754. return msg;
  6755. };
  6756. /**
  6757. * @alias ProtoBuf.Reflect.Message
  6758. * @expose
  6759. */
  6760. Reflect.Message = Message;
  6761. /**
  6762. * Constructs a new Message Field.
  6763. * @exports ProtoBuf.Reflect.Message.Field
  6764. * @param {!ProtoBuf.Builder} builder Builder reference
  6765. * @param {!ProtoBuf.Reflect.Message} message Message reference
  6766. * @param {string} rule Rule, one of requried, optional, repeated
  6767. * @param {string?} keytype Key data type, if any.
  6768. * @param {string} type Data type, e.g. int32
  6769. * @param {string} name Field name
  6770. * @param {number} id Unique field id
  6771. * @param {Object.<string,*>=} options Options
  6772. * @param {!ProtoBuf.Reflect.Message.OneOf=} oneof Enclosing OneOf
  6773. * @param {string?} syntax The syntax level of this definition (e.g., proto3)
  6774. * @constructor
  6775. * @extends ProtoBuf.Reflect.T
  6776. */
  6777. var Field = function(builder, message, rule, keytype, type, name, id, options, oneof, syntax) {
  6778. T.call(this, builder, message, name);
  6779. /**
  6780. * @override
  6781. */
  6782. this.className = "Message.Field";
  6783. /**
  6784. * Message field required flag.
  6785. * @type {boolean}
  6786. * @expose
  6787. */
  6788. this.required = rule === "required";
  6789. /**
  6790. * Message field repeated flag.
  6791. * @type {boolean}
  6792. * @expose
  6793. */
  6794. this.repeated = rule === "repeated";
  6795. /**
  6796. * Message field map flag.
  6797. * @type {boolean}
  6798. * @expose
  6799. */
  6800. this.map = rule === "map";
  6801. /**
  6802. * Message field key type. Type reference string if unresolved, protobuf
  6803. * type if resolved. Valid only if this.map === true, null otherwise.
  6804. * @type {string|{name: string, wireType: number}|null}
  6805. * @expose
  6806. */
  6807. this.keyType = keytype || null;
  6808. /**
  6809. * Message field type. Type reference string if unresolved, protobuf type if
  6810. * resolved. In a map field, this is the value type.
  6811. * @type {string|{name: string, wireType: number}}
  6812. * @expose
  6813. */
  6814. this.type = type;
  6815. /**
  6816. * Resolved type reference inside the global namespace.
  6817. * @type {ProtoBuf.Reflect.T|null}
  6818. * @expose
  6819. */
  6820. this.resolvedType = null;
  6821. /**
  6822. * Unique message field id.
  6823. * @type {number}
  6824. * @expose
  6825. */
  6826. this.id = id;
  6827. /**
  6828. * Message field options.
  6829. * @type {!Object.<string,*>}
  6830. * @dict
  6831. * @expose
  6832. */
  6833. this.options = options || {};
  6834. /**
  6835. * Default value.
  6836. * @type {*}
  6837. * @expose
  6838. */
  6839. this.defaultValue = null;
  6840. /**
  6841. * Enclosing OneOf.
  6842. * @type {?ProtoBuf.Reflect.Message.OneOf}
  6843. * @expose
  6844. */
  6845. this.oneof = oneof || null;
  6846. /**
  6847. * Syntax level of this definition (e.g., proto3).
  6848. * @type {string}
  6849. * @expose
  6850. */
  6851. this.syntax = syntax || 'proto2';
  6852. /**
  6853. * Original field name.
  6854. * @type {string}
  6855. * @expose
  6856. */
  6857. this.originalName = this.name; // Used to revert camelcase transformation on naming collisions
  6858. /**
  6859. * Element implementation. Created in build() after types are resolved.
  6860. * @type {ProtoBuf.Element}
  6861. * @expose
  6862. */
  6863. this.element = null;
  6864. /**
  6865. * Key element implementation, for map fields. Created in build() after
  6866. * types are resolved.
  6867. * @type {ProtoBuf.Element}
  6868. * @expose
  6869. */
  6870. this.keyElement = null;
  6871. // Convert field names to camel case notation if the override is set
  6872. if (this.builder.options['convertFieldsToCamelCase'] && !(this instanceof Message.ExtensionField))
  6873. this.name = ProtoBuf.Util.toCamelCase(this.name);
  6874. };
  6875. /**
  6876. * @alias ProtoBuf.Reflect.Message.Field.prototype
  6877. * @inner
  6878. */
  6879. var FieldPrototype = Field.prototype = Object.create(T.prototype);
  6880. /**
  6881. * Builds the field.
  6882. * @override
  6883. * @expose
  6884. */
  6885. FieldPrototype.build = function() {
  6886. this.element = new Element(this.type, this.resolvedType, false, this.syntax, this.name);
  6887. if (this.map)
  6888. this.keyElement = new Element(this.keyType, undefined, true, this.syntax, this.name);
  6889. // In proto3, fields do not have field presence, and every field is set to
  6890. // its type's default value ("", 0, 0.0, or false).
  6891. if (this.syntax === 'proto3' && !this.repeated && !this.map)
  6892. this.defaultValue = Element.defaultFieldValue(this.type);
  6893. // Otherwise, default values are present when explicitly specified
  6894. else if (typeof this.options['default'] !== 'undefined')
  6895. this.defaultValue = this.verifyValue(this.options['default']);
  6896. };
  6897. /**
  6898. * Checks if the given value can be set for this field.
  6899. * @param {*} value Value to check
  6900. * @param {boolean=} skipRepeated Whether to skip the repeated value check or not. Defaults to false.
  6901. * @return {*} Verified, maybe adjusted, value
  6902. * @throws {Error} If the value cannot be set for this field
  6903. * @expose
  6904. */
  6905. FieldPrototype.verifyValue = function(value, skipRepeated) {
  6906. skipRepeated = skipRepeated || false;
  6907. var self = this;
  6908. function fail(val, msg) {
  6909. throw Error("Illegal value for "+self.toString(true)+" of type "+self.type.name+": "+val+" ("+msg+")");
  6910. }
  6911. if (value === null) { // NULL values for optional fields
  6912. if (this.required)
  6913. fail(typeof value, "required");
  6914. if (this.syntax === 'proto3' && this.type !== ProtoBuf.TYPES["message"])
  6915. fail(typeof value, "proto3 field without field presence cannot be null");
  6916. return null;
  6917. }
  6918. var i;
  6919. if (this.repeated && !skipRepeated) { // Repeated values as arrays
  6920. if (!Array.isArray(value))
  6921. value = [value];
  6922. var res = [];
  6923. for (i=0; i<value.length; i++)
  6924. res.push(this.element.verifyValue(value[i]));
  6925. return res;
  6926. }
  6927. if (this.map && !skipRepeated) { // Map values as objects
  6928. if (!(value instanceof ProtoBuf.Map)) {
  6929. // If not already a Map, attempt to convert.
  6930. if (!(value instanceof Object)) {
  6931. fail(typeof value,
  6932. "expected ProtoBuf.Map or raw object for map field");
  6933. }
  6934. return new ProtoBuf.Map(this, value);
  6935. } else {
  6936. return value;
  6937. }
  6938. }
  6939. // All non-repeated fields expect no array
  6940. if (!this.repeated && Array.isArray(value))
  6941. fail(typeof value, "no array expected");
  6942. return this.element.verifyValue(value);
  6943. };
  6944. /**
  6945. * Determines whether the field will have a presence on the wire given its
  6946. * value.
  6947. * @param {*} value Verified field value
  6948. * @param {!ProtoBuf.Builder.Message} message Runtime message
  6949. * @return {boolean} Whether the field will be present on the wire
  6950. */
  6951. FieldPrototype.hasWirePresence = function(value, message) {
  6952. if (this.syntax !== 'proto3')
  6953. return (value !== null);
  6954. if (this.oneof && message[this.oneof.name] === this.name)
  6955. return true;
  6956. switch (this.type) {
  6957. case ProtoBuf.TYPES["int32"]:
  6958. case ProtoBuf.TYPES["sint32"]:
  6959. case ProtoBuf.TYPES["sfixed32"]:
  6960. case ProtoBuf.TYPES["uint32"]:
  6961. case ProtoBuf.TYPES["fixed32"]:
  6962. return value !== 0;
  6963. case ProtoBuf.TYPES["int64"]:
  6964. case ProtoBuf.TYPES["sint64"]:
  6965. case ProtoBuf.TYPES["sfixed64"]:
  6966. case ProtoBuf.TYPES["uint64"]:
  6967. case ProtoBuf.TYPES["fixed64"]:
  6968. return value.low !== 0 || value.high !== 0;
  6969. case ProtoBuf.TYPES["bool"]:
  6970. return value;
  6971. case ProtoBuf.TYPES["float"]:
  6972. case ProtoBuf.TYPES["double"]:
  6973. return value !== 0.0;
  6974. case ProtoBuf.TYPES["string"]:
  6975. return value.length > 0;
  6976. case ProtoBuf.TYPES["bytes"]:
  6977. return value.remaining() > 0;
  6978. case ProtoBuf.TYPES["enum"]:
  6979. return value !== 0;
  6980. case ProtoBuf.TYPES["message"]:
  6981. return value !== null;
  6982. default:
  6983. return true;
  6984. }
  6985. };
  6986. /**
  6987. * Encodes the specified field value to the specified buffer.
  6988. * @param {*} value Verified field value
  6989. * @param {ByteBuffer} buffer ByteBuffer to encode to
  6990. * @param {!ProtoBuf.Builder.Message} message Runtime message
  6991. * @return {ByteBuffer} The ByteBuffer for chaining
  6992. * @throws {Error} If the field cannot be encoded
  6993. * @expose
  6994. */
  6995. FieldPrototype.encode = function(value, buffer, message) {
  6996. if (this.type === null || typeof this.type !== 'object')
  6997. throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);
  6998. if (value === null || (this.repeated && value.length == 0))
  6999. return buffer; // Optional omitted
  7000. try {
  7001. if (this.repeated) {
  7002. var i;
  7003. // "Only repeated fields of primitive numeric types (types which use the varint, 32-bit, or 64-bit wire
  7004. // types) can be declared 'packed'."
  7005. if (this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {
  7006. // "All of the elements of the field are packed into a single key-value pair with wire type 2
  7007. // (length-delimited). Each element is encoded the same way it would be normally, except without a
  7008. // tag preceding it."
  7009. buffer.writeVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
  7010. buffer.ensureCapacity(buffer.offset += 1); // We do not know the length yet, so let's assume a varint of length 1
  7011. var start = buffer.offset; // Remember where the contents begin
  7012. for (i=0; i<value.length; i++)
  7013. this.element.encodeValue(this.id, value[i], buffer);
  7014. var len = buffer.offset-start,
  7015. varintLen = ByteBuffer.calculateVarint32(len);
  7016. if (varintLen > 1) { // We need to move the contents
  7017. var contents = buffer.slice(start, buffer.offset);
  7018. start += varintLen-1;
  7019. buffer.offset = start;
  7020. buffer.append(contents);
  7021. }
  7022. buffer.writeVarint32(len, start-varintLen);
  7023. } else {
  7024. // "If your message definition has repeated elements (without the [packed=true] option), the encoded
  7025. // message has zero or more key-value pairs with the same tag number"
  7026. for (i=0; i<value.length; i++)
  7027. buffer.writeVarint32((this.id << 3) | this.type.wireType),
  7028. this.element.encodeValue(this.id, value[i], buffer);
  7029. }
  7030. } else if (this.map) {
  7031. // Write out each map entry as a submessage.
  7032. value.forEach(function(val, key, m) {
  7033. // Compute the length of the submessage (key, val) pair.
  7034. var length =
  7035. ByteBuffer.calculateVarint32((1 << 3) | this.keyType.wireType) +
  7036. this.keyElement.calculateLength(1, key) +
  7037. ByteBuffer.calculateVarint32((2 << 3) | this.type.wireType) +
  7038. this.element.calculateLength(2, val);
  7039. // Submessage with wire type of length-delimited.
  7040. buffer.writeVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
  7041. buffer.writeVarint32(length);
  7042. // Write out the key and val.
  7043. buffer.writeVarint32((1 << 3) | this.keyType.wireType);
  7044. this.keyElement.encodeValue(1, key, buffer);
  7045. buffer.writeVarint32((2 << 3) | this.type.wireType);
  7046. this.element.encodeValue(2, val, buffer);
  7047. }, this);
  7048. } else {
  7049. if (this.hasWirePresence(value, message)) {
  7050. buffer.writeVarint32((this.id << 3) | this.type.wireType);
  7051. this.element.encodeValue(this.id, value, buffer);
  7052. }
  7053. }
  7054. } catch (e) {
  7055. throw Error("Illegal value for "+this.toString(true)+": "+value+" ("+e+")");
  7056. }
  7057. return buffer;
  7058. };
  7059. /**
  7060. * Calculates the length of this field's value on the network level.
  7061. * @param {*} value Field value
  7062. * @param {!ProtoBuf.Builder.Message} message Runtime message
  7063. * @returns {number} Byte length
  7064. * @expose
  7065. */
  7066. FieldPrototype.calculate = function(value, message) {
  7067. value = this.verifyValue(value); // May throw
  7068. if (this.type === null || typeof this.type !== 'object')
  7069. throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);
  7070. if (value === null || (this.repeated && value.length == 0))
  7071. return 0; // Optional omitted
  7072. var n = 0;
  7073. try {
  7074. if (this.repeated) {
  7075. var i, ni;
  7076. if (this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {
  7077. n += ByteBuffer.calculateVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
  7078. ni = 0;
  7079. for (i=0; i<value.length; i++)
  7080. ni += this.element.calculateLength(this.id, value[i]);
  7081. n += ByteBuffer.calculateVarint32(ni);
  7082. n += ni;
  7083. } else {
  7084. for (i=0; i<value.length; i++)
  7085. n += ByteBuffer.calculateVarint32((this.id << 3) | this.type.wireType),
  7086. n += this.element.calculateLength(this.id, value[i]);
  7087. }
  7088. } else if (this.map) {
  7089. // Each map entry becomes a submessage.
  7090. value.forEach(function(val, key, m) {
  7091. // Compute the length of the submessage (key, val) pair.
  7092. var length =
  7093. ByteBuffer.calculateVarint32((1 << 3) | this.keyType.wireType) +
  7094. this.keyElement.calculateLength(1, key) +
  7095. ByteBuffer.calculateVarint32((2 << 3) | this.type.wireType) +
  7096. this.element.calculateLength(2, val);
  7097. n += ByteBuffer.calculateVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
  7098. n += ByteBuffer.calculateVarint32(length);
  7099. n += length;
  7100. }, this);
  7101. } else {
  7102. if (this.hasWirePresence(value, message)) {
  7103. n += ByteBuffer.calculateVarint32((this.id << 3) | this.type.wireType);
  7104. n += this.element.calculateLength(this.id, value);
  7105. }
  7106. }
  7107. } catch (e) {
  7108. throw Error("Illegal value for "+this.toString(true)+": "+value+" ("+e+")");
  7109. }
  7110. return n;
  7111. };
  7112. /**
  7113. * Decode the field value from the specified buffer.
  7114. * @param {number} wireType Leading wire type
  7115. * @param {ByteBuffer} buffer ByteBuffer to decode from
  7116. * @param {boolean=} skipRepeated Whether to skip the repeated check or not. Defaults to false.
  7117. * @return {*} Decoded value: array for packed repeated fields, [key, value] for
  7118. * map fields, or an individual value otherwise.
  7119. * @throws {Error} If the field cannot be decoded
  7120. * @expose
  7121. */
  7122. FieldPrototype.decode = function(wireType, buffer, skipRepeated) {
  7123. var value, nBytes;
  7124. // We expect wireType to match the underlying type's wireType unless we see
  7125. // a packed repeated field, or unless this is a map field.
  7126. var wireTypeOK =
  7127. (!this.map && wireType == this.type.wireType) ||
  7128. (!skipRepeated && this.repeated && this.options["packed"] &&
  7129. wireType == ProtoBuf.WIRE_TYPES.LDELIM) ||
  7130. (this.map && wireType == ProtoBuf.WIRE_TYPES.LDELIM);
  7131. if (!wireTypeOK)
  7132. throw Error("Illegal wire type for field "+this.toString(true)+": "+wireType+" ("+this.type.wireType+" expected)");
  7133. // Handle packed repeated fields.
  7134. if (wireType == ProtoBuf.WIRE_TYPES.LDELIM && this.repeated && this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {
  7135. if (!skipRepeated) {
  7136. nBytes = buffer.readVarint32();
  7137. nBytes = buffer.offset + nBytes; // Limit
  7138. var values = [];
  7139. while (buffer.offset < nBytes)
  7140. values.push(this.decode(this.type.wireType, buffer, true));
  7141. return values;
  7142. }
  7143. // Read the next value otherwise...
  7144. }
  7145. // Handle maps.
  7146. if (this.map) {
  7147. // Read one (key, value) submessage, and return [key, value]
  7148. var key = Element.defaultFieldValue(this.keyType);
  7149. value = Element.defaultFieldValue(this.type);
  7150. // Read the length
  7151. nBytes = buffer.readVarint32();
  7152. if (buffer.remaining() < nBytes)
  7153. throw Error("Illegal number of bytes for "+this.toString(true)+": "+nBytes+" required but got only "+buffer.remaining());
  7154. // Get a sub-buffer of this key/value submessage
  7155. var msgbuf = buffer.clone();
  7156. msgbuf.limit = msgbuf.offset + nBytes;
  7157. buffer.offset += nBytes;
  7158. while (msgbuf.remaining() > 0) {
  7159. var tag = msgbuf.readVarint32();
  7160. wireType = tag & 0x07;
  7161. var id = tag >>> 3;
  7162. if (id === 1) {
  7163. key = this.keyElement.decode(msgbuf, wireType, id);
  7164. } else if (id === 2) {
  7165. value = this.element.decode(msgbuf, wireType, id);
  7166. } else {
  7167. throw Error("Unexpected tag in map field key/value submessage");
  7168. }
  7169. }
  7170. return [key, value];
  7171. }
  7172. // Handle singular and non-packed repeated field values.
  7173. return this.element.decode(buffer, wireType, this.id);
  7174. };
  7175. /**
  7176. * @alias ProtoBuf.Reflect.Message.Field
  7177. * @expose
  7178. */
  7179. Reflect.Message.Field = Field;
  7180. /**
  7181. * Constructs a new Message ExtensionField.
  7182. * @exports ProtoBuf.Reflect.Message.ExtensionField
  7183. * @param {!ProtoBuf.Builder} builder Builder reference
  7184. * @param {!ProtoBuf.Reflect.Message} message Message reference
  7185. * @param {string} rule Rule, one of requried, optional, repeated
  7186. * @param {string} type Data type, e.g. int32
  7187. * @param {string} name Field name
  7188. * @param {number} id Unique field id
  7189. * @param {!Object.<string,*>=} options Options
  7190. * @constructor
  7191. * @extends ProtoBuf.Reflect.Message.Field
  7192. */
  7193. var ExtensionField = function(builder, message, rule, type, name, id, options) {
  7194. Field.call(this, builder, message, rule, /* keytype = */ null, type, name, id, options);
  7195. /**
  7196. * Extension reference.
  7197. * @type {!ProtoBuf.Reflect.Extension}
  7198. * @expose
  7199. */
  7200. this.extension;
  7201. };
  7202. // Extends Field
  7203. ExtensionField.prototype = Object.create(Field.prototype);
  7204. /**
  7205. * @alias ProtoBuf.Reflect.Message.ExtensionField
  7206. * @expose
  7207. */
  7208. Reflect.Message.ExtensionField = ExtensionField;
  7209. /**
  7210. * Constructs a new Message OneOf.
  7211. * @exports ProtoBuf.Reflect.Message.OneOf
  7212. * @param {!ProtoBuf.Builder} builder Builder reference
  7213. * @param {!ProtoBuf.Reflect.Message} message Message reference
  7214. * @param {string} name OneOf name
  7215. * @constructor
  7216. * @extends ProtoBuf.Reflect.T
  7217. */
  7218. var OneOf = function(builder, message, name) {
  7219. T.call(this, builder, message, name);
  7220. /**
  7221. * Enclosed fields.
  7222. * @type {!Array.<!ProtoBuf.Reflect.Message.Field>}
  7223. * @expose
  7224. */
  7225. this.fields = [];
  7226. };
  7227. /**
  7228. * @alias ProtoBuf.Reflect.Message.OneOf
  7229. * @expose
  7230. */
  7231. Reflect.Message.OneOf = OneOf;
  7232. /**
  7233. * Constructs a new Enum.
  7234. * @exports ProtoBuf.Reflect.Enum
  7235. * @param {!ProtoBuf.Builder} builder Builder reference
  7236. * @param {!ProtoBuf.Reflect.T} parent Parent Reflect object
  7237. * @param {string} name Enum name
  7238. * @param {Object.<string,*>=} options Enum options
  7239. * @param {string?} syntax The syntax level (e.g., proto3)
  7240. * @constructor
  7241. * @extends ProtoBuf.Reflect.Namespace
  7242. */
  7243. var Enum = function(builder, parent, name, options, syntax) {
  7244. Namespace.call(this, builder, parent, name, options, syntax);
  7245. /**
  7246. * @override
  7247. */
  7248. this.className = "Enum";
  7249. /**
  7250. * Runtime enum object.
  7251. * @type {Object.<string,number>|null}
  7252. * @expose
  7253. */
  7254. this.object = null;
  7255. };
  7256. /**
  7257. * Gets the string name of an enum value.
  7258. * @param {!ProtoBuf.Builder.Enum} enm Runtime enum
  7259. * @param {number} value Enum value
  7260. * @returns {?string} Name or `null` if not present
  7261. * @expose
  7262. */
  7263. Enum.getName = function(enm, value) {
  7264. var keys = Object.keys(enm);
  7265. for (var i=0, key; i<keys.length; ++i)
  7266. if (enm[key = keys[i]] === value)
  7267. return key;
  7268. return null;
  7269. };
  7270. /**
  7271. * @alias ProtoBuf.Reflect.Enum.prototype
  7272. * @inner
  7273. */
  7274. var EnumPrototype = Enum.prototype = Object.create(Namespace.prototype);
  7275. /**
  7276. * Builds this enum and returns the runtime counterpart.
  7277. * @param {boolean} rebuild Whether to rebuild or not, defaults to false
  7278. * @returns {!Object.<string,number>}
  7279. * @expose
  7280. */
  7281. EnumPrototype.build = function(rebuild) {
  7282. if (this.object && !rebuild)
  7283. return this.object;
  7284. var enm = new ProtoBuf.Builder.Enum(),
  7285. values = this.getChildren(Enum.Value);
  7286. for (var i=0, k=values.length; i<k; ++i)
  7287. enm[values[i]['name']] = values[i]['id'];
  7288. if (Object.defineProperty)
  7289. Object.defineProperty(enm, '$options', {
  7290. "value": this.buildOpt(),
  7291. "enumerable": false
  7292. });
  7293. return this.object = enm;
  7294. };
  7295. /**
  7296. * @alias ProtoBuf.Reflect.Enum
  7297. * @expose
  7298. */
  7299. Reflect.Enum = Enum;
  7300. /**
  7301. * Constructs a new Enum Value.
  7302. * @exports ProtoBuf.Reflect.Enum.Value
  7303. * @param {!ProtoBuf.Builder} builder Builder reference
  7304. * @param {!ProtoBuf.Reflect.Enum} enm Enum reference
  7305. * @param {string} name Field name
  7306. * @param {number} id Unique field id
  7307. * @constructor
  7308. * @extends ProtoBuf.Reflect.T
  7309. */
  7310. var Value = function(builder, enm, name, id) {
  7311. T.call(this, builder, enm, name);
  7312. /**
  7313. * @override
  7314. */
  7315. this.className = "Enum.Value";
  7316. /**
  7317. * Unique enum value id.
  7318. * @type {number}
  7319. * @expose
  7320. */
  7321. this.id = id;
  7322. };
  7323. // Extends T
  7324. Value.prototype = Object.create(T.prototype);
  7325. /**
  7326. * @alias ProtoBuf.Reflect.Enum.Value
  7327. * @expose
  7328. */
  7329. Reflect.Enum.Value = Value;
  7330. /**
  7331. * An extension (field).
  7332. * @exports ProtoBuf.Reflect.Extension
  7333. * @constructor
  7334. * @param {!ProtoBuf.Builder} builder Builder reference
  7335. * @param {!ProtoBuf.Reflect.T} parent Parent object
  7336. * @param {string} name Object name
  7337. * @param {!ProtoBuf.Reflect.Message.Field} field Extension field
  7338. */
  7339. var Extension = function(builder, parent, name, field) {
  7340. T.call(this, builder, parent, name);
  7341. /**
  7342. * Extended message field.
  7343. * @type {!ProtoBuf.Reflect.Message.Field}
  7344. * @expose
  7345. */
  7346. this.field = field;
  7347. };
  7348. // Extends T
  7349. Extension.prototype = Object.create(T.prototype);
  7350. /**
  7351. * @alias ProtoBuf.Reflect.Extension
  7352. * @expose
  7353. */
  7354. Reflect.Extension = Extension;
  7355. /**
  7356. * Constructs a new Service.
  7357. * @exports ProtoBuf.Reflect.Service
  7358. * @param {!ProtoBuf.Builder} builder Builder reference
  7359. * @param {!ProtoBuf.Reflect.Namespace} root Root
  7360. * @param {string} name Service name
  7361. * @param {Object.<string,*>=} options Options
  7362. * @constructor
  7363. * @extends ProtoBuf.Reflect.Namespace
  7364. */
  7365. var Service = function(builder, root, name, options) {
  7366. Namespace.call(this, builder, root, name, options);
  7367. /**
  7368. * @override
  7369. */
  7370. this.className = "Service";
  7371. /**
  7372. * Built runtime service class.
  7373. * @type {?function(new:ProtoBuf.Builder.Service)}
  7374. */
  7375. this.clazz = null;
  7376. };
  7377. /**
  7378. * @alias ProtoBuf.Reflect.Service.prototype
  7379. * @inner
  7380. */
  7381. var ServicePrototype = Service.prototype = Object.create(Namespace.prototype);
  7382. /**
  7383. * Builds the service and returns the runtime counterpart, which is a fully functional class.
  7384. * @see ProtoBuf.Builder.Service
  7385. * @param {boolean=} rebuild Whether to rebuild or not
  7386. * @return {Function} Service class
  7387. * @throws {Error} If the message cannot be built
  7388. * @expose
  7389. */
  7390. ServicePrototype.build = function(rebuild) {
  7391. if (this.clazz && !rebuild)
  7392. return this.clazz;
  7393. // Create the runtime Service class in its own scope
  7394. return this.clazz = (function(ProtoBuf, T) {
  7395. /**
  7396. * Constructs a new runtime Service.
  7397. * @name ProtoBuf.Builder.Service
  7398. * @param {function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))=} rpcImpl RPC implementation receiving the method name and the message
  7399. * @class Barebone of all runtime services.
  7400. * @constructor
  7401. * @throws {Error} If the service cannot be created
  7402. */
  7403. var Service = function(rpcImpl) {
  7404. ProtoBuf.Builder.Service.call(this);
  7405. /**
  7406. * Service implementation.
  7407. * @name ProtoBuf.Builder.Service#rpcImpl
  7408. * @type {!function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))}
  7409. * @expose
  7410. */
  7411. this.rpcImpl = rpcImpl || function(name, msg, callback) {
  7412. // This is what a user has to implement: A function receiving the method name, the actual message to
  7413. // send (type checked) and the callback that's either provided with the error as its first
  7414. // argument or null and the actual response message.
  7415. setTimeout(callback.bind(this, Error("Not implemented, see: https://github.com/dcodeIO/ProtoBuf.js/wiki/Services")), 0); // Must be async!
  7416. };
  7417. };
  7418. /**
  7419. * @alias ProtoBuf.Builder.Service.prototype
  7420. * @inner
  7421. */
  7422. var ServicePrototype = Service.prototype = Object.create(ProtoBuf.Builder.Service.prototype);
  7423. /**
  7424. * Asynchronously performs an RPC call using the given RPC implementation.
  7425. * @name ProtoBuf.Builder.Service.[Method]
  7426. * @function
  7427. * @param {!function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))} rpcImpl RPC implementation
  7428. * @param {ProtoBuf.Builder.Message} req Request
  7429. * @param {function(Error, (ProtoBuf.Builder.Message|ByteBuffer|Buffer|string)=)} callback Callback receiving
  7430. * the error if any and the response either as a pre-parsed message or as its raw bytes
  7431. * @abstract
  7432. */
  7433. /**
  7434. * Asynchronously performs an RPC call using the instance's RPC implementation.
  7435. * @name ProtoBuf.Builder.Service#[Method]
  7436. * @function
  7437. * @param {ProtoBuf.Builder.Message} req Request
  7438. * @param {function(Error, (ProtoBuf.Builder.Message|ByteBuffer|Buffer|string)=)} callback Callback receiving
  7439. * the error if any and the response either as a pre-parsed message or as its raw bytes
  7440. * @abstract
  7441. */
  7442. var rpc = T.getChildren(ProtoBuf.Reflect.Service.RPCMethod);
  7443. for (var i=0; i<rpc.length; i++) {
  7444. (function(method) {
  7445. // service#Method(message, callback)
  7446. ServicePrototype[method.name] = function(req, callback) {
  7447. try {
  7448. try {
  7449. // If given as a buffer, decode the request. Will throw a TypeError if not a valid buffer.
  7450. req = method.resolvedRequestType.clazz.decode(ByteBuffer.wrap(req));
  7451. } catch (err) {
  7452. if (!(err instanceof TypeError))
  7453. throw err;
  7454. }
  7455. if (req === null || typeof req !== 'object')
  7456. throw Error("Illegal arguments");
  7457. if (!(req instanceof method.resolvedRequestType.clazz))
  7458. req = new method.resolvedRequestType.clazz(req);
  7459. this.rpcImpl(method.fqn(), req, function(err, res) { // Assumes that this is properly async
  7460. if (err) {
  7461. callback(err);
  7462. return;
  7463. }
  7464. // Coalesce to empty string when service response has empty content
  7465. if (res === null)
  7466. res = '';
  7467. try { res = method.resolvedResponseType.clazz.decode(res); } catch (notABuffer) {}
  7468. if (!res || !(res instanceof method.resolvedResponseType.clazz)) {
  7469. callback(Error("Illegal response type received in service method "+ T.name+"#"+method.name));
  7470. return;
  7471. }
  7472. callback(null, res);
  7473. });
  7474. } catch (err) {
  7475. setTimeout(callback.bind(this, err), 0);
  7476. }
  7477. };
  7478. // Service.Method(rpcImpl, message, callback)
  7479. Service[method.name] = function(rpcImpl, req, callback) {
  7480. new Service(rpcImpl)[method.name](req, callback);
  7481. };
  7482. if (Object.defineProperty)
  7483. Object.defineProperty(Service[method.name], "$options", { "value": method.buildOpt() }),
  7484. Object.defineProperty(ServicePrototype[method.name], "$options", { "value": Service[method.name]["$options"] });
  7485. })(rpc[i]);
  7486. }
  7487. if (Object.defineProperty)
  7488. Object.defineProperty(Service, "$options", { "value": T.buildOpt() }),
  7489. Object.defineProperty(ServicePrototype, "$options", { "value": Service["$options"] }),
  7490. Object.defineProperty(Service, "$type", { "value": T }),
  7491. Object.defineProperty(ServicePrototype, "$type", { "value": T });
  7492. return Service;
  7493. })(ProtoBuf, this);
  7494. };
  7495. /**
  7496. * @alias ProtoBuf.Reflect.Service
  7497. * @expose
  7498. */
  7499. Reflect.Service = Service;
  7500. /**
  7501. * Abstract service method.
  7502. * @exports ProtoBuf.Reflect.Service.Method
  7503. * @param {!ProtoBuf.Builder} builder Builder reference
  7504. * @param {!ProtoBuf.Reflect.Service} svc Service
  7505. * @param {string} name Method name
  7506. * @param {Object.<string,*>=} options Options
  7507. * @constructor
  7508. * @extends ProtoBuf.Reflect.T
  7509. */
  7510. var Method = function(builder, svc, name, options) {
  7511. T.call(this, builder, svc, name);
  7512. /**
  7513. * @override
  7514. */
  7515. this.className = "Service.Method";
  7516. /**
  7517. * Options.
  7518. * @type {Object.<string, *>}
  7519. * @expose
  7520. */
  7521. this.options = options || {};
  7522. };
  7523. /**
  7524. * @alias ProtoBuf.Reflect.Service.Method.prototype
  7525. * @inner
  7526. */
  7527. var MethodPrototype = Method.prototype = Object.create(T.prototype);
  7528. /**
  7529. * Builds the method's '$options' property.
  7530. * @name ProtoBuf.Reflect.Service.Method#buildOpt
  7531. * @function
  7532. * @return {Object.<string,*>}
  7533. */
  7534. MethodPrototype.buildOpt = NamespacePrototype.buildOpt;
  7535. /**
  7536. * @alias ProtoBuf.Reflect.Service.Method
  7537. * @expose
  7538. */
  7539. Reflect.Service.Method = Method;
  7540. /**
  7541. * RPC service method.
  7542. * @exports ProtoBuf.Reflect.Service.RPCMethod
  7543. * @param {!ProtoBuf.Builder} builder Builder reference
  7544. * @param {!ProtoBuf.Reflect.Service} svc Service
  7545. * @param {string} name Method name
  7546. * @param {string} request Request message name
  7547. * @param {string} response Response message name
  7548. * @param {boolean} request_stream Whether requests are streamed
  7549. * @param {boolean} response_stream Whether responses are streamed
  7550. * @param {Object.<string,*>=} options Options
  7551. * @constructor
  7552. * @extends ProtoBuf.Reflect.Service.Method
  7553. */
  7554. var RPCMethod = function(builder, svc, name, request, response, request_stream, response_stream, options) {
  7555. Method.call(this, builder, svc, name, options);
  7556. /**
  7557. * @override
  7558. */
  7559. this.className = "Service.RPCMethod";
  7560. /**
  7561. * Request message name.
  7562. * @type {string}
  7563. * @expose
  7564. */
  7565. this.requestName = request;
  7566. /**
  7567. * Response message name.
  7568. * @type {string}
  7569. * @expose
  7570. */
  7571. this.responseName = response;
  7572. /**
  7573. * Whether requests are streamed
  7574. * @type {bool}
  7575. * @expose
  7576. */
  7577. this.requestStream = request_stream;
  7578. /**
  7579. * Whether responses are streamed
  7580. * @type {bool}
  7581. * @expose
  7582. */
  7583. this.responseStream = response_stream;
  7584. /**
  7585. * Resolved request message type.
  7586. * @type {ProtoBuf.Reflect.Message}
  7587. * @expose
  7588. */
  7589. this.resolvedRequestType = null;
  7590. /**
  7591. * Resolved response message type.
  7592. * @type {ProtoBuf.Reflect.Message}
  7593. * @expose
  7594. */
  7595. this.resolvedResponseType = null;
  7596. };
  7597. // Extends Method
  7598. RPCMethod.prototype = Object.create(Method.prototype);
  7599. /**
  7600. * @alias ProtoBuf.Reflect.Service.RPCMethod
  7601. * @expose
  7602. */
  7603. Reflect.Service.RPCMethod = RPCMethod;
  7604. return Reflect;
  7605. })(ProtoBuf);
  7606. /**
  7607. * @alias ProtoBuf.Builder
  7608. * @expose
  7609. */
  7610. ProtoBuf.Builder = (function(ProtoBuf, Lang, Reflect) {
  7611. /**
  7612. * Constructs a new Builder.
  7613. * @exports ProtoBuf.Builder
  7614. * @class Provides the functionality to build protocol messages.
  7615. * @param {Object.<string,*>=} options Options
  7616. * @constructor
  7617. */
  7618. var Builder = function(options) {
  7619. /**
  7620. * Namespace.
  7621. * @type {ProtoBuf.Reflect.Namespace}
  7622. * @expose
  7623. */
  7624. this.ns = new Reflect.Namespace(this, null, ""); // Global namespace
  7625. /**
  7626. * Namespace pointer.
  7627. * @type {ProtoBuf.Reflect.T}
  7628. * @expose
  7629. */
  7630. this.ptr = this.ns;
  7631. /**
  7632. * Resolved flag.
  7633. * @type {boolean}
  7634. * @expose
  7635. */
  7636. this.resolved = false;
  7637. /**
  7638. * The current building result.
  7639. * @type {Object.<string,ProtoBuf.Builder.Message|Object>|null}
  7640. * @expose
  7641. */
  7642. this.result = null;
  7643. /**
  7644. * Imported files.
  7645. * @type {Array.<string>}
  7646. * @expose
  7647. */
  7648. this.files = {};
  7649. /**
  7650. * Import root override.
  7651. * @type {?string}
  7652. * @expose
  7653. */
  7654. this.importRoot = null;
  7655. /**
  7656. * Options.
  7657. * @type {!Object.<string, *>}
  7658. * @expose
  7659. */
  7660. this.options = options || {};
  7661. };
  7662. /**
  7663. * @alias ProtoBuf.Builder.prototype
  7664. * @inner
  7665. */
  7666. var BuilderPrototype = Builder.prototype;
  7667. // ----- Definition tests -----
  7668. /**
  7669. * Tests if a definition most likely describes a message.
  7670. * @param {!Object} def
  7671. * @returns {boolean}
  7672. * @expose
  7673. */
  7674. Builder.isMessage = function(def) {
  7675. // Messages require a string name
  7676. if (typeof def["name"] !== 'string')
  7677. return false;
  7678. // Messages do not contain values (enum) or rpc methods (service)
  7679. if (typeof def["values"] !== 'undefined' || typeof def["rpc"] !== 'undefined')
  7680. return false;
  7681. return true;
  7682. };
  7683. /**
  7684. * Tests if a definition most likely describes a message field.
  7685. * @param {!Object} def
  7686. * @returns {boolean}
  7687. * @expose
  7688. */
  7689. Builder.isMessageField = function(def) {
  7690. // Message fields require a string rule, name and type and an id
  7691. if (typeof def["rule"] !== 'string' || typeof def["name"] !== 'string' || typeof def["type"] !== 'string' || typeof def["id"] === 'undefined')
  7692. return false;
  7693. return true;
  7694. };
  7695. /**
  7696. * Tests if a definition most likely describes an enum.
  7697. * @param {!Object} def
  7698. * @returns {boolean}
  7699. * @expose
  7700. */
  7701. Builder.isEnum = function(def) {
  7702. // Enums require a string name
  7703. if (typeof def["name"] !== 'string')
  7704. return false;
  7705. // Enums require at least one value
  7706. if (typeof def["values"] === 'undefined' || !Array.isArray(def["values"]) || def["values"].length === 0)
  7707. return false;
  7708. return true;
  7709. };
  7710. /**
  7711. * Tests if a definition most likely describes a service.
  7712. * @param {!Object} def
  7713. * @returns {boolean}
  7714. * @expose
  7715. */
  7716. Builder.isService = function(def) {
  7717. // Services require a string name and an rpc object
  7718. if (typeof def["name"] !== 'string' || typeof def["rpc"] !== 'object' || !def["rpc"])
  7719. return false;
  7720. return true;
  7721. };
  7722. /**
  7723. * Tests if a definition most likely describes an extended message
  7724. * @param {!Object} def
  7725. * @returns {boolean}
  7726. * @expose
  7727. */
  7728. Builder.isExtend = function(def) {
  7729. // Extends rquire a string ref
  7730. if (typeof def["ref"] !== 'string')
  7731. return false;
  7732. return true;
  7733. };
  7734. // ----- Building -----
  7735. /**
  7736. * Resets the pointer to the root namespace.
  7737. * @returns {!ProtoBuf.Builder} this
  7738. * @expose
  7739. */
  7740. BuilderPrototype.reset = function() {
  7741. this.ptr = this.ns;
  7742. return this;
  7743. };
  7744. /**
  7745. * Defines a namespace on top of the current pointer position and places the pointer on it.
  7746. * @param {string} namespace
  7747. * @return {!ProtoBuf.Builder} this
  7748. * @expose
  7749. */
  7750. BuilderPrototype.define = function(namespace) {
  7751. if (typeof namespace !== 'string' || !Lang.TYPEREF.test(namespace))
  7752. throw Error("illegal namespace: "+namespace);
  7753. namespace.split(".").forEach(function(part) {
  7754. var ns = this.ptr.getChild(part);
  7755. if (ns === null) // Keep existing
  7756. this.ptr.addChild(ns = new Reflect.Namespace(this, this.ptr, part));
  7757. this.ptr = ns;
  7758. }, this);
  7759. return this;
  7760. };
  7761. /**
  7762. * Creates the specified definitions at the current pointer position.
  7763. * @param {!Array.<!Object>} defs Messages, enums or services to create
  7764. * @returns {!ProtoBuf.Builder} this
  7765. * @throws {Error} If a message definition is invalid
  7766. * @expose
  7767. */
  7768. BuilderPrototype.create = function(defs) {
  7769. if (!defs)
  7770. return this; // Nothing to create
  7771. if (!Array.isArray(defs))
  7772. defs = [defs];
  7773. else {
  7774. if (defs.length === 0)
  7775. return this;
  7776. defs = defs.slice();
  7777. }
  7778. // It's quite hard to keep track of scopes and memory here, so let's do this iteratively.
  7779. var stack = [defs];
  7780. while (stack.length > 0) {
  7781. defs = stack.pop();
  7782. if (!Array.isArray(defs)) // Stack always contains entire namespaces
  7783. throw Error("not a valid namespace: "+JSON.stringify(defs));
  7784. while (defs.length > 0) {
  7785. var def = defs.shift(); // Namespaces always contain an array of messages, enums and services
  7786. if (Builder.isMessage(def)) {
  7787. var obj = new Reflect.Message(this, this.ptr, def["name"], def["options"], def["isGroup"], def["syntax"]);
  7788. // Create OneOfs
  7789. var oneofs = {};
  7790. if (def["oneofs"])
  7791. Object.keys(def["oneofs"]).forEach(function(name) {
  7792. obj.addChild(oneofs[name] = new Reflect.Message.OneOf(this, obj, name));
  7793. }, this);
  7794. // Create fields
  7795. if (def["fields"])
  7796. def["fields"].forEach(function(fld) {
  7797. if (obj.getChild(fld["id"]|0) !== null)
  7798. throw Error("duplicate or invalid field id in "+obj.name+": "+fld['id']);
  7799. if (fld["options"] && typeof fld["options"] !== 'object')
  7800. throw Error("illegal field options in "+obj.name+"#"+fld["name"]);
  7801. var oneof = null;
  7802. if (typeof fld["oneof"] === 'string' && !(oneof = oneofs[fld["oneof"]]))
  7803. throw Error("illegal oneof in "+obj.name+"#"+fld["name"]+": "+fld["oneof"]);
  7804. fld = new Reflect.Message.Field(this, obj, fld["rule"], fld["keytype"], fld["type"], fld["name"], fld["id"], fld["options"], oneof, def["syntax"]);
  7805. if (oneof)
  7806. oneof.fields.push(fld);
  7807. obj.addChild(fld);
  7808. }, this);
  7809. // Push children to stack
  7810. var subObj = [];
  7811. if (def["enums"])
  7812. def["enums"].forEach(function(enm) {
  7813. subObj.push(enm);
  7814. });
  7815. if (def["messages"])
  7816. def["messages"].forEach(function(msg) {
  7817. subObj.push(msg);
  7818. });
  7819. if (def["services"])
  7820. def["services"].forEach(function(svc) {
  7821. subObj.push(svc);
  7822. });
  7823. // Set extension ranges
  7824. if (def["extensions"]) {
  7825. if (typeof def["extensions"][0] === 'number') // pre 5.0.1
  7826. obj.extensions = [ def["extensions"] ];
  7827. else
  7828. obj.extensions = def["extensions"];
  7829. }
  7830. // Create on top of current namespace
  7831. this.ptr.addChild(obj);
  7832. if (subObj.length > 0) {
  7833. stack.push(defs); // Push the current level back
  7834. defs = subObj; // Continue processing sub level
  7835. subObj = null;
  7836. this.ptr = obj; // And move the pointer to this namespace
  7837. obj = null;
  7838. continue;
  7839. }
  7840. subObj = null;
  7841. } else if (Builder.isEnum(def)) {
  7842. obj = new Reflect.Enum(this, this.ptr, def["name"], def["options"], def["syntax"]);
  7843. def["values"].forEach(function(val) {
  7844. obj.addChild(new Reflect.Enum.Value(this, obj, val["name"], val["id"]));
  7845. }, this);
  7846. this.ptr.addChild(obj);
  7847. } else if (Builder.isService(def)) {
  7848. obj = new Reflect.Service(this, this.ptr, def["name"], def["options"]);
  7849. Object.keys(def["rpc"]).forEach(function(name) {
  7850. var mtd = def["rpc"][name];
  7851. obj.addChild(new Reflect.Service.RPCMethod(this, obj, name, mtd["request"], mtd["response"], !!mtd["request_stream"], !!mtd["response_stream"], mtd["options"]));
  7852. }, this);
  7853. this.ptr.addChild(obj);
  7854. } else if (Builder.isExtend(def)) {
  7855. obj = this.ptr.resolve(def["ref"], true);
  7856. if (obj) {
  7857. def["fields"].forEach(function(fld) {
  7858. if (obj.getChild(fld['id']|0) !== null)
  7859. throw Error("duplicate extended field id in "+obj.name+": "+fld['id']);
  7860. // Check if field id is allowed to be extended
  7861. if (obj.extensions) {
  7862. var valid = false;
  7863. obj.extensions.forEach(function(range) {
  7864. if (fld["id"] >= range[0] && fld["id"] <= range[1])
  7865. valid = true;
  7866. });
  7867. if (!valid)
  7868. throw Error("illegal extended field id in "+obj.name+": "+fld['id']+" (not within valid ranges)");
  7869. }
  7870. // Convert extension field names to camel case notation if the override is set
  7871. var name = fld["name"];
  7872. if (this.options['convertFieldsToCamelCase'])
  7873. name = ProtoBuf.Util.toCamelCase(name);
  7874. // see #161: Extensions use their fully qualified name as their runtime key and...
  7875. var field = new Reflect.Message.ExtensionField(this, obj, fld["rule"], fld["type"], this.ptr.fqn()+'.'+name, fld["id"], fld["options"]);
  7876. // ...are added on top of the current namespace as an extension which is used for
  7877. // resolving their type later on (the extension always keeps the original name to
  7878. // prevent naming collisions)
  7879. var ext = new Reflect.Extension(this, this.ptr, fld["name"], field);
  7880. field.extension = ext;
  7881. this.ptr.addChild(ext);
  7882. obj.addChild(field);
  7883. }, this);
  7884. } else if (!/\.?google\.protobuf\./.test(def["ref"])) // Silently skip internal extensions
  7885. throw Error("extended message "+def["ref"]+" is not defined");
  7886. } else
  7887. throw Error("not a valid definition: "+JSON.stringify(def));
  7888. def = null;
  7889. obj = null;
  7890. }
  7891. // Break goes here
  7892. defs = null;
  7893. this.ptr = this.ptr.parent; // Namespace done, continue at parent
  7894. }
  7895. this.resolved = false; // Require re-resolve
  7896. this.result = null; // Require re-build
  7897. return this;
  7898. };
  7899. /**
  7900. * Propagates syntax to all children.
  7901. * @param {!Object} parent
  7902. * @inner
  7903. */
  7904. function propagateSyntax(parent) {
  7905. if (parent['messages']) {
  7906. parent['messages'].forEach(function(child) {
  7907. child["syntax"] = parent["syntax"];
  7908. propagateSyntax(child);
  7909. });
  7910. }
  7911. if (parent['enums']) {
  7912. parent['enums'].forEach(function(child) {
  7913. child["syntax"] = parent["syntax"];
  7914. });
  7915. }
  7916. }
  7917. /**
  7918. * Imports another definition into this builder.
  7919. * @param {Object.<string,*>} json Parsed import
  7920. * @param {(string|{root: string, file: string})=} filename Imported file name
  7921. * @returns {!ProtoBuf.Builder} this
  7922. * @throws {Error} If the definition or file cannot be imported
  7923. * @expose
  7924. */
  7925. BuilderPrototype["import"] = function(json, filename) {
  7926. var delim = '/';
  7927. // Make sure to skip duplicate imports
  7928. if (typeof filename === 'string') {
  7929. if (ProtoBuf.Util.IS_NODE)
  7930. filename = require$$2['resolve'](filename);
  7931. if (this.files[filename] === true)
  7932. return this.reset();
  7933. this.files[filename] = true;
  7934. } else if (typeof filename === 'object') { // Object with root, file.
  7935. var root = filename.root;
  7936. if (ProtoBuf.Util.IS_NODE)
  7937. root = require$$2['resolve'](root);
  7938. if (root.indexOf("\\") >= 0 || filename.file.indexOf("\\") >= 0)
  7939. delim = '\\';
  7940. var fname;
  7941. if (ProtoBuf.Util.IS_NODE)
  7942. fname = require$$2['join'](root, filename.file);
  7943. else
  7944. fname = root + delim + filename.file;
  7945. if (this.files[fname] === true)
  7946. return this.reset();
  7947. this.files[fname] = true;
  7948. }
  7949. // Import imports
  7950. if (json['imports'] && json['imports'].length > 0) {
  7951. var importRoot,
  7952. resetRoot = false;
  7953. if (typeof filename === 'object') { // If an import root is specified, override
  7954. this.importRoot = filename["root"]; resetRoot = true; // ... and reset afterwards
  7955. importRoot = this.importRoot;
  7956. filename = filename["file"];
  7957. if (importRoot.indexOf("\\") >= 0 || filename.indexOf("\\") >= 0)
  7958. delim = '\\';
  7959. } else if (typeof filename === 'string') {
  7960. if (this.importRoot) // If import root is overridden, use it
  7961. importRoot = this.importRoot;
  7962. else { // Otherwise compute from filename
  7963. if (filename.indexOf("/") >= 0) { // Unix
  7964. importRoot = filename.replace(/\/[^\/]*$/, "");
  7965. if (/* /file.proto */ importRoot === "")
  7966. importRoot = "/";
  7967. } else if (filename.indexOf("\\") >= 0) { // Windows
  7968. importRoot = filename.replace(/\\[^\\]*$/, "");
  7969. delim = '\\';
  7970. } else
  7971. importRoot = ".";
  7972. }
  7973. } else
  7974. importRoot = null;
  7975. for (var i=0; i<json['imports'].length; i++) {
  7976. if (typeof json['imports'][i] === 'string') { // Import file
  7977. if (!importRoot)
  7978. throw Error("cannot determine import root");
  7979. var importFilename = json['imports'][i];
  7980. if (importFilename === "google/protobuf/descriptor.proto")
  7981. continue; // Not needed and therefore not used
  7982. if (ProtoBuf.Util.IS_NODE)
  7983. importFilename = require$$2['join'](importRoot, importFilename);
  7984. else
  7985. importFilename = importRoot + delim + importFilename;
  7986. if (this.files[importFilename] === true)
  7987. continue; // Already imported
  7988. if (/\.proto$/i.test(importFilename) && !ProtoBuf.DotProto) // If this is a light build
  7989. importFilename = importFilename.replace(/\.proto$/, ".json"); // always load the JSON file
  7990. var contents = ProtoBuf.Util.fetch(importFilename);
  7991. if (contents === null)
  7992. throw Error("failed to import '"+importFilename+"' in '"+filename+"': file not found");
  7993. if (/\.json$/i.test(importFilename)) // Always possible
  7994. this["import"](JSON.parse(contents+""), importFilename); // May throw
  7995. else
  7996. this["import"](ProtoBuf.DotProto.Parser.parse(contents), importFilename); // May throw
  7997. } else // Import structure
  7998. if (!filename)
  7999. this["import"](json['imports'][i]);
  8000. else if (/\.(\w+)$/.test(filename)) // With extension: Append _importN to the name portion to make it unique
  8001. this["import"](json['imports'][i], filename.replace(/^(.+)\.(\w+)$/, function($0, $1, $2) { return $1+"_import"+i+"."+$2; }));
  8002. else // Without extension: Append _importN to make it unique
  8003. this["import"](json['imports'][i], filename+"_import"+i);
  8004. }
  8005. if (resetRoot) // Reset import root override when all imports are done
  8006. this.importRoot = null;
  8007. }
  8008. // Import structures
  8009. if (json['package'])
  8010. this.define(json['package']);
  8011. if (json['syntax'])
  8012. propagateSyntax(json);
  8013. var base = this.ptr;
  8014. if (json['options'])
  8015. Object.keys(json['options']).forEach(function(key) {
  8016. base.options[key] = json['options'][key];
  8017. });
  8018. if (json['messages'])
  8019. this.create(json['messages']),
  8020. this.ptr = base;
  8021. if (json['enums'])
  8022. this.create(json['enums']),
  8023. this.ptr = base;
  8024. if (json['services'])
  8025. this.create(json['services']),
  8026. this.ptr = base;
  8027. if (json['extends'])
  8028. this.create(json['extends']);
  8029. return this.reset();
  8030. };
  8031. /**
  8032. * Resolves all namespace objects.
  8033. * @throws {Error} If a type cannot be resolved
  8034. * @returns {!ProtoBuf.Builder} this
  8035. * @expose
  8036. */
  8037. BuilderPrototype.resolveAll = function() {
  8038. // Resolve all reflected objects
  8039. var res;
  8040. if (this.ptr == null || typeof this.ptr.type === 'object')
  8041. return this; // Done (already resolved)
  8042. if (this.ptr instanceof Reflect.Namespace) { // Resolve children
  8043. this.ptr.children.forEach(function(child) {
  8044. this.ptr = child;
  8045. this.resolveAll();
  8046. }, this);
  8047. } else if (this.ptr instanceof Reflect.Message.Field) { // Resolve type
  8048. if (!Lang.TYPE.test(this.ptr.type)) {
  8049. if (!Lang.TYPEREF.test(this.ptr.type))
  8050. throw Error("illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.type);
  8051. res = (this.ptr instanceof Reflect.Message.ExtensionField ? this.ptr.extension.parent : this.ptr.parent).resolve(this.ptr.type, true);
  8052. if (!res)
  8053. throw Error("unresolvable type reference in "+this.ptr.toString(true)+": "+this.ptr.type);
  8054. this.ptr.resolvedType = res;
  8055. if (res instanceof Reflect.Enum) {
  8056. this.ptr.type = ProtoBuf.TYPES["enum"];
  8057. if (this.ptr.syntax === 'proto3' && res.syntax !== 'proto3')
  8058. throw Error("proto3 message cannot reference proto2 enum");
  8059. }
  8060. else if (res instanceof Reflect.Message)
  8061. this.ptr.type = res.isGroup ? ProtoBuf.TYPES["group"] : ProtoBuf.TYPES["message"];
  8062. else
  8063. throw Error("illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.type);
  8064. } else
  8065. this.ptr.type = ProtoBuf.TYPES[this.ptr.type];
  8066. // If it's a map field, also resolve the key type. The key type can be only a numeric, string, or bool type
  8067. // (i.e., no enums or messages), so we don't need to resolve against the current namespace.
  8068. if (this.ptr.map) {
  8069. if (!Lang.TYPE.test(this.ptr.keyType))
  8070. throw Error("illegal key type for map field in "+this.ptr.toString(true)+": "+this.ptr.keyType);
  8071. this.ptr.keyType = ProtoBuf.TYPES[this.ptr.keyType];
  8072. }
  8073. // If it's a repeated and packable field then proto3 mandates it should be packed by
  8074. // default
  8075. if (
  8076. this.ptr.syntax === 'proto3' &&
  8077. this.ptr.repeated && this.ptr.options.packed === undefined &&
  8078. ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.ptr.type.wireType) !== -1
  8079. ) {
  8080. this.ptr.options.packed = true;
  8081. }
  8082. } else if (this.ptr instanceof ProtoBuf.Reflect.Service.Method) {
  8083. if (this.ptr instanceof ProtoBuf.Reflect.Service.RPCMethod) {
  8084. res = this.ptr.parent.resolve(this.ptr.requestName, true);
  8085. if (!res || !(res instanceof ProtoBuf.Reflect.Message))
  8086. throw Error("Illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.requestName);
  8087. this.ptr.resolvedRequestType = res;
  8088. res = this.ptr.parent.resolve(this.ptr.responseName, true);
  8089. if (!res || !(res instanceof ProtoBuf.Reflect.Message))
  8090. throw Error("Illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.responseName);
  8091. this.ptr.resolvedResponseType = res;
  8092. } else // Should not happen as nothing else is implemented
  8093. throw Error("illegal service type in "+this.ptr.toString(true));
  8094. } else if (
  8095. !(this.ptr instanceof ProtoBuf.Reflect.Message.OneOf) && // Not built
  8096. !(this.ptr instanceof ProtoBuf.Reflect.Extension) && // Not built
  8097. !(this.ptr instanceof ProtoBuf.Reflect.Enum.Value) // Built in enum
  8098. )
  8099. throw Error("illegal object in namespace: "+typeof(this.ptr)+": "+this.ptr);
  8100. return this.reset();
  8101. };
  8102. /**
  8103. * Builds the protocol. This will first try to resolve all definitions and, if this has been successful,
  8104. * return the built package.
  8105. * @param {(string|Array.<string>)=} path Specifies what to return. If omitted, the entire namespace will be returned.
  8106. * @returns {!ProtoBuf.Builder.Message|!Object.<string,*>}
  8107. * @throws {Error} If a type could not be resolved
  8108. * @expose
  8109. */
  8110. BuilderPrototype.build = function(path) {
  8111. this.reset();
  8112. if (!this.resolved)
  8113. this.resolveAll(),
  8114. this.resolved = true,
  8115. this.result = null; // Require re-build
  8116. if (this.result === null) // (Re-)Build
  8117. this.result = this.ns.build();
  8118. if (!path)
  8119. return this.result;
  8120. var part = typeof path === 'string' ? path.split(".") : path,
  8121. ptr = this.result; // Build namespace pointer (no hasChild etc.)
  8122. for (var i=0; i<part.length; i++)
  8123. if (ptr[part[i]])
  8124. ptr = ptr[part[i]];
  8125. else {
  8126. ptr = null;
  8127. break;
  8128. }
  8129. return ptr;
  8130. };
  8131. /**
  8132. * Similar to {@link ProtoBuf.Builder#build}, but looks up the internal reflection descriptor.
  8133. * @param {string=} path Specifies what to return. If omitted, the entire namespace wiil be returned.
  8134. * @param {boolean=} excludeNonNamespace Excludes non-namespace types like fields, defaults to `false`
  8135. * @returns {?ProtoBuf.Reflect.T} Reflection descriptor or `null` if not found
  8136. */
  8137. BuilderPrototype.lookup = function(path, excludeNonNamespace) {
  8138. return path ? this.ns.resolve(path, excludeNonNamespace) : this.ns;
  8139. };
  8140. /**
  8141. * Returns a string representation of this object.
  8142. * @return {string} String representation as of "Builder"
  8143. * @expose
  8144. */
  8145. BuilderPrototype.toString = function() {
  8146. return "Builder";
  8147. };
  8148. // ----- Base classes -----
  8149. // Exist for the sole purpose of being able to "... instanceof ProtoBuf.Builder.Message" etc.
  8150. /**
  8151. * @alias ProtoBuf.Builder.Message
  8152. */
  8153. Builder.Message = function() {};
  8154. /**
  8155. * @alias ProtoBuf.Builder.Enum
  8156. */
  8157. Builder.Enum = function() {};
  8158. /**
  8159. * @alias ProtoBuf.Builder.Message
  8160. */
  8161. Builder.Service = function() {};
  8162. return Builder;
  8163. })(ProtoBuf, ProtoBuf.Lang, ProtoBuf.Reflect);
  8164. /**
  8165. * @alias ProtoBuf.Map
  8166. * @expose
  8167. */
  8168. ProtoBuf.Map = (function(ProtoBuf, Reflect) {
  8169. /**
  8170. * Constructs a new Map. A Map is a container that is used to implement map
  8171. * fields on message objects. It closely follows the ES6 Map API; however,
  8172. * it is distinct because we do not want to depend on external polyfills or
  8173. * on ES6 itself.
  8174. *
  8175. * @exports ProtoBuf.Map
  8176. * @param {!ProtoBuf.Reflect.Field} field Map field
  8177. * @param {Object.<string,*>=} contents Initial contents
  8178. * @constructor
  8179. */
  8180. var Map = function(field, contents) {
  8181. if (!field.map)
  8182. throw Error("field is not a map");
  8183. /**
  8184. * The field corresponding to this map.
  8185. * @type {!ProtoBuf.Reflect.Field}
  8186. */
  8187. this.field = field;
  8188. /**
  8189. * Element instance corresponding to key type.
  8190. * @type {!ProtoBuf.Reflect.Element}
  8191. */
  8192. this.keyElem = new Reflect.Element(field.keyType, null, true, field.syntax);
  8193. /**
  8194. * Element instance corresponding to value type.
  8195. * @type {!ProtoBuf.Reflect.Element}
  8196. */
  8197. this.valueElem = new Reflect.Element(field.type, field.resolvedType, false, field.syntax);
  8198. /**
  8199. * Internal map: stores mapping of (string form of key) -> (key, value)
  8200. * pair.
  8201. *
  8202. * We provide map semantics for arbitrary key types, but we build on top
  8203. * of an Object, which has only string keys. In order to avoid the need
  8204. * to convert a string key back to its native type in many situations,
  8205. * we store the native key value alongside the value. Thus, we only need
  8206. * a one-way mapping from a key type to its string form that guarantees
  8207. * uniqueness and equality (i.e., str(K1) === str(K2) if and only if K1
  8208. * === K2).
  8209. *
  8210. * @type {!Object<string, {key: *, value: *}>}
  8211. */
  8212. this.map = {};
  8213. /**
  8214. * Returns the number of elements in the map.
  8215. */
  8216. Object.defineProperty(this, "size", {
  8217. get: function() { return Object.keys(this.map).length; }
  8218. });
  8219. // Fill initial contents from a raw object.
  8220. if (contents) {
  8221. var keys = Object.keys(contents);
  8222. for (var i = 0; i < keys.length; i++) {
  8223. var key = this.keyElem.valueFromString(keys[i]);
  8224. var val = this.valueElem.verifyValue(contents[keys[i]]);
  8225. this.map[this.keyElem.valueToString(key)] =
  8226. { key: key, value: val };
  8227. }
  8228. }
  8229. };
  8230. var MapPrototype = Map.prototype;
  8231. /**
  8232. * Helper: return an iterator over an array.
  8233. * @param {!Array<*>} arr the array
  8234. * @returns {!Object} an iterator
  8235. * @inner
  8236. */
  8237. function arrayIterator(arr) {
  8238. var idx = 0;
  8239. return {
  8240. next: function() {
  8241. if (idx < arr.length)
  8242. return { done: false, value: arr[idx++] };
  8243. return { done: true };
  8244. }
  8245. }
  8246. }
  8247. /**
  8248. * Clears the map.
  8249. */
  8250. MapPrototype.clear = function() {
  8251. this.map = {};
  8252. };
  8253. /**
  8254. * Deletes a particular key from the map.
  8255. * @returns {boolean} Whether any entry with this key was deleted.
  8256. */
  8257. MapPrototype["delete"] = function(key) {
  8258. var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));
  8259. var hadKey = keyValue in this.map;
  8260. delete this.map[keyValue];
  8261. return hadKey;
  8262. };
  8263. /**
  8264. * Returns an iterator over [key, value] pairs in the map.
  8265. * @returns {Object} The iterator
  8266. */
  8267. MapPrototype.entries = function() {
  8268. var entries = [];
  8269. var strKeys = Object.keys(this.map);
  8270. for (var i = 0, entry; i < strKeys.length; i++)
  8271. entries.push([(entry=this.map[strKeys[i]]).key, entry.value]);
  8272. return arrayIterator(entries);
  8273. };
  8274. /**
  8275. * Returns an iterator over keys in the map.
  8276. * @returns {Object} The iterator
  8277. */
  8278. MapPrototype.keys = function() {
  8279. var keys = [];
  8280. var strKeys = Object.keys(this.map);
  8281. for (var i = 0; i < strKeys.length; i++)
  8282. keys.push(this.map[strKeys[i]].key);
  8283. return arrayIterator(keys);
  8284. };
  8285. /**
  8286. * Returns an iterator over values in the map.
  8287. * @returns {!Object} The iterator
  8288. */
  8289. MapPrototype.values = function() {
  8290. var values = [];
  8291. var strKeys = Object.keys(this.map);
  8292. for (var i = 0; i < strKeys.length; i++)
  8293. values.push(this.map[strKeys[i]].value);
  8294. return arrayIterator(values);
  8295. };
  8296. /**
  8297. * Iterates over entries in the map, calling a function on each.
  8298. * @param {function(this:*, *, *, *)} cb The callback to invoke with value, key, and map arguments.
  8299. * @param {Object=} thisArg The `this` value for the callback
  8300. */
  8301. MapPrototype.forEach = function(cb, thisArg) {
  8302. var strKeys = Object.keys(this.map);
  8303. for (var i = 0, entry; i < strKeys.length; i++)
  8304. cb.call(thisArg, (entry=this.map[strKeys[i]]).value, entry.key, this);
  8305. };
  8306. /**
  8307. * Sets a key in the map to the given value.
  8308. * @param {*} key The key
  8309. * @param {*} value The value
  8310. * @returns {!ProtoBuf.Map} The map instance
  8311. */
  8312. MapPrototype.set = function(key, value) {
  8313. var keyValue = this.keyElem.verifyValue(key);
  8314. var valValue = this.valueElem.verifyValue(value);
  8315. this.map[this.keyElem.valueToString(keyValue)] =
  8316. { key: keyValue, value: valValue };
  8317. return this;
  8318. };
  8319. /**
  8320. * Gets the value corresponding to a key in the map.
  8321. * @param {*} key The key
  8322. * @returns {*|undefined} The value, or `undefined` if key not present
  8323. */
  8324. MapPrototype.get = function(key) {
  8325. var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));
  8326. if (!(keyValue in this.map))
  8327. return undefined;
  8328. return this.map[keyValue].value;
  8329. };
  8330. /**
  8331. * Determines whether the given key is present in the map.
  8332. * @param {*} key The key
  8333. * @returns {boolean} `true` if the key is present
  8334. */
  8335. MapPrototype.has = function(key) {
  8336. var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));
  8337. return (keyValue in this.map);
  8338. };
  8339. return Map;
  8340. })(ProtoBuf, ProtoBuf.Reflect);
  8341. /**
  8342. * Constructs a new empty Builder.
  8343. * @param {Object.<string,*>=} options Builder options, defaults to global options set on ProtoBuf
  8344. * @return {!ProtoBuf.Builder} Builder
  8345. * @expose
  8346. */
  8347. ProtoBuf.newBuilder = function(options) {
  8348. options = options || {};
  8349. if (typeof options['convertFieldsToCamelCase'] === 'undefined')
  8350. options['convertFieldsToCamelCase'] = ProtoBuf.convertFieldsToCamelCase;
  8351. if (typeof options['populateAccessors'] === 'undefined')
  8352. options['populateAccessors'] = ProtoBuf.populateAccessors;
  8353. return new ProtoBuf.Builder(options);
  8354. };
  8355. /**
  8356. * Loads a .json definition and returns the Builder.
  8357. * @param {!*|string} json JSON definition
  8358. * @param {(ProtoBuf.Builder|string|{root: string, file: string})=} builder Builder to append to. Will create a new one if omitted.
  8359. * @param {(string|{root: string, file: string})=} filename The corresponding file name if known. Must be specified for imports.
  8360. * @return {ProtoBuf.Builder} Builder to create new messages
  8361. * @throws {Error} If the definition cannot be parsed or built
  8362. * @expose
  8363. */
  8364. ProtoBuf.loadJson = function(json, builder, filename) {
  8365. if (typeof builder === 'string' || (builder && typeof builder["file"] === 'string' && typeof builder["root"] === 'string'))
  8366. filename = builder,
  8367. builder = null;
  8368. if (!builder || typeof builder !== 'object')
  8369. builder = ProtoBuf.newBuilder();
  8370. if (typeof json === 'string')
  8371. json = JSON.parse(json);
  8372. builder["import"](json, filename);
  8373. builder.resolveAll();
  8374. return builder;
  8375. };
  8376. /**
  8377. * Loads a .json file and returns the Builder.
  8378. * @param {string|!{root: string, file: string}} filename Path to json file or an object specifying 'file' with
  8379. * an overridden 'root' path for all imported files.
  8380. * @param {function(?Error, !ProtoBuf.Builder=)=} callback Callback that will receive `null` as the first and
  8381. * the Builder as its second argument on success, otherwise the error as its first argument. If omitted, the
  8382. * file will be read synchronously and this function will return the Builder.
  8383. * @param {ProtoBuf.Builder=} builder Builder to append to. Will create a new one if omitted.
  8384. * @return {?ProtoBuf.Builder|undefined} The Builder if synchronous (no callback specified, will be NULL if the
  8385. * request has failed), else undefined
  8386. * @expose
  8387. */
  8388. ProtoBuf.loadJsonFile = function(filename, callback, builder) {
  8389. if (callback && typeof callback === 'object')
  8390. builder = callback,
  8391. callback = null;
  8392. else if (!callback || typeof callback !== 'function')
  8393. callback = null;
  8394. if (callback)
  8395. return ProtoBuf.Util.fetch(typeof filename === 'string' ? filename : filename["root"]+"/"+filename["file"], function(contents) {
  8396. if (contents === null) {
  8397. callback(Error("Failed to fetch file"));
  8398. return;
  8399. }
  8400. try {
  8401. callback(null, ProtoBuf.loadJson(JSON.parse(contents), builder, filename));
  8402. } catch (e) {
  8403. callback(e);
  8404. }
  8405. });
  8406. var contents = ProtoBuf.Util.fetch(typeof filename === 'object' ? filename["root"]+"/"+filename["file"] : filename);
  8407. return contents === null ? null : ProtoBuf.loadJson(JSON.parse(contents), builder, filename);
  8408. };
  8409. return ProtoBuf;
  8410. });
  8411. });
  8412. var messageCompiled = protobufLight.newBuilder({})['import']({
  8413. package: 'push_server.messages2',
  8414. syntax: 'proto2',
  8415. options: {
  8416. objc_class_prefix: 'AVIM'
  8417. },
  8418. messages: [{
  8419. name: 'JsonObjectMessage',
  8420. syntax: 'proto2',
  8421. fields: [{
  8422. rule: 'required',
  8423. type: 'string',
  8424. name: 'data',
  8425. id: 1
  8426. }]
  8427. }, {
  8428. name: 'UnreadTuple',
  8429. syntax: 'proto2',
  8430. fields: [{
  8431. rule: 'required',
  8432. type: 'string',
  8433. name: 'cid',
  8434. id: 1
  8435. }, {
  8436. rule: 'required',
  8437. type: 'int32',
  8438. name: 'unread',
  8439. id: 2
  8440. }, {
  8441. rule: 'optional',
  8442. type: 'string',
  8443. name: 'mid',
  8444. id: 3
  8445. }, {
  8446. rule: 'optional',
  8447. type: 'int64',
  8448. name: 'timestamp',
  8449. id: 4
  8450. }, {
  8451. rule: 'optional',
  8452. type: 'string',
  8453. name: 'from',
  8454. id: 5
  8455. }, {
  8456. rule: 'optional',
  8457. type: 'string',
  8458. name: 'data',
  8459. id: 6
  8460. }, {
  8461. rule: 'optional',
  8462. type: 'int64',
  8463. name: 'patchTimestamp',
  8464. id: 7
  8465. }, {
  8466. rule: 'optional',
  8467. type: 'bool',
  8468. name: 'mentioned',
  8469. id: 8
  8470. }, {
  8471. rule: 'optional',
  8472. type: 'bytes',
  8473. name: 'binaryMsg',
  8474. id: 9
  8475. }, {
  8476. rule: 'optional',
  8477. type: 'int32',
  8478. name: 'convType',
  8479. id: 10
  8480. }]
  8481. }, {
  8482. name: 'LogItem',
  8483. syntax: 'proto2',
  8484. fields: [{
  8485. rule: 'optional',
  8486. type: 'string',
  8487. name: 'from',
  8488. id: 1
  8489. }, {
  8490. rule: 'optional',
  8491. type: 'string',
  8492. name: 'data',
  8493. id: 2
  8494. }, {
  8495. rule: 'optional',
  8496. type: 'int64',
  8497. name: 'timestamp',
  8498. id: 3
  8499. }, {
  8500. rule: 'optional',
  8501. type: 'string',
  8502. name: 'msgId',
  8503. id: 4
  8504. }, {
  8505. rule: 'optional',
  8506. type: 'int64',
  8507. name: 'ackAt',
  8508. id: 5
  8509. }, {
  8510. rule: 'optional',
  8511. type: 'int64',
  8512. name: 'readAt',
  8513. id: 6
  8514. }, {
  8515. rule: 'optional',
  8516. type: 'int64',
  8517. name: 'patchTimestamp',
  8518. id: 7
  8519. }, {
  8520. rule: 'optional',
  8521. type: 'bool',
  8522. name: 'mentionAll',
  8523. id: 8
  8524. }, {
  8525. rule: 'repeated',
  8526. type: 'string',
  8527. name: 'mentionPids',
  8528. id: 9
  8529. }, {
  8530. rule: 'optional',
  8531. type: 'bool',
  8532. name: 'bin',
  8533. id: 10
  8534. }, {
  8535. rule: 'optional',
  8536. type: 'int32',
  8537. name: 'convType',
  8538. id: 11
  8539. }]
  8540. }, {
  8541. name: 'ConvMemberInfo',
  8542. syntax: 'proto2',
  8543. fields: [{
  8544. rule: 'optional',
  8545. type: 'string',
  8546. name: 'pid',
  8547. id: 1
  8548. }, {
  8549. rule: 'optional',
  8550. type: 'string',
  8551. name: 'role',
  8552. id: 2
  8553. }, {
  8554. rule: 'optional',
  8555. type: 'string',
  8556. name: 'infoId',
  8557. id: 3
  8558. }]
  8559. }, {
  8560. name: 'DataCommand',
  8561. syntax: 'proto2',
  8562. fields: [{
  8563. rule: 'repeated',
  8564. type: 'string',
  8565. name: 'ids',
  8566. id: 1
  8567. }, {
  8568. rule: 'repeated',
  8569. type: 'JsonObjectMessage',
  8570. name: 'msg',
  8571. id: 2
  8572. }, {
  8573. rule: 'optional',
  8574. type: 'bool',
  8575. name: 'offline',
  8576. id: 3
  8577. }]
  8578. }, {
  8579. name: 'SessionCommand',
  8580. syntax: 'proto2',
  8581. fields: [{
  8582. rule: 'optional',
  8583. type: 'int64',
  8584. name: 't',
  8585. id: 1
  8586. }, {
  8587. rule: 'optional',
  8588. type: 'string',
  8589. name: 'n',
  8590. id: 2
  8591. }, {
  8592. rule: 'optional',
  8593. type: 'string',
  8594. name: 's',
  8595. id: 3
  8596. }, {
  8597. rule: 'optional',
  8598. type: 'string',
  8599. name: 'ua',
  8600. id: 4
  8601. }, {
  8602. rule: 'optional',
  8603. type: 'bool',
  8604. name: 'r',
  8605. id: 5
  8606. }, {
  8607. rule: 'optional',
  8608. type: 'string',
  8609. name: 'tag',
  8610. id: 6
  8611. }, {
  8612. rule: 'optional',
  8613. type: 'string',
  8614. name: 'deviceId',
  8615. id: 7
  8616. }, {
  8617. rule: 'repeated',
  8618. type: 'string',
  8619. name: 'sessionPeerIds',
  8620. id: 8
  8621. }, {
  8622. rule: 'repeated',
  8623. type: 'string',
  8624. name: 'onlineSessionPeerIds',
  8625. id: 9
  8626. }, {
  8627. rule: 'optional',
  8628. type: 'string',
  8629. name: 'st',
  8630. id: 10
  8631. }, {
  8632. rule: 'optional',
  8633. type: 'int32',
  8634. name: 'stTtl',
  8635. id: 11
  8636. }, {
  8637. rule: 'optional',
  8638. type: 'int32',
  8639. name: 'code',
  8640. id: 12
  8641. }, {
  8642. rule: 'optional',
  8643. type: 'string',
  8644. name: 'reason',
  8645. id: 13
  8646. }, {
  8647. rule: 'optional',
  8648. type: 'string',
  8649. name: 'deviceToken',
  8650. id: 14
  8651. }, {
  8652. rule: 'optional',
  8653. type: 'bool',
  8654. name: 'sp',
  8655. id: 15
  8656. }, {
  8657. rule: 'optional',
  8658. type: 'string',
  8659. name: 'detail',
  8660. id: 16
  8661. }, {
  8662. rule: 'optional',
  8663. type: 'int64',
  8664. name: 'lastUnreadNotifTime',
  8665. id: 17
  8666. }, {
  8667. rule: 'optional',
  8668. type: 'int64',
  8669. name: 'lastPatchTime',
  8670. id: 18
  8671. }, {
  8672. rule: 'optional',
  8673. type: 'int64',
  8674. name: 'configBitmap',
  8675. id: 19
  8676. }]
  8677. }, {
  8678. name: 'ErrorCommand',
  8679. syntax: 'proto2',
  8680. fields: [{
  8681. rule: 'required',
  8682. type: 'int32',
  8683. name: 'code',
  8684. id: 1
  8685. }, {
  8686. rule: 'required',
  8687. type: 'string',
  8688. name: 'reason',
  8689. id: 2
  8690. }, {
  8691. rule: 'optional',
  8692. type: 'int32',
  8693. name: 'appCode',
  8694. id: 3
  8695. }, {
  8696. rule: 'optional',
  8697. type: 'string',
  8698. name: 'detail',
  8699. id: 4
  8700. }, {
  8701. rule: 'repeated',
  8702. type: 'string',
  8703. name: 'pids',
  8704. id: 5
  8705. }, {
  8706. rule: 'optional',
  8707. type: 'string',
  8708. name: 'appMsg',
  8709. id: 6
  8710. }]
  8711. }, {
  8712. name: 'DirectCommand',
  8713. syntax: 'proto2',
  8714. fields: [{
  8715. rule: 'optional',
  8716. type: 'string',
  8717. name: 'msg',
  8718. id: 1
  8719. }, {
  8720. rule: 'optional',
  8721. type: 'string',
  8722. name: 'uid',
  8723. id: 2
  8724. }, {
  8725. rule: 'optional',
  8726. type: 'string',
  8727. name: 'fromPeerId',
  8728. id: 3
  8729. }, {
  8730. rule: 'optional',
  8731. type: 'int64',
  8732. name: 'timestamp',
  8733. id: 4
  8734. }, {
  8735. rule: 'optional',
  8736. type: 'bool',
  8737. name: 'offline',
  8738. id: 5
  8739. }, {
  8740. rule: 'optional',
  8741. type: 'bool',
  8742. name: 'hasMore',
  8743. id: 6
  8744. }, {
  8745. rule: 'repeated',
  8746. type: 'string',
  8747. name: 'toPeerIds',
  8748. id: 7
  8749. }, {
  8750. rule: 'optional',
  8751. type: 'bool',
  8752. name: 'r',
  8753. id: 10
  8754. }, {
  8755. rule: 'optional',
  8756. type: 'string',
  8757. name: 'cid',
  8758. id: 11
  8759. }, {
  8760. rule: 'optional',
  8761. type: 'string',
  8762. name: 'id',
  8763. id: 12
  8764. }, {
  8765. rule: 'optional',
  8766. type: 'bool',
  8767. name: 'transient',
  8768. id: 13
  8769. }, {
  8770. rule: 'optional',
  8771. type: 'string',
  8772. name: 'dt',
  8773. id: 14
  8774. }, {
  8775. rule: 'optional',
  8776. type: 'string',
  8777. name: 'roomId',
  8778. id: 15
  8779. }, {
  8780. rule: 'optional',
  8781. type: 'string',
  8782. name: 'pushData',
  8783. id: 16
  8784. }, {
  8785. rule: 'optional',
  8786. type: 'bool',
  8787. name: 'will',
  8788. id: 17
  8789. }, {
  8790. rule: 'optional',
  8791. type: 'int64',
  8792. name: 'patchTimestamp',
  8793. id: 18
  8794. }, {
  8795. rule: 'optional',
  8796. type: 'bytes',
  8797. name: 'binaryMsg',
  8798. id: 19
  8799. }, {
  8800. rule: 'repeated',
  8801. type: 'string',
  8802. name: 'mentionPids',
  8803. id: 20
  8804. }, {
  8805. rule: 'optional',
  8806. type: 'bool',
  8807. name: 'mentionAll',
  8808. id: 21
  8809. }, {
  8810. rule: 'optional',
  8811. type: 'int32',
  8812. name: 'convType',
  8813. id: 22
  8814. }]
  8815. }, {
  8816. name: 'AckCommand',
  8817. syntax: 'proto2',
  8818. fields: [{
  8819. rule: 'optional',
  8820. type: 'int32',
  8821. name: 'code',
  8822. id: 1
  8823. }, {
  8824. rule: 'optional',
  8825. type: 'string',
  8826. name: 'reason',
  8827. id: 2
  8828. }, {
  8829. rule: 'optional',
  8830. type: 'string',
  8831. name: 'mid',
  8832. id: 3
  8833. }, {
  8834. rule: 'optional',
  8835. type: 'string',
  8836. name: 'cid',
  8837. id: 4
  8838. }, {
  8839. rule: 'optional',
  8840. type: 'int64',
  8841. name: 't',
  8842. id: 5
  8843. }, {
  8844. rule: 'optional',
  8845. type: 'string',
  8846. name: 'uid',
  8847. id: 6
  8848. }, {
  8849. rule: 'optional',
  8850. type: 'int64',
  8851. name: 'fromts',
  8852. id: 7
  8853. }, {
  8854. rule: 'optional',
  8855. type: 'int64',
  8856. name: 'tots',
  8857. id: 8
  8858. }, {
  8859. rule: 'optional',
  8860. type: 'string',
  8861. name: 'type',
  8862. id: 9
  8863. }, {
  8864. rule: 'repeated',
  8865. type: 'string',
  8866. name: 'ids',
  8867. id: 10
  8868. }, {
  8869. rule: 'optional',
  8870. type: 'int32',
  8871. name: 'appCode',
  8872. id: 11
  8873. }, {
  8874. rule: 'optional',
  8875. type: 'string',
  8876. name: 'appMsg',
  8877. id: 12
  8878. }]
  8879. }, {
  8880. name: 'UnreadCommand',
  8881. syntax: 'proto2',
  8882. fields: [{
  8883. rule: 'repeated',
  8884. type: 'UnreadTuple',
  8885. name: 'convs',
  8886. id: 1
  8887. }, {
  8888. rule: 'optional',
  8889. type: 'int64',
  8890. name: 'notifTime',
  8891. id: 2
  8892. }]
  8893. }, {
  8894. name: 'ConvCommand',
  8895. syntax: 'proto2',
  8896. fields: [{
  8897. rule: 'repeated',
  8898. type: 'string',
  8899. name: 'm',
  8900. id: 1
  8901. }, {
  8902. rule: 'optional',
  8903. type: 'bool',
  8904. name: 'transient',
  8905. id: 2
  8906. }, {
  8907. rule: 'optional',
  8908. type: 'bool',
  8909. name: 'unique',
  8910. id: 3
  8911. }, {
  8912. rule: 'optional',
  8913. type: 'string',
  8914. name: 'cid',
  8915. id: 4
  8916. }, {
  8917. rule: 'optional',
  8918. type: 'string',
  8919. name: 'cdate',
  8920. id: 5
  8921. }, {
  8922. rule: 'optional',
  8923. type: 'string',
  8924. name: 'initBy',
  8925. id: 6
  8926. }, {
  8927. rule: 'optional',
  8928. type: 'string',
  8929. name: 'sort',
  8930. id: 7
  8931. }, {
  8932. rule: 'optional',
  8933. type: 'int32',
  8934. name: 'limit',
  8935. id: 8
  8936. }, {
  8937. rule: 'optional',
  8938. type: 'int32',
  8939. name: 'skip',
  8940. id: 9
  8941. }, {
  8942. rule: 'optional',
  8943. type: 'int32',
  8944. name: 'flag',
  8945. id: 10
  8946. }, {
  8947. rule: 'optional',
  8948. type: 'int32',
  8949. name: 'count',
  8950. id: 11
  8951. }, {
  8952. rule: 'optional',
  8953. type: 'string',
  8954. name: 'udate',
  8955. id: 12
  8956. }, {
  8957. rule: 'optional',
  8958. type: 'int64',
  8959. name: 't',
  8960. id: 13
  8961. }, {
  8962. rule: 'optional',
  8963. type: 'string',
  8964. name: 'n',
  8965. id: 14
  8966. }, {
  8967. rule: 'optional',
  8968. type: 'string',
  8969. name: 's',
  8970. id: 15
  8971. }, {
  8972. rule: 'optional',
  8973. type: 'bool',
  8974. name: 'statusSub',
  8975. id: 16
  8976. }, {
  8977. rule: 'optional',
  8978. type: 'bool',
  8979. name: 'statusPub',
  8980. id: 17
  8981. }, {
  8982. rule: 'optional',
  8983. type: 'int32',
  8984. name: 'statusTTL',
  8985. id: 18
  8986. }, {
  8987. rule: 'optional',
  8988. type: 'string',
  8989. name: 'uniqueId',
  8990. id: 19
  8991. }, {
  8992. rule: 'optional',
  8993. type: 'string',
  8994. name: 'targetClientId',
  8995. id: 20
  8996. }, {
  8997. rule: 'optional',
  8998. type: 'int64',
  8999. name: 'maxReadTimestamp',
  9000. id: 21
  9001. }, {
  9002. rule: 'optional',
  9003. type: 'int64',
  9004. name: 'maxAckTimestamp',
  9005. id: 22
  9006. }, {
  9007. rule: 'optional',
  9008. type: 'bool',
  9009. name: 'queryAllMembers',
  9010. id: 23
  9011. }, {
  9012. rule: 'repeated',
  9013. type: 'MaxReadTuple',
  9014. name: 'maxReadTuples',
  9015. id: 24
  9016. }, {
  9017. rule: 'repeated',
  9018. type: 'string',
  9019. name: 'cids',
  9020. id: 25
  9021. }, {
  9022. rule: 'optional',
  9023. type: 'ConvMemberInfo',
  9024. name: 'info',
  9025. id: 26
  9026. }, {
  9027. rule: 'optional',
  9028. type: 'bool',
  9029. name: 'tempConv',
  9030. id: 27
  9031. }, {
  9032. rule: 'optional',
  9033. type: 'int32',
  9034. name: 'tempConvTTL',
  9035. id: 28
  9036. }, {
  9037. rule: 'repeated',
  9038. type: 'string',
  9039. name: 'tempConvIds',
  9040. id: 29
  9041. }, {
  9042. rule: 'repeated',
  9043. type: 'string',
  9044. name: 'allowedPids',
  9045. id: 30
  9046. }, {
  9047. rule: 'repeated',
  9048. type: 'ErrorCommand',
  9049. name: 'failedPids',
  9050. id: 31
  9051. }, {
  9052. rule: 'optional',
  9053. type: 'string',
  9054. name: 'next',
  9055. id: 40
  9056. }, {
  9057. rule: 'optional',
  9058. type: 'JsonObjectMessage',
  9059. name: 'results',
  9060. id: 100
  9061. }, {
  9062. rule: 'optional',
  9063. type: 'JsonObjectMessage',
  9064. name: 'where',
  9065. id: 101
  9066. }, {
  9067. rule: 'optional',
  9068. type: 'JsonObjectMessage',
  9069. name: 'attr',
  9070. id: 103
  9071. }, {
  9072. rule: 'optional',
  9073. type: 'JsonObjectMessage',
  9074. name: 'attrModified',
  9075. id: 104
  9076. }]
  9077. }, {
  9078. name: 'RoomCommand',
  9079. syntax: 'proto2',
  9080. fields: [{
  9081. rule: 'optional',
  9082. type: 'string',
  9083. name: 'roomId',
  9084. id: 1
  9085. }, {
  9086. rule: 'optional',
  9087. type: 'string',
  9088. name: 's',
  9089. id: 2
  9090. }, {
  9091. rule: 'optional',
  9092. type: 'int64',
  9093. name: 't',
  9094. id: 3
  9095. }, {
  9096. rule: 'optional',
  9097. type: 'string',
  9098. name: 'n',
  9099. id: 4
  9100. }, {
  9101. rule: 'optional',
  9102. type: 'bool',
  9103. name: 'transient',
  9104. id: 5
  9105. }, {
  9106. rule: 'repeated',
  9107. type: 'string',
  9108. name: 'roomPeerIds',
  9109. id: 6
  9110. }, {
  9111. rule: 'optional',
  9112. type: 'string',
  9113. name: 'byPeerId',
  9114. id: 7
  9115. }]
  9116. }, {
  9117. name: 'LogsCommand',
  9118. syntax: 'proto2',
  9119. fields: [{
  9120. rule: 'optional',
  9121. type: 'string',
  9122. name: 'cid',
  9123. id: 1
  9124. }, {
  9125. rule: 'optional',
  9126. type: 'int32',
  9127. name: 'l',
  9128. id: 2
  9129. }, {
  9130. rule: 'optional',
  9131. type: 'int32',
  9132. name: 'limit',
  9133. id: 3
  9134. }, {
  9135. rule: 'optional',
  9136. type: 'int64',
  9137. name: 't',
  9138. id: 4
  9139. }, {
  9140. rule: 'optional',
  9141. type: 'int64',
  9142. name: 'tt',
  9143. id: 5
  9144. }, {
  9145. rule: 'optional',
  9146. type: 'string',
  9147. name: 'tmid',
  9148. id: 6
  9149. }, {
  9150. rule: 'optional',
  9151. type: 'string',
  9152. name: 'mid',
  9153. id: 7
  9154. }, {
  9155. rule: 'optional',
  9156. type: 'string',
  9157. name: 'checksum',
  9158. id: 8
  9159. }, {
  9160. rule: 'optional',
  9161. type: 'bool',
  9162. name: 'stored',
  9163. id: 9
  9164. }, {
  9165. rule: 'optional',
  9166. type: 'QueryDirection',
  9167. name: 'direction',
  9168. id: 10,
  9169. options: {
  9170. default: 'OLD'
  9171. }
  9172. }, {
  9173. rule: 'optional',
  9174. type: 'bool',
  9175. name: 'tIncluded',
  9176. id: 11
  9177. }, {
  9178. rule: 'optional',
  9179. type: 'bool',
  9180. name: 'ttIncluded',
  9181. id: 12
  9182. }, {
  9183. rule: 'optional',
  9184. type: 'int32',
  9185. name: 'lctype',
  9186. id: 13
  9187. }, {
  9188. rule: 'repeated',
  9189. type: 'LogItem',
  9190. name: 'logs',
  9191. id: 105
  9192. }],
  9193. enums: [{
  9194. name: 'QueryDirection',
  9195. syntax: 'proto2',
  9196. values: [{
  9197. name: 'OLD',
  9198. id: 1
  9199. }, {
  9200. name: 'NEW',
  9201. id: 2
  9202. }]
  9203. }]
  9204. }, {
  9205. name: 'RcpCommand',
  9206. syntax: 'proto2',
  9207. fields: [{
  9208. rule: 'optional',
  9209. type: 'string',
  9210. name: 'id',
  9211. id: 1
  9212. }, {
  9213. rule: 'optional',
  9214. type: 'string',
  9215. name: 'cid',
  9216. id: 2
  9217. }, {
  9218. rule: 'optional',
  9219. type: 'int64',
  9220. name: 't',
  9221. id: 3
  9222. }, {
  9223. rule: 'optional',
  9224. type: 'bool',
  9225. name: 'read',
  9226. id: 4
  9227. }, {
  9228. rule: 'optional',
  9229. type: 'string',
  9230. name: 'from',
  9231. id: 5
  9232. }]
  9233. }, {
  9234. name: 'ReadTuple',
  9235. syntax: 'proto2',
  9236. fields: [{
  9237. rule: 'required',
  9238. type: 'string',
  9239. name: 'cid',
  9240. id: 1
  9241. }, {
  9242. rule: 'optional',
  9243. type: 'int64',
  9244. name: 'timestamp',
  9245. id: 2
  9246. }, {
  9247. rule: 'optional',
  9248. type: 'string',
  9249. name: 'mid',
  9250. id: 3
  9251. }]
  9252. }, {
  9253. name: 'MaxReadTuple',
  9254. syntax: 'proto2',
  9255. fields: [{
  9256. rule: 'optional',
  9257. type: 'string',
  9258. name: 'pid',
  9259. id: 1
  9260. }, {
  9261. rule: 'optional',
  9262. type: 'int64',
  9263. name: 'maxAckTimestamp',
  9264. id: 2
  9265. }, {
  9266. rule: 'optional',
  9267. type: 'int64',
  9268. name: 'maxReadTimestamp',
  9269. id: 3
  9270. }]
  9271. }, {
  9272. name: 'ReadCommand',
  9273. syntax: 'proto2',
  9274. fields: [{
  9275. rule: 'optional',
  9276. type: 'string',
  9277. name: 'cid',
  9278. id: 1
  9279. }, {
  9280. rule: 'repeated',
  9281. type: 'string',
  9282. name: 'cids',
  9283. id: 2
  9284. }, {
  9285. rule: 'repeated',
  9286. type: 'ReadTuple',
  9287. name: 'convs',
  9288. id: 3
  9289. }]
  9290. }, {
  9291. name: 'PresenceCommand',
  9292. syntax: 'proto2',
  9293. fields: [{
  9294. rule: 'optional',
  9295. type: 'StatusType',
  9296. name: 'status',
  9297. id: 1
  9298. }, {
  9299. rule: 'repeated',
  9300. type: 'string',
  9301. name: 'sessionPeerIds',
  9302. id: 2
  9303. }, {
  9304. rule: 'optional',
  9305. type: 'string',
  9306. name: 'cid',
  9307. id: 3
  9308. }]
  9309. }, {
  9310. name: 'ReportCommand',
  9311. syntax: 'proto2',
  9312. fields: [{
  9313. rule: 'optional',
  9314. type: 'bool',
  9315. name: 'initiative',
  9316. id: 1
  9317. }, {
  9318. rule: 'optional',
  9319. type: 'string',
  9320. name: 'type',
  9321. id: 2
  9322. }, {
  9323. rule: 'optional',
  9324. type: 'string',
  9325. name: 'data',
  9326. id: 3
  9327. }]
  9328. }, {
  9329. name: 'PatchItem',
  9330. syntax: 'proto2',
  9331. fields: [{
  9332. rule: 'optional',
  9333. type: 'string',
  9334. name: 'cid',
  9335. id: 1
  9336. }, {
  9337. rule: 'optional',
  9338. type: 'string',
  9339. name: 'mid',
  9340. id: 2
  9341. }, {
  9342. rule: 'optional',
  9343. type: 'int64',
  9344. name: 'timestamp',
  9345. id: 3
  9346. }, {
  9347. rule: 'optional',
  9348. type: 'bool',
  9349. name: 'recall',
  9350. id: 4
  9351. }, {
  9352. rule: 'optional',
  9353. type: 'string',
  9354. name: 'data',
  9355. id: 5
  9356. }, {
  9357. rule: 'optional',
  9358. type: 'int64',
  9359. name: 'patchTimestamp',
  9360. id: 6
  9361. }, {
  9362. rule: 'optional',
  9363. type: 'string',
  9364. name: 'from',
  9365. id: 7
  9366. }, {
  9367. rule: 'optional',
  9368. type: 'bytes',
  9369. name: 'binaryMsg',
  9370. id: 8
  9371. }, {
  9372. rule: 'optional',
  9373. type: 'bool',
  9374. name: 'mentionAll',
  9375. id: 9
  9376. }, {
  9377. rule: 'repeated',
  9378. type: 'string',
  9379. name: 'mentionPids',
  9380. id: 10
  9381. }, {
  9382. rule: 'optional',
  9383. type: 'int64',
  9384. name: 'patchCode',
  9385. id: 11
  9386. }, {
  9387. rule: 'optional',
  9388. type: 'string',
  9389. name: 'patchReason',
  9390. id: 12
  9391. }]
  9392. }, {
  9393. name: 'PatchCommand',
  9394. syntax: 'proto2',
  9395. fields: [{
  9396. rule: 'repeated',
  9397. type: 'PatchItem',
  9398. name: 'patches',
  9399. id: 1
  9400. }, {
  9401. rule: 'optional',
  9402. type: 'int64',
  9403. name: 'lastPatchTime',
  9404. id: 2
  9405. }]
  9406. }, {
  9407. name: 'PubsubCommand',
  9408. syntax: 'proto2',
  9409. fields: [{
  9410. rule: 'optional',
  9411. type: 'string',
  9412. name: 'cid',
  9413. id: 1
  9414. }, {
  9415. rule: 'repeated',
  9416. type: 'string',
  9417. name: 'cids',
  9418. id: 2
  9419. }, {
  9420. rule: 'optional',
  9421. type: 'string',
  9422. name: 'topic',
  9423. id: 3
  9424. }, {
  9425. rule: 'optional',
  9426. type: 'string',
  9427. name: 'subtopic',
  9428. id: 4
  9429. }, {
  9430. rule: 'repeated',
  9431. type: 'string',
  9432. name: 'topics',
  9433. id: 5
  9434. }, {
  9435. rule: 'repeated',
  9436. type: 'string',
  9437. name: 'subtopics',
  9438. id: 6
  9439. }, {
  9440. rule: 'optional',
  9441. type: 'JsonObjectMessage',
  9442. name: 'results',
  9443. id: 7
  9444. }]
  9445. }, {
  9446. name: 'BlacklistCommand',
  9447. syntax: 'proto2',
  9448. fields: [{
  9449. rule: 'optional',
  9450. type: 'string',
  9451. name: 'srcCid',
  9452. id: 1
  9453. }, {
  9454. rule: 'repeated',
  9455. type: 'string',
  9456. name: 'toPids',
  9457. id: 2
  9458. }, {
  9459. rule: 'optional',
  9460. type: 'string',
  9461. name: 'srcPid',
  9462. id: 3
  9463. }, {
  9464. rule: 'repeated',
  9465. type: 'string',
  9466. name: 'toCids',
  9467. id: 4
  9468. }, {
  9469. rule: 'optional',
  9470. type: 'int32',
  9471. name: 'limit',
  9472. id: 5
  9473. }, {
  9474. rule: 'optional',
  9475. type: 'string',
  9476. name: 'next',
  9477. id: 6
  9478. }, {
  9479. rule: 'repeated',
  9480. type: 'string',
  9481. name: 'blockedPids',
  9482. id: 8
  9483. }, {
  9484. rule: 'repeated',
  9485. type: 'string',
  9486. name: 'blockedCids',
  9487. id: 9
  9488. }, {
  9489. rule: 'repeated',
  9490. type: 'string',
  9491. name: 'allowedPids',
  9492. id: 10
  9493. }, {
  9494. rule: 'repeated',
  9495. type: 'ErrorCommand',
  9496. name: 'failedPids',
  9497. id: 11
  9498. }, {
  9499. rule: 'optional',
  9500. type: 'int64',
  9501. name: 't',
  9502. id: 12
  9503. }, {
  9504. rule: 'optional',
  9505. type: 'string',
  9506. name: 'n',
  9507. id: 13
  9508. }, {
  9509. rule: 'optional',
  9510. type: 'string',
  9511. name: 's',
  9512. id: 14
  9513. }]
  9514. }, {
  9515. name: 'GenericCommand',
  9516. syntax: 'proto2',
  9517. fields: [{
  9518. rule: 'optional',
  9519. type: 'CommandType',
  9520. name: 'cmd',
  9521. id: 1
  9522. }, {
  9523. rule: 'optional',
  9524. type: 'OpType',
  9525. name: 'op',
  9526. id: 2
  9527. }, {
  9528. rule: 'optional',
  9529. type: 'string',
  9530. name: 'appId',
  9531. id: 3
  9532. }, {
  9533. rule: 'optional',
  9534. type: 'string',
  9535. name: 'peerId',
  9536. id: 4
  9537. }, {
  9538. rule: 'optional',
  9539. type: 'int32',
  9540. name: 'i',
  9541. id: 5
  9542. }, {
  9543. rule: 'optional',
  9544. type: 'string',
  9545. name: 'installationId',
  9546. id: 6
  9547. }, {
  9548. rule: 'optional',
  9549. type: 'int32',
  9550. name: 'priority',
  9551. id: 7
  9552. }, {
  9553. rule: 'optional',
  9554. type: 'int32',
  9555. name: 'service',
  9556. id: 8
  9557. }, {
  9558. rule: 'optional',
  9559. type: 'int64',
  9560. name: 'serverTs',
  9561. id: 9
  9562. }, {
  9563. rule: 'optional',
  9564. type: 'int64',
  9565. name: 'clientTs',
  9566. id: 10
  9567. }, {
  9568. rule: 'optional',
  9569. type: 'int32',
  9570. name: 'notificationType',
  9571. id: 11
  9572. }, {
  9573. rule: 'optional',
  9574. type: 'DataCommand',
  9575. name: 'dataMessage',
  9576. id: 101
  9577. }, {
  9578. rule: 'optional',
  9579. type: 'SessionCommand',
  9580. name: 'sessionMessage',
  9581. id: 102
  9582. }, {
  9583. rule: 'optional',
  9584. type: 'ErrorCommand',
  9585. name: 'errorMessage',
  9586. id: 103
  9587. }, {
  9588. rule: 'optional',
  9589. type: 'DirectCommand',
  9590. name: 'directMessage',
  9591. id: 104
  9592. }, {
  9593. rule: 'optional',
  9594. type: 'AckCommand',
  9595. name: 'ackMessage',
  9596. id: 105
  9597. }, {
  9598. rule: 'optional',
  9599. type: 'UnreadCommand',
  9600. name: 'unreadMessage',
  9601. id: 106
  9602. }, {
  9603. rule: 'optional',
  9604. type: 'ReadCommand',
  9605. name: 'readMessage',
  9606. id: 107
  9607. }, {
  9608. rule: 'optional',
  9609. type: 'RcpCommand',
  9610. name: 'rcpMessage',
  9611. id: 108
  9612. }, {
  9613. rule: 'optional',
  9614. type: 'LogsCommand',
  9615. name: 'logsMessage',
  9616. id: 109
  9617. }, {
  9618. rule: 'optional',
  9619. type: 'ConvCommand',
  9620. name: 'convMessage',
  9621. id: 110
  9622. }, {
  9623. rule: 'optional',
  9624. type: 'RoomCommand',
  9625. name: 'roomMessage',
  9626. id: 111
  9627. }, {
  9628. rule: 'optional',
  9629. type: 'PresenceCommand',
  9630. name: 'presenceMessage',
  9631. id: 112
  9632. }, {
  9633. rule: 'optional',
  9634. type: 'ReportCommand',
  9635. name: 'reportMessage',
  9636. id: 113
  9637. }, {
  9638. rule: 'optional',
  9639. type: 'PatchCommand',
  9640. name: 'patchMessage',
  9641. id: 114
  9642. }, {
  9643. rule: 'optional',
  9644. type: 'PubsubCommand',
  9645. name: 'pubsubMessage',
  9646. id: 115
  9647. }, {
  9648. rule: 'optional',
  9649. type: 'BlacklistCommand',
  9650. name: 'blacklistMessage',
  9651. id: 116
  9652. }]
  9653. }],
  9654. enums: [{
  9655. name: 'CommandType',
  9656. syntax: 'proto2',
  9657. values: [{
  9658. name: 'session',
  9659. id: 0
  9660. }, {
  9661. name: 'conv',
  9662. id: 1
  9663. }, {
  9664. name: 'direct',
  9665. id: 2
  9666. }, {
  9667. name: 'ack',
  9668. id: 3
  9669. }, {
  9670. name: 'rcp',
  9671. id: 4
  9672. }, {
  9673. name: 'unread',
  9674. id: 5
  9675. }, {
  9676. name: 'logs',
  9677. id: 6
  9678. }, {
  9679. name: 'error',
  9680. id: 7
  9681. }, {
  9682. name: 'login',
  9683. id: 8
  9684. }, {
  9685. name: 'data',
  9686. id: 9
  9687. }, {
  9688. name: 'room',
  9689. id: 10
  9690. }, {
  9691. name: 'read',
  9692. id: 11
  9693. }, {
  9694. name: 'presence',
  9695. id: 12
  9696. }, {
  9697. name: 'report',
  9698. id: 13
  9699. }, {
  9700. name: 'echo',
  9701. id: 14
  9702. }, {
  9703. name: 'loggedin',
  9704. id: 15
  9705. }, {
  9706. name: 'logout',
  9707. id: 16
  9708. }, {
  9709. name: 'loggedout',
  9710. id: 17
  9711. }, {
  9712. name: 'patch',
  9713. id: 18
  9714. }, {
  9715. name: 'pubsub',
  9716. id: 19
  9717. }, {
  9718. name: 'blacklist',
  9719. id: 20
  9720. }, {
  9721. name: 'goaway',
  9722. id: 21
  9723. }]
  9724. }, {
  9725. name: 'OpType',
  9726. syntax: 'proto2',
  9727. values: [{
  9728. name: 'open',
  9729. id: 1
  9730. }, {
  9731. name: 'add',
  9732. id: 2
  9733. }, {
  9734. name: 'remove',
  9735. id: 3
  9736. }, {
  9737. name: 'close',
  9738. id: 4
  9739. }, {
  9740. name: 'opened',
  9741. id: 5
  9742. }, {
  9743. name: 'closed',
  9744. id: 6
  9745. }, {
  9746. name: 'query',
  9747. id: 7
  9748. }, {
  9749. name: 'query_result',
  9750. id: 8
  9751. }, {
  9752. name: 'conflict',
  9753. id: 9
  9754. }, {
  9755. name: 'added',
  9756. id: 10
  9757. }, {
  9758. name: 'removed',
  9759. id: 11
  9760. }, {
  9761. name: 'refresh',
  9762. id: 12
  9763. }, {
  9764. name: 'refreshed',
  9765. id: 13
  9766. }, {
  9767. name: 'start',
  9768. id: 30
  9769. }, {
  9770. name: 'started',
  9771. id: 31
  9772. }, {
  9773. name: 'joined',
  9774. id: 32
  9775. }, {
  9776. name: 'members_joined',
  9777. id: 33
  9778. }, {
  9779. name: 'left',
  9780. id: 39
  9781. }, {
  9782. name: 'members_left',
  9783. id: 40
  9784. }, {
  9785. name: 'results',
  9786. id: 42
  9787. }, {
  9788. name: 'count',
  9789. id: 43
  9790. }, {
  9791. name: 'result',
  9792. id: 44
  9793. }, {
  9794. name: 'update',
  9795. id: 45
  9796. }, {
  9797. name: 'updated',
  9798. id: 46
  9799. }, {
  9800. name: 'mute',
  9801. id: 47
  9802. }, {
  9803. name: 'unmute',
  9804. id: 48
  9805. }, {
  9806. name: 'status',
  9807. id: 49
  9808. }, {
  9809. name: 'members',
  9810. id: 50
  9811. }, {
  9812. name: 'max_read',
  9813. id: 51
  9814. }, {
  9815. name: 'is_member',
  9816. id: 52
  9817. }, {
  9818. name: 'member_info_update',
  9819. id: 53
  9820. }, {
  9821. name: 'member_info_updated',
  9822. id: 54
  9823. }, {
  9824. name: 'member_info_changed',
  9825. id: 55
  9826. }, {
  9827. name: 'join',
  9828. id: 80
  9829. }, {
  9830. name: 'invite',
  9831. id: 81
  9832. }, {
  9833. name: 'leave',
  9834. id: 82
  9835. }, {
  9836. name: 'kick',
  9837. id: 83
  9838. }, {
  9839. name: 'reject',
  9840. id: 84
  9841. }, {
  9842. name: 'invited',
  9843. id: 85
  9844. }, {
  9845. name: 'kicked',
  9846. id: 86
  9847. }, {
  9848. name: 'upload',
  9849. id: 100
  9850. }, {
  9851. name: 'uploaded',
  9852. id: 101
  9853. }, {
  9854. name: 'subscribe',
  9855. id: 120
  9856. }, {
  9857. name: 'subscribed',
  9858. id: 121
  9859. }, {
  9860. name: 'unsubscribe',
  9861. id: 122
  9862. }, {
  9863. name: 'unsubscribed',
  9864. id: 123
  9865. }, {
  9866. name: 'is_subscribed',
  9867. id: 124
  9868. }, {
  9869. name: 'modify',
  9870. id: 150
  9871. }, {
  9872. name: 'modified',
  9873. id: 151
  9874. }, {
  9875. name: 'block',
  9876. id: 170
  9877. }, {
  9878. name: 'unblock',
  9879. id: 171
  9880. }, {
  9881. name: 'blocked',
  9882. id: 172
  9883. }, {
  9884. name: 'unblocked',
  9885. id: 173
  9886. }, {
  9887. name: 'members_blocked',
  9888. id: 174
  9889. }, {
  9890. name: 'members_unblocked',
  9891. id: 175
  9892. }, {
  9893. name: 'check_block',
  9894. id: 176
  9895. }, {
  9896. name: 'check_result',
  9897. id: 177
  9898. }, {
  9899. name: 'add_shutup',
  9900. id: 180
  9901. }, {
  9902. name: 'remove_shutup',
  9903. id: 181
  9904. }, {
  9905. name: 'query_shutup',
  9906. id: 182
  9907. }, {
  9908. name: 'shutup_added',
  9909. id: 183
  9910. }, {
  9911. name: 'shutup_removed',
  9912. id: 184
  9913. }, {
  9914. name: 'shutup_result',
  9915. id: 185
  9916. }, {
  9917. name: 'shutuped',
  9918. id: 186
  9919. }, {
  9920. name: 'unshutuped',
  9921. id: 187
  9922. }, {
  9923. name: 'members_shutuped',
  9924. id: 188
  9925. }, {
  9926. name: 'members_unshutuped',
  9927. id: 189
  9928. }, {
  9929. name: 'check_shutup',
  9930. id: 190
  9931. }]
  9932. }, {
  9933. name: 'StatusType',
  9934. syntax: 'proto2',
  9935. values: [{
  9936. name: 'on',
  9937. id: 1
  9938. }, {
  9939. name: 'off',
  9940. id: 2
  9941. }]
  9942. }],
  9943. isNamespace: true
  9944. }).build();
  9945. const {
  9946. JsonObjectMessage,
  9947. UnreadTuple,
  9948. LogItem,
  9949. DataCommand,
  9950. SessionCommand,
  9951. ErrorCommand,
  9952. DirectCommand,
  9953. AckCommand,
  9954. UnreadCommand,
  9955. ConvCommand,
  9956. RoomCommand,
  9957. LogsCommand,
  9958. RcpCommand,
  9959. ReadTuple,
  9960. MaxReadTuple,
  9961. ReadCommand,
  9962. PresenceCommand,
  9963. ReportCommand,
  9964. GenericCommand,
  9965. BlacklistCommand,
  9966. PatchCommand,
  9967. PatchItem,
  9968. ConvMemberInfo,
  9969. CommandType,
  9970. OpType,
  9971. StatusType
  9972. } = messageCompiled.push_server.messages2;
  9973. var message = /*#__PURE__*/Object.freeze({
  9974. __proto__: null,
  9975. JsonObjectMessage: JsonObjectMessage,
  9976. UnreadTuple: UnreadTuple,
  9977. LogItem: LogItem,
  9978. DataCommand: DataCommand,
  9979. SessionCommand: SessionCommand,
  9980. ErrorCommand: ErrorCommand,
  9981. DirectCommand: DirectCommand,
  9982. AckCommand: AckCommand,
  9983. UnreadCommand: UnreadCommand,
  9984. ConvCommand: ConvCommand,
  9985. RoomCommand: RoomCommand,
  9986. LogsCommand: LogsCommand,
  9987. RcpCommand: RcpCommand,
  9988. ReadTuple: ReadTuple,
  9989. MaxReadTuple: MaxReadTuple,
  9990. ReadCommand: ReadCommand,
  9991. PresenceCommand: PresenceCommand,
  9992. ReportCommand: ReportCommand,
  9993. GenericCommand: GenericCommand,
  9994. BlacklistCommand: BlacklistCommand,
  9995. PatchCommand: PatchCommand,
  9996. PatchItem: PatchItem,
  9997. ConvMemberInfo: ConvMemberInfo,
  9998. CommandType: CommandType,
  9999. OpType: OpType,
  10000. StatusType: StatusType
  10001. });
  10002. var eventemitter3 = createCommonjsModule(function (module) {
  10003. var has = Object.prototype.hasOwnProperty
  10004. , prefix = '~';
  10005. /**
  10006. * Constructor to create a storage for our `EE` objects.
  10007. * An `Events` instance is a plain object whose properties are event names.
  10008. *
  10009. * @constructor
  10010. * @private
  10011. */
  10012. function Events() {}
  10013. //
  10014. // We try to not inherit from `Object.prototype`. In some engines creating an
  10015. // instance in this way is faster than calling `Object.create(null)` directly.
  10016. // If `Object.create(null)` is not supported we prefix the event names with a
  10017. // character to make sure that the built-in object properties are not
  10018. // overridden or used as an attack vector.
  10019. //
  10020. if (Object.create) {
  10021. Events.prototype = Object.create(null);
  10022. //
  10023. // This hack is needed because the `__proto__` property is still inherited in
  10024. // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
  10025. //
  10026. if (!new Events().__proto__) prefix = false;
  10027. }
  10028. /**
  10029. * Representation of a single event listener.
  10030. *
  10031. * @param {Function} fn The listener function.
  10032. * @param {*} context The context to invoke the listener with.
  10033. * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
  10034. * @constructor
  10035. * @private
  10036. */
  10037. function EE(fn, context, once) {
  10038. this.fn = fn;
  10039. this.context = context;
  10040. this.once = once || false;
  10041. }
  10042. /**
  10043. * Add a listener for a given event.
  10044. *
  10045. * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
  10046. * @param {(String|Symbol)} event The event name.
  10047. * @param {Function} fn The listener function.
  10048. * @param {*} context The context to invoke the listener with.
  10049. * @param {Boolean} once Specify if the listener is a one-time listener.
  10050. * @returns {EventEmitter}
  10051. * @private
  10052. */
  10053. function addListener(emitter, event, fn, context, once) {
  10054. if (typeof fn !== 'function') {
  10055. throw new TypeError('The listener must be a function');
  10056. }
  10057. var listener = new EE(fn, context || emitter, once)
  10058. , evt = prefix ? prefix + event : event;
  10059. if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
  10060. else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
  10061. else emitter._events[evt] = [emitter._events[evt], listener];
  10062. return emitter;
  10063. }
  10064. /**
  10065. * Clear event by name.
  10066. *
  10067. * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
  10068. * @param {(String|Symbol)} evt The Event name.
  10069. * @private
  10070. */
  10071. function clearEvent(emitter, evt) {
  10072. if (--emitter._eventsCount === 0) emitter._events = new Events();
  10073. else delete emitter._events[evt];
  10074. }
  10075. /**
  10076. * Minimal `EventEmitter` interface that is molded against the Node.js
  10077. * `EventEmitter` interface.
  10078. *
  10079. * @constructor
  10080. * @public
  10081. */
  10082. function EventEmitter() {
  10083. this._events = new Events();
  10084. this._eventsCount = 0;
  10085. }
  10086. /**
  10087. * Return an array listing the events for which the emitter has registered
  10088. * listeners.
  10089. *
  10090. * @returns {Array}
  10091. * @public
  10092. */
  10093. EventEmitter.prototype.eventNames = function eventNames() {
  10094. var names = []
  10095. , events
  10096. , name;
  10097. if (this._eventsCount === 0) return names;
  10098. for (name in (events = this._events)) {
  10099. if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
  10100. }
  10101. if (Object.getOwnPropertySymbols) {
  10102. return names.concat(Object.getOwnPropertySymbols(events));
  10103. }
  10104. return names;
  10105. };
  10106. /**
  10107. * Return the listeners registered for a given event.
  10108. *
  10109. * @param {(String|Symbol)} event The event name.
  10110. * @returns {Array} The registered listeners.
  10111. * @public
  10112. */
  10113. EventEmitter.prototype.listeners = function listeners(event) {
  10114. var evt = prefix ? prefix + event : event
  10115. , handlers = this._events[evt];
  10116. if (!handlers) return [];
  10117. if (handlers.fn) return [handlers.fn];
  10118. for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
  10119. ee[i] = handlers[i].fn;
  10120. }
  10121. return ee;
  10122. };
  10123. /**
  10124. * Return the number of listeners listening to a given event.
  10125. *
  10126. * @param {(String|Symbol)} event The event name.
  10127. * @returns {Number} The number of listeners.
  10128. * @public
  10129. */
  10130. EventEmitter.prototype.listenerCount = function listenerCount(event) {
  10131. var evt = prefix ? prefix + event : event
  10132. , listeners = this._events[evt];
  10133. if (!listeners) return 0;
  10134. if (listeners.fn) return 1;
  10135. return listeners.length;
  10136. };
  10137. /**
  10138. * Calls each of the listeners registered for a given event.
  10139. *
  10140. * @param {(String|Symbol)} event The event name.
  10141. * @returns {Boolean} `true` if the event had listeners, else `false`.
  10142. * @public
  10143. */
  10144. EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
  10145. var evt = prefix ? prefix + event : event;
  10146. if (!this._events[evt]) return false;
  10147. var listeners = this._events[evt]
  10148. , len = arguments.length
  10149. , args
  10150. , i;
  10151. if (listeners.fn) {
  10152. if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
  10153. switch (len) {
  10154. case 1: return listeners.fn.call(listeners.context), true;
  10155. case 2: return listeners.fn.call(listeners.context, a1), true;
  10156. case 3: return listeners.fn.call(listeners.context, a1, a2), true;
  10157. case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
  10158. case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
  10159. case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
  10160. }
  10161. for (i = 1, args = new Array(len -1); i < len; i++) {
  10162. args[i - 1] = arguments[i];
  10163. }
  10164. listeners.fn.apply(listeners.context, args);
  10165. } else {
  10166. var length = listeners.length
  10167. , j;
  10168. for (i = 0; i < length; i++) {
  10169. if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
  10170. switch (len) {
  10171. case 1: listeners[i].fn.call(listeners[i].context); break;
  10172. case 2: listeners[i].fn.call(listeners[i].context, a1); break;
  10173. case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
  10174. case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
  10175. default:
  10176. if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
  10177. args[j - 1] = arguments[j];
  10178. }
  10179. listeners[i].fn.apply(listeners[i].context, args);
  10180. }
  10181. }
  10182. }
  10183. return true;
  10184. };
  10185. /**
  10186. * Add a listener for a given event.
  10187. *
  10188. * @param {(String|Symbol)} event The event name.
  10189. * @param {Function} fn The listener function.
  10190. * @param {*} [context=this] The context to invoke the listener with.
  10191. * @returns {EventEmitter} `this`.
  10192. * @public
  10193. */
  10194. EventEmitter.prototype.on = function on(event, fn, context) {
  10195. return addListener(this, event, fn, context, false);
  10196. };
  10197. /**
  10198. * Add a one-time listener for a given event.
  10199. *
  10200. * @param {(String|Symbol)} event The event name.
  10201. * @param {Function} fn The listener function.
  10202. * @param {*} [context=this] The context to invoke the listener with.
  10203. * @returns {EventEmitter} `this`.
  10204. * @public
  10205. */
  10206. EventEmitter.prototype.once = function once(event, fn, context) {
  10207. return addListener(this, event, fn, context, true);
  10208. };
  10209. /**
  10210. * Remove the listeners of a given event.
  10211. *
  10212. * @param {(String|Symbol)} event The event name.
  10213. * @param {Function} fn Only remove the listeners that match this function.
  10214. * @param {*} context Only remove the listeners that have this context.
  10215. * @param {Boolean} once Only remove one-time listeners.
  10216. * @returns {EventEmitter} `this`.
  10217. * @public
  10218. */
  10219. EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
  10220. var evt = prefix ? prefix + event : event;
  10221. if (!this._events[evt]) return this;
  10222. if (!fn) {
  10223. clearEvent(this, evt);
  10224. return this;
  10225. }
  10226. var listeners = this._events[evt];
  10227. if (listeners.fn) {
  10228. if (
  10229. listeners.fn === fn &&
  10230. (!once || listeners.once) &&
  10231. (!context || listeners.context === context)
  10232. ) {
  10233. clearEvent(this, evt);
  10234. }
  10235. } else {
  10236. for (var i = 0, events = [], length = listeners.length; i < length; i++) {
  10237. if (
  10238. listeners[i].fn !== fn ||
  10239. (once && !listeners[i].once) ||
  10240. (context && listeners[i].context !== context)
  10241. ) {
  10242. events.push(listeners[i]);
  10243. }
  10244. }
  10245. //
  10246. // Reset the array, or remove it completely if we have no more listeners.
  10247. //
  10248. if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
  10249. else clearEvent(this, evt);
  10250. }
  10251. return this;
  10252. };
  10253. /**
  10254. * Remove all listeners, or those of the specified event.
  10255. *
  10256. * @param {(String|Symbol)} [event] The event name.
  10257. * @returns {EventEmitter} `this`.
  10258. * @public
  10259. */
  10260. EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
  10261. var evt;
  10262. if (event) {
  10263. evt = prefix ? prefix + event : event;
  10264. if (this._events[evt]) clearEvent(this, evt);
  10265. } else {
  10266. this._events = new Events();
  10267. this._eventsCount = 0;
  10268. }
  10269. return this;
  10270. };
  10271. //
  10272. // Alias methods names because people roll like that.
  10273. //
  10274. EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
  10275. EventEmitter.prototype.addListener = EventEmitter.prototype.on;
  10276. //
  10277. // Expose the prefix.
  10278. //
  10279. EventEmitter.prefixed = prefix;
  10280. //
  10281. // Allow `EventEmitter` to be imported as module namespace.
  10282. //
  10283. EventEmitter.EventEmitter = EventEmitter;
  10284. //
  10285. // Expose the module.
  10286. //
  10287. {
  10288. module.exports = EventEmitter;
  10289. }
  10290. });
  10291. /**
  10292. * Helpers.
  10293. */
  10294. var s = 1000;
  10295. var m = s * 60;
  10296. var h = m * 60;
  10297. var d = h * 24;
  10298. var w = d * 7;
  10299. var y = d * 365.25;
  10300. /**
  10301. * Parse or format the given `val`.
  10302. *
  10303. * Options:
  10304. *
  10305. * - `long` verbose formatting [false]
  10306. *
  10307. * @param {String|Number} val
  10308. * @param {Object} [options]
  10309. * @throws {Error} throw an error if val is not a non-empty string or a number
  10310. * @return {String|Number}
  10311. * @api public
  10312. */
  10313. var ms = function(val, options) {
  10314. options = options || {};
  10315. var type = typeof val;
  10316. if (type === 'string' && val.length > 0) {
  10317. return parse(val);
  10318. } else if (type === 'number' && isNaN(val) === false) {
  10319. return options.long ? fmtLong(val) : fmtShort(val);
  10320. }
  10321. throw new Error(
  10322. 'val is not a non-empty string or a valid number. val=' +
  10323. JSON.stringify(val)
  10324. );
  10325. };
  10326. /**
  10327. * Parse the given `str` and return milliseconds.
  10328. *
  10329. * @param {String} str
  10330. * @return {Number}
  10331. * @api private
  10332. */
  10333. function parse(str) {
  10334. str = String(str);
  10335. if (str.length > 100) {
  10336. return;
  10337. }
  10338. 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(
  10339. str
  10340. );
  10341. if (!match) {
  10342. return;
  10343. }
  10344. var n = parseFloat(match[1]);
  10345. var type = (match[2] || 'ms').toLowerCase();
  10346. switch (type) {
  10347. case 'years':
  10348. case 'year':
  10349. case 'yrs':
  10350. case 'yr':
  10351. case 'y':
  10352. return n * y;
  10353. case 'weeks':
  10354. case 'week':
  10355. case 'w':
  10356. return n * w;
  10357. case 'days':
  10358. case 'day':
  10359. case 'd':
  10360. return n * d;
  10361. case 'hours':
  10362. case 'hour':
  10363. case 'hrs':
  10364. case 'hr':
  10365. case 'h':
  10366. return n * h;
  10367. case 'minutes':
  10368. case 'minute':
  10369. case 'mins':
  10370. case 'min':
  10371. case 'm':
  10372. return n * m;
  10373. case 'seconds':
  10374. case 'second':
  10375. case 'secs':
  10376. case 'sec':
  10377. case 's':
  10378. return n * s;
  10379. case 'milliseconds':
  10380. case 'millisecond':
  10381. case 'msecs':
  10382. case 'msec':
  10383. case 'ms':
  10384. return n;
  10385. default:
  10386. return undefined;
  10387. }
  10388. }
  10389. /**
  10390. * Short format for `ms`.
  10391. *
  10392. * @param {Number} ms
  10393. * @return {String}
  10394. * @api private
  10395. */
  10396. function fmtShort(ms) {
  10397. var msAbs = Math.abs(ms);
  10398. if (msAbs >= d) {
  10399. return Math.round(ms / d) + 'd';
  10400. }
  10401. if (msAbs >= h) {
  10402. return Math.round(ms / h) + 'h';
  10403. }
  10404. if (msAbs >= m) {
  10405. return Math.round(ms / m) + 'm';
  10406. }
  10407. if (msAbs >= s) {
  10408. return Math.round(ms / s) + 's';
  10409. }
  10410. return ms + 'ms';
  10411. }
  10412. /**
  10413. * Long format for `ms`.
  10414. *
  10415. * @param {Number} ms
  10416. * @return {String}
  10417. * @api private
  10418. */
  10419. function fmtLong(ms) {
  10420. var msAbs = Math.abs(ms);
  10421. if (msAbs >= d) {
  10422. return plural(ms, msAbs, d, 'day');
  10423. }
  10424. if (msAbs >= h) {
  10425. return plural(ms, msAbs, h, 'hour');
  10426. }
  10427. if (msAbs >= m) {
  10428. return plural(ms, msAbs, m, 'minute');
  10429. }
  10430. if (msAbs >= s) {
  10431. return plural(ms, msAbs, s, 'second');
  10432. }
  10433. return ms + ' ms';
  10434. }
  10435. /**
  10436. * Pluralization helper.
  10437. */
  10438. function plural(ms, msAbs, n, name) {
  10439. var isPlural = msAbs >= n * 1.5;
  10440. return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
  10441. }
  10442. /**
  10443. * This is the common logic for both the Node.js and web browser
  10444. * implementations of `debug()`.
  10445. */
  10446. function setup(env) {
  10447. createDebug.debug = createDebug;
  10448. createDebug.default = createDebug;
  10449. createDebug.coerce = coerce;
  10450. createDebug.disable = disable;
  10451. createDebug.enable = enable;
  10452. createDebug.enabled = enabled;
  10453. createDebug.humanize = ms;
  10454. Object.keys(env).forEach(function (key) {
  10455. createDebug[key] = env[key];
  10456. });
  10457. /**
  10458. * Active `debug` instances.
  10459. */
  10460. createDebug.instances = [];
  10461. /**
  10462. * The currently active debug mode names, and names to skip.
  10463. */
  10464. createDebug.names = [];
  10465. createDebug.skips = [];
  10466. /**
  10467. * Map of special "%n" handling functions, for the debug "format" argument.
  10468. *
  10469. * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
  10470. */
  10471. createDebug.formatters = {};
  10472. /**
  10473. * Selects a color for a debug namespace
  10474. * @param {String} namespace The namespace string for the for the debug instance to be colored
  10475. * @return {Number|String} An ANSI color code for the given namespace
  10476. * @api private
  10477. */
  10478. function selectColor(namespace) {
  10479. var hash = 0;
  10480. for (var i = 0; i < namespace.length; i++) {
  10481. hash = (hash << 5) - hash + namespace.charCodeAt(i);
  10482. hash |= 0; // Convert to 32bit integer
  10483. }
  10484. return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
  10485. }
  10486. createDebug.selectColor = selectColor;
  10487. /**
  10488. * Create a debugger with the given `namespace`.
  10489. *
  10490. * @param {String} namespace
  10491. * @return {Function}
  10492. * @api public
  10493. */
  10494. function createDebug(namespace) {
  10495. var prevTime;
  10496. function debug() {
  10497. // Disabled?
  10498. if (!debug.enabled) {
  10499. return;
  10500. }
  10501. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  10502. args[_key] = arguments[_key];
  10503. }
  10504. var self = debug; // Set `diff` timestamp
  10505. var curr = Number(new Date());
  10506. var ms = curr - (prevTime || curr);
  10507. self.diff = ms;
  10508. self.prev = prevTime;
  10509. self.curr = curr;
  10510. prevTime = curr;
  10511. args[0] = createDebug.coerce(args[0]);
  10512. if (typeof args[0] !== 'string') {
  10513. // Anything else let's inspect with %O
  10514. args.unshift('%O');
  10515. } // Apply any `formatters` transformations
  10516. var index = 0;
  10517. args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) {
  10518. // If we encounter an escaped % then don't increase the array index
  10519. if (match === '%%') {
  10520. return match;
  10521. }
  10522. index++;
  10523. var formatter = createDebug.formatters[format];
  10524. if (typeof formatter === 'function') {
  10525. var val = args[index];
  10526. match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format`
  10527. args.splice(index, 1);
  10528. index--;
  10529. }
  10530. return match;
  10531. }); // Apply env-specific formatting (colors, etc.)
  10532. createDebug.formatArgs.call(self, args);
  10533. var logFn = self.log || createDebug.log;
  10534. logFn.apply(self, args);
  10535. }
  10536. debug.namespace = namespace;
  10537. debug.enabled = createDebug.enabled(namespace);
  10538. debug.useColors = createDebug.useColors();
  10539. debug.color = selectColor(namespace);
  10540. debug.destroy = destroy;
  10541. debug.extend = extend; // Debug.formatArgs = formatArgs;
  10542. // debug.rawLog = rawLog;
  10543. // env-specific initialization logic for debug instances
  10544. if (typeof createDebug.init === 'function') {
  10545. createDebug.init(debug);
  10546. }
  10547. createDebug.instances.push(debug);
  10548. return debug;
  10549. }
  10550. function destroy() {
  10551. var index = createDebug.instances.indexOf(this);
  10552. if (index !== -1) {
  10553. createDebug.instances.splice(index, 1);
  10554. return true;
  10555. }
  10556. return false;
  10557. }
  10558. function extend(namespace, delimiter) {
  10559. return createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
  10560. }
  10561. /**
  10562. * Enables a debug mode by namespaces. This can include modes
  10563. * separated by a colon and wildcards.
  10564. *
  10565. * @param {String} namespaces
  10566. * @api public
  10567. */
  10568. function enable(namespaces) {
  10569. createDebug.save(namespaces);
  10570. createDebug.names = [];
  10571. createDebug.skips = [];
  10572. var i;
  10573. var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
  10574. var len = split.length;
  10575. for (i = 0; i < len; i++) {
  10576. if (!split[i]) {
  10577. // ignore empty strings
  10578. continue;
  10579. }
  10580. namespaces = split[i].replace(/\*/g, '.*?');
  10581. if (namespaces[0] === '-') {
  10582. createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
  10583. } else {
  10584. createDebug.names.push(new RegExp('^' + namespaces + '$'));
  10585. }
  10586. }
  10587. for (i = 0; i < createDebug.instances.length; i++) {
  10588. var instance = createDebug.instances[i];
  10589. instance.enabled = createDebug.enabled(instance.namespace);
  10590. }
  10591. }
  10592. /**
  10593. * Disable debug output.
  10594. *
  10595. * @api public
  10596. */
  10597. function disable() {
  10598. createDebug.enable('');
  10599. }
  10600. /**
  10601. * Returns true if the given mode name is enabled, false otherwise.
  10602. *
  10603. * @param {String} name
  10604. * @return {Boolean}
  10605. * @api public
  10606. */
  10607. function enabled(name) {
  10608. if (name[name.length - 1] === '*') {
  10609. return true;
  10610. }
  10611. var i;
  10612. var len;
  10613. for (i = 0, len = createDebug.skips.length; i < len; i++) {
  10614. if (createDebug.skips[i].test(name)) {
  10615. return false;
  10616. }
  10617. }
  10618. for (i = 0, len = createDebug.names.length; i < len; i++) {
  10619. if (createDebug.names[i].test(name)) {
  10620. return true;
  10621. }
  10622. }
  10623. return false;
  10624. }
  10625. /**
  10626. * Coerce `val`.
  10627. *
  10628. * @param {Mixed} val
  10629. * @return {Mixed}
  10630. * @api private
  10631. */
  10632. function coerce(val) {
  10633. if (val instanceof Error) {
  10634. return val.stack || val.message;
  10635. }
  10636. return val;
  10637. }
  10638. createDebug.enable(createDebug.load());
  10639. return createDebug;
  10640. }
  10641. var common = setup;
  10642. var browser = createCommonjsModule(function (module, exports) {
  10643. 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); }
  10644. /* eslint-env browser */
  10645. /**
  10646. * This is the web browser implementation of `debug()`.
  10647. */
  10648. exports.log = log;
  10649. exports.formatArgs = formatArgs;
  10650. exports.save = save;
  10651. exports.load = load;
  10652. exports.useColors = useColors;
  10653. exports.storage = localstorage();
  10654. /**
  10655. * Colors.
  10656. */
  10657. 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'];
  10658. /**
  10659. * Currently only WebKit-based Web Inspectors, Firefox >= v31,
  10660. * and the Firebug extension (any Firefox version) are known
  10661. * to support "%c" CSS customizations.
  10662. *
  10663. * TODO: add a `localStorage` variable to explicitly enable/disable colors
  10664. */
  10665. // eslint-disable-next-line complexity
  10666. function useColors() {
  10667. // NB: In an Electron preload script, document will be defined but not fully
  10668. // initialized. Since we know we're in Chrome, we'll just detect this case
  10669. // explicitly
  10670. if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
  10671. return true;
  10672. } // Internet Explorer and Edge do not support colors.
  10673. if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
  10674. return false;
  10675. } // Is webkit? http://stackoverflow.com/a/16459606/376773
  10676. // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
  10677. return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773
  10678. typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?
  10679. // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
  10680. 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
  10681. typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
  10682. }
  10683. /**
  10684. * Colorize log arguments if enabled.
  10685. *
  10686. * @api public
  10687. */
  10688. function formatArgs(args) {
  10689. args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff);
  10690. if (!this.useColors) {
  10691. return;
  10692. }
  10693. var c = 'color: ' + this.color;
  10694. args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other
  10695. // arguments passed either before or after the %c, so we need to
  10696. // figure out the correct index to insert the CSS into
  10697. var index = 0;
  10698. var lastC = 0;
  10699. args[0].replace(/%[a-zA-Z%]/g, function (match) {
  10700. if (match === '%%') {
  10701. return;
  10702. }
  10703. index++;
  10704. if (match === '%c') {
  10705. // We only are interested in the *last* %c
  10706. // (the user may have provided their own)
  10707. lastC = index;
  10708. }
  10709. });
  10710. args.splice(lastC, 0, c);
  10711. }
  10712. /**
  10713. * Invokes `console.log()` when available.
  10714. * No-op when `console.log` is not a "function".
  10715. *
  10716. * @api public
  10717. */
  10718. function log() {
  10719. var _console;
  10720. // This hackery is required for IE8/9, where
  10721. // the `console.log` function doesn't have 'apply'
  10722. return (typeof console === "undefined" ? "undefined" : _typeof(console)) === 'object' && console.log && (_console = console).log.apply(_console, arguments);
  10723. }
  10724. /**
  10725. * Save `namespaces`.
  10726. *
  10727. * @param {String} namespaces
  10728. * @api private
  10729. */
  10730. function save(namespaces) {
  10731. try {
  10732. if (namespaces) {
  10733. exports.storage.setItem('debug', namespaces);
  10734. } else {
  10735. exports.storage.removeItem('debug');
  10736. }
  10737. } catch (error) {// Swallow
  10738. // XXX (@Qix-) should we be logging these?
  10739. }
  10740. }
  10741. /**
  10742. * Load `namespaces`.
  10743. *
  10744. * @return {String} returns the previously persisted debug modes
  10745. * @api private
  10746. */
  10747. function load() {
  10748. var r;
  10749. try {
  10750. r = exports.storage.getItem('debug');
  10751. } catch (error) {} // Swallow
  10752. // XXX (@Qix-) should we be logging these?
  10753. // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
  10754. if (!r && typeof process !== 'undefined' && 'env' in process) {
  10755. r = process.env.DEBUG;
  10756. }
  10757. return r;
  10758. }
  10759. /**
  10760. * Localstorage attempts to return the localstorage.
  10761. *
  10762. * This is necessary because safari throws
  10763. * when a user disables cookies/localstorage
  10764. * and you attempt to access it.
  10765. *
  10766. * @return {LocalStorage}
  10767. * @api private
  10768. */
  10769. function localstorage() {
  10770. try {
  10771. // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
  10772. // The Browser also has localStorage in the global context.
  10773. return localStorage;
  10774. } catch (error) {// Swallow
  10775. // XXX (@Qix-) should we be logging these?
  10776. }
  10777. }
  10778. module.exports = common(exports);
  10779. var formatters = module.exports.formatters;
  10780. /**
  10781. * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
  10782. */
  10783. formatters.j = function (v) {
  10784. try {
  10785. return JSON.stringify(v);
  10786. } catch (error) {
  10787. return '[UnexpectedJSONParseError]: ' + error.message;
  10788. }
  10789. };
  10790. });
  10791. var browser_1 = browser.log;
  10792. var browser_2 = browser.formatArgs;
  10793. var browser_3 = browser.save;
  10794. var browser_4 = browser.load;
  10795. var browser_5 = browser.useColors;
  10796. var browser_6 = browser.storage;
  10797. var browser_7 = browser.colors;
  10798. /**
  10799. * Copies the values of `source` to `array`.
  10800. *
  10801. * @private
  10802. * @param {Array} source The array to copy values from.
  10803. * @param {Array} [array=[]] The array to copy values to.
  10804. * @returns {Array} Returns `array`.
  10805. */
  10806. function copyArray(source, array) {
  10807. var index = -1,
  10808. length = source.length;
  10809. array || (array = Array(length));
  10810. while (++index < length) {
  10811. array[index] = source[index];
  10812. }
  10813. return array;
  10814. }
  10815. var _copyArray = copyArray;
  10816. /* Built-in method references for those with the same name as other `lodash` methods. */
  10817. var nativeFloor = Math.floor,
  10818. nativeRandom = Math.random;
  10819. /**
  10820. * The base implementation of `_.random` without support for returning
  10821. * floating-point numbers.
  10822. *
  10823. * @private
  10824. * @param {number} lower The lower bound.
  10825. * @param {number} upper The upper bound.
  10826. * @returns {number} Returns the random number.
  10827. */
  10828. function baseRandom(lower, upper) {
  10829. return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
  10830. }
  10831. var _baseRandom = baseRandom;
  10832. /**
  10833. * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
  10834. *
  10835. * @private
  10836. * @param {Array} array The array to shuffle.
  10837. * @param {number} [size=array.length] The size of `array`.
  10838. * @returns {Array} Returns `array`.
  10839. */
  10840. function shuffleSelf(array, size) {
  10841. var index = -1,
  10842. length = array.length,
  10843. lastIndex = length - 1;
  10844. size = size === undefined ? length : size;
  10845. while (++index < size) {
  10846. var rand = _baseRandom(index, lastIndex),
  10847. value = array[rand];
  10848. array[rand] = array[index];
  10849. array[index] = value;
  10850. }
  10851. array.length = size;
  10852. return array;
  10853. }
  10854. var _shuffleSelf = shuffleSelf;
  10855. /**
  10856. * A specialized version of `_.shuffle` for arrays.
  10857. *
  10858. * @private
  10859. * @param {Array} array The array to shuffle.
  10860. * @returns {Array} Returns the new shuffled array.
  10861. */
  10862. function arrayShuffle(array) {
  10863. return _shuffleSelf(_copyArray(array));
  10864. }
  10865. var _arrayShuffle = arrayShuffle;
  10866. /**
  10867. * A specialized version of `_.map` for arrays without support for iteratee
  10868. * shorthands.
  10869. *
  10870. * @private
  10871. * @param {Array} [array] The array to iterate over.
  10872. * @param {Function} iteratee The function invoked per iteration.
  10873. * @returns {Array} Returns the new mapped array.
  10874. */
  10875. function arrayMap(array, iteratee) {
  10876. var index = -1,
  10877. length = array == null ? 0 : array.length,
  10878. result = Array(length);
  10879. while (++index < length) {
  10880. result[index] = iteratee(array[index], index, array);
  10881. }
  10882. return result;
  10883. }
  10884. var _arrayMap = arrayMap;
  10885. /**
  10886. * The base implementation of `_.values` and `_.valuesIn` which creates an
  10887. * array of `object` property values corresponding to the property names
  10888. * of `props`.
  10889. *
  10890. * @private
  10891. * @param {Object} object The object to query.
  10892. * @param {Array} props The property names to get values for.
  10893. * @returns {Object} Returns the array of property values.
  10894. */
  10895. function baseValues(object, props) {
  10896. return _arrayMap(props, function(key) {
  10897. return object[key];
  10898. });
  10899. }
  10900. var _baseValues = baseValues;
  10901. /**
  10902. * The base implementation of `_.times` without support for iteratee shorthands
  10903. * or max array length checks.
  10904. *
  10905. * @private
  10906. * @param {number} n The number of times to invoke `iteratee`.
  10907. * @param {Function} iteratee The function invoked per iteration.
  10908. * @returns {Array} Returns the array of results.
  10909. */
  10910. function baseTimes(n, iteratee) {
  10911. var index = -1,
  10912. result = Array(n);
  10913. while (++index < n) {
  10914. result[index] = iteratee(index);
  10915. }
  10916. return result;
  10917. }
  10918. var _baseTimes = baseTimes;
  10919. /** Detect free variable `global` from Node.js. */
  10920. var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
  10921. var _freeGlobal = freeGlobal;
  10922. /** Detect free variable `self`. */
  10923. var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
  10924. /** Used as a reference to the global object. */
  10925. var root = _freeGlobal || freeSelf || Function('return this')();
  10926. var _root = root;
  10927. /** Built-in value references. */
  10928. var Symbol$1 = _root.Symbol;
  10929. var _Symbol = Symbol$1;
  10930. /** Used for built-in method references. */
  10931. var objectProto = Object.prototype;
  10932. /** Used to check objects for own properties. */
  10933. var hasOwnProperty = objectProto.hasOwnProperty;
  10934. /**
  10935. * Used to resolve the
  10936. * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
  10937. * of values.
  10938. */
  10939. var nativeObjectToString = objectProto.toString;
  10940. /** Built-in value references. */
  10941. var symToStringTag = _Symbol ? _Symbol.toStringTag : undefined;
  10942. /**
  10943. * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
  10944. *
  10945. * @private
  10946. * @param {*} value The value to query.
  10947. * @returns {string} Returns the raw `toStringTag`.
  10948. */
  10949. function getRawTag(value) {
  10950. var isOwn = hasOwnProperty.call(value, symToStringTag),
  10951. tag = value[symToStringTag];
  10952. try {
  10953. value[symToStringTag] = undefined;
  10954. var unmasked = true;
  10955. } catch (e) {}
  10956. var result = nativeObjectToString.call(value);
  10957. if (unmasked) {
  10958. if (isOwn) {
  10959. value[symToStringTag] = tag;
  10960. } else {
  10961. delete value[symToStringTag];
  10962. }
  10963. }
  10964. return result;
  10965. }
  10966. var _getRawTag = getRawTag;
  10967. /** Used for built-in method references. */
  10968. var objectProto$1 = Object.prototype;
  10969. /**
  10970. * Used to resolve the
  10971. * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
  10972. * of values.
  10973. */
  10974. var nativeObjectToString$1 = objectProto$1.toString;
  10975. /**
  10976. * Converts `value` to a string using `Object.prototype.toString`.
  10977. *
  10978. * @private
  10979. * @param {*} value The value to convert.
  10980. * @returns {string} Returns the converted string.
  10981. */
  10982. function objectToString(value) {
  10983. return nativeObjectToString$1.call(value);
  10984. }
  10985. var _objectToString = objectToString;
  10986. /** `Object#toString` result references. */
  10987. var nullTag = '[object Null]',
  10988. undefinedTag = '[object Undefined]';
  10989. /** Built-in value references. */
  10990. var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined;
  10991. /**
  10992. * The base implementation of `getTag` without fallbacks for buggy environments.
  10993. *
  10994. * @private
  10995. * @param {*} value The value to query.
  10996. * @returns {string} Returns the `toStringTag`.
  10997. */
  10998. function baseGetTag(value) {
  10999. if (value == null) {
  11000. return value === undefined ? undefinedTag : nullTag;
  11001. }
  11002. return (symToStringTag$1 && symToStringTag$1 in Object(value))
  11003. ? _getRawTag(value)
  11004. : _objectToString(value);
  11005. }
  11006. var _baseGetTag = baseGetTag;
  11007. /**
  11008. * Checks if `value` is object-like. A value is object-like if it's not `null`
  11009. * and has a `typeof` result of "object".
  11010. *
  11011. * @static
  11012. * @memberOf _
  11013. * @since 4.0.0
  11014. * @category Lang
  11015. * @param {*} value The value to check.
  11016. * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
  11017. * @example
  11018. *
  11019. * _.isObjectLike({});
  11020. * // => true
  11021. *
  11022. * _.isObjectLike([1, 2, 3]);
  11023. * // => true
  11024. *
  11025. * _.isObjectLike(_.noop);
  11026. * // => false
  11027. *
  11028. * _.isObjectLike(null);
  11029. * // => false
  11030. */
  11031. function isObjectLike(value) {
  11032. return value != null && typeof value == 'object';
  11033. }
  11034. var isObjectLike_1 = isObjectLike;
  11035. /** `Object#toString` result references. */
  11036. var argsTag = '[object Arguments]';
  11037. /**
  11038. * The base implementation of `_.isArguments`.
  11039. *
  11040. * @private
  11041. * @param {*} value The value to check.
  11042. * @returns {boolean} Returns `true` if `value` is an `arguments` object,
  11043. */
  11044. function baseIsArguments(value) {
  11045. return isObjectLike_1(value) && _baseGetTag(value) == argsTag;
  11046. }
  11047. var _baseIsArguments = baseIsArguments;
  11048. /** Used for built-in method references. */
  11049. var objectProto$2 = Object.prototype;
  11050. /** Used to check objects for own properties. */
  11051. var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
  11052. /** Built-in value references. */
  11053. var propertyIsEnumerable = objectProto$2.propertyIsEnumerable;
  11054. /**
  11055. * Checks if `value` is likely an `arguments` object.
  11056. *
  11057. * @static
  11058. * @memberOf _
  11059. * @since 0.1.0
  11060. * @category Lang
  11061. * @param {*} value The value to check.
  11062. * @returns {boolean} Returns `true` if `value` is an `arguments` object,
  11063. * else `false`.
  11064. * @example
  11065. *
  11066. * _.isArguments(function() { return arguments; }());
  11067. * // => true
  11068. *
  11069. * _.isArguments([1, 2, 3]);
  11070. * // => false
  11071. */
  11072. var isArguments = _baseIsArguments(function() { return arguments; }()) ? _baseIsArguments : function(value) {
  11073. return isObjectLike_1(value) && hasOwnProperty$1.call(value, 'callee') &&
  11074. !propertyIsEnumerable.call(value, 'callee');
  11075. };
  11076. var isArguments_1 = isArguments;
  11077. /**
  11078. * Checks if `value` is classified as an `Array` object.
  11079. *
  11080. * @static
  11081. * @memberOf _
  11082. * @since 0.1.0
  11083. * @category Lang
  11084. * @param {*} value The value to check.
  11085. * @returns {boolean} Returns `true` if `value` is an array, else `false`.
  11086. * @example
  11087. *
  11088. * _.isArray([1, 2, 3]);
  11089. * // => true
  11090. *
  11091. * _.isArray(document.body.children);
  11092. * // => false
  11093. *
  11094. * _.isArray('abc');
  11095. * // => false
  11096. *
  11097. * _.isArray(_.noop);
  11098. * // => false
  11099. */
  11100. var isArray = Array.isArray;
  11101. var isArray_1 = isArray;
  11102. /**
  11103. * This method returns `false`.
  11104. *
  11105. * @static
  11106. * @memberOf _
  11107. * @since 4.13.0
  11108. * @category Util
  11109. * @returns {boolean} Returns `false`.
  11110. * @example
  11111. *
  11112. * _.times(2, _.stubFalse);
  11113. * // => [false, false]
  11114. */
  11115. function stubFalse() {
  11116. return false;
  11117. }
  11118. var stubFalse_1 = stubFalse;
  11119. var isBuffer_1 = createCommonjsModule(function (module, exports) {
  11120. /** Detect free variable `exports`. */
  11121. var freeExports = exports && !exports.nodeType && exports;
  11122. /** Detect free variable `module`. */
  11123. var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
  11124. /** Detect the popular CommonJS extension `module.exports`. */
  11125. var moduleExports = freeModule && freeModule.exports === freeExports;
  11126. /** Built-in value references. */
  11127. var Buffer = moduleExports ? _root.Buffer : undefined;
  11128. /* Built-in method references for those with the same name as other `lodash` methods. */
  11129. var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
  11130. /**
  11131. * Checks if `value` is a buffer.
  11132. *
  11133. * @static
  11134. * @memberOf _
  11135. * @since 4.3.0
  11136. * @category Lang
  11137. * @param {*} value The value to check.
  11138. * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
  11139. * @example
  11140. *
  11141. * _.isBuffer(new Buffer(2));
  11142. * // => true
  11143. *
  11144. * _.isBuffer(new Uint8Array(2));
  11145. * // => false
  11146. */
  11147. var isBuffer = nativeIsBuffer || stubFalse_1;
  11148. module.exports = isBuffer;
  11149. });
  11150. /** Used as references for various `Number` constants. */
  11151. var MAX_SAFE_INTEGER = 9007199254740991;
  11152. /** Used to detect unsigned integer values. */
  11153. var reIsUint = /^(?:0|[1-9]\d*)$/;
  11154. /**
  11155. * Checks if `value` is a valid array-like index.
  11156. *
  11157. * @private
  11158. * @param {*} value The value to check.
  11159. * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
  11160. * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
  11161. */
  11162. function isIndex(value, length) {
  11163. var type = typeof value;
  11164. length = length == null ? MAX_SAFE_INTEGER : length;
  11165. return !!length &&
  11166. (type == 'number' ||
  11167. (type != 'symbol' && reIsUint.test(value))) &&
  11168. (value > -1 && value % 1 == 0 && value < length);
  11169. }
  11170. var _isIndex = isIndex;
  11171. /** Used as references for various `Number` constants. */
  11172. var MAX_SAFE_INTEGER$1 = 9007199254740991;
  11173. /**
  11174. * Checks if `value` is a valid array-like length.
  11175. *
  11176. * **Note:** This method is loosely based on
  11177. * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
  11178. *
  11179. * @static
  11180. * @memberOf _
  11181. * @since 4.0.0
  11182. * @category Lang
  11183. * @param {*} value The value to check.
  11184. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
  11185. * @example
  11186. *
  11187. * _.isLength(3);
  11188. * // => true
  11189. *
  11190. * _.isLength(Number.MIN_VALUE);
  11191. * // => false
  11192. *
  11193. * _.isLength(Infinity);
  11194. * // => false
  11195. *
  11196. * _.isLength('3');
  11197. * // => false
  11198. */
  11199. function isLength(value) {
  11200. return typeof value == 'number' &&
  11201. value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1;
  11202. }
  11203. var isLength_1 = isLength;
  11204. /** `Object#toString` result references. */
  11205. var argsTag$1 = '[object Arguments]',
  11206. arrayTag = '[object Array]',
  11207. boolTag = '[object Boolean]',
  11208. dateTag = '[object Date]',
  11209. errorTag = '[object Error]',
  11210. funcTag = '[object Function]',
  11211. mapTag = '[object Map]',
  11212. numberTag = '[object Number]',
  11213. objectTag = '[object Object]',
  11214. regexpTag = '[object RegExp]',
  11215. setTag = '[object Set]',
  11216. stringTag = '[object String]',
  11217. weakMapTag = '[object WeakMap]';
  11218. var arrayBufferTag = '[object ArrayBuffer]',
  11219. dataViewTag = '[object DataView]',
  11220. float32Tag = '[object Float32Array]',
  11221. float64Tag = '[object Float64Array]',
  11222. int8Tag = '[object Int8Array]',
  11223. int16Tag = '[object Int16Array]',
  11224. int32Tag = '[object Int32Array]',
  11225. uint8Tag = '[object Uint8Array]',
  11226. uint8ClampedTag = '[object Uint8ClampedArray]',
  11227. uint16Tag = '[object Uint16Array]',
  11228. uint32Tag = '[object Uint32Array]';
  11229. /** Used to identify `toStringTag` values of typed arrays. */
  11230. var typedArrayTags = {};
  11231. typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
  11232. typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
  11233. typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
  11234. typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
  11235. typedArrayTags[uint32Tag] = true;
  11236. typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] =
  11237. typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
  11238. typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
  11239. typedArrayTags[errorTag] = typedArrayTags[funcTag] =
  11240. typedArrayTags[mapTag] = typedArrayTags[numberTag] =
  11241. typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
  11242. typedArrayTags[setTag] = typedArrayTags[stringTag] =
  11243. typedArrayTags[weakMapTag] = false;
  11244. /**
  11245. * The base implementation of `_.isTypedArray` without Node.js optimizations.
  11246. *
  11247. * @private
  11248. * @param {*} value The value to check.
  11249. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
  11250. */
  11251. function baseIsTypedArray(value) {
  11252. return isObjectLike_1(value) &&
  11253. isLength_1(value.length) && !!typedArrayTags[_baseGetTag(value)];
  11254. }
  11255. var _baseIsTypedArray = baseIsTypedArray;
  11256. /**
  11257. * The base implementation of `_.unary` without support for storing metadata.
  11258. *
  11259. * @private
  11260. * @param {Function} func The function to cap arguments for.
  11261. * @returns {Function} Returns the new capped function.
  11262. */
  11263. function baseUnary(func) {
  11264. return function(value) {
  11265. return func(value);
  11266. };
  11267. }
  11268. var _baseUnary = baseUnary;
  11269. var _nodeUtil = createCommonjsModule(function (module, exports) {
  11270. /** Detect free variable `exports`. */
  11271. var freeExports = exports && !exports.nodeType && exports;
  11272. /** Detect free variable `module`. */
  11273. var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
  11274. /** Detect the popular CommonJS extension `module.exports`. */
  11275. var moduleExports = freeModule && freeModule.exports === freeExports;
  11276. /** Detect free variable `process` from Node.js. */
  11277. var freeProcess = moduleExports && _freeGlobal.process;
  11278. /** Used to access faster Node.js helpers. */
  11279. var nodeUtil = (function() {
  11280. try {
  11281. // Use `util.types` for Node.js 10+.
  11282. var types = freeModule && freeModule.require && freeModule.require('util').types;
  11283. if (types) {
  11284. return types;
  11285. }
  11286. // Legacy `process.binding('util')` for Node.js < 10.
  11287. return freeProcess && freeProcess.binding && freeProcess.binding('util');
  11288. } catch (e) {}
  11289. }());
  11290. module.exports = nodeUtil;
  11291. });
  11292. /* Node.js helper references. */
  11293. var nodeIsTypedArray = _nodeUtil && _nodeUtil.isTypedArray;
  11294. /**
  11295. * Checks if `value` is classified as a typed array.
  11296. *
  11297. * @static
  11298. * @memberOf _
  11299. * @since 3.0.0
  11300. * @category Lang
  11301. * @param {*} value The value to check.
  11302. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
  11303. * @example
  11304. *
  11305. * _.isTypedArray(new Uint8Array);
  11306. * // => true
  11307. *
  11308. * _.isTypedArray([]);
  11309. * // => false
  11310. */
  11311. var isTypedArray = nodeIsTypedArray ? _baseUnary(nodeIsTypedArray) : _baseIsTypedArray;
  11312. var isTypedArray_1 = isTypedArray;
  11313. /** Used for built-in method references. */
  11314. var objectProto$3 = Object.prototype;
  11315. /** Used to check objects for own properties. */
  11316. var hasOwnProperty$2 = objectProto$3.hasOwnProperty;
  11317. /**
  11318. * Creates an array of the enumerable property names of the array-like `value`.
  11319. *
  11320. * @private
  11321. * @param {*} value The value to query.
  11322. * @param {boolean} inherited Specify returning inherited property names.
  11323. * @returns {Array} Returns the array of property names.
  11324. */
  11325. function arrayLikeKeys(value, inherited) {
  11326. var isArr = isArray_1(value),
  11327. isArg = !isArr && isArguments_1(value),
  11328. isBuff = !isArr && !isArg && isBuffer_1(value),
  11329. isType = !isArr && !isArg && !isBuff && isTypedArray_1(value),
  11330. skipIndexes = isArr || isArg || isBuff || isType,
  11331. result = skipIndexes ? _baseTimes(value.length, String) : [],
  11332. length = result.length;
  11333. for (var key in value) {
  11334. if ((inherited || hasOwnProperty$2.call(value, key)) &&
  11335. !(skipIndexes && (
  11336. // Safari 9 has enumerable `arguments.length` in strict mode.
  11337. key == 'length' ||
  11338. // Node.js 0.10 has enumerable non-index properties on buffers.
  11339. (isBuff && (key == 'offset' || key == 'parent')) ||
  11340. // PhantomJS 2 has enumerable non-index properties on typed arrays.
  11341. (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
  11342. // Skip index properties.
  11343. _isIndex(key, length)
  11344. ))) {
  11345. result.push(key);
  11346. }
  11347. }
  11348. return result;
  11349. }
  11350. var _arrayLikeKeys = arrayLikeKeys;
  11351. /** Used for built-in method references. */
  11352. var objectProto$4 = Object.prototype;
  11353. /**
  11354. * Checks if `value` is likely a prototype object.
  11355. *
  11356. * @private
  11357. * @param {*} value The value to check.
  11358. * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
  11359. */
  11360. function isPrototype(value) {
  11361. var Ctor = value && value.constructor,
  11362. proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$4;
  11363. return value === proto;
  11364. }
  11365. var _isPrototype = isPrototype;
  11366. /**
  11367. * Creates a unary function that invokes `func` with its argument transformed.
  11368. *
  11369. * @private
  11370. * @param {Function} func The function to wrap.
  11371. * @param {Function} transform The argument transform.
  11372. * @returns {Function} Returns the new function.
  11373. */
  11374. function overArg(func, transform) {
  11375. return function(arg) {
  11376. return func(transform(arg));
  11377. };
  11378. }
  11379. var _overArg = overArg;
  11380. /* Built-in method references for those with the same name as other `lodash` methods. */
  11381. var nativeKeys = _overArg(Object.keys, Object);
  11382. var _nativeKeys = nativeKeys;
  11383. /** Used for built-in method references. */
  11384. var objectProto$5 = Object.prototype;
  11385. /** Used to check objects for own properties. */
  11386. var hasOwnProperty$3 = objectProto$5.hasOwnProperty;
  11387. /**
  11388. * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
  11389. *
  11390. * @private
  11391. * @param {Object} object The object to query.
  11392. * @returns {Array} Returns the array of property names.
  11393. */
  11394. function baseKeys(object) {
  11395. if (!_isPrototype(object)) {
  11396. return _nativeKeys(object);
  11397. }
  11398. var result = [];
  11399. for (var key in Object(object)) {
  11400. if (hasOwnProperty$3.call(object, key) && key != 'constructor') {
  11401. result.push(key);
  11402. }
  11403. }
  11404. return result;
  11405. }
  11406. var _baseKeys = baseKeys;
  11407. /**
  11408. * Checks if `value` is the
  11409. * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
  11410. * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  11411. *
  11412. * @static
  11413. * @memberOf _
  11414. * @since 0.1.0
  11415. * @category Lang
  11416. * @param {*} value The value to check.
  11417. * @returns {boolean} Returns `true` if `value` is an object, else `false`.
  11418. * @example
  11419. *
  11420. * _.isObject({});
  11421. * // => true
  11422. *
  11423. * _.isObject([1, 2, 3]);
  11424. * // => true
  11425. *
  11426. * _.isObject(_.noop);
  11427. * // => true
  11428. *
  11429. * _.isObject(null);
  11430. * // => false
  11431. */
  11432. function isObject(value) {
  11433. var type = typeof value;
  11434. return value != null && (type == 'object' || type == 'function');
  11435. }
  11436. var isObject_1 = isObject;
  11437. /** `Object#toString` result references. */
  11438. var asyncTag = '[object AsyncFunction]',
  11439. funcTag$1 = '[object Function]',
  11440. genTag = '[object GeneratorFunction]',
  11441. proxyTag = '[object Proxy]';
  11442. /**
  11443. * Checks if `value` is classified as a `Function` object.
  11444. *
  11445. * @static
  11446. * @memberOf _
  11447. * @since 0.1.0
  11448. * @category Lang
  11449. * @param {*} value The value to check.
  11450. * @returns {boolean} Returns `true` if `value` is a function, else `false`.
  11451. * @example
  11452. *
  11453. * _.isFunction(_);
  11454. * // => true
  11455. *
  11456. * _.isFunction(/abc/);
  11457. * // => false
  11458. */
  11459. function isFunction(value) {
  11460. if (!isObject_1(value)) {
  11461. return false;
  11462. }
  11463. // The use of `Object#toString` avoids issues with the `typeof` operator
  11464. // in Safari 9 which returns 'object' for typed arrays and other constructors.
  11465. var tag = _baseGetTag(value);
  11466. return tag == funcTag$1 || tag == genTag || tag == asyncTag || tag == proxyTag;
  11467. }
  11468. var isFunction_1 = isFunction;
  11469. /**
  11470. * Checks if `value` is array-like. A value is considered array-like if it's
  11471. * not a function and has a `value.length` that's an integer greater than or
  11472. * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
  11473. *
  11474. * @static
  11475. * @memberOf _
  11476. * @since 4.0.0
  11477. * @category Lang
  11478. * @param {*} value The value to check.
  11479. * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
  11480. * @example
  11481. *
  11482. * _.isArrayLike([1, 2, 3]);
  11483. * // => true
  11484. *
  11485. * _.isArrayLike(document.body.children);
  11486. * // => true
  11487. *
  11488. * _.isArrayLike('abc');
  11489. * // => true
  11490. *
  11491. * _.isArrayLike(_.noop);
  11492. * // => false
  11493. */
  11494. function isArrayLike(value) {
  11495. return value != null && isLength_1(value.length) && !isFunction_1(value);
  11496. }
  11497. var isArrayLike_1 = isArrayLike;
  11498. /**
  11499. * Creates an array of the own enumerable property names of `object`.
  11500. *
  11501. * **Note:** Non-object values are coerced to objects. See the
  11502. * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
  11503. * for more details.
  11504. *
  11505. * @static
  11506. * @since 0.1.0
  11507. * @memberOf _
  11508. * @category Object
  11509. * @param {Object} object The object to query.
  11510. * @returns {Array} Returns the array of property names.
  11511. * @example
  11512. *
  11513. * function Foo() {
  11514. * this.a = 1;
  11515. * this.b = 2;
  11516. * }
  11517. *
  11518. * Foo.prototype.c = 3;
  11519. *
  11520. * _.keys(new Foo);
  11521. * // => ['a', 'b'] (iteration order is not guaranteed)
  11522. *
  11523. * _.keys('hi');
  11524. * // => ['0', '1']
  11525. */
  11526. function keys(object) {
  11527. return isArrayLike_1(object) ? _arrayLikeKeys(object) : _baseKeys(object);
  11528. }
  11529. var keys_1 = keys;
  11530. /**
  11531. * Creates an array of the own enumerable string keyed property values of `object`.
  11532. *
  11533. * **Note:** Non-object values are coerced to objects.
  11534. *
  11535. * @static
  11536. * @since 0.1.0
  11537. * @memberOf _
  11538. * @category Object
  11539. * @param {Object} object The object to query.
  11540. * @returns {Array} Returns the array of property values.
  11541. * @example
  11542. *
  11543. * function Foo() {
  11544. * this.a = 1;
  11545. * this.b = 2;
  11546. * }
  11547. *
  11548. * Foo.prototype.c = 3;
  11549. *
  11550. * _.values(new Foo);
  11551. * // => [1, 2] (iteration order is not guaranteed)
  11552. *
  11553. * _.values('hi');
  11554. * // => ['h', 'i']
  11555. */
  11556. function values(object) {
  11557. return object == null ? [] : _baseValues(object, keys_1(object));
  11558. }
  11559. var values_1 = values;
  11560. /**
  11561. * The base implementation of `_.shuffle`.
  11562. *
  11563. * @private
  11564. * @param {Array|Object} collection The collection to shuffle.
  11565. * @returns {Array} Returns the new shuffled array.
  11566. */
  11567. function baseShuffle(collection) {
  11568. return _shuffleSelf(values_1(collection));
  11569. }
  11570. var _baseShuffle = baseShuffle;
  11571. /**
  11572. * Creates an array of shuffled values, using a version of the
  11573. * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
  11574. *
  11575. * @static
  11576. * @memberOf _
  11577. * @since 0.1.0
  11578. * @category Collection
  11579. * @param {Array|Object} collection The collection to shuffle.
  11580. * @returns {Array} Returns the new shuffled array.
  11581. * @example
  11582. *
  11583. * _.shuffle([1, 2, 3, 4]);
  11584. * // => [4, 1, 3, 2]
  11585. */
  11586. function shuffle(collection) {
  11587. var func = isArray_1(collection) ? _arrayShuffle : _baseShuffle;
  11588. return func(collection);
  11589. }
  11590. var shuffle_1 = shuffle;
  11591. function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
  11592. var desc = {};
  11593. Object.keys(descriptor).forEach(function (key) {
  11594. desc[key] = descriptor[key];
  11595. });
  11596. desc.enumerable = !!desc.enumerable;
  11597. desc.configurable = !!desc.configurable;
  11598. if ('value' in desc || desc.initializer) {
  11599. desc.writable = true;
  11600. }
  11601. desc = decorators.slice().reverse().reduce(function (desc, decorator) {
  11602. return decorator(target, property, desc) || desc;
  11603. }, desc);
  11604. if (context && desc.initializer !== void 0) {
  11605. desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
  11606. desc.initializer = undefined;
  11607. }
  11608. if (desc.initializer === void 0) {
  11609. Object.defineProperty(target, property, desc);
  11610. desc = null;
  11611. }
  11612. return desc;
  11613. }
  11614. var stateMachine = createCommonjsModule(function (module, exports) {
  11615. /*
  11616. Javascript State Machine Library - https://github.com/jakesgordon/javascript-state-machine
  11617. Copyright (c) 2012, 2013, 2014, 2015, Jake Gordon and contributors
  11618. Released under the MIT license - https://github.com/jakesgordon/javascript-state-machine/blob/master/LICENSE
  11619. */
  11620. (function () {
  11621. var StateMachine = {
  11622. //---------------------------------------------------------------------------
  11623. VERSION: "2.4.0",
  11624. //---------------------------------------------------------------------------
  11625. Result: {
  11626. SUCCEEDED: 1, // the event transitioned successfully from one state to another
  11627. NOTRANSITION: 2, // the event was successfull but no state transition was necessary
  11628. CANCELLED: 3, // the event was cancelled by the caller in a beforeEvent callback
  11629. PENDING: 4 // the event is asynchronous and the caller is in control of when the transition occurs
  11630. },
  11631. Error: {
  11632. INVALID_TRANSITION: 100, // caller tried to fire an event that was innapropriate in the current state
  11633. PENDING_TRANSITION: 200, // caller tried to fire an event while an async transition was still pending
  11634. INVALID_CALLBACK: 300 // caller provided callback function threw an exception
  11635. },
  11636. WILDCARD: '*',
  11637. ASYNC: 'async',
  11638. //---------------------------------------------------------------------------
  11639. create: function(cfg, target) {
  11640. 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 }
  11641. var terminal = cfg.terminal || cfg['final'];
  11642. var fsm = target || cfg.target || {};
  11643. var events = cfg.events || [];
  11644. var callbacks = cfg.callbacks || {};
  11645. var map = {}; // track state transitions allowed for an event { event: { from: [ to ] } }
  11646. var transitions = {}; // track events allowed from a state { state: [ event ] }
  11647. var add = function(e) {
  11648. var from = Array.isArray(e.from) ? e.from : (e.from ? [e.from] : [StateMachine.WILDCARD]); // allow 'wildcard' transition if 'from' is not specified
  11649. map[e.name] = map[e.name] || {};
  11650. for (var n = 0 ; n < from.length ; n++) {
  11651. transitions[from[n]] = transitions[from[n]] || [];
  11652. transitions[from[n]].push(e.name);
  11653. map[e.name][from[n]] = e.to || from[n]; // allow no-op transition if 'to' is not specified
  11654. }
  11655. if (e.to)
  11656. transitions[e.to] = transitions[e.to] || [];
  11657. };
  11658. if (initial) {
  11659. initial.event = initial.event || 'startup';
  11660. add({ name: initial.event, from: 'none', to: initial.state });
  11661. }
  11662. for(var n = 0 ; n < events.length ; n++)
  11663. add(events[n]);
  11664. for(var name in map) {
  11665. if (map.hasOwnProperty(name))
  11666. fsm[name] = StateMachine.buildEvent(name, map[name]);
  11667. }
  11668. for(var name in callbacks) {
  11669. if (callbacks.hasOwnProperty(name))
  11670. fsm[name] = callbacks[name];
  11671. }
  11672. fsm.current = 'none';
  11673. fsm.is = function(state) { return Array.isArray(state) ? (state.indexOf(this.current) >= 0) : (this.current === state); };
  11674. fsm.can = function(event) { return !this.transition && (map[event] !== undefined) && (map[event].hasOwnProperty(this.current) || map[event].hasOwnProperty(StateMachine.WILDCARD)); };
  11675. fsm.cannot = function(event) { return !this.can(event); };
  11676. fsm.transitions = function() { return (transitions[this.current] || []).concat(transitions[StateMachine.WILDCARD] || []); };
  11677. fsm.isFinished = function() { return this.is(terminal); };
  11678. 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)
  11679. fsm.states = function() { return Object.keys(transitions).sort() };
  11680. if (initial && !initial.defer)
  11681. fsm[initial.event]();
  11682. return fsm;
  11683. },
  11684. //===========================================================================
  11685. doCallback: function(fsm, func, name, from, to, args) {
  11686. if (func) {
  11687. try {
  11688. return func.apply(fsm, [name, from, to].concat(args));
  11689. }
  11690. catch(e) {
  11691. return fsm.error(name, from, to, args, StateMachine.Error.INVALID_CALLBACK, "an exception occurred in a caller-provided callback function", e);
  11692. }
  11693. }
  11694. },
  11695. beforeAnyEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbeforeevent'], name, from, to, args); },
  11696. afterAnyEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafterevent'] || fsm['onevent'], name, from, to, args); },
  11697. leaveAnyState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleavestate'], name, from, to, args); },
  11698. enterAnyState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenterstate'] || fsm['onstate'], name, from, to, args); },
  11699. changeState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onchangestate'], name, from, to, args); },
  11700. beforeThisEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbefore' + name], name, from, to, args); },
  11701. afterThisEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafter' + name] || fsm['on' + name], name, from, to, args); },
  11702. leaveThisState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleave' + from], name, from, to, args); },
  11703. enterThisState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenter' + to] || fsm['on' + to], name, from, to, args); },
  11704. beforeEvent: function(fsm, name, from, to, args) {
  11705. if ((false === StateMachine.beforeThisEvent(fsm, name, from, to, args)) ||
  11706. (false === StateMachine.beforeAnyEvent( fsm, name, from, to, args)))
  11707. return false;
  11708. },
  11709. afterEvent: function(fsm, name, from, to, args) {
  11710. StateMachine.afterThisEvent(fsm, name, from, to, args);
  11711. StateMachine.afterAnyEvent( fsm, name, from, to, args);
  11712. },
  11713. leaveState: function(fsm, name, from, to, args) {
  11714. var specific = StateMachine.leaveThisState(fsm, name, from, to, args),
  11715. general = StateMachine.leaveAnyState( fsm, name, from, to, args);
  11716. if ((false === specific) || (false === general))
  11717. return false;
  11718. else if ((StateMachine.ASYNC === specific) || (StateMachine.ASYNC === general))
  11719. return StateMachine.ASYNC;
  11720. },
  11721. enterState: function(fsm, name, from, to, args) {
  11722. StateMachine.enterThisState(fsm, name, from, to, args);
  11723. StateMachine.enterAnyState( fsm, name, from, to, args);
  11724. },
  11725. //===========================================================================
  11726. buildEvent: function(name, map) {
  11727. return function() {
  11728. var from = this.current;
  11729. var to = map[from] || (map[StateMachine.WILDCARD] != StateMachine.WILDCARD ? map[StateMachine.WILDCARD] : from) || from;
  11730. var args = Array.prototype.slice.call(arguments); // turn arguments into pure array
  11731. if (this.transition)
  11732. return this.error(name, from, to, args, StateMachine.Error.PENDING_TRANSITION, "event " + name + " inappropriate because previous transition did not complete");
  11733. if (this.cannot(name))
  11734. return this.error(name, from, to, args, StateMachine.Error.INVALID_TRANSITION, "event " + name + " inappropriate in current state " + this.current);
  11735. if (false === StateMachine.beforeEvent(this, name, from, to, args))
  11736. return StateMachine.Result.CANCELLED;
  11737. if (from === to) {
  11738. StateMachine.afterEvent(this, name, from, to, args);
  11739. return StateMachine.Result.NOTRANSITION;
  11740. }
  11741. // 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)
  11742. var fsm = this;
  11743. this.transition = function() {
  11744. fsm.transition = null; // this method should only ever be called once
  11745. fsm.current = to;
  11746. StateMachine.enterState( fsm, name, from, to, args);
  11747. StateMachine.changeState(fsm, name, from, to, args);
  11748. StateMachine.afterEvent( fsm, name, from, to, args);
  11749. return StateMachine.Result.SUCCEEDED;
  11750. };
  11751. this.transition.cancel = function() { // provide a way for caller to cancel async transition if desired (issue #22)
  11752. fsm.transition = null;
  11753. StateMachine.afterEvent(fsm, name, from, to, args);
  11754. };
  11755. var leave = StateMachine.leaveState(this, name, from, to, args);
  11756. if (false === leave) {
  11757. this.transition = null;
  11758. return StateMachine.Result.CANCELLED;
  11759. }
  11760. else if (StateMachine.ASYNC === leave) {
  11761. return StateMachine.Result.PENDING;
  11762. }
  11763. else {
  11764. if (this.transition) // need to check in case user manually called transition() but forgot to return StateMachine.ASYNC
  11765. return this.transition();
  11766. }
  11767. };
  11768. }
  11769. }; // StateMachine
  11770. //===========================================================================
  11771. //======
  11772. // NODE
  11773. //======
  11774. {
  11775. if ( module.exports) {
  11776. exports = module.exports = StateMachine;
  11777. }
  11778. exports.StateMachine = StateMachine;
  11779. }
  11780. }());
  11781. });
  11782. var stateMachine_1 = stateMachine.StateMachine;
  11783. const adapters = {};
  11784. const getAdapter = name => {
  11785. const adapter = adapters[name];
  11786. if (adapter === undefined) {
  11787. throw new Error(`${name} adapter is not configured`);
  11788. }
  11789. return adapter;
  11790. };
  11791. /**
  11792. * 指定 Adapters
  11793. * @function
  11794. * @memberof module:leancloud-realtime
  11795. * @param {Adapters} newAdapters Adapters 的类型请参考 {@link https://url.leanapp.cn/adapter-type-definitions @leancloud/adapter-types} 中的定义
  11796. */
  11797. const setAdapters = newAdapters => {
  11798. Object.assign(adapters, newAdapters);
  11799. };
  11800. /** Built-in value references. */
  11801. var getPrototype = _overArg(Object.getPrototypeOf, Object);
  11802. var _getPrototype = getPrototype;
  11803. /** `Object#toString` result references. */
  11804. var objectTag$1 = '[object Object]';
  11805. /** Used for built-in method references. */
  11806. var funcProto = Function.prototype,
  11807. objectProto$6 = Object.prototype;
  11808. /** Used to resolve the decompiled source of functions. */
  11809. var funcToString = funcProto.toString;
  11810. /** Used to check objects for own properties. */
  11811. var hasOwnProperty$4 = objectProto$6.hasOwnProperty;
  11812. /** Used to infer the `Object` constructor. */
  11813. var objectCtorString = funcToString.call(Object);
  11814. /**
  11815. * Checks if `value` is a plain object, that is, an object created by the
  11816. * `Object` constructor or one with a `[[Prototype]]` of `null`.
  11817. *
  11818. * @static
  11819. * @memberOf _
  11820. * @since 0.8.0
  11821. * @category Lang
  11822. * @param {*} value The value to check.
  11823. * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
  11824. * @example
  11825. *
  11826. * function Foo() {
  11827. * this.a = 1;
  11828. * }
  11829. *
  11830. * _.isPlainObject(new Foo);
  11831. * // => false
  11832. *
  11833. * _.isPlainObject([1, 2, 3]);
  11834. * // => false
  11835. *
  11836. * _.isPlainObject({ 'x': 0, 'y': 0 });
  11837. * // => true
  11838. *
  11839. * _.isPlainObject(Object.create(null));
  11840. * // => true
  11841. */
  11842. function isPlainObject(value) {
  11843. if (!isObjectLike_1(value) || _baseGetTag(value) != objectTag$1) {
  11844. return false;
  11845. }
  11846. var proto = _getPrototype(value);
  11847. if (proto === null) {
  11848. return true;
  11849. }
  11850. var Ctor = hasOwnProperty$4.call(proto, 'constructor') && proto.constructor;
  11851. return typeof Ctor == 'function' && Ctor instanceof Ctor &&
  11852. funcToString.call(Ctor) == objectCtorString;
  11853. }
  11854. var isPlainObject_1 = isPlainObject;
  11855. /* eslint-disable */
  11856. var global$1 = typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : {};
  11857. const EXPIRED = Symbol('expired');
  11858. const debug = browser('LC:Expirable');
  11859. class Expirable {
  11860. constructor(value, ttl) {
  11861. this.originalValue = value;
  11862. if (typeof ttl === 'number') {
  11863. this.expiredAt = Date.now() + ttl;
  11864. }
  11865. }
  11866. get value() {
  11867. const expired = this.expiredAt && this.expiredAt <= Date.now();
  11868. if (expired) debug(`expired: ${this.originalValue}`);
  11869. return expired ? EXPIRED : this.originalValue;
  11870. }
  11871. }
  11872. Expirable.EXPIRED = EXPIRED;
  11873. const debug$1 = browser('LC:Cache');
  11874. class Cache {
  11875. constructor(name = 'anonymous') {
  11876. this.name = name;
  11877. this._map = {};
  11878. }
  11879. get(key) {
  11880. const cache = this._map[key];
  11881. if (cache) {
  11882. const {
  11883. value
  11884. } = cache;
  11885. if (value !== Expirable.EXPIRED) {
  11886. debug$1('[%s] hit: %s', this.name, key);
  11887. return value;
  11888. }
  11889. delete this._map[key];
  11890. }
  11891. debug$1(`[${this.name}] missed: ${key}`);
  11892. return null;
  11893. }
  11894. set(key, value, ttl) {
  11895. debug$1('[%s] set: %s %d', this.name, key, ttl);
  11896. this._map[key] = new Expirable(value, ttl);
  11897. }
  11898. }
  11899. /**
  11900. * 调试日志控制器
  11901. * @const
  11902. * @memberof module:leancloud-realtime
  11903. * @example
  11904. * debug.enable(); // 启用调试日志
  11905. * debug.disable(); // 关闭调试日志
  11906. */
  11907. const debug$2 = {
  11908. enable: (namespaces = 'LC*') => browser.enable(namespaces),
  11909. disable: browser.disable
  11910. };
  11911. const tryAll = promiseConstructors => {
  11912. const promise = new Promise(promiseConstructors[0]);
  11913. if (promiseConstructors.length === 1) {
  11914. return promise;
  11915. }
  11916. return promise.catch(() => tryAll(promiseConstructors.slice(1)));
  11917. }; // eslint-disable-next-line no-sequences
  11918. const tap = interceptor => value => (interceptor(value), value);
  11919. const finalize = callback => [// eslint-disable-next-line no-sequences
  11920. value => (callback(), value), error => {
  11921. callback();
  11922. throw error;
  11923. }];
  11924. /**
  11925. * 将对象转换为 Date,支持 string、number、ProtoBuf Long 以及 LeanCloud 的 Date 类型,
  11926. * 其他情况下(包括对象为 falsy)返回原值。
  11927. * @private
  11928. */
  11929. const decodeDate = date => {
  11930. if (!date) return date;
  11931. if (typeof date === 'string' || typeof date === 'number') {
  11932. return new Date(date);
  11933. }
  11934. if (date.__type === 'Date' && date.iso) {
  11935. return new Date(date.iso);
  11936. } // Long
  11937. if (typeof date.toNumber === 'function') {
  11938. return new Date(date.toNumber());
  11939. }
  11940. return date;
  11941. };
  11942. /**
  11943. * 获取 Date 的毫秒数,如果不是一个 Date 返回 undefined。
  11944. * @private
  11945. */
  11946. const getTime = date => date && date.getTime ? date.getTime() : undefined;
  11947. /**
  11948. * 解码对象中的 LeanCloud 数据结构。
  11949. * 目前仅会处理 Date 类型。
  11950. * @private
  11951. */
  11952. const decode = value => {
  11953. if (!value) return value;
  11954. if (value.__type === 'Date' && value.iso) {
  11955. return new Date(value.iso);
  11956. }
  11957. if (Array.isArray(value)) {
  11958. return value.map(decode);
  11959. }
  11960. if (isPlainObject_1(value)) {
  11961. return Object.keys(value).reduce((result, key) => ({ ...result,
  11962. [key]: decode(value[key])
  11963. }), {});
  11964. }
  11965. return value;
  11966. };
  11967. /**
  11968. * 将对象中的特殊类型编码为 LeanCloud 数据结构。
  11969. * 目前仅会处理 Date 类型。
  11970. * @private
  11971. */
  11972. const encode = value => {
  11973. if (value instanceof Date) return {
  11974. __type: 'Date',
  11975. iso: value.toJSON()
  11976. };
  11977. if (Array.isArray(value)) {
  11978. return value.map(encode);
  11979. }
  11980. if (isPlainObject_1(value)) {
  11981. return Object.keys(value).reduce((result, key) => ({ ...result,
  11982. [key]: encode(value[key])
  11983. }), {});
  11984. }
  11985. return value;
  11986. };
  11987. const keyRemap = (keymap, obj) => Object.keys(obj).reduce((newObj, key) => {
  11988. const newKey = keymap[key] || key;
  11989. return Object.assign(newObj, {
  11990. [newKey]: obj[key]
  11991. });
  11992. }, {});
  11993. const isIE10 = global$1.navigator && global$1.navigator.userAgent && global$1.navigator.userAgent.indexOf('MSIE 10.') !== -1;
  11994. /* eslint-disable no-proto */
  11995. const getStaticProperty = (klass, property) => klass[property] || (klass.__proto__ ? getStaticProperty(klass.__proto__, property) : undefined);
  11996. /* eslint-enable no-proto */
  11997. const union = (a, b) => Array.from(new Set([...a, ...b]));
  11998. const difference = (a, b) => Array.from((bSet => new Set(a.filter(x => !bSet.has(x))))(new Set(b)));
  11999. const map = new WeakMap(); // protected property helper
  12000. const internal = object => {
  12001. if (!map.has(object)) {
  12002. map.set(object, {});
  12003. }
  12004. return map.get(object);
  12005. };
  12006. const compact = (obj, filter) => {
  12007. if (!isPlainObject_1(obj)) return obj;
  12008. const object = { ...obj
  12009. };
  12010. Object.keys(object).forEach(prop => {
  12011. const value = object[prop];
  12012. if (value === filter) {
  12013. delete object[prop];
  12014. } else {
  12015. object[prop] = compact(value, filter);
  12016. }
  12017. });
  12018. return object;
  12019. }; // debug utility
  12020. const removeNull = obj => compact(obj, null);
  12021. const trim = message => removeNull(JSON.parse(JSON.stringify(message)));
  12022. const ensureArray = target => {
  12023. if (Array.isArray(target)) {
  12024. return target;
  12025. }
  12026. if (target === undefined || target === null) {
  12027. return [];
  12028. }
  12029. return [target];
  12030. };
  12031. const setValue = (target, key, value) => {
  12032. // '.' is not allowed in Class keys, escaping is not in concern now.
  12033. const segs = key.split('.');
  12034. const lastSeg = segs.pop();
  12035. let currentTarget = target;
  12036. segs.forEach(seg => {
  12037. if (currentTarget[seg] === undefined) currentTarget[seg] = {};
  12038. currentTarget = currentTarget[seg];
  12039. });
  12040. currentTarget[lastSeg] = value;
  12041. return target;
  12042. };
  12043. const isWeapp = // eslint-disable-next-line no-undef
  12044. typeof wx === 'object' && typeof wx.connectSocket === 'function'; // throttle decorator
  12045. const throttle = wait => (target, property, descriptor) => {
  12046. const callback = descriptor.value; // very naive, internal use only
  12047. if (callback.length) {
  12048. throw new Error('throttled function should not accept any arguments');
  12049. }
  12050. return { ...descriptor,
  12051. value() {
  12052. let {
  12053. throttleMeta
  12054. } = internal(this);
  12055. if (!throttleMeta) {
  12056. throttleMeta = {};
  12057. internal(this).throttleMeta = throttleMeta;
  12058. }
  12059. let {
  12060. [property]: propertyMeta
  12061. } = throttleMeta;
  12062. if (!propertyMeta) {
  12063. propertyMeta = {};
  12064. throttleMeta[property] = propertyMeta;
  12065. }
  12066. const {
  12067. previouseTimestamp = 0,
  12068. timeout
  12069. } = propertyMeta;
  12070. const now = Date.now();
  12071. const remainingTime = wait - (now - previouseTimestamp);
  12072. if (remainingTime <= 0) {
  12073. throttleMeta[property].previouseTimestamp = now;
  12074. callback.apply(this);
  12075. } else if (!timeout) {
  12076. propertyMeta.timeout = setTimeout(() => {
  12077. propertyMeta.previouseTimestamp = Date.now();
  12078. delete propertyMeta.timeout;
  12079. callback.apply(this);
  12080. }, remainingTime);
  12081. }
  12082. }
  12083. };
  12084. };
  12085. const isCNApp = appId => appId.slice(-9) !== '-MdYXbMMI';
  12086. const equalBuffer = (buffer1, buffer2) => {
  12087. if (!buffer1 || !buffer2) return false;
  12088. if (buffer1.byteLength !== buffer2.byteLength) return false;
  12089. const a = new Uint8Array(buffer1);
  12090. const b = new Uint8Array(buffer2);
  12091. return !a.some((value, index) => value !== b[index]);
  12092. };
  12093. var _class;
  12094. const debug$3 = browser('LC:WebSocketPlus');
  12095. const OPEN = 'open';
  12096. const DISCONNECT = 'disconnect';
  12097. const RECONNECT = 'reconnect';
  12098. const RETRY = 'retry';
  12099. const SCHEDULE = 'schedule';
  12100. const OFFLINE = 'offline';
  12101. const ONLINE = 'online';
  12102. const ERROR = 'error';
  12103. const MESSAGE = 'message';
  12104. const HEARTBEAT_TIME = 180000;
  12105. const TIMEOUT_TIME = 380000;
  12106. const DEFAULT_RETRY_STRATEGY = attempt => Math.min(1000 * 2 ** attempt, 300000);
  12107. const requireConnected = (target, name, descriptor) => ({ ...descriptor,
  12108. value: function requireConnectedWrapper(...args) {
  12109. this.checkConnectionAvailability(name);
  12110. return descriptor.value.call(this, ...args);
  12111. }
  12112. });
  12113. let WebSocketPlus = (_class = class WebSocketPlus extends eventemitter3 {
  12114. get urls() {
  12115. return this._urls;
  12116. }
  12117. set urls(urls) {
  12118. this._urls = ensureArray(urls);
  12119. }
  12120. constructor(getUrls, protocol) {
  12121. super();
  12122. this.init();
  12123. this._protocol = protocol;
  12124. Promise.resolve(typeof getUrls === 'function' ? getUrls() : getUrls).then(ensureArray).then(urls => {
  12125. this._urls = urls;
  12126. return this._open();
  12127. }).then(() => {
  12128. this.__postponeTimeoutTimer = this._postponeTimeoutTimer.bind(this);
  12129. if (global$1.addEventListener) {
  12130. this.__pause = () => {
  12131. if (this.can('pause')) this.pause();
  12132. };
  12133. this.__resume = () => {
  12134. if (this.can('resume')) this.resume();
  12135. };
  12136. global$1.addEventListener('offline', this.__pause);
  12137. global$1.addEventListener('online', this.__resume);
  12138. }
  12139. this.open();
  12140. }).catch(this.throw.bind(this));
  12141. }
  12142. _open() {
  12143. return this._createWs(this._urls, this._protocol).then(ws => {
  12144. const [first, ...reset] = this._urls;
  12145. this._urls = [...reset, first];
  12146. return ws;
  12147. });
  12148. }
  12149. _createWs(urls, protocol) {
  12150. return tryAll(urls.map(url => (resolve, reject) => {
  12151. debug$3(`connect [${url}] ${protocol}`);
  12152. const WebSocket = getAdapter('WebSocket');
  12153. const ws = protocol ? new WebSocket(url, protocol) : new WebSocket(url);
  12154. ws.binaryType = this.binaryType || 'arraybuffer';
  12155. ws.onopen = () => resolve(ws);
  12156. ws.onclose = error => {
  12157. if (error instanceof Error) {
  12158. return reject(error);
  12159. } // in browser, error event is useless
  12160. return reject(new Error(`Failed to connect [${url}]`));
  12161. };
  12162. ws.onerror = ws.onclose;
  12163. })).then(ws => {
  12164. this._ws = ws;
  12165. this._ws.onclose = this._handleClose.bind(this);
  12166. this._ws.onmessage = this._handleMessage.bind(this);
  12167. return ws;
  12168. });
  12169. }
  12170. _destroyWs() {
  12171. const ws = this._ws;
  12172. if (!ws) return;
  12173. ws.onopen = null;
  12174. ws.onclose = null;
  12175. ws.onerror = null;
  12176. ws.onmessage = null;
  12177. this._ws = null;
  12178. ws.close();
  12179. } // eslint-disable-next-line class-methods-use-this
  12180. onbeforeevent(event, from, to, ...payload) {
  12181. debug$3(`${event}: ${from} -> ${to} %o`, payload);
  12182. }
  12183. onopen() {
  12184. this.emit(OPEN);
  12185. }
  12186. onconnected() {
  12187. this._startConnectionKeeper();
  12188. }
  12189. onleaveconnected(event, from, to) {
  12190. this._stopConnectionKeeper();
  12191. this._destroyWs();
  12192. if (to === 'offline' || to === 'disconnected') {
  12193. this.emit(DISCONNECT);
  12194. }
  12195. }
  12196. onpause() {
  12197. this.emit(OFFLINE);
  12198. }
  12199. onbeforeresume() {
  12200. this.emit(ONLINE);
  12201. }
  12202. onreconnect() {
  12203. this.emit(RECONNECT);
  12204. }
  12205. ondisconnected(event, from, to, attempt = 0) {
  12206. const delay = from === OFFLINE ? 0 : DEFAULT_RETRY_STRATEGY.call(null, attempt);
  12207. debug$3(`schedule attempt=${attempt} delay=${delay}`);
  12208. this.emit(SCHEDULE, attempt, delay);
  12209. if (this.__scheduledRetry) {
  12210. clearTimeout(this.__scheduledRetry);
  12211. }
  12212. this.__scheduledRetry = setTimeout(() => {
  12213. if (this.is('disconnected')) {
  12214. this.retry(attempt);
  12215. }
  12216. }, delay);
  12217. }
  12218. onretry(event, from, to, attempt = 0) {
  12219. this.emit(RETRY, attempt);
  12220. this._open().then(() => this.can('reconnect') && this.reconnect(), () => this.can('fail') && this.fail(attempt + 1));
  12221. }
  12222. onerror(event, from, to, error) {
  12223. this.emit(ERROR, error);
  12224. }
  12225. onclose() {
  12226. if (global$1.removeEventListener) {
  12227. if (this.__pause) global$1.removeEventListener('offline', this.__pause);
  12228. if (this.__resume) global$1.removeEventListener('online', this.__resume);
  12229. }
  12230. }
  12231. checkConnectionAvailability(name = 'API') {
  12232. if (!this.is('connected')) {
  12233. const currentState = this.current;
  12234. console.warn(`${name} should not be called when the connection is ${currentState}`);
  12235. if (this.is('disconnected') || this.is('reconnecting')) {
  12236. console.warn('disconnect and reconnect event should be handled to avoid such calls.');
  12237. }
  12238. throw new Error('Connection unavailable');
  12239. }
  12240. } // jsdoc-ignore-start
  12241. // jsdoc-ignore-end
  12242. _ping() {
  12243. debug$3('ping');
  12244. try {
  12245. this.ping();
  12246. } catch (error) {
  12247. console.warn(`websocket ping error: ${error.message}`);
  12248. }
  12249. }
  12250. ping() {
  12251. if (this._ws.ping) {
  12252. this._ws.ping();
  12253. } else {
  12254. console.warn(`The WebSocket implement does not support sending ping frame.
  12255. Override ping method to use application defined ping/pong mechanism.`);
  12256. }
  12257. }
  12258. _postponeTimeoutTimer() {
  12259. debug$3('_postponeTimeoutTimer');
  12260. this._clearTimeoutTimers();
  12261. this._timeoutTimer = setTimeout(() => {
  12262. debug$3('timeout');
  12263. this.disconnect();
  12264. }, TIMEOUT_TIME);
  12265. }
  12266. _clearTimeoutTimers() {
  12267. if (this._timeoutTimer) {
  12268. clearTimeout(this._timeoutTimer);
  12269. }
  12270. }
  12271. _startConnectionKeeper() {
  12272. debug$3('start connection keeper');
  12273. this._heartbeatTimer = setInterval(this._ping.bind(this), HEARTBEAT_TIME);
  12274. const addListener = this._ws.addListener || this._ws.addEventListener;
  12275. if (!addListener) {
  12276. debug$3('connection keeper disabled due to the lack of #addEventListener.');
  12277. return;
  12278. }
  12279. addListener.call(this._ws, 'message', this.__postponeTimeoutTimer);
  12280. addListener.call(this._ws, 'pong', this.__postponeTimeoutTimer);
  12281. this._postponeTimeoutTimer();
  12282. }
  12283. _stopConnectionKeeper() {
  12284. debug$3('stop connection keeper'); // websockets/ws#489
  12285. const removeListener = this._ws.removeListener || this._ws.removeEventListener;
  12286. if (removeListener) {
  12287. removeListener.call(this._ws, 'message', this.__postponeTimeoutTimer);
  12288. removeListener.call(this._ws, 'pong', this.__postponeTimeoutTimer);
  12289. this._clearTimeoutTimers();
  12290. }
  12291. if (this._heartbeatTimer) {
  12292. clearInterval(this._heartbeatTimer);
  12293. }
  12294. }
  12295. _handleClose(event) {
  12296. debug$3(`ws closed [${event.code}] ${event.reason}`); // socket closed manually, ignore close event.
  12297. if (this.isFinished()) return;
  12298. this.handleClose(event);
  12299. }
  12300. handleClose() {
  12301. // reconnect
  12302. this.disconnect();
  12303. } // jsdoc-ignore-start
  12304. // jsdoc-ignore-end
  12305. send(data) {
  12306. debug$3('send', data);
  12307. this._ws.send(data);
  12308. }
  12309. _handleMessage(event) {
  12310. debug$3('message', event.data);
  12311. this.handleMessage(event.data);
  12312. }
  12313. handleMessage(message) {
  12314. this.emit(MESSAGE, message);
  12315. }
  12316. }, (_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);
  12317. stateMachine.create({
  12318. target: WebSocketPlus.prototype,
  12319. initial: {
  12320. state: 'initialized',
  12321. event: 'init',
  12322. defer: true
  12323. },
  12324. terminal: 'closed',
  12325. events: [{
  12326. name: 'open',
  12327. from: 'initialized',
  12328. to: 'connected'
  12329. }, {
  12330. name: 'disconnect',
  12331. from: 'connected',
  12332. to: 'disconnected'
  12333. }, {
  12334. name: 'retry',
  12335. from: 'disconnected',
  12336. to: 'reconnecting'
  12337. }, {
  12338. name: 'fail',
  12339. from: 'reconnecting',
  12340. to: 'disconnected'
  12341. }, {
  12342. name: 'reconnect',
  12343. from: 'reconnecting',
  12344. to: 'connected'
  12345. }, {
  12346. name: 'pause',
  12347. from: ['connected', 'disconnected', 'reconnecting'],
  12348. to: 'offline'
  12349. }, {}, {
  12350. name: 'resume',
  12351. from: 'offline',
  12352. to: 'disconnected'
  12353. }, {
  12354. name: 'close',
  12355. from: ['connected', 'disconnected', 'reconnecting', 'offline'],
  12356. to: 'closed'
  12357. }, {
  12358. name: 'throw',
  12359. from: '*',
  12360. to: 'error'
  12361. }]
  12362. });
  12363. const error = Object.freeze({
  12364. 1000: {
  12365. name: 'CLOSE_NORMAL'
  12366. },
  12367. 1006: {
  12368. name: 'CLOSE_ABNORMAL'
  12369. },
  12370. 4100: {
  12371. name: 'APP_NOT_AVAILABLE',
  12372. message: 'App not exists or realtime message service is disabled.'
  12373. },
  12374. 4102: {
  12375. name: 'SIGNATURE_FAILED',
  12376. message: 'Login signature mismatch.'
  12377. },
  12378. 4103: {
  12379. name: 'INVALID_LOGIN',
  12380. message: 'Malformed clientId.'
  12381. },
  12382. 4105: {
  12383. name: 'SESSION_REQUIRED',
  12384. message: 'Message sent before session opened.'
  12385. },
  12386. 4107: {
  12387. name: 'READ_TIMEOUT'
  12388. },
  12389. 4108: {
  12390. name: 'LOGIN_TIMEOUT'
  12391. },
  12392. 4109: {
  12393. name: 'FRAME_TOO_LONG'
  12394. },
  12395. 4110: {
  12396. name: 'INVALID_ORIGIN',
  12397. message: 'Access denied by domain whitelist.'
  12398. },
  12399. 4111: {
  12400. name: 'SESSION_CONFLICT'
  12401. },
  12402. 4112: {
  12403. name: 'SESSION_TOKEN_EXPIRED'
  12404. },
  12405. 4113: {
  12406. name: 'APP_QUOTA_EXCEEDED',
  12407. message: 'The daily active users limit exceeded.'
  12408. },
  12409. 4116: {
  12410. name: 'MESSAGE_SENT_QUOTA_EXCEEDED',
  12411. message: 'Command sent too fast.'
  12412. },
  12413. 4200: {
  12414. name: 'INTERNAL_ERROR',
  12415. message: 'Internal error, please contact LeanCloud for support.'
  12416. },
  12417. 4301: {
  12418. name: 'CONVERSATION_API_FAILED',
  12419. message: 'Upstream Conversatoin API failed, see error.detail for details.'
  12420. },
  12421. 4302: {
  12422. name: 'CONVERSATION_SIGNATURE_FAILED',
  12423. message: 'Conversation action signature mismatch.'
  12424. },
  12425. 4303: {
  12426. name: 'CONVERSATION_NOT_FOUND'
  12427. },
  12428. 4304: {
  12429. name: 'CONVERSATION_FULL'
  12430. },
  12431. 4305: {
  12432. name: 'CONVERSATION_REJECTED_BY_APP',
  12433. message: 'Conversation action rejected by hook.'
  12434. },
  12435. 4306: {
  12436. name: 'CONVERSATION_UPDATE_FAILED'
  12437. },
  12438. 4307: {
  12439. name: 'CONVERSATION_READ_ONLY'
  12440. },
  12441. 4308: {
  12442. name: 'CONVERSATION_NOT_ALLOWED'
  12443. },
  12444. 4309: {
  12445. name: 'CONVERSATION_UPDATE_REJECTED',
  12446. message: 'Conversation update rejected because the client is not a member.'
  12447. },
  12448. 4310: {
  12449. name: 'CONVERSATION_QUERY_FAILED',
  12450. message: 'Conversation query failed because it is too expansive.'
  12451. },
  12452. 4311: {
  12453. name: 'CONVERSATION_LOG_FAILED'
  12454. },
  12455. 4312: {
  12456. name: 'CONVERSATION_LOG_REJECTED',
  12457. message: 'Message query rejected because the client is not a member of the conversation.'
  12458. },
  12459. 4313: {
  12460. name: 'SYSTEM_CONVERSATION_REQUIRED'
  12461. },
  12462. 4314: {
  12463. name: 'NORMAL_CONVERSATION_REQUIRED'
  12464. },
  12465. 4315: {
  12466. name: 'CONVERSATION_BLACKLISTED',
  12467. message: 'Blacklisted in the conversation.'
  12468. },
  12469. 4316: {
  12470. name: 'TRANSIENT_CONVERSATION_REQUIRED'
  12471. },
  12472. 4317: {
  12473. name: 'CONVERSATION_MEMBERSHIP_REQUIRED'
  12474. },
  12475. 4318: {
  12476. name: 'CONVERSATION_API_QUOTA_EXCEEDED',
  12477. message: 'LeanCloud API quota exceeded. You may upgrade your plan.'
  12478. },
  12479. 4323: {
  12480. name: 'TEMPORARY_CONVERSATION_EXPIRED',
  12481. message: 'Temporary conversation expired or does not exist.'
  12482. },
  12483. 4401: {
  12484. name: 'INVALID_MESSAGING_TARGET',
  12485. message: 'Conversation does not exist or client is not a member.'
  12486. },
  12487. 4402: {
  12488. name: 'MESSAGE_REJECTED_BY_APP',
  12489. message: 'Message rejected by hook.'
  12490. },
  12491. 4403: {
  12492. name: 'MESSAGE_OWNERSHIP_REQUIRED'
  12493. },
  12494. 4404: {
  12495. name: 'MESSAGE_NOT_FOUND'
  12496. },
  12497. 4405: {
  12498. name: 'MESSAGE_UPDATE_REJECTED_BY_APP',
  12499. message: 'Message update rejected by hook.'
  12500. },
  12501. 4406: {
  12502. name: 'MESSAGE_EDIT_DISABLED'
  12503. },
  12504. 4407: {
  12505. name: 'MESSAGE_RECALL_DISABLED'
  12506. },
  12507. 5130: {
  12508. name: 'OWNER_PROMOTION_NOT_ALLOWED',
  12509. message: "Updating a member's role to owner is not allowed."
  12510. }
  12511. });
  12512. const ErrorCode = Object.freeze(Object.keys(error).reduce((result, code) => Object.assign(result, {
  12513. [error[code].name]: Number(code)
  12514. }), {}));
  12515. const createError = ({
  12516. code,
  12517. reason,
  12518. appCode,
  12519. detail,
  12520. error: errorMessage
  12521. }) => {
  12522. let message = reason || detail || errorMessage;
  12523. let name = reason;
  12524. if (!message && error[code]) {
  12525. ({
  12526. name
  12527. } = error[code]);
  12528. message = error[code].message || name;
  12529. }
  12530. if (!message) {
  12531. message = `Unknow Error: ${code}`;
  12532. }
  12533. const err = new Error(message);
  12534. return Object.assign(err, {
  12535. code,
  12536. appCode,
  12537. detail,
  12538. name
  12539. });
  12540. };
  12541. const debug$4 = browser('LC:Connection');
  12542. const COMMAND_TIMEOUT = 20000;
  12543. const EXPIRE = Symbol('expire');
  12544. 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));
  12545. class Connection extends WebSocketPlus {
  12546. constructor(getUrl, {
  12547. format,
  12548. version
  12549. }) {
  12550. debug$4('initializing Connection');
  12551. const protocolString = `lc.${format}.${version}`;
  12552. super(getUrl, protocolString);
  12553. this._protocolFormat = format;
  12554. this._commands = {};
  12555. this._serialId = 0;
  12556. }
  12557. async send(command, waitingForRespond = true) {
  12558. let buffer;
  12559. let serialId;
  12560. if (waitingForRespond) {
  12561. if (isIdempotentCommand(command)) {
  12562. buffer = command.toArrayBuffer();
  12563. const duplicatedCommand = values_1(this._commands).find(({
  12564. buffer: targetBuffer,
  12565. command: targetCommand
  12566. }) => targetCommand.cmd === command.cmd && targetCommand.op === command.op && equalBuffer(targetBuffer, buffer));
  12567. if (duplicatedCommand) {
  12568. console.warn(`Duplicated command [cmd:${command.cmd} op:${command.op}] is throttled.`);
  12569. return duplicatedCommand.promise;
  12570. }
  12571. }
  12572. this._serialId += 1;
  12573. serialId = this._serialId;
  12574. command.i = serialId; // eslint-disable-line no-param-reassign
  12575. }
  12576. if (debug$4.enabled) debug$4('↑ %O sent', trim(command));
  12577. let message;
  12578. if (this._protocolFormat === 'proto2base64') {
  12579. message = command.toBase64();
  12580. } else if (command.toArrayBuffer) {
  12581. message = command.toArrayBuffer();
  12582. }
  12583. if (!message) {
  12584. throw new TypeError(`${command} is not a GenericCommand`);
  12585. }
  12586. super.send(message);
  12587. if (!waitingForRespond) return undefined;
  12588. const promise = new Promise((resolve, reject) => {
  12589. this._commands[serialId] = {
  12590. command,
  12591. buffer,
  12592. resolve,
  12593. reject,
  12594. timeout: setTimeout(() => {
  12595. if (this._commands[serialId]) {
  12596. if (debug$4.enabled) debug$4('✗ %O timeout', trim(command));
  12597. reject(createError({
  12598. error: `Command Timeout [cmd:${command.cmd} op:${command.op}]`,
  12599. name: 'COMMAND_TIMEOUT'
  12600. }));
  12601. delete this._commands[serialId];
  12602. }
  12603. }, COMMAND_TIMEOUT)
  12604. };
  12605. });
  12606. this._commands[serialId].promise = promise;
  12607. return promise;
  12608. }
  12609. handleMessage(msg) {
  12610. let message;
  12611. try {
  12612. message = GenericCommand.decode(msg);
  12613. if (debug$4.enabled) debug$4('↓ %O received', trim(message));
  12614. } catch (e) {
  12615. console.warn('Decode message failed:', e.message, msg);
  12616. return;
  12617. }
  12618. const serialId = message.i;
  12619. if (serialId) {
  12620. if (this._commands[serialId]) {
  12621. clearTimeout(this._commands[serialId].timeout);
  12622. if (message.cmd === CommandType.error) {
  12623. this._commands[serialId].reject(createError(message.errorMessage));
  12624. } else {
  12625. this._commands[serialId].resolve(message);
  12626. }
  12627. delete this._commands[serialId];
  12628. } else {
  12629. console.warn(`Unexpected command received with serialId [${serialId}],
  12630. which have timed out or never been requested.`);
  12631. }
  12632. } else {
  12633. switch (message.cmd) {
  12634. case CommandType.error:
  12635. {
  12636. this.emit(ERROR, createError(message.errorMessage));
  12637. return;
  12638. }
  12639. case CommandType.goaway:
  12640. {
  12641. this.emit(EXPIRE);
  12642. return;
  12643. }
  12644. default:
  12645. {
  12646. this.emit(MESSAGE, message);
  12647. }
  12648. }
  12649. }
  12650. }
  12651. ping() {
  12652. return this.send(new GenericCommand({
  12653. cmd: CommandType.echo
  12654. })).catch(error => debug$4('ping failed:', error));
  12655. }
  12656. }
  12657. var promiseTimeout = createCommonjsModule(function (module) {
  12658. /**
  12659. * Local reference to TimeoutError
  12660. * @private
  12661. */
  12662. var TimeoutError;
  12663. /**
  12664. * Rejects a promise with a {@link TimeoutError} if it does not settle within
  12665. * the specified timeout.
  12666. *
  12667. * @param {Promise} promise The promise.
  12668. * @param {number} timeoutMillis Number of milliseconds to wait on settling.
  12669. * @returns {Promise} Either resolves/rejects with `promise`, or rejects with
  12670. * `TimeoutError`, whichever settles first.
  12671. */
  12672. var timeout = module.exports.timeout = function (promise, timeoutMillis) {
  12673. var error = new TimeoutError(),
  12674. timeout;
  12675. return Promise.race([promise, new Promise(function (resolve, reject) {
  12676. timeout = setTimeout(function () {
  12677. reject(error);
  12678. }, timeoutMillis);
  12679. })]).then(function (v) {
  12680. clearTimeout(timeout);
  12681. return v;
  12682. }, function (err) {
  12683. clearTimeout(timeout);
  12684. throw err;
  12685. });
  12686. };
  12687. /**
  12688. * Exception indicating that the timeout expired.
  12689. */
  12690. TimeoutError = module.exports.TimeoutError = function () {
  12691. Error.call(this);
  12692. this.stack = Error().stack;
  12693. this.message = 'Timeout';
  12694. };
  12695. TimeoutError.prototype = Object.create(Error.prototype);
  12696. TimeoutError.prototype.name = "TimeoutError";
  12697. });
  12698. var promiseTimeout_1 = promiseTimeout.timeout;
  12699. var promiseTimeout_2 = promiseTimeout.TimeoutError;
  12700. const debug$5 = browser('LC:request');
  12701. var request = (({
  12702. method = 'GET',
  12703. url: _url,
  12704. query,
  12705. headers,
  12706. data,
  12707. timeout: time
  12708. }) => {
  12709. let url = _url;
  12710. if (query) {
  12711. const queryString = Object.keys(query).map(key => {
  12712. const value = query[key];
  12713. if (value === undefined) return undefined;
  12714. const v = isPlainObject_1(value) ? JSON.stringify(value) : value;
  12715. return `${encodeURIComponent(key)}=${encodeURIComponent(v)}`;
  12716. }).filter(qs => qs).join('&');
  12717. url = `${url}?${queryString}`;
  12718. }
  12719. debug$5('Req: %O %O %O', method, url, {
  12720. headers,
  12721. data
  12722. });
  12723. const request = getAdapter('request');
  12724. const promise = request(url, {
  12725. method,
  12726. headers,
  12727. data
  12728. }).then(response => {
  12729. if (response.ok === false) {
  12730. const error = createError(response.data);
  12731. error.response = response;
  12732. throw error;
  12733. }
  12734. debug$5('Res: %O %O %O', url, response.status, response.data);
  12735. return response.data;
  12736. }).catch(error => {
  12737. if (error.response) {
  12738. debug$5('Error: %O %O %O', url, error.response.status, error.response.data);
  12739. }
  12740. throw error;
  12741. });
  12742. return time ? promiseTimeout_1(promise, time) : promise;
  12743. });
  12744. /* eslint-disable max-len */
  12745. const checkType = middleware => param => {
  12746. const {
  12747. constructor
  12748. } = param;
  12749. return Promise.resolve(param).then(middleware).then(tap(result => {
  12750. if (result === undefined || result === null) {
  12751. // eslint-disable-next-line max-len
  12752. 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.`);
  12753. }
  12754. if (!(result instanceof constructor)) {
  12755. // eslint-disable-next-line max-len
  12756. 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.`);
  12757. }
  12758. return 0;
  12759. }));
  12760. };
  12761. const applyDecorators = (decorators, target) => {
  12762. if (decorators) {
  12763. decorators.forEach(decorator => {
  12764. try {
  12765. decorator(target);
  12766. } catch (error) {
  12767. if (decorator._pluginName) {
  12768. error.message += `[${decorator._pluginName}]`;
  12769. }
  12770. throw error;
  12771. }
  12772. });
  12773. }
  12774. };
  12775. const applyMiddlewares = middlewares => target => ensureArray(middlewares).reduce((previousPromise, middleware) => previousPromise.then(checkType(middleware)).catch(error => {
  12776. if (middleware._pluginName) {
  12777. // eslint-disable-next-line no-param-reassign
  12778. error.message += `[${middleware._pluginName}]`;
  12779. }
  12780. throw error;
  12781. }), Promise.resolve(target));
  12782. const applyDispatcher = (dispatchers, payload) => ensureArray(dispatchers).reduce((resultPromise, dispatcher) => resultPromise.then(shouldDispatch => shouldDispatch === false ? false : dispatcher(...payload)).catch(error => {
  12783. if (dispatcher._pluginName) {
  12784. // eslint-disable-next-line no-param-reassign
  12785. error.message += `[${dispatcher._pluginName}]`;
  12786. }
  12787. throw error;
  12788. }), Promise.resolve(true));
  12789. var version = "5.0.0-rc.7";
  12790. // eslint-disable-next-line max-classes-per-file
  12791. const debug$6 = browser('LC:Realtime');
  12792. const routerCache = new Cache('push-router');
  12793. const initializedApp = {};
  12794. class Realtime extends eventemitter3 {
  12795. /**
  12796. * @extends EventEmitter
  12797. * @param {Object} options
  12798. * @param {String} options.appId
  12799. * @param {String} options.appKey (since 4.0.0)
  12800. * @param {String|Object} [options.server] 指定服务器域名,中国节点应用此参数必填(since 4.0.0)
  12801. * @param {Boolean} [options.noBinary=false] 设置 WebSocket 使用字符串格式收发消息(默认为二进制格式)。
  12802. * 适用于 WebSocket 实现不支持二进制数据格式的情况
  12803. * @param {Boolean} [options.ssl=true] 使用 wss 进行连接
  12804. * @param {String|String[]} [options.RTMServers] 指定私有部署的 RTM 服务器地址(since 4.0.0)
  12805. * @param {Plugin[]} [options.plugins] 加载插件(since 3.1.0)
  12806. */
  12807. constructor({
  12808. plugins,
  12809. ...options
  12810. }) {
  12811. debug$6('initializing Realtime %s %O', version, options);
  12812. super();
  12813. const {
  12814. appId
  12815. } = options;
  12816. if (typeof appId !== 'string') {
  12817. throw new TypeError(`appId [${appId}] is not a string`);
  12818. }
  12819. if (initializedApp[appId]) {
  12820. throw new Error(`App [${appId}] is already initialized.`);
  12821. }
  12822. initializedApp[appId] = true;
  12823. if (typeof options.appKey !== 'string') {
  12824. throw new TypeError(`appKey [${options.appKey}] is not a string`);
  12825. }
  12826. if (isCNApp(appId)) {
  12827. if (!options.server) {
  12828. throw new TypeError(`server option is required for apps from CN region`);
  12829. }
  12830. }
  12831. this._options = {
  12832. appId: undefined,
  12833. appKey: undefined,
  12834. noBinary: false,
  12835. ssl: true,
  12836. RTMServerName: typeof process !== 'undefined' ? process.env.RTM_SERVER_NAME : undefined,
  12837. // undocumented on purpose, internal use only
  12838. ...options
  12839. };
  12840. this._cache = new Cache('endpoints');
  12841. const _this = internal(this);
  12842. _this.clients = new Set();
  12843. _this.pendingClients = new Set();
  12844. const mergedPlugins = [...ensureArray(Realtime.__preRegisteredPlugins), ...ensureArray(plugins)];
  12845. debug$6('Using plugins %o', mergedPlugins.map(plugin => plugin.name));
  12846. this._plugins = mergedPlugins.reduce((result, plugin) => {
  12847. Object.keys(plugin).forEach(hook => {
  12848. if ({}.hasOwnProperty.call(plugin, hook) && hook !== 'name') {
  12849. if (plugin.name) {
  12850. ensureArray(plugin[hook]).forEach(value => {
  12851. // eslint-disable-next-line no-param-reassign
  12852. value._pluginName = plugin.name;
  12853. });
  12854. } // eslint-disable-next-line no-param-reassign
  12855. result[hook] = ensureArray(result[hook]).concat(plugin[hook]);
  12856. }
  12857. });
  12858. return result;
  12859. }, {}); // onRealtimeCreate hook
  12860. applyDecorators(this._plugins.onRealtimeCreate, this);
  12861. }
  12862. async _request({
  12863. method,
  12864. url: _url,
  12865. version = '1.1',
  12866. path,
  12867. query,
  12868. headers,
  12869. data
  12870. }) {
  12871. let url = _url;
  12872. if (!url) {
  12873. const {
  12874. appId,
  12875. server
  12876. } = this._options;
  12877. const {
  12878. api
  12879. } = await this.constructor._getServerUrls({
  12880. appId,
  12881. server
  12882. });
  12883. url = `${api}/${version}${path}`;
  12884. }
  12885. return request({
  12886. url,
  12887. method,
  12888. query,
  12889. headers: {
  12890. 'X-LC-Id': this._options.appId,
  12891. 'X-LC-Key': this._options.appKey,
  12892. ...headers
  12893. },
  12894. data
  12895. });
  12896. }
  12897. _open() {
  12898. if (this._openPromise) return this._openPromise;
  12899. let format = 'protobuf2';
  12900. if (this._options.noBinary) {
  12901. // 不发送 binary data,fallback to base64 string
  12902. format = 'proto2base64';
  12903. }
  12904. const version = 3;
  12905. const protocol = {
  12906. format,
  12907. version
  12908. };
  12909. this._openPromise = new Promise((resolve, reject) => {
  12910. debug$6('No connection established, create a new one.');
  12911. const connection = new Connection(() => this._getRTMServers(this._options), protocol);
  12912. connection.on(OPEN, () => resolve(connection)).on(ERROR, error => {
  12913. delete this._openPromise;
  12914. reject(error);
  12915. }).on(EXPIRE, async () => {
  12916. debug$6('Connection expired. Refresh endpoints.');
  12917. this._cache.set('endpoints', null, 0);
  12918. connection.urls = await this._getRTMServers(this._options);
  12919. connection.disconnect();
  12920. }).on(MESSAGE, this._dispatchCommand.bind(this));
  12921. /**
  12922. * 连接断开。
  12923. * 连接断开可能是因为 SDK 进入了离线状态(see {@link Realtime#event:OFFLINE}),或长时间没有收到服务器心跳。
  12924. * 连接断开后所有的网络操作都会失败,请在连接断开后禁用相关的 UI 元素。
  12925. * @event Realtime#DISCONNECT
  12926. */
  12927. /**
  12928. * 计划在一段时间后尝试重新连接
  12929. * @event Realtime#SCHEDULE
  12930. * @param {Number} attempt 尝试重连的次数
  12931. * @param {Number} delay 延迟的毫秒数
  12932. */
  12933. /**
  12934. * 正在尝试重新连接
  12935. * @event Realtime#RETRY
  12936. * @param {Number} attempt 尝试重连的次数
  12937. */
  12938. /**
  12939. * 连接恢复正常。
  12940. * 请重新启用在 {@link Realtime#event:DISCONNECT} 事件中禁用的相关 UI 元素
  12941. * @event Realtime#RECONNECT
  12942. */
  12943. /**
  12944. * 客户端连接断开
  12945. * @event IMClient#DISCONNECT
  12946. * @see Realtime#event:DISCONNECT
  12947. * @since 3.2.0
  12948. */
  12949. /**
  12950. * 计划在一段时间后尝试重新连接
  12951. * @event IMClient#SCHEDULE
  12952. * @param {Number} attempt 尝试重连的次数
  12953. * @param {Number} delay 延迟的毫秒数
  12954. * @since 3.2.0
  12955. */
  12956. /**
  12957. * 正在尝试重新连接
  12958. * @event IMClient#RETRY
  12959. * @param {Number} attempt 尝试重连的次数
  12960. * @since 3.2.0
  12961. */
  12962. /**
  12963. * 客户端进入离线状态。
  12964. * 这通常意味着网络已断开,或者 {@link Realtime#pause} 被调用
  12965. * @event Realtime#OFFLINE
  12966. * @since 3.4.0
  12967. */
  12968. /**
  12969. * 客户端恢复在线状态
  12970. * 这通常意味着网络已恢复,或者 {@link Realtime#resume} 被调用
  12971. * @event Realtime#ONLINE
  12972. * @since 3.4.0
  12973. */
  12974. /**
  12975. * 进入离线状态。
  12976. * 这通常意味着网络已断开,或者 {@link Realtime#pause} 被调用
  12977. * @event IMClient#OFFLINE
  12978. * @since 3.4.0
  12979. */
  12980. /**
  12981. * 恢复在线状态
  12982. * 这通常意味着网络已恢复,或者 {@link Realtime#resume} 被调用
  12983. * @event IMClient#ONLINE
  12984. * @since 3.4.0
  12985. */
  12986. // event proxy
  12987. [DISCONNECT, RECONNECT, RETRY, SCHEDULE, OFFLINE, ONLINE].forEach(event => connection.on(event, (...payload) => {
  12988. debug$6(`${event} event emitted. %o`, payload);
  12989. this.emit(event, ...payload);
  12990. if (event !== RECONNECT) {
  12991. internal(this).clients.forEach(client => {
  12992. client.emit(event, ...payload);
  12993. });
  12994. }
  12995. })); // override handleClose
  12996. connection.handleClose = function handleClose(event) {
  12997. const isFatal = [ErrorCode.APP_NOT_AVAILABLE, ErrorCode.INVALID_LOGIN, ErrorCode.INVALID_ORIGIN].some(errorCode => errorCode === event.code);
  12998. if (isFatal) {
  12999. // in these cases, SDK should throw.
  13000. this.throw(createError(event));
  13001. } else {
  13002. // reconnect
  13003. this.disconnect();
  13004. }
  13005. };
  13006. internal(this).connection = connection;
  13007. });
  13008. return this._openPromise;
  13009. }
  13010. async _getRTMServers(options) {
  13011. if (options.RTMServers) return shuffle_1(ensureArray(options.RTMServers));
  13012. let info;
  13013. const cachedEndPoints = this._cache.get('endpoints');
  13014. if (cachedEndPoints) {
  13015. info = cachedEndPoints;
  13016. } else {
  13017. info = await this.constructor._fetchRTMServers(options);
  13018. const {
  13019. server,
  13020. secondary,
  13021. ttl
  13022. } = info;
  13023. if (typeof server !== 'string' && typeof secondary !== 'string' && typeof ttl !== 'number') {
  13024. throw new Error(`malformed RTM route response: ${JSON.stringify(info)}`);
  13025. }
  13026. this._cache.set('endpoints', info, info.ttl * 1000);
  13027. }
  13028. debug$6('endpoint info: %O', info);
  13029. return [info.server, info.secondary];
  13030. }
  13031. static async _getServerUrls({
  13032. appId,
  13033. server
  13034. }) {
  13035. debug$6('fetch server urls');
  13036. if (server) {
  13037. if (typeof server !== 'string') return server;
  13038. return {
  13039. RTMRouter: server,
  13040. api: server
  13041. };
  13042. }
  13043. const cachedRouter = routerCache.get(appId);
  13044. if (cachedRouter) return cachedRouter;
  13045. const defaultProtocol = 'https://';
  13046. return request({
  13047. url: 'https://app-router.com/2/route',
  13048. query: {
  13049. appId
  13050. },
  13051. timeout: 20000
  13052. }).then(tap(debug$6)).then(({
  13053. rtm_router_server: RTMRouterServer,
  13054. api_server: APIServer,
  13055. ttl = 3600
  13056. }) => {
  13057. if (!RTMRouterServer) {
  13058. throw new Error('rtm router not exists');
  13059. }
  13060. const serverUrls = {
  13061. RTMRouter: `${defaultProtocol}${RTMRouterServer}`,
  13062. api: `${defaultProtocol}${APIServer}`
  13063. };
  13064. routerCache.set(appId, serverUrls, ttl * 1000);
  13065. return serverUrls;
  13066. }).catch(() => {
  13067. const id = appId.slice(0, 8).toLowerCase();
  13068. const domain = 'lncldglobal.com';
  13069. return {
  13070. RTMRouter: `${defaultProtocol}${id}.rtm.${domain}`,
  13071. api: `${defaultProtocol}${id}.api.${domain}`
  13072. };
  13073. });
  13074. }
  13075. static _fetchRTMServers({
  13076. appId,
  13077. ssl,
  13078. server,
  13079. RTMServerName
  13080. }) {
  13081. debug$6('fetch endpoint info');
  13082. return this._getServerUrls({
  13083. appId,
  13084. server
  13085. }).then(tap(debug$6)).then(({
  13086. RTMRouter
  13087. }) => request({
  13088. url: `${RTMRouter}/v1/route`,
  13089. query: {
  13090. appId,
  13091. secure: ssl,
  13092. features: isWeapp ? 'wechat' : undefined,
  13093. server: RTMServerName,
  13094. _t: Date.now()
  13095. },
  13096. timeout: 20000
  13097. }).then(tap(debug$6)));
  13098. }
  13099. _close() {
  13100. if (this._openPromise) {
  13101. this._openPromise.then(connection => connection.close());
  13102. }
  13103. delete this._openPromise;
  13104. }
  13105. /**
  13106. * 手动进行重连。
  13107. * SDK 在网络出现异常时会自动按照一定的时间间隔尝试重连,调用该方法会立即尝试重连并重置重连尝试计数器。
  13108. * 只能在 `SCHEDULE` 事件之后,`RETRY` 事件之前调用,如果当前网络正常或者正在进行重连,调用该方法会抛异常。
  13109. */
  13110. retry() {
  13111. const {
  13112. connection
  13113. } = internal(this);
  13114. if (!connection) {
  13115. throw new Error('no connection established');
  13116. }
  13117. if (connection.cannot('retry')) {
  13118. throw new Error(`retrying not allowed when not disconnected. the connection is now ${connection.current}`);
  13119. }
  13120. return connection.retry();
  13121. }
  13122. /**
  13123. * 暂停,使 SDK 进入离线状态。
  13124. * 你可以在网络断开、应用进入后台等时刻调用该方法让 SDK 进入离线状态,离线状态下不会尝试重连。
  13125. * 在浏览器中 SDK 会自动监听网络变化,因此无需手动调用该方法。
  13126. *
  13127. * @since 3.4.0
  13128. * @see Realtime#event:OFFLINE
  13129. */
  13130. pause() {
  13131. // 这个方法常常在网络断开、进入后台时被调用,此时 connection 可能没有建立或者已经 close。
  13132. // 因此不像 retry,这个方法应该尽可能 loose
  13133. const {
  13134. connection
  13135. } = internal(this);
  13136. if (!connection) return;
  13137. if (connection.can('pause')) connection.pause();
  13138. }
  13139. /**
  13140. * 恢复在线状态。
  13141. * 你可以在网络恢复、应用回到前台等时刻调用该方法让 SDK 恢复在线状态,恢复在线状态后 SDK 会开始尝试重连。
  13142. *
  13143. * @since 3.4.0
  13144. * @see Realtime#event:ONLINE
  13145. */
  13146. resume() {
  13147. // 与 pause 一样,这个方法应该尽可能 loose
  13148. const {
  13149. connection
  13150. } = internal(this);
  13151. if (!connection) return;
  13152. if (connection.can('resume')) connection.resume();
  13153. }
  13154. _registerPending(value) {
  13155. internal(this).pendingClients.add(value);
  13156. }
  13157. _deregisterPending(client) {
  13158. internal(this).pendingClients.delete(client);
  13159. }
  13160. _register(client) {
  13161. internal(this).clients.add(client);
  13162. }
  13163. _deregister(client) {
  13164. const _this = internal(this);
  13165. _this.clients.delete(client);
  13166. if (_this.clients.size + _this.pendingClients.size === 0) {
  13167. this._close();
  13168. }
  13169. }
  13170. _dispatchCommand(command) {
  13171. return applyDispatcher(this._plugins.beforeCommandDispatch, [command, this]).then(shouldDispatch => {
  13172. // no plugin handled this command
  13173. if (shouldDispatch) return debug$6('[WARN] Unexpected message received: %O', trim(command));
  13174. return false;
  13175. });
  13176. }
  13177. } // For test purpose only
  13178. const polyfilledPromise = Promise;
  13179. var rngBrowser = createCommonjsModule(function (module) {
  13180. // Unique ID creation requires a high quality random # generator. In the
  13181. // browser this is a little complicated due to unknown quality of Math.random()
  13182. // and inconsistent support for the `crypto` API. We do the best we can via
  13183. // feature-detection
  13184. // getRandomValues needs to be invoked in a context where "this" is a Crypto
  13185. // implementation. Also, find the complete implementation of crypto on IE11.
  13186. var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||
  13187. (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));
  13188. if (getRandomValues) {
  13189. // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
  13190. var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef
  13191. module.exports = function whatwgRNG() {
  13192. getRandomValues(rnds8);
  13193. return rnds8;
  13194. };
  13195. } else {
  13196. // Math.random()-based (RNG)
  13197. //
  13198. // If all else fails, use Math.random(). It's fast, but is of unspecified
  13199. // quality.
  13200. var rnds = new Array(16);
  13201. module.exports = function mathRNG() {
  13202. for (var i = 0, r; i < 16; i++) {
  13203. if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
  13204. rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
  13205. }
  13206. return rnds;
  13207. };
  13208. }
  13209. });
  13210. /**
  13211. * Convert array of 16 byte values to UUID string format of the form:
  13212. * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
  13213. */
  13214. var byteToHex = [];
  13215. for (var i = 0; i < 256; ++i) {
  13216. byteToHex[i] = (i + 0x100).toString(16).substr(1);
  13217. }
  13218. function bytesToUuid(buf, offset) {
  13219. var i = offset || 0;
  13220. var bth = byteToHex;
  13221. // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
  13222. return ([bth[buf[i++]], bth[buf[i++]],
  13223. bth[buf[i++]], bth[buf[i++]], '-',
  13224. bth[buf[i++]], bth[buf[i++]], '-',
  13225. bth[buf[i++]], bth[buf[i++]], '-',
  13226. bth[buf[i++]], bth[buf[i++]], '-',
  13227. bth[buf[i++]], bth[buf[i++]],
  13228. bth[buf[i++]], bth[buf[i++]],
  13229. bth[buf[i++]], bth[buf[i++]]]).join('');
  13230. }
  13231. var bytesToUuid_1 = bytesToUuid;
  13232. function v4(options, buf, offset) {
  13233. var i = buf && offset || 0;
  13234. if (typeof(options) == 'string') {
  13235. buf = options === 'binary' ? new Array(16) : null;
  13236. options = null;
  13237. }
  13238. options = options || {};
  13239. var rnds = options.random || (options.rng || rngBrowser)();
  13240. // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
  13241. rnds[6] = (rnds[6] & 0x0f) | 0x40;
  13242. rnds[8] = (rnds[8] & 0x3f) | 0x80;
  13243. // Copy bytes to buffer, if provided
  13244. if (buf) {
  13245. for (var ii = 0; ii < 16; ++ii) {
  13246. buf[i + ii] = rnds[ii];
  13247. }
  13248. }
  13249. return buf || bytesToUuid_1(rnds);
  13250. }
  13251. var v4_1 = v4;
  13252. var base64Arraybuffer = createCommonjsModule(function (module, exports) {
  13253. /*
  13254. * base64-arraybuffer
  13255. * https://github.com/niklasvh/base64-arraybuffer
  13256. *
  13257. * Copyright (c) 2012 Niklas von Hertzen
  13258. * Licensed under the MIT license.
  13259. */
  13260. (function(){
  13261. var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  13262. // Use a lookup table to find the index.
  13263. var lookup = new Uint8Array(256);
  13264. for (var i = 0; i < chars.length; i++) {
  13265. lookup[chars.charCodeAt(i)] = i;
  13266. }
  13267. exports.encode = function(arraybuffer) {
  13268. var bytes = new Uint8Array(arraybuffer),
  13269. i, len = bytes.length, base64 = "";
  13270. for (i = 0; i < len; i+=3) {
  13271. base64 += chars[bytes[i] >> 2];
  13272. base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
  13273. base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
  13274. base64 += chars[bytes[i + 2] & 63];
  13275. }
  13276. if ((len % 3) === 2) {
  13277. base64 = base64.substring(0, base64.length - 1) + "=";
  13278. } else if (len % 3 === 1) {
  13279. base64 = base64.substring(0, base64.length - 2) + "==";
  13280. }
  13281. return base64;
  13282. };
  13283. exports.decode = function(base64) {
  13284. var bufferLength = base64.length * 0.75,
  13285. len = base64.length, i, p = 0,
  13286. encoded1, encoded2, encoded3, encoded4;
  13287. if (base64[base64.length - 1] === "=") {
  13288. bufferLength--;
  13289. if (base64[base64.length - 2] === "=") {
  13290. bufferLength--;
  13291. }
  13292. }
  13293. var arraybuffer = new ArrayBuffer(bufferLength),
  13294. bytes = new Uint8Array(arraybuffer);
  13295. for (i = 0; i < len; i+=4) {
  13296. encoded1 = lookup[base64.charCodeAt(i)];
  13297. encoded2 = lookup[base64.charCodeAt(i+1)];
  13298. encoded3 = lookup[base64.charCodeAt(i+2)];
  13299. encoded4 = lookup[base64.charCodeAt(i+3)];
  13300. bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
  13301. bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
  13302. bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
  13303. }
  13304. return arraybuffer;
  13305. };
  13306. })();
  13307. });
  13308. var base64Arraybuffer_1 = base64Arraybuffer.encode;
  13309. var base64Arraybuffer_2 = base64Arraybuffer.decode;
  13310. /**
  13311. * Removes all key-value entries from the list cache.
  13312. *
  13313. * @private
  13314. * @name clear
  13315. * @memberOf ListCache
  13316. */
  13317. function listCacheClear() {
  13318. this.__data__ = [];
  13319. this.size = 0;
  13320. }
  13321. var _listCacheClear = listCacheClear;
  13322. /**
  13323. * Performs a
  13324. * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  13325. * comparison between two values to determine if they are equivalent.
  13326. *
  13327. * @static
  13328. * @memberOf _
  13329. * @since 4.0.0
  13330. * @category Lang
  13331. * @param {*} value The value to compare.
  13332. * @param {*} other The other value to compare.
  13333. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  13334. * @example
  13335. *
  13336. * var object = { 'a': 1 };
  13337. * var other = { 'a': 1 };
  13338. *
  13339. * _.eq(object, object);
  13340. * // => true
  13341. *
  13342. * _.eq(object, other);
  13343. * // => false
  13344. *
  13345. * _.eq('a', 'a');
  13346. * // => true
  13347. *
  13348. * _.eq('a', Object('a'));
  13349. * // => false
  13350. *
  13351. * _.eq(NaN, NaN);
  13352. * // => true
  13353. */
  13354. function eq(value, other) {
  13355. return value === other || (value !== value && other !== other);
  13356. }
  13357. var eq_1 = eq;
  13358. /**
  13359. * Gets the index at which the `key` is found in `array` of key-value pairs.
  13360. *
  13361. * @private
  13362. * @param {Array} array The array to inspect.
  13363. * @param {*} key The key to search for.
  13364. * @returns {number} Returns the index of the matched value, else `-1`.
  13365. */
  13366. function assocIndexOf(array, key) {
  13367. var length = array.length;
  13368. while (length--) {
  13369. if (eq_1(array[length][0], key)) {
  13370. return length;
  13371. }
  13372. }
  13373. return -1;
  13374. }
  13375. var _assocIndexOf = assocIndexOf;
  13376. /** Used for built-in method references. */
  13377. var arrayProto = Array.prototype;
  13378. /** Built-in value references. */
  13379. var splice = arrayProto.splice;
  13380. /**
  13381. * Removes `key` and its value from the list cache.
  13382. *
  13383. * @private
  13384. * @name delete
  13385. * @memberOf ListCache
  13386. * @param {string} key The key of the value to remove.
  13387. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  13388. */
  13389. function listCacheDelete(key) {
  13390. var data = this.__data__,
  13391. index = _assocIndexOf(data, key);
  13392. if (index < 0) {
  13393. return false;
  13394. }
  13395. var lastIndex = data.length - 1;
  13396. if (index == lastIndex) {
  13397. data.pop();
  13398. } else {
  13399. splice.call(data, index, 1);
  13400. }
  13401. --this.size;
  13402. return true;
  13403. }
  13404. var _listCacheDelete = listCacheDelete;
  13405. /**
  13406. * Gets the list cache value for `key`.
  13407. *
  13408. * @private
  13409. * @name get
  13410. * @memberOf ListCache
  13411. * @param {string} key The key of the value to get.
  13412. * @returns {*} Returns the entry value.
  13413. */
  13414. function listCacheGet(key) {
  13415. var data = this.__data__,
  13416. index = _assocIndexOf(data, key);
  13417. return index < 0 ? undefined : data[index][1];
  13418. }
  13419. var _listCacheGet = listCacheGet;
  13420. /**
  13421. * Checks if a list cache value for `key` exists.
  13422. *
  13423. * @private
  13424. * @name has
  13425. * @memberOf ListCache
  13426. * @param {string} key The key of the entry to check.
  13427. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  13428. */
  13429. function listCacheHas(key) {
  13430. return _assocIndexOf(this.__data__, key) > -1;
  13431. }
  13432. var _listCacheHas = listCacheHas;
  13433. /**
  13434. * Sets the list cache `key` to `value`.
  13435. *
  13436. * @private
  13437. * @name set
  13438. * @memberOf ListCache
  13439. * @param {string} key The key of the value to set.
  13440. * @param {*} value The value to set.
  13441. * @returns {Object} Returns the list cache instance.
  13442. */
  13443. function listCacheSet(key, value) {
  13444. var data = this.__data__,
  13445. index = _assocIndexOf(data, key);
  13446. if (index < 0) {
  13447. ++this.size;
  13448. data.push([key, value]);
  13449. } else {
  13450. data[index][1] = value;
  13451. }
  13452. return this;
  13453. }
  13454. var _listCacheSet = listCacheSet;
  13455. /**
  13456. * Creates an list cache object.
  13457. *
  13458. * @private
  13459. * @constructor
  13460. * @param {Array} [entries] The key-value pairs to cache.
  13461. */
  13462. function ListCache(entries) {
  13463. var index = -1,
  13464. length = entries == null ? 0 : entries.length;
  13465. this.clear();
  13466. while (++index < length) {
  13467. var entry = entries[index];
  13468. this.set(entry[0], entry[1]);
  13469. }
  13470. }
  13471. // Add methods to `ListCache`.
  13472. ListCache.prototype.clear = _listCacheClear;
  13473. ListCache.prototype['delete'] = _listCacheDelete;
  13474. ListCache.prototype.get = _listCacheGet;
  13475. ListCache.prototype.has = _listCacheHas;
  13476. ListCache.prototype.set = _listCacheSet;
  13477. var _ListCache = ListCache;
  13478. /**
  13479. * Removes all key-value entries from the stack.
  13480. *
  13481. * @private
  13482. * @name clear
  13483. * @memberOf Stack
  13484. */
  13485. function stackClear() {
  13486. this.__data__ = new _ListCache;
  13487. this.size = 0;
  13488. }
  13489. var _stackClear = stackClear;
  13490. /**
  13491. * Removes `key` and its value from the stack.
  13492. *
  13493. * @private
  13494. * @name delete
  13495. * @memberOf Stack
  13496. * @param {string} key The key of the value to remove.
  13497. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  13498. */
  13499. function stackDelete(key) {
  13500. var data = this.__data__,
  13501. result = data['delete'](key);
  13502. this.size = data.size;
  13503. return result;
  13504. }
  13505. var _stackDelete = stackDelete;
  13506. /**
  13507. * Gets the stack value for `key`.
  13508. *
  13509. * @private
  13510. * @name get
  13511. * @memberOf Stack
  13512. * @param {string} key The key of the value to get.
  13513. * @returns {*} Returns the entry value.
  13514. */
  13515. function stackGet(key) {
  13516. return this.__data__.get(key);
  13517. }
  13518. var _stackGet = stackGet;
  13519. /**
  13520. * Checks if a stack value for `key` exists.
  13521. *
  13522. * @private
  13523. * @name has
  13524. * @memberOf Stack
  13525. * @param {string} key The key of the entry to check.
  13526. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  13527. */
  13528. function stackHas(key) {
  13529. return this.__data__.has(key);
  13530. }
  13531. var _stackHas = stackHas;
  13532. /** Used to detect overreaching core-js shims. */
  13533. var coreJsData = _root['__core-js_shared__'];
  13534. var _coreJsData = coreJsData;
  13535. /** Used to detect methods masquerading as native. */
  13536. var maskSrcKey = (function() {
  13537. var uid = /[^.]+$/.exec(_coreJsData && _coreJsData.keys && _coreJsData.keys.IE_PROTO || '');
  13538. return uid ? ('Symbol(src)_1.' + uid) : '';
  13539. }());
  13540. /**
  13541. * Checks if `func` has its source masked.
  13542. *
  13543. * @private
  13544. * @param {Function} func The function to check.
  13545. * @returns {boolean} Returns `true` if `func` is masked, else `false`.
  13546. */
  13547. function isMasked(func) {
  13548. return !!maskSrcKey && (maskSrcKey in func);
  13549. }
  13550. var _isMasked = isMasked;
  13551. /** Used for built-in method references. */
  13552. var funcProto$1 = Function.prototype;
  13553. /** Used to resolve the decompiled source of functions. */
  13554. var funcToString$1 = funcProto$1.toString;
  13555. /**
  13556. * Converts `func` to its source code.
  13557. *
  13558. * @private
  13559. * @param {Function} func The function to convert.
  13560. * @returns {string} Returns the source code.
  13561. */
  13562. function toSource(func) {
  13563. if (func != null) {
  13564. try {
  13565. return funcToString$1.call(func);
  13566. } catch (e) {}
  13567. try {
  13568. return (func + '');
  13569. } catch (e) {}
  13570. }
  13571. return '';
  13572. }
  13573. var _toSource = toSource;
  13574. /**
  13575. * Used to match `RegExp`
  13576. * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
  13577. */
  13578. var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
  13579. /** Used to detect host constructors (Safari). */
  13580. var reIsHostCtor = /^\[object .+?Constructor\]$/;
  13581. /** Used for built-in method references. */
  13582. var funcProto$2 = Function.prototype,
  13583. objectProto$7 = Object.prototype;
  13584. /** Used to resolve the decompiled source of functions. */
  13585. var funcToString$2 = funcProto$2.toString;
  13586. /** Used to check objects for own properties. */
  13587. var hasOwnProperty$5 = objectProto$7.hasOwnProperty;
  13588. /** Used to detect if a method is native. */
  13589. var reIsNative = RegExp('^' +
  13590. funcToString$2.call(hasOwnProperty$5).replace(reRegExpChar, '\\$&')
  13591. .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
  13592. );
  13593. /**
  13594. * The base implementation of `_.isNative` without bad shim checks.
  13595. *
  13596. * @private
  13597. * @param {*} value The value to check.
  13598. * @returns {boolean} Returns `true` if `value` is a native function,
  13599. * else `false`.
  13600. */
  13601. function baseIsNative(value) {
  13602. if (!isObject_1(value) || _isMasked(value)) {
  13603. return false;
  13604. }
  13605. var pattern = isFunction_1(value) ? reIsNative : reIsHostCtor;
  13606. return pattern.test(_toSource(value));
  13607. }
  13608. var _baseIsNative = baseIsNative;
  13609. /**
  13610. * Gets the value at `key` of `object`.
  13611. *
  13612. * @private
  13613. * @param {Object} [object] The object to query.
  13614. * @param {string} key The key of the property to get.
  13615. * @returns {*} Returns the property value.
  13616. */
  13617. function getValue(object, key) {
  13618. return object == null ? undefined : object[key];
  13619. }
  13620. var _getValue = getValue;
  13621. /**
  13622. * Gets the native function at `key` of `object`.
  13623. *
  13624. * @private
  13625. * @param {Object} object The object to query.
  13626. * @param {string} key The key of the method to get.
  13627. * @returns {*} Returns the function if it's native, else `undefined`.
  13628. */
  13629. function getNative(object, key) {
  13630. var value = _getValue(object, key);
  13631. return _baseIsNative(value) ? value : undefined;
  13632. }
  13633. var _getNative = getNative;
  13634. /* Built-in method references that are verified to be native. */
  13635. var Map = _getNative(_root, 'Map');
  13636. var _Map = Map;
  13637. /* Built-in method references that are verified to be native. */
  13638. var nativeCreate = _getNative(Object, 'create');
  13639. var _nativeCreate = nativeCreate;
  13640. /**
  13641. * Removes all key-value entries from the hash.
  13642. *
  13643. * @private
  13644. * @name clear
  13645. * @memberOf Hash
  13646. */
  13647. function hashClear() {
  13648. this.__data__ = _nativeCreate ? _nativeCreate(null) : {};
  13649. this.size = 0;
  13650. }
  13651. var _hashClear = hashClear;
  13652. /**
  13653. * Removes `key` and its value from the hash.
  13654. *
  13655. * @private
  13656. * @name delete
  13657. * @memberOf Hash
  13658. * @param {Object} hash The hash to modify.
  13659. * @param {string} key The key of the value to remove.
  13660. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  13661. */
  13662. function hashDelete(key) {
  13663. var result = this.has(key) && delete this.__data__[key];
  13664. this.size -= result ? 1 : 0;
  13665. return result;
  13666. }
  13667. var _hashDelete = hashDelete;
  13668. /** Used to stand-in for `undefined` hash values. */
  13669. var HASH_UNDEFINED = '__lodash_hash_undefined__';
  13670. /** Used for built-in method references. */
  13671. var objectProto$8 = Object.prototype;
  13672. /** Used to check objects for own properties. */
  13673. var hasOwnProperty$6 = objectProto$8.hasOwnProperty;
  13674. /**
  13675. * Gets the hash value for `key`.
  13676. *
  13677. * @private
  13678. * @name get
  13679. * @memberOf Hash
  13680. * @param {string} key The key of the value to get.
  13681. * @returns {*} Returns the entry value.
  13682. */
  13683. function hashGet(key) {
  13684. var data = this.__data__;
  13685. if (_nativeCreate) {
  13686. var result = data[key];
  13687. return result === HASH_UNDEFINED ? undefined : result;
  13688. }
  13689. return hasOwnProperty$6.call(data, key) ? data[key] : undefined;
  13690. }
  13691. var _hashGet = hashGet;
  13692. /** Used for built-in method references. */
  13693. var objectProto$9 = Object.prototype;
  13694. /** Used to check objects for own properties. */
  13695. var hasOwnProperty$7 = objectProto$9.hasOwnProperty;
  13696. /**
  13697. * Checks if a hash value for `key` exists.
  13698. *
  13699. * @private
  13700. * @name has
  13701. * @memberOf Hash
  13702. * @param {string} key The key of the entry to check.
  13703. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  13704. */
  13705. function hashHas(key) {
  13706. var data = this.__data__;
  13707. return _nativeCreate ? (data[key] !== undefined) : hasOwnProperty$7.call(data, key);
  13708. }
  13709. var _hashHas = hashHas;
  13710. /** Used to stand-in for `undefined` hash values. */
  13711. var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';
  13712. /**
  13713. * Sets the hash `key` to `value`.
  13714. *
  13715. * @private
  13716. * @name set
  13717. * @memberOf Hash
  13718. * @param {string} key The key of the value to set.
  13719. * @param {*} value The value to set.
  13720. * @returns {Object} Returns the hash instance.
  13721. */
  13722. function hashSet(key, value) {
  13723. var data = this.__data__;
  13724. this.size += this.has(key) ? 0 : 1;
  13725. data[key] = (_nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value;
  13726. return this;
  13727. }
  13728. var _hashSet = hashSet;
  13729. /**
  13730. * Creates a hash object.
  13731. *
  13732. * @private
  13733. * @constructor
  13734. * @param {Array} [entries] The key-value pairs to cache.
  13735. */
  13736. function Hash(entries) {
  13737. var index = -1,
  13738. length = entries == null ? 0 : entries.length;
  13739. this.clear();
  13740. while (++index < length) {
  13741. var entry = entries[index];
  13742. this.set(entry[0], entry[1]);
  13743. }
  13744. }
  13745. // Add methods to `Hash`.
  13746. Hash.prototype.clear = _hashClear;
  13747. Hash.prototype['delete'] = _hashDelete;
  13748. Hash.prototype.get = _hashGet;
  13749. Hash.prototype.has = _hashHas;
  13750. Hash.prototype.set = _hashSet;
  13751. var _Hash = Hash;
  13752. /**
  13753. * Removes all key-value entries from the map.
  13754. *
  13755. * @private
  13756. * @name clear
  13757. * @memberOf MapCache
  13758. */
  13759. function mapCacheClear() {
  13760. this.size = 0;
  13761. this.__data__ = {
  13762. 'hash': new _Hash,
  13763. 'map': new (_Map || _ListCache),
  13764. 'string': new _Hash
  13765. };
  13766. }
  13767. var _mapCacheClear = mapCacheClear;
  13768. /**
  13769. * Checks if `value` is suitable for use as unique object key.
  13770. *
  13771. * @private
  13772. * @param {*} value The value to check.
  13773. * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
  13774. */
  13775. function isKeyable(value) {
  13776. var type = typeof value;
  13777. return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
  13778. ? (value !== '__proto__')
  13779. : (value === null);
  13780. }
  13781. var _isKeyable = isKeyable;
  13782. /**
  13783. * Gets the data for `map`.
  13784. *
  13785. * @private
  13786. * @param {Object} map The map to query.
  13787. * @param {string} key The reference key.
  13788. * @returns {*} Returns the map data.
  13789. */
  13790. function getMapData(map, key) {
  13791. var data = map.__data__;
  13792. return _isKeyable(key)
  13793. ? data[typeof key == 'string' ? 'string' : 'hash']
  13794. : data.map;
  13795. }
  13796. var _getMapData = getMapData;
  13797. /**
  13798. * Removes `key` and its value from the map.
  13799. *
  13800. * @private
  13801. * @name delete
  13802. * @memberOf MapCache
  13803. * @param {string} key The key of the value to remove.
  13804. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  13805. */
  13806. function mapCacheDelete(key) {
  13807. var result = _getMapData(this, key)['delete'](key);
  13808. this.size -= result ? 1 : 0;
  13809. return result;
  13810. }
  13811. var _mapCacheDelete = mapCacheDelete;
  13812. /**
  13813. * Gets the map value for `key`.
  13814. *
  13815. * @private
  13816. * @name get
  13817. * @memberOf MapCache
  13818. * @param {string} key The key of the value to get.
  13819. * @returns {*} Returns the entry value.
  13820. */
  13821. function mapCacheGet(key) {
  13822. return _getMapData(this, key).get(key);
  13823. }
  13824. var _mapCacheGet = mapCacheGet;
  13825. /**
  13826. * Checks if a map value for `key` exists.
  13827. *
  13828. * @private
  13829. * @name has
  13830. * @memberOf MapCache
  13831. * @param {string} key The key of the entry to check.
  13832. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  13833. */
  13834. function mapCacheHas(key) {
  13835. return _getMapData(this, key).has(key);
  13836. }
  13837. var _mapCacheHas = mapCacheHas;
  13838. /**
  13839. * Sets the map `key` to `value`.
  13840. *
  13841. * @private
  13842. * @name set
  13843. * @memberOf MapCache
  13844. * @param {string} key The key of the value to set.
  13845. * @param {*} value The value to set.
  13846. * @returns {Object} Returns the map cache instance.
  13847. */
  13848. function mapCacheSet(key, value) {
  13849. var data = _getMapData(this, key),
  13850. size = data.size;
  13851. data.set(key, value);
  13852. this.size += data.size == size ? 0 : 1;
  13853. return this;
  13854. }
  13855. var _mapCacheSet = mapCacheSet;
  13856. /**
  13857. * Creates a map cache object to store key-value pairs.
  13858. *
  13859. * @private
  13860. * @constructor
  13861. * @param {Array} [entries] The key-value pairs to cache.
  13862. */
  13863. function MapCache(entries) {
  13864. var index = -1,
  13865. length = entries == null ? 0 : entries.length;
  13866. this.clear();
  13867. while (++index < length) {
  13868. var entry = entries[index];
  13869. this.set(entry[0], entry[1]);
  13870. }
  13871. }
  13872. // Add methods to `MapCache`.
  13873. MapCache.prototype.clear = _mapCacheClear;
  13874. MapCache.prototype['delete'] = _mapCacheDelete;
  13875. MapCache.prototype.get = _mapCacheGet;
  13876. MapCache.prototype.has = _mapCacheHas;
  13877. MapCache.prototype.set = _mapCacheSet;
  13878. var _MapCache = MapCache;
  13879. /** Used as the size to enable large array optimizations. */
  13880. var LARGE_ARRAY_SIZE = 200;
  13881. /**
  13882. * Sets the stack `key` to `value`.
  13883. *
  13884. * @private
  13885. * @name set
  13886. * @memberOf Stack
  13887. * @param {string} key The key of the value to set.
  13888. * @param {*} value The value to set.
  13889. * @returns {Object} Returns the stack cache instance.
  13890. */
  13891. function stackSet(key, value) {
  13892. var data = this.__data__;
  13893. if (data instanceof _ListCache) {
  13894. var pairs = data.__data__;
  13895. if (!_Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
  13896. pairs.push([key, value]);
  13897. this.size = ++data.size;
  13898. return this;
  13899. }
  13900. data = this.__data__ = new _MapCache(pairs);
  13901. }
  13902. data.set(key, value);
  13903. this.size = data.size;
  13904. return this;
  13905. }
  13906. var _stackSet = stackSet;
  13907. /**
  13908. * Creates a stack cache object to store key-value pairs.
  13909. *
  13910. * @private
  13911. * @constructor
  13912. * @param {Array} [entries] The key-value pairs to cache.
  13913. */
  13914. function Stack(entries) {
  13915. var data = this.__data__ = new _ListCache(entries);
  13916. this.size = data.size;
  13917. }
  13918. // Add methods to `Stack`.
  13919. Stack.prototype.clear = _stackClear;
  13920. Stack.prototype['delete'] = _stackDelete;
  13921. Stack.prototype.get = _stackGet;
  13922. Stack.prototype.has = _stackHas;
  13923. Stack.prototype.set = _stackSet;
  13924. var _Stack = Stack;
  13925. /** Used to stand-in for `undefined` hash values. */
  13926. var HASH_UNDEFINED$2 = '__lodash_hash_undefined__';
  13927. /**
  13928. * Adds `value` to the array cache.
  13929. *
  13930. * @private
  13931. * @name add
  13932. * @memberOf SetCache
  13933. * @alias push
  13934. * @param {*} value The value to cache.
  13935. * @returns {Object} Returns the cache instance.
  13936. */
  13937. function setCacheAdd(value) {
  13938. this.__data__.set(value, HASH_UNDEFINED$2);
  13939. return this;
  13940. }
  13941. var _setCacheAdd = setCacheAdd;
  13942. /**
  13943. * Checks if `value` is in the array cache.
  13944. *
  13945. * @private
  13946. * @name has
  13947. * @memberOf SetCache
  13948. * @param {*} value The value to search for.
  13949. * @returns {number} Returns `true` if `value` is found, else `false`.
  13950. */
  13951. function setCacheHas(value) {
  13952. return this.__data__.has(value);
  13953. }
  13954. var _setCacheHas = setCacheHas;
  13955. /**
  13956. *
  13957. * Creates an array cache object to store unique values.
  13958. *
  13959. * @private
  13960. * @constructor
  13961. * @param {Array} [values] The values to cache.
  13962. */
  13963. function SetCache(values) {
  13964. var index = -1,
  13965. length = values == null ? 0 : values.length;
  13966. this.__data__ = new _MapCache;
  13967. while (++index < length) {
  13968. this.add(values[index]);
  13969. }
  13970. }
  13971. // Add methods to `SetCache`.
  13972. SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd;
  13973. SetCache.prototype.has = _setCacheHas;
  13974. var _SetCache = SetCache;
  13975. /**
  13976. * A specialized version of `_.some` for arrays without support for iteratee
  13977. * shorthands.
  13978. *
  13979. * @private
  13980. * @param {Array} [array] The array to iterate over.
  13981. * @param {Function} predicate The function invoked per iteration.
  13982. * @returns {boolean} Returns `true` if any element passes the predicate check,
  13983. * else `false`.
  13984. */
  13985. function arraySome(array, predicate) {
  13986. var index = -1,
  13987. length = array == null ? 0 : array.length;
  13988. while (++index < length) {
  13989. if (predicate(array[index], index, array)) {
  13990. return true;
  13991. }
  13992. }
  13993. return false;
  13994. }
  13995. var _arraySome = arraySome;
  13996. /**
  13997. * Checks if a `cache` value for `key` exists.
  13998. *
  13999. * @private
  14000. * @param {Object} cache The cache to query.
  14001. * @param {string} key The key of the entry to check.
  14002. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  14003. */
  14004. function cacheHas(cache, key) {
  14005. return cache.has(key);
  14006. }
  14007. var _cacheHas = cacheHas;
  14008. /** Used to compose bitmasks for value comparisons. */
  14009. var COMPARE_PARTIAL_FLAG = 1,
  14010. COMPARE_UNORDERED_FLAG = 2;
  14011. /**
  14012. * A specialized version of `baseIsEqualDeep` for arrays with support for
  14013. * partial deep comparisons.
  14014. *
  14015. * @private
  14016. * @param {Array} array The array to compare.
  14017. * @param {Array} other The other array to compare.
  14018. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  14019. * @param {Function} customizer The function to customize comparisons.
  14020. * @param {Function} equalFunc The function to determine equivalents of values.
  14021. * @param {Object} stack Tracks traversed `array` and `other` objects.
  14022. * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
  14023. */
  14024. function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
  14025. var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
  14026. arrLength = array.length,
  14027. othLength = other.length;
  14028. if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
  14029. return false;
  14030. }
  14031. // Check that cyclic values are equal.
  14032. var arrStacked = stack.get(array);
  14033. var othStacked = stack.get(other);
  14034. if (arrStacked && othStacked) {
  14035. return arrStacked == other && othStacked == array;
  14036. }
  14037. var index = -1,
  14038. result = true,
  14039. seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache : undefined;
  14040. stack.set(array, other);
  14041. stack.set(other, array);
  14042. // Ignore non-index properties.
  14043. while (++index < arrLength) {
  14044. var arrValue = array[index],
  14045. othValue = other[index];
  14046. if (customizer) {
  14047. var compared = isPartial
  14048. ? customizer(othValue, arrValue, index, other, array, stack)
  14049. : customizer(arrValue, othValue, index, array, other, stack);
  14050. }
  14051. if (compared !== undefined) {
  14052. if (compared) {
  14053. continue;
  14054. }
  14055. result = false;
  14056. break;
  14057. }
  14058. // Recursively compare arrays (susceptible to call stack limits).
  14059. if (seen) {
  14060. if (!_arraySome(other, function(othValue, othIndex) {
  14061. if (!_cacheHas(seen, othIndex) &&
  14062. (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
  14063. return seen.push(othIndex);
  14064. }
  14065. })) {
  14066. result = false;
  14067. break;
  14068. }
  14069. } else if (!(
  14070. arrValue === othValue ||
  14071. equalFunc(arrValue, othValue, bitmask, customizer, stack)
  14072. )) {
  14073. result = false;
  14074. break;
  14075. }
  14076. }
  14077. stack['delete'](array);
  14078. stack['delete'](other);
  14079. return result;
  14080. }
  14081. var _equalArrays = equalArrays;
  14082. /** Built-in value references. */
  14083. var Uint8Array$1 = _root.Uint8Array;
  14084. var _Uint8Array = Uint8Array$1;
  14085. /**
  14086. * Converts `map` to its key-value pairs.
  14087. *
  14088. * @private
  14089. * @param {Object} map The map to convert.
  14090. * @returns {Array} Returns the key-value pairs.
  14091. */
  14092. function mapToArray(map) {
  14093. var index = -1,
  14094. result = Array(map.size);
  14095. map.forEach(function(value, key) {
  14096. result[++index] = [key, value];
  14097. });
  14098. return result;
  14099. }
  14100. var _mapToArray = mapToArray;
  14101. /**
  14102. * Converts `set` to an array of its values.
  14103. *
  14104. * @private
  14105. * @param {Object} set The set to convert.
  14106. * @returns {Array} Returns the values.
  14107. */
  14108. function setToArray(set) {
  14109. var index = -1,
  14110. result = Array(set.size);
  14111. set.forEach(function(value) {
  14112. result[++index] = value;
  14113. });
  14114. return result;
  14115. }
  14116. var _setToArray = setToArray;
  14117. /** Used to compose bitmasks for value comparisons. */
  14118. var COMPARE_PARTIAL_FLAG$1 = 1,
  14119. COMPARE_UNORDERED_FLAG$1 = 2;
  14120. /** `Object#toString` result references. */
  14121. var boolTag$1 = '[object Boolean]',
  14122. dateTag$1 = '[object Date]',
  14123. errorTag$1 = '[object Error]',
  14124. mapTag$1 = '[object Map]',
  14125. numberTag$1 = '[object Number]',
  14126. regexpTag$1 = '[object RegExp]',
  14127. setTag$1 = '[object Set]',
  14128. stringTag$1 = '[object String]',
  14129. symbolTag = '[object Symbol]';
  14130. var arrayBufferTag$1 = '[object ArrayBuffer]',
  14131. dataViewTag$1 = '[object DataView]';
  14132. /** Used to convert symbols to primitives and strings. */
  14133. var symbolProto = _Symbol ? _Symbol.prototype : undefined,
  14134. symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
  14135. /**
  14136. * A specialized version of `baseIsEqualDeep` for comparing objects of
  14137. * the same `toStringTag`.
  14138. *
  14139. * **Note:** This function only supports comparing values with tags of
  14140. * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
  14141. *
  14142. * @private
  14143. * @param {Object} object The object to compare.
  14144. * @param {Object} other The other object to compare.
  14145. * @param {string} tag The `toStringTag` of the objects to compare.
  14146. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  14147. * @param {Function} customizer The function to customize comparisons.
  14148. * @param {Function} equalFunc The function to determine equivalents of values.
  14149. * @param {Object} stack Tracks traversed `object` and `other` objects.
  14150. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  14151. */
  14152. function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
  14153. switch (tag) {
  14154. case dataViewTag$1:
  14155. if ((object.byteLength != other.byteLength) ||
  14156. (object.byteOffset != other.byteOffset)) {
  14157. return false;
  14158. }
  14159. object = object.buffer;
  14160. other = other.buffer;
  14161. case arrayBufferTag$1:
  14162. if ((object.byteLength != other.byteLength) ||
  14163. !equalFunc(new _Uint8Array(object), new _Uint8Array(other))) {
  14164. return false;
  14165. }
  14166. return true;
  14167. case boolTag$1:
  14168. case dateTag$1:
  14169. case numberTag$1:
  14170. // Coerce booleans to `1` or `0` and dates to milliseconds.
  14171. // Invalid dates are coerced to `NaN`.
  14172. return eq_1(+object, +other);
  14173. case errorTag$1:
  14174. return object.name == other.name && object.message == other.message;
  14175. case regexpTag$1:
  14176. case stringTag$1:
  14177. // Coerce regexes to strings and treat strings, primitives and objects,
  14178. // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
  14179. // for more details.
  14180. return object == (other + '');
  14181. case mapTag$1:
  14182. var convert = _mapToArray;
  14183. case setTag$1:
  14184. var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1;
  14185. convert || (convert = _setToArray);
  14186. if (object.size != other.size && !isPartial) {
  14187. return false;
  14188. }
  14189. // Assume cyclic values are equal.
  14190. var stacked = stack.get(object);
  14191. if (stacked) {
  14192. return stacked == other;
  14193. }
  14194. bitmask |= COMPARE_UNORDERED_FLAG$1;
  14195. // Recursively compare objects (susceptible to call stack limits).
  14196. stack.set(object, other);
  14197. var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
  14198. stack['delete'](object);
  14199. return result;
  14200. case symbolTag:
  14201. if (symbolValueOf) {
  14202. return symbolValueOf.call(object) == symbolValueOf.call(other);
  14203. }
  14204. }
  14205. return false;
  14206. }
  14207. var _equalByTag = equalByTag;
  14208. /**
  14209. * Appends the elements of `values` to `array`.
  14210. *
  14211. * @private
  14212. * @param {Array} array The array to modify.
  14213. * @param {Array} values The values to append.
  14214. * @returns {Array} Returns `array`.
  14215. */
  14216. function arrayPush(array, values) {
  14217. var index = -1,
  14218. length = values.length,
  14219. offset = array.length;
  14220. while (++index < length) {
  14221. array[offset + index] = values[index];
  14222. }
  14223. return array;
  14224. }
  14225. var _arrayPush = arrayPush;
  14226. /**
  14227. * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
  14228. * `keysFunc` and `symbolsFunc` to get the enumerable property names and
  14229. * symbols of `object`.
  14230. *
  14231. * @private
  14232. * @param {Object} object The object to query.
  14233. * @param {Function} keysFunc The function to get the keys of `object`.
  14234. * @param {Function} symbolsFunc The function to get the symbols of `object`.
  14235. * @returns {Array} Returns the array of property names and symbols.
  14236. */
  14237. function baseGetAllKeys(object, keysFunc, symbolsFunc) {
  14238. var result = keysFunc(object);
  14239. return isArray_1(object) ? result : _arrayPush(result, symbolsFunc(object));
  14240. }
  14241. var _baseGetAllKeys = baseGetAllKeys;
  14242. /**
  14243. * A specialized version of `_.filter` for arrays without support for
  14244. * iteratee shorthands.
  14245. *
  14246. * @private
  14247. * @param {Array} [array] The array to iterate over.
  14248. * @param {Function} predicate The function invoked per iteration.
  14249. * @returns {Array} Returns the new filtered array.
  14250. */
  14251. function arrayFilter(array, predicate) {
  14252. var index = -1,
  14253. length = array == null ? 0 : array.length,
  14254. resIndex = 0,
  14255. result = [];
  14256. while (++index < length) {
  14257. var value = array[index];
  14258. if (predicate(value, index, array)) {
  14259. result[resIndex++] = value;
  14260. }
  14261. }
  14262. return result;
  14263. }
  14264. var _arrayFilter = arrayFilter;
  14265. /**
  14266. * This method returns a new empty array.
  14267. *
  14268. * @static
  14269. * @memberOf _
  14270. * @since 4.13.0
  14271. * @category Util
  14272. * @returns {Array} Returns the new empty array.
  14273. * @example
  14274. *
  14275. * var arrays = _.times(2, _.stubArray);
  14276. *
  14277. * console.log(arrays);
  14278. * // => [[], []]
  14279. *
  14280. * console.log(arrays[0] === arrays[1]);
  14281. * // => false
  14282. */
  14283. function stubArray() {
  14284. return [];
  14285. }
  14286. var stubArray_1 = stubArray;
  14287. /** Used for built-in method references. */
  14288. var objectProto$a = Object.prototype;
  14289. /** Built-in value references. */
  14290. var propertyIsEnumerable$1 = objectProto$a.propertyIsEnumerable;
  14291. /* Built-in method references for those with the same name as other `lodash` methods. */
  14292. var nativeGetSymbols = Object.getOwnPropertySymbols;
  14293. /**
  14294. * Creates an array of the own enumerable symbols of `object`.
  14295. *
  14296. * @private
  14297. * @param {Object} object The object to query.
  14298. * @returns {Array} Returns the array of symbols.
  14299. */
  14300. var getSymbols = !nativeGetSymbols ? stubArray_1 : function(object) {
  14301. if (object == null) {
  14302. return [];
  14303. }
  14304. object = Object(object);
  14305. return _arrayFilter(nativeGetSymbols(object), function(symbol) {
  14306. return propertyIsEnumerable$1.call(object, symbol);
  14307. });
  14308. };
  14309. var _getSymbols = getSymbols;
  14310. /**
  14311. * Creates an array of own enumerable property names and symbols of `object`.
  14312. *
  14313. * @private
  14314. * @param {Object} object The object to query.
  14315. * @returns {Array} Returns the array of property names and symbols.
  14316. */
  14317. function getAllKeys(object) {
  14318. return _baseGetAllKeys(object, keys_1, _getSymbols);
  14319. }
  14320. var _getAllKeys = getAllKeys;
  14321. /** Used to compose bitmasks for value comparisons. */
  14322. var COMPARE_PARTIAL_FLAG$2 = 1;
  14323. /** Used for built-in method references. */
  14324. var objectProto$b = Object.prototype;
  14325. /** Used to check objects for own properties. */
  14326. var hasOwnProperty$8 = objectProto$b.hasOwnProperty;
  14327. /**
  14328. * A specialized version of `baseIsEqualDeep` for objects with support for
  14329. * partial deep comparisons.
  14330. *
  14331. * @private
  14332. * @param {Object} object The object to compare.
  14333. * @param {Object} other The other object to compare.
  14334. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  14335. * @param {Function} customizer The function to customize comparisons.
  14336. * @param {Function} equalFunc The function to determine equivalents of values.
  14337. * @param {Object} stack Tracks traversed `object` and `other` objects.
  14338. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  14339. */
  14340. function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
  14341. var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2,
  14342. objProps = _getAllKeys(object),
  14343. objLength = objProps.length,
  14344. othProps = _getAllKeys(other),
  14345. othLength = othProps.length;
  14346. if (objLength != othLength && !isPartial) {
  14347. return false;
  14348. }
  14349. var index = objLength;
  14350. while (index--) {
  14351. var key = objProps[index];
  14352. if (!(isPartial ? key in other : hasOwnProperty$8.call(other, key))) {
  14353. return false;
  14354. }
  14355. }
  14356. // Check that cyclic values are equal.
  14357. var objStacked = stack.get(object);
  14358. var othStacked = stack.get(other);
  14359. if (objStacked && othStacked) {
  14360. return objStacked == other && othStacked == object;
  14361. }
  14362. var result = true;
  14363. stack.set(object, other);
  14364. stack.set(other, object);
  14365. var skipCtor = isPartial;
  14366. while (++index < objLength) {
  14367. key = objProps[index];
  14368. var objValue = object[key],
  14369. othValue = other[key];
  14370. if (customizer) {
  14371. var compared = isPartial
  14372. ? customizer(othValue, objValue, key, other, object, stack)
  14373. : customizer(objValue, othValue, key, object, other, stack);
  14374. }
  14375. // Recursively compare objects (susceptible to call stack limits).
  14376. if (!(compared === undefined
  14377. ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
  14378. : compared
  14379. )) {
  14380. result = false;
  14381. break;
  14382. }
  14383. skipCtor || (skipCtor = key == 'constructor');
  14384. }
  14385. if (result && !skipCtor) {
  14386. var objCtor = object.constructor,
  14387. othCtor = other.constructor;
  14388. // Non `Object` object instances with different constructors are not equal.
  14389. if (objCtor != othCtor &&
  14390. ('constructor' in object && 'constructor' in other) &&
  14391. !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
  14392. typeof othCtor == 'function' && othCtor instanceof othCtor)) {
  14393. result = false;
  14394. }
  14395. }
  14396. stack['delete'](object);
  14397. stack['delete'](other);
  14398. return result;
  14399. }
  14400. var _equalObjects = equalObjects;
  14401. /* Built-in method references that are verified to be native. */
  14402. var DataView = _getNative(_root, 'DataView');
  14403. var _DataView = DataView;
  14404. /* Built-in method references that are verified to be native. */
  14405. var Promise$1 = _getNative(_root, 'Promise');
  14406. var _Promise = Promise$1;
  14407. /* Built-in method references that are verified to be native. */
  14408. var Set$1 = _getNative(_root, 'Set');
  14409. var _Set = Set$1;
  14410. /* Built-in method references that are verified to be native. */
  14411. var WeakMap$1 = _getNative(_root, 'WeakMap');
  14412. var _WeakMap = WeakMap$1;
  14413. /** `Object#toString` result references. */
  14414. var mapTag$2 = '[object Map]',
  14415. objectTag$2 = '[object Object]',
  14416. promiseTag = '[object Promise]',
  14417. setTag$2 = '[object Set]',
  14418. weakMapTag$1 = '[object WeakMap]';
  14419. var dataViewTag$2 = '[object DataView]';
  14420. /** Used to detect maps, sets, and weakmaps. */
  14421. var dataViewCtorString = _toSource(_DataView),
  14422. mapCtorString = _toSource(_Map),
  14423. promiseCtorString = _toSource(_Promise),
  14424. setCtorString = _toSource(_Set),
  14425. weakMapCtorString = _toSource(_WeakMap);
  14426. /**
  14427. * Gets the `toStringTag` of `value`.
  14428. *
  14429. * @private
  14430. * @param {*} value The value to query.
  14431. * @returns {string} Returns the `toStringTag`.
  14432. */
  14433. var getTag = _baseGetTag;
  14434. // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
  14435. if ((_DataView && getTag(new _DataView(new ArrayBuffer(1))) != dataViewTag$2) ||
  14436. (_Map && getTag(new _Map) != mapTag$2) ||
  14437. (_Promise && getTag(_Promise.resolve()) != promiseTag) ||
  14438. (_Set && getTag(new _Set) != setTag$2) ||
  14439. (_WeakMap && getTag(new _WeakMap) != weakMapTag$1)) {
  14440. getTag = function(value) {
  14441. var result = _baseGetTag(value),
  14442. Ctor = result == objectTag$2 ? value.constructor : undefined,
  14443. ctorString = Ctor ? _toSource(Ctor) : '';
  14444. if (ctorString) {
  14445. switch (ctorString) {
  14446. case dataViewCtorString: return dataViewTag$2;
  14447. case mapCtorString: return mapTag$2;
  14448. case promiseCtorString: return promiseTag;
  14449. case setCtorString: return setTag$2;
  14450. case weakMapCtorString: return weakMapTag$1;
  14451. }
  14452. }
  14453. return result;
  14454. };
  14455. }
  14456. var _getTag = getTag;
  14457. /** Used to compose bitmasks for value comparisons. */
  14458. var COMPARE_PARTIAL_FLAG$3 = 1;
  14459. /** `Object#toString` result references. */
  14460. var argsTag$2 = '[object Arguments]',
  14461. arrayTag$1 = '[object Array]',
  14462. objectTag$3 = '[object Object]';
  14463. /** Used for built-in method references. */
  14464. var objectProto$c = Object.prototype;
  14465. /** Used to check objects for own properties. */
  14466. var hasOwnProperty$9 = objectProto$c.hasOwnProperty;
  14467. /**
  14468. * A specialized version of `baseIsEqual` for arrays and objects which performs
  14469. * deep comparisons and tracks traversed objects enabling objects with circular
  14470. * references to be compared.
  14471. *
  14472. * @private
  14473. * @param {Object} object The object to compare.
  14474. * @param {Object} other The other object to compare.
  14475. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
  14476. * @param {Function} customizer The function to customize comparisons.
  14477. * @param {Function} equalFunc The function to determine equivalents of values.
  14478. * @param {Object} [stack] Tracks traversed `object` and `other` objects.
  14479. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
  14480. */
  14481. function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
  14482. var objIsArr = isArray_1(object),
  14483. othIsArr = isArray_1(other),
  14484. objTag = objIsArr ? arrayTag$1 : _getTag(object),
  14485. othTag = othIsArr ? arrayTag$1 : _getTag(other);
  14486. objTag = objTag == argsTag$2 ? objectTag$3 : objTag;
  14487. othTag = othTag == argsTag$2 ? objectTag$3 : othTag;
  14488. var objIsObj = objTag == objectTag$3,
  14489. othIsObj = othTag == objectTag$3,
  14490. isSameTag = objTag == othTag;
  14491. if (isSameTag && isBuffer_1(object)) {
  14492. if (!isBuffer_1(other)) {
  14493. return false;
  14494. }
  14495. objIsArr = true;
  14496. objIsObj = false;
  14497. }
  14498. if (isSameTag && !objIsObj) {
  14499. stack || (stack = new _Stack);
  14500. return (objIsArr || isTypedArray_1(object))
  14501. ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack)
  14502. : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
  14503. }
  14504. if (!(bitmask & COMPARE_PARTIAL_FLAG$3)) {
  14505. var objIsWrapped = objIsObj && hasOwnProperty$9.call(object, '__wrapped__'),
  14506. othIsWrapped = othIsObj && hasOwnProperty$9.call(other, '__wrapped__');
  14507. if (objIsWrapped || othIsWrapped) {
  14508. var objUnwrapped = objIsWrapped ? object.value() : object,
  14509. othUnwrapped = othIsWrapped ? other.value() : other;
  14510. stack || (stack = new _Stack);
  14511. return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
  14512. }
  14513. }
  14514. if (!isSameTag) {
  14515. return false;
  14516. }
  14517. stack || (stack = new _Stack);
  14518. return _equalObjects(object, other, bitmask, customizer, equalFunc, stack);
  14519. }
  14520. var _baseIsEqualDeep = baseIsEqualDeep;
  14521. /**
  14522. * The base implementation of `_.isEqual` which supports partial comparisons
  14523. * and tracks traversed objects.
  14524. *
  14525. * @private
  14526. * @param {*} value The value to compare.
  14527. * @param {*} other The other value to compare.
  14528. * @param {boolean} bitmask The bitmask flags.
  14529. * 1 - Unordered comparison
  14530. * 2 - Partial comparison
  14531. * @param {Function} [customizer] The function to customize comparisons.
  14532. * @param {Object} [stack] Tracks traversed `value` and `other` objects.
  14533. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  14534. */
  14535. function baseIsEqual(value, other, bitmask, customizer, stack) {
  14536. if (value === other) {
  14537. return true;
  14538. }
  14539. if (value == null || other == null || (!isObjectLike_1(value) && !isObjectLike_1(other))) {
  14540. return value !== value && other !== other;
  14541. }
  14542. return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
  14543. }
  14544. var _baseIsEqual = baseIsEqual;
  14545. /** Used to compose bitmasks for value comparisons. */
  14546. var COMPARE_PARTIAL_FLAG$4 = 1,
  14547. COMPARE_UNORDERED_FLAG$2 = 2;
  14548. /**
  14549. * The base implementation of `_.isMatch` without support for iteratee shorthands.
  14550. *
  14551. * @private
  14552. * @param {Object} object The object to inspect.
  14553. * @param {Object} source The object of property values to match.
  14554. * @param {Array} matchData The property names, values, and compare flags to match.
  14555. * @param {Function} [customizer] The function to customize comparisons.
  14556. * @returns {boolean} Returns `true` if `object` is a match, else `false`.
  14557. */
  14558. function baseIsMatch(object, source, matchData, customizer) {
  14559. var index = matchData.length,
  14560. length = index,
  14561. noCustomizer = !customizer;
  14562. if (object == null) {
  14563. return !length;
  14564. }
  14565. object = Object(object);
  14566. while (index--) {
  14567. var data = matchData[index];
  14568. if ((noCustomizer && data[2])
  14569. ? data[1] !== object[data[0]]
  14570. : !(data[0] in object)
  14571. ) {
  14572. return false;
  14573. }
  14574. }
  14575. while (++index < length) {
  14576. data = matchData[index];
  14577. var key = data[0],
  14578. objValue = object[key],
  14579. srcValue = data[1];
  14580. if (noCustomizer && data[2]) {
  14581. if (objValue === undefined && !(key in object)) {
  14582. return false;
  14583. }
  14584. } else {
  14585. var stack = new _Stack;
  14586. if (customizer) {
  14587. var result = customizer(objValue, srcValue, key, object, source, stack);
  14588. }
  14589. if (!(result === undefined
  14590. ? _baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$4 | COMPARE_UNORDERED_FLAG$2, customizer, stack)
  14591. : result
  14592. )) {
  14593. return false;
  14594. }
  14595. }
  14596. }
  14597. return true;
  14598. }
  14599. var _baseIsMatch = baseIsMatch;
  14600. /**
  14601. * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
  14602. *
  14603. * @private
  14604. * @param {*} value The value to check.
  14605. * @returns {boolean} Returns `true` if `value` if suitable for strict
  14606. * equality comparisons, else `false`.
  14607. */
  14608. function isStrictComparable(value) {
  14609. return value === value && !isObject_1(value);
  14610. }
  14611. var _isStrictComparable = isStrictComparable;
  14612. /**
  14613. * Gets the property names, values, and compare flags of `object`.
  14614. *
  14615. * @private
  14616. * @param {Object} object The object to query.
  14617. * @returns {Array} Returns the match data of `object`.
  14618. */
  14619. function getMatchData(object) {
  14620. var result = keys_1(object),
  14621. length = result.length;
  14622. while (length--) {
  14623. var key = result[length],
  14624. value = object[key];
  14625. result[length] = [key, value, _isStrictComparable(value)];
  14626. }
  14627. return result;
  14628. }
  14629. var _getMatchData = getMatchData;
  14630. /**
  14631. * A specialized version of `matchesProperty` for source values suitable
  14632. * for strict equality comparisons, i.e. `===`.
  14633. *
  14634. * @private
  14635. * @param {string} key The key of the property to get.
  14636. * @param {*} srcValue The value to match.
  14637. * @returns {Function} Returns the new spec function.
  14638. */
  14639. function matchesStrictComparable(key, srcValue) {
  14640. return function(object) {
  14641. if (object == null) {
  14642. return false;
  14643. }
  14644. return object[key] === srcValue &&
  14645. (srcValue !== undefined || (key in Object(object)));
  14646. };
  14647. }
  14648. var _matchesStrictComparable = matchesStrictComparable;
  14649. /**
  14650. * The base implementation of `_.matches` which doesn't clone `source`.
  14651. *
  14652. * @private
  14653. * @param {Object} source The object of property values to match.
  14654. * @returns {Function} Returns the new spec function.
  14655. */
  14656. function baseMatches(source) {
  14657. var matchData = _getMatchData(source);
  14658. if (matchData.length == 1 && matchData[0][2]) {
  14659. return _matchesStrictComparable(matchData[0][0], matchData[0][1]);
  14660. }
  14661. return function(object) {
  14662. return object === source || _baseIsMatch(object, source, matchData);
  14663. };
  14664. }
  14665. var _baseMatches = baseMatches;
  14666. /** `Object#toString` result references. */
  14667. var symbolTag$1 = '[object Symbol]';
  14668. /**
  14669. * Checks if `value` is classified as a `Symbol` primitive or object.
  14670. *
  14671. * @static
  14672. * @memberOf _
  14673. * @since 4.0.0
  14674. * @category Lang
  14675. * @param {*} value The value to check.
  14676. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
  14677. * @example
  14678. *
  14679. * _.isSymbol(Symbol.iterator);
  14680. * // => true
  14681. *
  14682. * _.isSymbol('abc');
  14683. * // => false
  14684. */
  14685. function isSymbol(value) {
  14686. return typeof value == 'symbol' ||
  14687. (isObjectLike_1(value) && _baseGetTag(value) == symbolTag$1);
  14688. }
  14689. var isSymbol_1 = isSymbol;
  14690. /** Used to match property names within property paths. */
  14691. var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
  14692. reIsPlainProp = /^\w*$/;
  14693. /**
  14694. * Checks if `value` is a property name and not a property path.
  14695. *
  14696. * @private
  14697. * @param {*} value The value to check.
  14698. * @param {Object} [object] The object to query keys on.
  14699. * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
  14700. */
  14701. function isKey(value, object) {
  14702. if (isArray_1(value)) {
  14703. return false;
  14704. }
  14705. var type = typeof value;
  14706. if (type == 'number' || type == 'symbol' || type == 'boolean' ||
  14707. value == null || isSymbol_1(value)) {
  14708. return true;
  14709. }
  14710. return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
  14711. (object != null && value in Object(object));
  14712. }
  14713. var _isKey = isKey;
  14714. /** Error message constants. */
  14715. var FUNC_ERROR_TEXT = 'Expected a function';
  14716. /**
  14717. * Creates a function that memoizes the result of `func`. If `resolver` is
  14718. * provided, it determines the cache key for storing the result based on the
  14719. * arguments provided to the memoized function. By default, the first argument
  14720. * provided to the memoized function is used as the map cache key. The `func`
  14721. * is invoked with the `this` binding of the memoized function.
  14722. *
  14723. * **Note:** The cache is exposed as the `cache` property on the memoized
  14724. * function. Its creation may be customized by replacing the `_.memoize.Cache`
  14725. * constructor with one whose instances implement the
  14726. * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
  14727. * method interface of `clear`, `delete`, `get`, `has`, and `set`.
  14728. *
  14729. * @static
  14730. * @memberOf _
  14731. * @since 0.1.0
  14732. * @category Function
  14733. * @param {Function} func The function to have its output memoized.
  14734. * @param {Function} [resolver] The function to resolve the cache key.
  14735. * @returns {Function} Returns the new memoized function.
  14736. * @example
  14737. *
  14738. * var object = { 'a': 1, 'b': 2 };
  14739. * var other = { 'c': 3, 'd': 4 };
  14740. *
  14741. * var values = _.memoize(_.values);
  14742. * values(object);
  14743. * // => [1, 2]
  14744. *
  14745. * values(other);
  14746. * // => [3, 4]
  14747. *
  14748. * object.a = 2;
  14749. * values(object);
  14750. * // => [1, 2]
  14751. *
  14752. * // Modify the result cache.
  14753. * values.cache.set(object, ['a', 'b']);
  14754. * values(object);
  14755. * // => ['a', 'b']
  14756. *
  14757. * // Replace `_.memoize.Cache`.
  14758. * _.memoize.Cache = WeakMap;
  14759. */
  14760. function memoize(func, resolver) {
  14761. if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
  14762. throw new TypeError(FUNC_ERROR_TEXT);
  14763. }
  14764. var memoized = function() {
  14765. var args = arguments,
  14766. key = resolver ? resolver.apply(this, args) : args[0],
  14767. cache = memoized.cache;
  14768. if (cache.has(key)) {
  14769. return cache.get(key);
  14770. }
  14771. var result = func.apply(this, args);
  14772. memoized.cache = cache.set(key, result) || cache;
  14773. return result;
  14774. };
  14775. memoized.cache = new (memoize.Cache || _MapCache);
  14776. return memoized;
  14777. }
  14778. // Expose `MapCache`.
  14779. memoize.Cache = _MapCache;
  14780. var memoize_1 = memoize;
  14781. /** Used as the maximum memoize cache size. */
  14782. var MAX_MEMOIZE_SIZE = 500;
  14783. /**
  14784. * A specialized version of `_.memoize` which clears the memoized function's
  14785. * cache when it exceeds `MAX_MEMOIZE_SIZE`.
  14786. *
  14787. * @private
  14788. * @param {Function} func The function to have its output memoized.
  14789. * @returns {Function} Returns the new memoized function.
  14790. */
  14791. function memoizeCapped(func) {
  14792. var result = memoize_1(func, function(key) {
  14793. if (cache.size === MAX_MEMOIZE_SIZE) {
  14794. cache.clear();
  14795. }
  14796. return key;
  14797. });
  14798. var cache = result.cache;
  14799. return result;
  14800. }
  14801. var _memoizeCapped = memoizeCapped;
  14802. /** Used to match property names within property paths. */
  14803. var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
  14804. /** Used to match backslashes in property paths. */
  14805. var reEscapeChar = /\\(\\)?/g;
  14806. /**
  14807. * Converts `string` to a property path array.
  14808. *
  14809. * @private
  14810. * @param {string} string The string to convert.
  14811. * @returns {Array} Returns the property path array.
  14812. */
  14813. var stringToPath = _memoizeCapped(function(string) {
  14814. var result = [];
  14815. if (string.charCodeAt(0) === 46 /* . */) {
  14816. result.push('');
  14817. }
  14818. string.replace(rePropName, function(match, number, quote, subString) {
  14819. result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
  14820. });
  14821. return result;
  14822. });
  14823. var _stringToPath = stringToPath;
  14824. /** Used as references for various `Number` constants. */
  14825. var INFINITY = 1 / 0;
  14826. /** Used to convert symbols to primitives and strings. */
  14827. var symbolProto$1 = _Symbol ? _Symbol.prototype : undefined,
  14828. symbolToString = symbolProto$1 ? symbolProto$1.toString : undefined;
  14829. /**
  14830. * The base implementation of `_.toString` which doesn't convert nullish
  14831. * values to empty strings.
  14832. *
  14833. * @private
  14834. * @param {*} value The value to process.
  14835. * @returns {string} Returns the string.
  14836. */
  14837. function baseToString(value) {
  14838. // Exit early for strings to avoid a performance hit in some environments.
  14839. if (typeof value == 'string') {
  14840. return value;
  14841. }
  14842. if (isArray_1(value)) {
  14843. // Recursively convert values (susceptible to call stack limits).
  14844. return _arrayMap(value, baseToString) + '';
  14845. }
  14846. if (isSymbol_1(value)) {
  14847. return symbolToString ? symbolToString.call(value) : '';
  14848. }
  14849. var result = (value + '');
  14850. return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
  14851. }
  14852. var _baseToString = baseToString;
  14853. /**
  14854. * Converts `value` to a string. An empty string is returned for `null`
  14855. * and `undefined` values. The sign of `-0` is preserved.
  14856. *
  14857. * @static
  14858. * @memberOf _
  14859. * @since 4.0.0
  14860. * @category Lang
  14861. * @param {*} value The value to convert.
  14862. * @returns {string} Returns the converted string.
  14863. * @example
  14864. *
  14865. * _.toString(null);
  14866. * // => ''
  14867. *
  14868. * _.toString(-0);
  14869. * // => '-0'
  14870. *
  14871. * _.toString([1, 2, 3]);
  14872. * // => '1,2,3'
  14873. */
  14874. function toString(value) {
  14875. return value == null ? '' : _baseToString(value);
  14876. }
  14877. var toString_1 = toString;
  14878. /**
  14879. * Casts `value` to a path array if it's not one.
  14880. *
  14881. * @private
  14882. * @param {*} value The value to inspect.
  14883. * @param {Object} [object] The object to query keys on.
  14884. * @returns {Array} Returns the cast property path array.
  14885. */
  14886. function castPath(value, object) {
  14887. if (isArray_1(value)) {
  14888. return value;
  14889. }
  14890. return _isKey(value, object) ? [value] : _stringToPath(toString_1(value));
  14891. }
  14892. var _castPath = castPath;
  14893. /** Used as references for various `Number` constants. */
  14894. var INFINITY$1 = 1 / 0;
  14895. /**
  14896. * Converts `value` to a string key if it's not a string or symbol.
  14897. *
  14898. * @private
  14899. * @param {*} value The value to inspect.
  14900. * @returns {string|symbol} Returns the key.
  14901. */
  14902. function toKey(value) {
  14903. if (typeof value == 'string' || isSymbol_1(value)) {
  14904. return value;
  14905. }
  14906. var result = (value + '');
  14907. return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result;
  14908. }
  14909. var _toKey = toKey;
  14910. /**
  14911. * The base implementation of `_.get` without support for default values.
  14912. *
  14913. * @private
  14914. * @param {Object} object The object to query.
  14915. * @param {Array|string} path The path of the property to get.
  14916. * @returns {*} Returns the resolved value.
  14917. */
  14918. function baseGet(object, path) {
  14919. path = _castPath(path, object);
  14920. var index = 0,
  14921. length = path.length;
  14922. while (object != null && index < length) {
  14923. object = object[_toKey(path[index++])];
  14924. }
  14925. return (index && index == length) ? object : undefined;
  14926. }
  14927. var _baseGet = baseGet;
  14928. /**
  14929. * Gets the value at `path` of `object`. If the resolved value is
  14930. * `undefined`, the `defaultValue` is returned in its place.
  14931. *
  14932. * @static
  14933. * @memberOf _
  14934. * @since 3.7.0
  14935. * @category Object
  14936. * @param {Object} object The object to query.
  14937. * @param {Array|string} path The path of the property to get.
  14938. * @param {*} [defaultValue] The value returned for `undefined` resolved values.
  14939. * @returns {*} Returns the resolved value.
  14940. * @example
  14941. *
  14942. * var object = { 'a': [{ 'b': { 'c': 3 } }] };
  14943. *
  14944. * _.get(object, 'a[0].b.c');
  14945. * // => 3
  14946. *
  14947. * _.get(object, ['a', '0', 'b', 'c']);
  14948. * // => 3
  14949. *
  14950. * _.get(object, 'a.b.c', 'default');
  14951. * // => 'default'
  14952. */
  14953. function get(object, path, defaultValue) {
  14954. var result = object == null ? undefined : _baseGet(object, path);
  14955. return result === undefined ? defaultValue : result;
  14956. }
  14957. var get_1 = get;
  14958. /**
  14959. * The base implementation of `_.hasIn` without support for deep paths.
  14960. *
  14961. * @private
  14962. * @param {Object} [object] The object to query.
  14963. * @param {Array|string} key The key to check.
  14964. * @returns {boolean} Returns `true` if `key` exists, else `false`.
  14965. */
  14966. function baseHasIn(object, key) {
  14967. return object != null && key in Object(object);
  14968. }
  14969. var _baseHasIn = baseHasIn;
  14970. /**
  14971. * Checks if `path` exists on `object`.
  14972. *
  14973. * @private
  14974. * @param {Object} object The object to query.
  14975. * @param {Array|string} path The path to check.
  14976. * @param {Function} hasFunc The function to check properties.
  14977. * @returns {boolean} Returns `true` if `path` exists, else `false`.
  14978. */
  14979. function hasPath(object, path, hasFunc) {
  14980. path = _castPath(path, object);
  14981. var index = -1,
  14982. length = path.length,
  14983. result = false;
  14984. while (++index < length) {
  14985. var key = _toKey(path[index]);
  14986. if (!(result = object != null && hasFunc(object, key))) {
  14987. break;
  14988. }
  14989. object = object[key];
  14990. }
  14991. if (result || ++index != length) {
  14992. return result;
  14993. }
  14994. length = object == null ? 0 : object.length;
  14995. return !!length && isLength_1(length) && _isIndex(key, length) &&
  14996. (isArray_1(object) || isArguments_1(object));
  14997. }
  14998. var _hasPath = hasPath;
  14999. /**
  15000. * Checks if `path` is a direct or inherited property of `object`.
  15001. *
  15002. * @static
  15003. * @memberOf _
  15004. * @since 4.0.0
  15005. * @category Object
  15006. * @param {Object} object The object to query.
  15007. * @param {Array|string} path The path to check.
  15008. * @returns {boolean} Returns `true` if `path` exists, else `false`.
  15009. * @example
  15010. *
  15011. * var object = _.create({ 'a': _.create({ 'b': 2 }) });
  15012. *
  15013. * _.hasIn(object, 'a');
  15014. * // => true
  15015. *
  15016. * _.hasIn(object, 'a.b');
  15017. * // => true
  15018. *
  15019. * _.hasIn(object, ['a', 'b']);
  15020. * // => true
  15021. *
  15022. * _.hasIn(object, 'b');
  15023. * // => false
  15024. */
  15025. function hasIn(object, path) {
  15026. return object != null && _hasPath(object, path, _baseHasIn);
  15027. }
  15028. var hasIn_1 = hasIn;
  15029. /** Used to compose bitmasks for value comparisons. */
  15030. var COMPARE_PARTIAL_FLAG$5 = 1,
  15031. COMPARE_UNORDERED_FLAG$3 = 2;
  15032. /**
  15033. * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
  15034. *
  15035. * @private
  15036. * @param {string} path The path of the property to get.
  15037. * @param {*} srcValue The value to match.
  15038. * @returns {Function} Returns the new spec function.
  15039. */
  15040. function baseMatchesProperty(path, srcValue) {
  15041. if (_isKey(path) && _isStrictComparable(srcValue)) {
  15042. return _matchesStrictComparable(_toKey(path), srcValue);
  15043. }
  15044. return function(object) {
  15045. var objValue = get_1(object, path);
  15046. return (objValue === undefined && objValue === srcValue)
  15047. ? hasIn_1(object, path)
  15048. : _baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$5 | COMPARE_UNORDERED_FLAG$3);
  15049. };
  15050. }
  15051. var _baseMatchesProperty = baseMatchesProperty;
  15052. /**
  15053. * This method returns the first argument it receives.
  15054. *
  15055. * @static
  15056. * @since 0.1.0
  15057. * @memberOf _
  15058. * @category Util
  15059. * @param {*} value Any value.
  15060. * @returns {*} Returns `value`.
  15061. * @example
  15062. *
  15063. * var object = { 'a': 1 };
  15064. *
  15065. * console.log(_.identity(object) === object);
  15066. * // => true
  15067. */
  15068. function identity(value) {
  15069. return value;
  15070. }
  15071. var identity_1 = identity;
  15072. /**
  15073. * The base implementation of `_.property` without support for deep paths.
  15074. *
  15075. * @private
  15076. * @param {string} key The key of the property to get.
  15077. * @returns {Function} Returns the new accessor function.
  15078. */
  15079. function baseProperty(key) {
  15080. return function(object) {
  15081. return object == null ? undefined : object[key];
  15082. };
  15083. }
  15084. var _baseProperty = baseProperty;
  15085. /**
  15086. * A specialized version of `baseProperty` which supports deep paths.
  15087. *
  15088. * @private
  15089. * @param {Array|string} path The path of the property to get.
  15090. * @returns {Function} Returns the new accessor function.
  15091. */
  15092. function basePropertyDeep(path) {
  15093. return function(object) {
  15094. return _baseGet(object, path);
  15095. };
  15096. }
  15097. var _basePropertyDeep = basePropertyDeep;
  15098. /**
  15099. * Creates a function that returns the value at `path` of a given object.
  15100. *
  15101. * @static
  15102. * @memberOf _
  15103. * @since 2.4.0
  15104. * @category Util
  15105. * @param {Array|string} path The path of the property to get.
  15106. * @returns {Function} Returns the new accessor function.
  15107. * @example
  15108. *
  15109. * var objects = [
  15110. * { 'a': { 'b': 2 } },
  15111. * { 'a': { 'b': 1 } }
  15112. * ];
  15113. *
  15114. * _.map(objects, _.property('a.b'));
  15115. * // => [2, 1]
  15116. *
  15117. * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
  15118. * // => [1, 2]
  15119. */
  15120. function property(path) {
  15121. return _isKey(path) ? _baseProperty(_toKey(path)) : _basePropertyDeep(path);
  15122. }
  15123. var property_1 = property;
  15124. /**
  15125. * The base implementation of `_.iteratee`.
  15126. *
  15127. * @private
  15128. * @param {*} [value=_.identity] The value to convert to an iteratee.
  15129. * @returns {Function} Returns the iteratee.
  15130. */
  15131. function baseIteratee(value) {
  15132. // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
  15133. // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
  15134. if (typeof value == 'function') {
  15135. return value;
  15136. }
  15137. if (value == null) {
  15138. return identity_1;
  15139. }
  15140. if (typeof value == 'object') {
  15141. return isArray_1(value)
  15142. ? _baseMatchesProperty(value[0], value[1])
  15143. : _baseMatches(value);
  15144. }
  15145. return property_1(value);
  15146. }
  15147. var _baseIteratee = baseIteratee;
  15148. /**
  15149. * Gets the last element of `array`.
  15150. *
  15151. * @static
  15152. * @memberOf _
  15153. * @since 0.1.0
  15154. * @category Array
  15155. * @param {Array} array The array to query.
  15156. * @returns {*} Returns the last element of `array`.
  15157. * @example
  15158. *
  15159. * _.last([1, 2, 3]);
  15160. * // => 3
  15161. */
  15162. function last(array) {
  15163. var length = array == null ? 0 : array.length;
  15164. return length ? array[length - 1] : undefined;
  15165. }
  15166. var last_1 = last;
  15167. /**
  15168. * The base implementation of `_.slice` without an iteratee call guard.
  15169. *
  15170. * @private
  15171. * @param {Array} array The array to slice.
  15172. * @param {number} [start=0] The start position.
  15173. * @param {number} [end=array.length] The end position.
  15174. * @returns {Array} Returns the slice of `array`.
  15175. */
  15176. function baseSlice(array, start, end) {
  15177. var index = -1,
  15178. length = array.length;
  15179. if (start < 0) {
  15180. start = -start > length ? 0 : (length + start);
  15181. }
  15182. end = end > length ? length : end;
  15183. if (end < 0) {
  15184. end += length;
  15185. }
  15186. length = start > end ? 0 : ((end - start) >>> 0);
  15187. start >>>= 0;
  15188. var result = Array(length);
  15189. while (++index < length) {
  15190. result[index] = array[index + start];
  15191. }
  15192. return result;
  15193. }
  15194. var _baseSlice = baseSlice;
  15195. /**
  15196. * Gets the parent value at `path` of `object`.
  15197. *
  15198. * @private
  15199. * @param {Object} object The object to query.
  15200. * @param {Array} path The path to get the parent value of.
  15201. * @returns {*} Returns the parent value.
  15202. */
  15203. function parent(object, path) {
  15204. return path.length < 2 ? object : _baseGet(object, _baseSlice(path, 0, -1));
  15205. }
  15206. var _parent = parent;
  15207. /**
  15208. * The base implementation of `_.unset`.
  15209. *
  15210. * @private
  15211. * @param {Object} object The object to modify.
  15212. * @param {Array|string} path The property path to unset.
  15213. * @returns {boolean} Returns `true` if the property is deleted, else `false`.
  15214. */
  15215. function baseUnset(object, path) {
  15216. path = _castPath(path, object);
  15217. object = _parent(object, path);
  15218. return object == null || delete object[_toKey(last_1(path))];
  15219. }
  15220. var _baseUnset = baseUnset;
  15221. /** Used for built-in method references. */
  15222. var arrayProto$1 = Array.prototype;
  15223. /** Built-in value references. */
  15224. var splice$1 = arrayProto$1.splice;
  15225. /**
  15226. * The base implementation of `_.pullAt` without support for individual
  15227. * indexes or capturing the removed elements.
  15228. *
  15229. * @private
  15230. * @param {Array} array The array to modify.
  15231. * @param {number[]} indexes The indexes of elements to remove.
  15232. * @returns {Array} Returns `array`.
  15233. */
  15234. function basePullAt(array, indexes) {
  15235. var length = array ? indexes.length : 0,
  15236. lastIndex = length - 1;
  15237. while (length--) {
  15238. var index = indexes[length];
  15239. if (length == lastIndex || index !== previous) {
  15240. var previous = index;
  15241. if (_isIndex(index)) {
  15242. splice$1.call(array, index, 1);
  15243. } else {
  15244. _baseUnset(array, index);
  15245. }
  15246. }
  15247. }
  15248. return array;
  15249. }
  15250. var _basePullAt = basePullAt;
  15251. /**
  15252. * Removes all elements from `array` that `predicate` returns truthy for
  15253. * and returns an array of the removed elements. The predicate is invoked
  15254. * with three arguments: (value, index, array).
  15255. *
  15256. * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
  15257. * to pull elements from an array by value.
  15258. *
  15259. * @static
  15260. * @memberOf _
  15261. * @since 2.0.0
  15262. * @category Array
  15263. * @param {Array} array The array to modify.
  15264. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  15265. * @returns {Array} Returns the new array of removed elements.
  15266. * @example
  15267. *
  15268. * var array = [1, 2, 3, 4];
  15269. * var evens = _.remove(array, function(n) {
  15270. * return n % 2 == 0;
  15271. * });
  15272. *
  15273. * console.log(array);
  15274. * // => [1, 3]
  15275. *
  15276. * console.log(evens);
  15277. * // => [2, 4]
  15278. */
  15279. function remove(array, predicate) {
  15280. var result = [];
  15281. if (!(array && array.length)) {
  15282. return result;
  15283. }
  15284. var index = -1,
  15285. indexes = [],
  15286. length = array.length;
  15287. predicate = _baseIteratee(predicate);
  15288. while (++index < length) {
  15289. var value = array[index];
  15290. if (predicate(value, index, array)) {
  15291. result.push(value);
  15292. indexes.push(index);
  15293. }
  15294. }
  15295. _basePullAt(array, indexes);
  15296. return result;
  15297. }
  15298. var remove_1 = remove;
  15299. /** `Object#toString` result references. */
  15300. var mapTag$3 = '[object Map]',
  15301. setTag$3 = '[object Set]';
  15302. /** Used for built-in method references. */
  15303. var objectProto$d = Object.prototype;
  15304. /** Used to check objects for own properties. */
  15305. var hasOwnProperty$a = objectProto$d.hasOwnProperty;
  15306. /**
  15307. * Checks if `value` is an empty object, collection, map, or set.
  15308. *
  15309. * Objects are considered empty if they have no own enumerable string keyed
  15310. * properties.
  15311. *
  15312. * Array-like values such as `arguments` objects, arrays, buffers, strings, or
  15313. * jQuery-like collections are considered empty if they have a `length` of `0`.
  15314. * Similarly, maps and sets are considered empty if they have a `size` of `0`.
  15315. *
  15316. * @static
  15317. * @memberOf _
  15318. * @since 0.1.0
  15319. * @category Lang
  15320. * @param {*} value The value to check.
  15321. * @returns {boolean} Returns `true` if `value` is empty, else `false`.
  15322. * @example
  15323. *
  15324. * _.isEmpty(null);
  15325. * // => true
  15326. *
  15327. * _.isEmpty(true);
  15328. * // => true
  15329. *
  15330. * _.isEmpty(1);
  15331. * // => true
  15332. *
  15333. * _.isEmpty([1, 2, 3]);
  15334. * // => false
  15335. *
  15336. * _.isEmpty({ 'a': 1 });
  15337. * // => false
  15338. */
  15339. function isEmpty(value) {
  15340. if (value == null) {
  15341. return true;
  15342. }
  15343. if (isArrayLike_1(value) &&
  15344. (isArray_1(value) || typeof value == 'string' || typeof value.splice == 'function' ||
  15345. isBuffer_1(value) || isTypedArray_1(value) || isArguments_1(value))) {
  15346. return !value.length;
  15347. }
  15348. var tag = _getTag(value);
  15349. if (tag == mapTag$3 || tag == setTag$3) {
  15350. return !value.size;
  15351. }
  15352. if (_isPrototype(value)) {
  15353. return !_baseKeys(value).length;
  15354. }
  15355. for (var key in value) {
  15356. if (hasOwnProperty$a.call(value, key)) {
  15357. return false;
  15358. }
  15359. }
  15360. return true;
  15361. }
  15362. var isEmpty_1 = isEmpty;
  15363. /**
  15364. * A specialized version of `_.forEach` for arrays without support for
  15365. * iteratee shorthands.
  15366. *
  15367. * @private
  15368. * @param {Array} [array] The array to iterate over.
  15369. * @param {Function} iteratee The function invoked per iteration.
  15370. * @returns {Array} Returns `array`.
  15371. */
  15372. function arrayEach(array, iteratee) {
  15373. var index = -1,
  15374. length = array == null ? 0 : array.length;
  15375. while (++index < length) {
  15376. if (iteratee(array[index], index, array) === false) {
  15377. break;
  15378. }
  15379. }
  15380. return array;
  15381. }
  15382. var _arrayEach = arrayEach;
  15383. var defineProperty = (function() {
  15384. try {
  15385. var func = _getNative(Object, 'defineProperty');
  15386. func({}, '', {});
  15387. return func;
  15388. } catch (e) {}
  15389. }());
  15390. var _defineProperty = defineProperty;
  15391. /**
  15392. * The base implementation of `assignValue` and `assignMergeValue` without
  15393. * value checks.
  15394. *
  15395. * @private
  15396. * @param {Object} object The object to modify.
  15397. * @param {string} key The key of the property to assign.
  15398. * @param {*} value The value to assign.
  15399. */
  15400. function baseAssignValue(object, key, value) {
  15401. if (key == '__proto__' && _defineProperty) {
  15402. _defineProperty(object, key, {
  15403. 'configurable': true,
  15404. 'enumerable': true,
  15405. 'value': value,
  15406. 'writable': true
  15407. });
  15408. } else {
  15409. object[key] = value;
  15410. }
  15411. }
  15412. var _baseAssignValue = baseAssignValue;
  15413. /** Used for built-in method references. */
  15414. var objectProto$e = Object.prototype;
  15415. /** Used to check objects for own properties. */
  15416. var hasOwnProperty$b = objectProto$e.hasOwnProperty;
  15417. /**
  15418. * Assigns `value` to `key` of `object` if the existing value is not equivalent
  15419. * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  15420. * for equality comparisons.
  15421. *
  15422. * @private
  15423. * @param {Object} object The object to modify.
  15424. * @param {string} key The key of the property to assign.
  15425. * @param {*} value The value to assign.
  15426. */
  15427. function assignValue(object, key, value) {
  15428. var objValue = object[key];
  15429. if (!(hasOwnProperty$b.call(object, key) && eq_1(objValue, value)) ||
  15430. (value === undefined && !(key in object))) {
  15431. _baseAssignValue(object, key, value);
  15432. }
  15433. }
  15434. var _assignValue = assignValue;
  15435. /**
  15436. * Copies properties of `source` to `object`.
  15437. *
  15438. * @private
  15439. * @param {Object} source The object to copy properties from.
  15440. * @param {Array} props The property identifiers to copy.
  15441. * @param {Object} [object={}] The object to copy properties to.
  15442. * @param {Function} [customizer] The function to customize copied values.
  15443. * @returns {Object} Returns `object`.
  15444. */
  15445. function copyObject(source, props, object, customizer) {
  15446. var isNew = !object;
  15447. object || (object = {});
  15448. var index = -1,
  15449. length = props.length;
  15450. while (++index < length) {
  15451. var key = props[index];
  15452. var newValue = customizer
  15453. ? customizer(object[key], source[key], key, object, source)
  15454. : undefined;
  15455. if (newValue === undefined) {
  15456. newValue = source[key];
  15457. }
  15458. if (isNew) {
  15459. _baseAssignValue(object, key, newValue);
  15460. } else {
  15461. _assignValue(object, key, newValue);
  15462. }
  15463. }
  15464. return object;
  15465. }
  15466. var _copyObject = copyObject;
  15467. /**
  15468. * The base implementation of `_.assign` without support for multiple sources
  15469. * or `customizer` functions.
  15470. *
  15471. * @private
  15472. * @param {Object} object The destination object.
  15473. * @param {Object} source The source object.
  15474. * @returns {Object} Returns `object`.
  15475. */
  15476. function baseAssign(object, source) {
  15477. return object && _copyObject(source, keys_1(source), object);
  15478. }
  15479. var _baseAssign = baseAssign;
  15480. /**
  15481. * This function is like
  15482. * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
  15483. * except that it includes inherited enumerable properties.
  15484. *
  15485. * @private
  15486. * @param {Object} object The object to query.
  15487. * @returns {Array} Returns the array of property names.
  15488. */
  15489. function nativeKeysIn(object) {
  15490. var result = [];
  15491. if (object != null) {
  15492. for (var key in Object(object)) {
  15493. result.push(key);
  15494. }
  15495. }
  15496. return result;
  15497. }
  15498. var _nativeKeysIn = nativeKeysIn;
  15499. /** Used for built-in method references. */
  15500. var objectProto$f = Object.prototype;
  15501. /** Used to check objects for own properties. */
  15502. var hasOwnProperty$c = objectProto$f.hasOwnProperty;
  15503. /**
  15504. * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
  15505. *
  15506. * @private
  15507. * @param {Object} object The object to query.
  15508. * @returns {Array} Returns the array of property names.
  15509. */
  15510. function baseKeysIn(object) {
  15511. if (!isObject_1(object)) {
  15512. return _nativeKeysIn(object);
  15513. }
  15514. var isProto = _isPrototype(object),
  15515. result = [];
  15516. for (var key in object) {
  15517. if (!(key == 'constructor' && (isProto || !hasOwnProperty$c.call(object, key)))) {
  15518. result.push(key);
  15519. }
  15520. }
  15521. return result;
  15522. }
  15523. var _baseKeysIn = baseKeysIn;
  15524. /**
  15525. * Creates an array of the own and inherited enumerable property names of `object`.
  15526. *
  15527. * **Note:** Non-object values are coerced to objects.
  15528. *
  15529. * @static
  15530. * @memberOf _
  15531. * @since 3.0.0
  15532. * @category Object
  15533. * @param {Object} object The object to query.
  15534. * @returns {Array} Returns the array of property names.
  15535. * @example
  15536. *
  15537. * function Foo() {
  15538. * this.a = 1;
  15539. * this.b = 2;
  15540. * }
  15541. *
  15542. * Foo.prototype.c = 3;
  15543. *
  15544. * _.keysIn(new Foo);
  15545. * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
  15546. */
  15547. function keysIn(object) {
  15548. return isArrayLike_1(object) ? _arrayLikeKeys(object, true) : _baseKeysIn(object);
  15549. }
  15550. var keysIn_1 = keysIn;
  15551. /**
  15552. * The base implementation of `_.assignIn` without support for multiple sources
  15553. * or `customizer` functions.
  15554. *
  15555. * @private
  15556. * @param {Object} object The destination object.
  15557. * @param {Object} source The source object.
  15558. * @returns {Object} Returns `object`.
  15559. */
  15560. function baseAssignIn(object, source) {
  15561. return object && _copyObject(source, keysIn_1(source), object);
  15562. }
  15563. var _baseAssignIn = baseAssignIn;
  15564. var _cloneBuffer = createCommonjsModule(function (module, exports) {
  15565. /** Detect free variable `exports`. */
  15566. var freeExports = exports && !exports.nodeType && exports;
  15567. /** Detect free variable `module`. */
  15568. var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
  15569. /** Detect the popular CommonJS extension `module.exports`. */
  15570. var moduleExports = freeModule && freeModule.exports === freeExports;
  15571. /** Built-in value references. */
  15572. var Buffer = moduleExports ? _root.Buffer : undefined,
  15573. allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;
  15574. /**
  15575. * Creates a clone of `buffer`.
  15576. *
  15577. * @private
  15578. * @param {Buffer} buffer The buffer to clone.
  15579. * @param {boolean} [isDeep] Specify a deep clone.
  15580. * @returns {Buffer} Returns the cloned buffer.
  15581. */
  15582. function cloneBuffer(buffer, isDeep) {
  15583. if (isDeep) {
  15584. return buffer.slice();
  15585. }
  15586. var length = buffer.length,
  15587. result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
  15588. buffer.copy(result);
  15589. return result;
  15590. }
  15591. module.exports = cloneBuffer;
  15592. });
  15593. /**
  15594. * Copies own symbols of `source` to `object`.
  15595. *
  15596. * @private
  15597. * @param {Object} source The object to copy symbols from.
  15598. * @param {Object} [object={}] The object to copy symbols to.
  15599. * @returns {Object} Returns `object`.
  15600. */
  15601. function copySymbols(source, object) {
  15602. return _copyObject(source, _getSymbols(source), object);
  15603. }
  15604. var _copySymbols = copySymbols;
  15605. /* Built-in method references for those with the same name as other `lodash` methods. */
  15606. var nativeGetSymbols$1 = Object.getOwnPropertySymbols;
  15607. /**
  15608. * Creates an array of the own and inherited enumerable symbols of `object`.
  15609. *
  15610. * @private
  15611. * @param {Object} object The object to query.
  15612. * @returns {Array} Returns the array of symbols.
  15613. */
  15614. var getSymbolsIn = !nativeGetSymbols$1 ? stubArray_1 : function(object) {
  15615. var result = [];
  15616. while (object) {
  15617. _arrayPush(result, _getSymbols(object));
  15618. object = _getPrototype(object);
  15619. }
  15620. return result;
  15621. };
  15622. var _getSymbolsIn = getSymbolsIn;
  15623. /**
  15624. * Copies own and inherited symbols of `source` to `object`.
  15625. *
  15626. * @private
  15627. * @param {Object} source The object to copy symbols from.
  15628. * @param {Object} [object={}] The object to copy symbols to.
  15629. * @returns {Object} Returns `object`.
  15630. */
  15631. function copySymbolsIn(source, object) {
  15632. return _copyObject(source, _getSymbolsIn(source), object);
  15633. }
  15634. var _copySymbolsIn = copySymbolsIn;
  15635. /**
  15636. * Creates an array of own and inherited enumerable property names and
  15637. * symbols of `object`.
  15638. *
  15639. * @private
  15640. * @param {Object} object The object to query.
  15641. * @returns {Array} Returns the array of property names and symbols.
  15642. */
  15643. function getAllKeysIn(object) {
  15644. return _baseGetAllKeys(object, keysIn_1, _getSymbolsIn);
  15645. }
  15646. var _getAllKeysIn = getAllKeysIn;
  15647. /** Used for built-in method references. */
  15648. var objectProto$g = Object.prototype;
  15649. /** Used to check objects for own properties. */
  15650. var hasOwnProperty$d = objectProto$g.hasOwnProperty;
  15651. /**
  15652. * Initializes an array clone.
  15653. *
  15654. * @private
  15655. * @param {Array} array The array to clone.
  15656. * @returns {Array} Returns the initialized clone.
  15657. */
  15658. function initCloneArray(array) {
  15659. var length = array.length,
  15660. result = new array.constructor(length);
  15661. // Add properties assigned by `RegExp#exec`.
  15662. if (length && typeof array[0] == 'string' && hasOwnProperty$d.call(array, 'index')) {
  15663. result.index = array.index;
  15664. result.input = array.input;
  15665. }
  15666. return result;
  15667. }
  15668. var _initCloneArray = initCloneArray;
  15669. /**
  15670. * Creates a clone of `arrayBuffer`.
  15671. *
  15672. * @private
  15673. * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
  15674. * @returns {ArrayBuffer} Returns the cloned array buffer.
  15675. */
  15676. function cloneArrayBuffer(arrayBuffer) {
  15677. var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
  15678. new _Uint8Array(result).set(new _Uint8Array(arrayBuffer));
  15679. return result;
  15680. }
  15681. var _cloneArrayBuffer = cloneArrayBuffer;
  15682. /**
  15683. * Creates a clone of `dataView`.
  15684. *
  15685. * @private
  15686. * @param {Object} dataView The data view to clone.
  15687. * @param {boolean} [isDeep] Specify a deep clone.
  15688. * @returns {Object} Returns the cloned data view.
  15689. */
  15690. function cloneDataView(dataView, isDeep) {
  15691. var buffer = isDeep ? _cloneArrayBuffer(dataView.buffer) : dataView.buffer;
  15692. return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
  15693. }
  15694. var _cloneDataView = cloneDataView;
  15695. /** Used to match `RegExp` flags from their coerced string values. */
  15696. var reFlags = /\w*$/;
  15697. /**
  15698. * Creates a clone of `regexp`.
  15699. *
  15700. * @private
  15701. * @param {Object} regexp The regexp to clone.
  15702. * @returns {Object} Returns the cloned regexp.
  15703. */
  15704. function cloneRegExp(regexp) {
  15705. var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
  15706. result.lastIndex = regexp.lastIndex;
  15707. return result;
  15708. }
  15709. var _cloneRegExp = cloneRegExp;
  15710. /** Used to convert symbols to primitives and strings. */
  15711. var symbolProto$2 = _Symbol ? _Symbol.prototype : undefined,
  15712. symbolValueOf$1 = symbolProto$2 ? symbolProto$2.valueOf : undefined;
  15713. /**
  15714. * Creates a clone of the `symbol` object.
  15715. *
  15716. * @private
  15717. * @param {Object} symbol The symbol object to clone.
  15718. * @returns {Object} Returns the cloned symbol object.
  15719. */
  15720. function cloneSymbol(symbol) {
  15721. return symbolValueOf$1 ? Object(symbolValueOf$1.call(symbol)) : {};
  15722. }
  15723. var _cloneSymbol = cloneSymbol;
  15724. /**
  15725. * Creates a clone of `typedArray`.
  15726. *
  15727. * @private
  15728. * @param {Object} typedArray The typed array to clone.
  15729. * @param {boolean} [isDeep] Specify a deep clone.
  15730. * @returns {Object} Returns the cloned typed array.
  15731. */
  15732. function cloneTypedArray(typedArray, isDeep) {
  15733. var buffer = isDeep ? _cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
  15734. return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
  15735. }
  15736. var _cloneTypedArray = cloneTypedArray;
  15737. /** `Object#toString` result references. */
  15738. var boolTag$2 = '[object Boolean]',
  15739. dateTag$2 = '[object Date]',
  15740. mapTag$4 = '[object Map]',
  15741. numberTag$2 = '[object Number]',
  15742. regexpTag$2 = '[object RegExp]',
  15743. setTag$4 = '[object Set]',
  15744. stringTag$2 = '[object String]',
  15745. symbolTag$2 = '[object Symbol]';
  15746. var arrayBufferTag$2 = '[object ArrayBuffer]',
  15747. dataViewTag$3 = '[object DataView]',
  15748. float32Tag$1 = '[object Float32Array]',
  15749. float64Tag$1 = '[object Float64Array]',
  15750. int8Tag$1 = '[object Int8Array]',
  15751. int16Tag$1 = '[object Int16Array]',
  15752. int32Tag$1 = '[object Int32Array]',
  15753. uint8Tag$1 = '[object Uint8Array]',
  15754. uint8ClampedTag$1 = '[object Uint8ClampedArray]',
  15755. uint16Tag$1 = '[object Uint16Array]',
  15756. uint32Tag$1 = '[object Uint32Array]';
  15757. /**
  15758. * Initializes an object clone based on its `toStringTag`.
  15759. *
  15760. * **Note:** This function only supports cloning values with tags of
  15761. * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
  15762. *
  15763. * @private
  15764. * @param {Object} object The object to clone.
  15765. * @param {string} tag The `toStringTag` of the object to clone.
  15766. * @param {boolean} [isDeep] Specify a deep clone.
  15767. * @returns {Object} Returns the initialized clone.
  15768. */
  15769. function initCloneByTag(object, tag, isDeep) {
  15770. var Ctor = object.constructor;
  15771. switch (tag) {
  15772. case arrayBufferTag$2:
  15773. return _cloneArrayBuffer(object);
  15774. case boolTag$2:
  15775. case dateTag$2:
  15776. return new Ctor(+object);
  15777. case dataViewTag$3:
  15778. return _cloneDataView(object, isDeep);
  15779. case float32Tag$1: case float64Tag$1:
  15780. case int8Tag$1: case int16Tag$1: case int32Tag$1:
  15781. case uint8Tag$1: case uint8ClampedTag$1: case uint16Tag$1: case uint32Tag$1:
  15782. return _cloneTypedArray(object, isDeep);
  15783. case mapTag$4:
  15784. return new Ctor;
  15785. case numberTag$2:
  15786. case stringTag$2:
  15787. return new Ctor(object);
  15788. case regexpTag$2:
  15789. return _cloneRegExp(object);
  15790. case setTag$4:
  15791. return new Ctor;
  15792. case symbolTag$2:
  15793. return _cloneSymbol(object);
  15794. }
  15795. }
  15796. var _initCloneByTag = initCloneByTag;
  15797. /** Built-in value references. */
  15798. var objectCreate = Object.create;
  15799. /**
  15800. * The base implementation of `_.create` without support for assigning
  15801. * properties to the created object.
  15802. *
  15803. * @private
  15804. * @param {Object} proto The object to inherit from.
  15805. * @returns {Object} Returns the new object.
  15806. */
  15807. var baseCreate = (function() {
  15808. function object() {}
  15809. return function(proto) {
  15810. if (!isObject_1(proto)) {
  15811. return {};
  15812. }
  15813. if (objectCreate) {
  15814. return objectCreate(proto);
  15815. }
  15816. object.prototype = proto;
  15817. var result = new object;
  15818. object.prototype = undefined;
  15819. return result;
  15820. };
  15821. }());
  15822. var _baseCreate = baseCreate;
  15823. /**
  15824. * Initializes an object clone.
  15825. *
  15826. * @private
  15827. * @param {Object} object The object to clone.
  15828. * @returns {Object} Returns the initialized clone.
  15829. */
  15830. function initCloneObject(object) {
  15831. return (typeof object.constructor == 'function' && !_isPrototype(object))
  15832. ? _baseCreate(_getPrototype(object))
  15833. : {};
  15834. }
  15835. var _initCloneObject = initCloneObject;
  15836. /** `Object#toString` result references. */
  15837. var mapTag$5 = '[object Map]';
  15838. /**
  15839. * The base implementation of `_.isMap` without Node.js optimizations.
  15840. *
  15841. * @private
  15842. * @param {*} value The value to check.
  15843. * @returns {boolean} Returns `true` if `value` is a map, else `false`.
  15844. */
  15845. function baseIsMap(value) {
  15846. return isObjectLike_1(value) && _getTag(value) == mapTag$5;
  15847. }
  15848. var _baseIsMap = baseIsMap;
  15849. /* Node.js helper references. */
  15850. var nodeIsMap = _nodeUtil && _nodeUtil.isMap;
  15851. /**
  15852. * Checks if `value` is classified as a `Map` object.
  15853. *
  15854. * @static
  15855. * @memberOf _
  15856. * @since 4.3.0
  15857. * @category Lang
  15858. * @param {*} value The value to check.
  15859. * @returns {boolean} Returns `true` if `value` is a map, else `false`.
  15860. * @example
  15861. *
  15862. * _.isMap(new Map);
  15863. * // => true
  15864. *
  15865. * _.isMap(new WeakMap);
  15866. * // => false
  15867. */
  15868. var isMap = nodeIsMap ? _baseUnary(nodeIsMap) : _baseIsMap;
  15869. var isMap_1 = isMap;
  15870. /** `Object#toString` result references. */
  15871. var setTag$5 = '[object Set]';
  15872. /**
  15873. * The base implementation of `_.isSet` without Node.js optimizations.
  15874. *
  15875. * @private
  15876. * @param {*} value The value to check.
  15877. * @returns {boolean} Returns `true` if `value` is a set, else `false`.
  15878. */
  15879. function baseIsSet(value) {
  15880. return isObjectLike_1(value) && _getTag(value) == setTag$5;
  15881. }
  15882. var _baseIsSet = baseIsSet;
  15883. /* Node.js helper references. */
  15884. var nodeIsSet = _nodeUtil && _nodeUtil.isSet;
  15885. /**
  15886. * Checks if `value` is classified as a `Set` object.
  15887. *
  15888. * @static
  15889. * @memberOf _
  15890. * @since 4.3.0
  15891. * @category Lang
  15892. * @param {*} value The value to check.
  15893. * @returns {boolean} Returns `true` if `value` is a set, else `false`.
  15894. * @example
  15895. *
  15896. * _.isSet(new Set);
  15897. * // => true
  15898. *
  15899. * _.isSet(new WeakSet);
  15900. * // => false
  15901. */
  15902. var isSet = nodeIsSet ? _baseUnary(nodeIsSet) : _baseIsSet;
  15903. var isSet_1 = isSet;
  15904. /** Used to compose bitmasks for cloning. */
  15905. var CLONE_DEEP_FLAG = 1,
  15906. CLONE_FLAT_FLAG = 2,
  15907. CLONE_SYMBOLS_FLAG = 4;
  15908. /** `Object#toString` result references. */
  15909. var argsTag$3 = '[object Arguments]',
  15910. arrayTag$2 = '[object Array]',
  15911. boolTag$3 = '[object Boolean]',
  15912. dateTag$3 = '[object Date]',
  15913. errorTag$2 = '[object Error]',
  15914. funcTag$2 = '[object Function]',
  15915. genTag$1 = '[object GeneratorFunction]',
  15916. mapTag$6 = '[object Map]',
  15917. numberTag$3 = '[object Number]',
  15918. objectTag$4 = '[object Object]',
  15919. regexpTag$3 = '[object RegExp]',
  15920. setTag$6 = '[object Set]',
  15921. stringTag$3 = '[object String]',
  15922. symbolTag$3 = '[object Symbol]',
  15923. weakMapTag$2 = '[object WeakMap]';
  15924. var arrayBufferTag$3 = '[object ArrayBuffer]',
  15925. dataViewTag$4 = '[object DataView]',
  15926. float32Tag$2 = '[object Float32Array]',
  15927. float64Tag$2 = '[object Float64Array]',
  15928. int8Tag$2 = '[object Int8Array]',
  15929. int16Tag$2 = '[object Int16Array]',
  15930. int32Tag$2 = '[object Int32Array]',
  15931. uint8Tag$2 = '[object Uint8Array]',
  15932. uint8ClampedTag$2 = '[object Uint8ClampedArray]',
  15933. uint16Tag$2 = '[object Uint16Array]',
  15934. uint32Tag$2 = '[object Uint32Array]';
  15935. /** Used to identify `toStringTag` values supported by `_.clone`. */
  15936. var cloneableTags = {};
  15937. cloneableTags[argsTag$3] = cloneableTags[arrayTag$2] =
  15938. cloneableTags[arrayBufferTag$3] = cloneableTags[dataViewTag$4] =
  15939. cloneableTags[boolTag$3] = cloneableTags[dateTag$3] =
  15940. cloneableTags[float32Tag$2] = cloneableTags[float64Tag$2] =
  15941. cloneableTags[int8Tag$2] = cloneableTags[int16Tag$2] =
  15942. cloneableTags[int32Tag$2] = cloneableTags[mapTag$6] =
  15943. cloneableTags[numberTag$3] = cloneableTags[objectTag$4] =
  15944. cloneableTags[regexpTag$3] = cloneableTags[setTag$6] =
  15945. cloneableTags[stringTag$3] = cloneableTags[symbolTag$3] =
  15946. cloneableTags[uint8Tag$2] = cloneableTags[uint8ClampedTag$2] =
  15947. cloneableTags[uint16Tag$2] = cloneableTags[uint32Tag$2] = true;
  15948. cloneableTags[errorTag$2] = cloneableTags[funcTag$2] =
  15949. cloneableTags[weakMapTag$2] = false;
  15950. /**
  15951. * The base implementation of `_.clone` and `_.cloneDeep` which tracks
  15952. * traversed objects.
  15953. *
  15954. * @private
  15955. * @param {*} value The value to clone.
  15956. * @param {boolean} bitmask The bitmask flags.
  15957. * 1 - Deep clone
  15958. * 2 - Flatten inherited properties
  15959. * 4 - Clone symbols
  15960. * @param {Function} [customizer] The function to customize cloning.
  15961. * @param {string} [key] The key of `value`.
  15962. * @param {Object} [object] The parent object of `value`.
  15963. * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
  15964. * @returns {*} Returns the cloned value.
  15965. */
  15966. function baseClone(value, bitmask, customizer, key, object, stack) {
  15967. var result,
  15968. isDeep = bitmask & CLONE_DEEP_FLAG,
  15969. isFlat = bitmask & CLONE_FLAT_FLAG,
  15970. isFull = bitmask & CLONE_SYMBOLS_FLAG;
  15971. if (customizer) {
  15972. result = object ? customizer(value, key, object, stack) : customizer(value);
  15973. }
  15974. if (result !== undefined) {
  15975. return result;
  15976. }
  15977. if (!isObject_1(value)) {
  15978. return value;
  15979. }
  15980. var isArr = isArray_1(value);
  15981. if (isArr) {
  15982. result = _initCloneArray(value);
  15983. if (!isDeep) {
  15984. return _copyArray(value, result);
  15985. }
  15986. } else {
  15987. var tag = _getTag(value),
  15988. isFunc = tag == funcTag$2 || tag == genTag$1;
  15989. if (isBuffer_1(value)) {
  15990. return _cloneBuffer(value, isDeep);
  15991. }
  15992. if (tag == objectTag$4 || tag == argsTag$3 || (isFunc && !object)) {
  15993. result = (isFlat || isFunc) ? {} : _initCloneObject(value);
  15994. if (!isDeep) {
  15995. return isFlat
  15996. ? _copySymbolsIn(value, _baseAssignIn(result, value))
  15997. : _copySymbols(value, _baseAssign(result, value));
  15998. }
  15999. } else {
  16000. if (!cloneableTags[tag]) {
  16001. return object ? value : {};
  16002. }
  16003. result = _initCloneByTag(value, tag, isDeep);
  16004. }
  16005. }
  16006. // Check for circular references and return its corresponding clone.
  16007. stack || (stack = new _Stack);
  16008. var stacked = stack.get(value);
  16009. if (stacked) {
  16010. return stacked;
  16011. }
  16012. stack.set(value, result);
  16013. if (isSet_1(value)) {
  16014. value.forEach(function(subValue) {
  16015. result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
  16016. });
  16017. } else if (isMap_1(value)) {
  16018. value.forEach(function(subValue, key) {
  16019. result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
  16020. });
  16021. }
  16022. var keysFunc = isFull
  16023. ? (isFlat ? _getAllKeysIn : _getAllKeys)
  16024. : (isFlat ? keysIn_1 : keys_1);
  16025. var props = isArr ? undefined : keysFunc(value);
  16026. _arrayEach(props || value, function(subValue, key) {
  16027. if (props) {
  16028. key = subValue;
  16029. subValue = value[key];
  16030. }
  16031. // Recursively populate clone (susceptible to call stack limits).
  16032. _assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
  16033. });
  16034. return result;
  16035. }
  16036. var _baseClone = baseClone;
  16037. /** Used to compose bitmasks for cloning. */
  16038. var CLONE_DEEP_FLAG$1 = 1,
  16039. CLONE_SYMBOLS_FLAG$1 = 4;
  16040. /**
  16041. * This method is like `_.clone` except that it recursively clones `value`.
  16042. *
  16043. * @static
  16044. * @memberOf _
  16045. * @since 1.0.0
  16046. * @category Lang
  16047. * @param {*} value The value to recursively clone.
  16048. * @returns {*} Returns the deep cloned value.
  16049. * @see _.clone
  16050. * @example
  16051. *
  16052. * var objects = [{ 'a': 1 }, { 'b': 2 }];
  16053. *
  16054. * var deep = _.cloneDeep(objects);
  16055. * console.log(deep[0] === objects[0]);
  16056. * // => false
  16057. */
  16058. function cloneDeep(value) {
  16059. return _baseClone(value, CLONE_DEEP_FLAG$1 | CLONE_SYMBOLS_FLAG$1);
  16060. }
  16061. var cloneDeep_1 = cloneDeep;
  16062. /**
  16063. * Creates a `_.find` or `_.findLast` function.
  16064. *
  16065. * @private
  16066. * @param {Function} findIndexFunc The function to find the collection index.
  16067. * @returns {Function} Returns the new find function.
  16068. */
  16069. function createFind(findIndexFunc) {
  16070. return function(collection, predicate, fromIndex) {
  16071. var iterable = Object(collection);
  16072. if (!isArrayLike_1(collection)) {
  16073. var iteratee = _baseIteratee(predicate);
  16074. collection = keys_1(collection);
  16075. predicate = function(key) { return iteratee(iterable[key], key, iterable); };
  16076. }
  16077. var index = findIndexFunc(collection, predicate, fromIndex);
  16078. return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
  16079. };
  16080. }
  16081. var _createFind = createFind;
  16082. /**
  16083. * The base implementation of `_.findIndex` and `_.findLastIndex` without
  16084. * support for iteratee shorthands.
  16085. *
  16086. * @private
  16087. * @param {Array} array The array to inspect.
  16088. * @param {Function} predicate The function invoked per iteration.
  16089. * @param {number} fromIndex The index to search from.
  16090. * @param {boolean} [fromRight] Specify iterating from right to left.
  16091. * @returns {number} Returns the index of the matched value, else `-1`.
  16092. */
  16093. function baseFindIndex(array, predicate, fromIndex, fromRight) {
  16094. var length = array.length,
  16095. index = fromIndex + (fromRight ? 1 : -1);
  16096. while ((fromRight ? index-- : ++index < length)) {
  16097. if (predicate(array[index], index, array)) {
  16098. return index;
  16099. }
  16100. }
  16101. return -1;
  16102. }
  16103. var _baseFindIndex = baseFindIndex;
  16104. /** Used to match a single whitespace character. */
  16105. var reWhitespace = /\s/;
  16106. /**
  16107. * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
  16108. * character of `string`.
  16109. *
  16110. * @private
  16111. * @param {string} string The string to inspect.
  16112. * @returns {number} Returns the index of the last non-whitespace character.
  16113. */
  16114. function trimmedEndIndex(string) {
  16115. var index = string.length;
  16116. while (index-- && reWhitespace.test(string.charAt(index))) {}
  16117. return index;
  16118. }
  16119. var _trimmedEndIndex = trimmedEndIndex;
  16120. /** Used to match leading whitespace. */
  16121. var reTrimStart = /^\s+/;
  16122. /**
  16123. * The base implementation of `_.trim`.
  16124. *
  16125. * @private
  16126. * @param {string} string The string to trim.
  16127. * @returns {string} Returns the trimmed string.
  16128. */
  16129. function baseTrim(string) {
  16130. return string
  16131. ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '')
  16132. : string;
  16133. }
  16134. var _baseTrim = baseTrim;
  16135. /** Used as references for various `Number` constants. */
  16136. var NAN = 0 / 0;
  16137. /** Used to detect bad signed hexadecimal string values. */
  16138. var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
  16139. /** Used to detect binary string values. */
  16140. var reIsBinary = /^0b[01]+$/i;
  16141. /** Used to detect octal string values. */
  16142. var reIsOctal = /^0o[0-7]+$/i;
  16143. /** Built-in method references without a dependency on `root`. */
  16144. var freeParseInt = parseInt;
  16145. /**
  16146. * Converts `value` to a number.
  16147. *
  16148. * @static
  16149. * @memberOf _
  16150. * @since 4.0.0
  16151. * @category Lang
  16152. * @param {*} value The value to process.
  16153. * @returns {number} Returns the number.
  16154. * @example
  16155. *
  16156. * _.toNumber(3.2);
  16157. * // => 3.2
  16158. *
  16159. * _.toNumber(Number.MIN_VALUE);
  16160. * // => 5e-324
  16161. *
  16162. * _.toNumber(Infinity);
  16163. * // => Infinity
  16164. *
  16165. * _.toNumber('3.2');
  16166. * // => 3.2
  16167. */
  16168. function toNumber(value) {
  16169. if (typeof value == 'number') {
  16170. return value;
  16171. }
  16172. if (isSymbol_1(value)) {
  16173. return NAN;
  16174. }
  16175. if (isObject_1(value)) {
  16176. var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
  16177. value = isObject_1(other) ? (other + '') : other;
  16178. }
  16179. if (typeof value != 'string') {
  16180. return value === 0 ? value : +value;
  16181. }
  16182. value = _baseTrim(value);
  16183. var isBinary = reIsBinary.test(value);
  16184. return (isBinary || reIsOctal.test(value))
  16185. ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
  16186. : (reIsBadHex.test(value) ? NAN : +value);
  16187. }
  16188. var toNumber_1 = toNumber;
  16189. /** Used as references for various `Number` constants. */
  16190. var INFINITY$2 = 1 / 0,
  16191. MAX_INTEGER = 1.7976931348623157e+308;
  16192. /**
  16193. * Converts `value` to a finite number.
  16194. *
  16195. * @static
  16196. * @memberOf _
  16197. * @since 4.12.0
  16198. * @category Lang
  16199. * @param {*} value The value to convert.
  16200. * @returns {number} Returns the converted number.
  16201. * @example
  16202. *
  16203. * _.toFinite(3.2);
  16204. * // => 3.2
  16205. *
  16206. * _.toFinite(Number.MIN_VALUE);
  16207. * // => 5e-324
  16208. *
  16209. * _.toFinite(Infinity);
  16210. * // => 1.7976931348623157e+308
  16211. *
  16212. * _.toFinite('3.2');
  16213. * // => 3.2
  16214. */
  16215. function toFinite(value) {
  16216. if (!value) {
  16217. return value === 0 ? value : 0;
  16218. }
  16219. value = toNumber_1(value);
  16220. if (value === INFINITY$2 || value === -INFINITY$2) {
  16221. var sign = (value < 0 ? -1 : 1);
  16222. return sign * MAX_INTEGER;
  16223. }
  16224. return value === value ? value : 0;
  16225. }
  16226. var toFinite_1 = toFinite;
  16227. /**
  16228. * Converts `value` to an integer.
  16229. *
  16230. * **Note:** This method is loosely based on
  16231. * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
  16232. *
  16233. * @static
  16234. * @memberOf _
  16235. * @since 4.0.0
  16236. * @category Lang
  16237. * @param {*} value The value to convert.
  16238. * @returns {number} Returns the converted integer.
  16239. * @example
  16240. *
  16241. * _.toInteger(3.2);
  16242. * // => 3
  16243. *
  16244. * _.toInteger(Number.MIN_VALUE);
  16245. * // => 0
  16246. *
  16247. * _.toInteger(Infinity);
  16248. * // => 1.7976931348623157e+308
  16249. *
  16250. * _.toInteger('3.2');
  16251. * // => 3
  16252. */
  16253. function toInteger(value) {
  16254. var result = toFinite_1(value),
  16255. remainder = result % 1;
  16256. return result === result ? (remainder ? result - remainder : result) : 0;
  16257. }
  16258. var toInteger_1 = toInteger;
  16259. /* Built-in method references for those with the same name as other `lodash` methods. */
  16260. var nativeMax = Math.max;
  16261. /**
  16262. * This method is like `_.find` except that it returns the index of the first
  16263. * element `predicate` returns truthy for instead of the element itself.
  16264. *
  16265. * @static
  16266. * @memberOf _
  16267. * @since 1.1.0
  16268. * @category Array
  16269. * @param {Array} array The array to inspect.
  16270. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  16271. * @param {number} [fromIndex=0] The index to search from.
  16272. * @returns {number} Returns the index of the found element, else `-1`.
  16273. * @example
  16274. *
  16275. * var users = [
  16276. * { 'user': 'barney', 'active': false },
  16277. * { 'user': 'fred', 'active': false },
  16278. * { 'user': 'pebbles', 'active': true }
  16279. * ];
  16280. *
  16281. * _.findIndex(users, function(o) { return o.user == 'barney'; });
  16282. * // => 0
  16283. *
  16284. * // The `_.matches` iteratee shorthand.
  16285. * _.findIndex(users, { 'user': 'fred', 'active': false });
  16286. * // => 1
  16287. *
  16288. * // The `_.matchesProperty` iteratee shorthand.
  16289. * _.findIndex(users, ['active', false]);
  16290. * // => 0
  16291. *
  16292. * // The `_.property` iteratee shorthand.
  16293. * _.findIndex(users, 'active');
  16294. * // => 2
  16295. */
  16296. function findIndex(array, predicate, fromIndex) {
  16297. var length = array == null ? 0 : array.length;
  16298. if (!length) {
  16299. return -1;
  16300. }
  16301. var index = fromIndex == null ? 0 : toInteger_1(fromIndex);
  16302. if (index < 0) {
  16303. index = nativeMax(length + index, 0);
  16304. }
  16305. return _baseFindIndex(array, _baseIteratee(predicate), index);
  16306. }
  16307. var findIndex_1 = findIndex;
  16308. /**
  16309. * Iterates over elements of `collection`, returning the first element
  16310. * `predicate` returns truthy for. The predicate is invoked with three
  16311. * arguments: (value, index|key, collection).
  16312. *
  16313. * @static
  16314. * @memberOf _
  16315. * @since 0.1.0
  16316. * @category Collection
  16317. * @param {Array|Object} collection The collection to inspect.
  16318. * @param {Function} [predicate=_.identity] The function invoked per iteration.
  16319. * @param {number} [fromIndex=0] The index to search from.
  16320. * @returns {*} Returns the matched element, else `undefined`.
  16321. * @example
  16322. *
  16323. * var users = [
  16324. * { 'user': 'barney', 'age': 36, 'active': true },
  16325. * { 'user': 'fred', 'age': 40, 'active': false },
  16326. * { 'user': 'pebbles', 'age': 1, 'active': true }
  16327. * ];
  16328. *
  16329. * _.find(users, function(o) { return o.age < 40; });
  16330. * // => object for 'barney'
  16331. *
  16332. * // The `_.matches` iteratee shorthand.
  16333. * _.find(users, { 'age': 1, 'active': true });
  16334. * // => object for 'pebbles'
  16335. *
  16336. * // The `_.matchesProperty` iteratee shorthand.
  16337. * _.find(users, ['active', false]);
  16338. * // => object for 'fred'
  16339. *
  16340. * // The `_.property` iteratee shorthand.
  16341. * _.find(users, 'active');
  16342. * // => object for 'barney'
  16343. */
  16344. var find = _createFind(findIndex_1);
  16345. var find_1 = find;
  16346. // IMClient
  16347. const UNREAD_MESSAGES_COUNT_UPDATE = 'unreadmessagescountupdate';
  16348. const CLOSE = 'close';
  16349. const CONFLICT = 'conflict';
  16350. const CONVERSATION_INFO_UPDATED = 'conversationinfoupdated';
  16351. const UNHANDLED_MESSAGE = 'unhandledmessage'; // shared
  16352. const INVITED = 'invited';
  16353. const KICKED = 'kicked';
  16354. const MEMBERS_JOINED = 'membersjoined';
  16355. const MEMBERS_LEFT = 'membersleft';
  16356. const MEMBER_INFO_UPDATED = 'memberinfoupdated';
  16357. const BLOCKED = 'blocked';
  16358. const UNBLOCKED = 'unblocked';
  16359. const MEMBERS_BLOCKED = 'membersblocked';
  16360. const MEMBERS_UNBLOCKED = 'membersunblocked';
  16361. const MUTED = 'muted';
  16362. const UNMUTED = 'unmuted';
  16363. const MEMBERS_MUTED = 'membersmuted';
  16364. const MEMBERS_UNMUTED = 'membersunmuted';
  16365. const MESSAGE$1 = 'message';
  16366. const MESSAGE_RECALL = 'messagerecall';
  16367. const MESSAGE_UPDATE = 'messageupdate'; // Conversation
  16368. const LAST_DELIVERED_AT_UPDATE = 'lastdeliveredatupdate';
  16369. const LAST_READ_AT_UPDATE = 'lastreadatupdate';
  16370. const INFO_UPDATED = 'infoupdated';
  16371. var IMEvent = /*#__PURE__*/Object.freeze({
  16372. __proto__: null,
  16373. UNREAD_MESSAGES_COUNT_UPDATE: UNREAD_MESSAGES_COUNT_UPDATE,
  16374. CLOSE: CLOSE,
  16375. CONFLICT: CONFLICT,
  16376. CONVERSATION_INFO_UPDATED: CONVERSATION_INFO_UPDATED,
  16377. UNHANDLED_MESSAGE: UNHANDLED_MESSAGE,
  16378. INVITED: INVITED,
  16379. KICKED: KICKED,
  16380. MEMBERS_JOINED: MEMBERS_JOINED,
  16381. MEMBERS_LEFT: MEMBERS_LEFT,
  16382. MEMBER_INFO_UPDATED: MEMBER_INFO_UPDATED,
  16383. BLOCKED: BLOCKED,
  16384. UNBLOCKED: UNBLOCKED,
  16385. MEMBERS_BLOCKED: MEMBERS_BLOCKED,
  16386. MEMBERS_UNBLOCKED: MEMBERS_UNBLOCKED,
  16387. MUTED: MUTED,
  16388. UNMUTED: UNMUTED,
  16389. MEMBERS_MUTED: MEMBERS_MUTED,
  16390. MEMBERS_UNMUTED: MEMBERS_UNMUTED,
  16391. MESSAGE: MESSAGE$1,
  16392. MESSAGE_RECALL: MESSAGE_RECALL,
  16393. MESSAGE_UPDATE: MESSAGE_UPDATE,
  16394. LAST_DELIVERED_AT_UPDATE: LAST_DELIVERED_AT_UPDATE,
  16395. LAST_READ_AT_UPDATE: LAST_READ_AT_UPDATE,
  16396. INFO_UPDATED: INFO_UPDATED
  16397. });
  16398. /**
  16399. * 消息状态枚举
  16400. * @enum {Symbol}
  16401. * @since 3.2.0
  16402. * @memberof module:leancloud-realtime
  16403. */
  16404. const MessageStatus = {
  16405. /** 初始状态、未知状态 */
  16406. NONE: Symbol('none'),
  16407. /** 正在发送 */
  16408. SENDING: Symbol('sending'),
  16409. /** 已发送 */
  16410. SENT: Symbol('sent'),
  16411. /** 已送达 */
  16412. DELIVERED: Symbol('delivered'),
  16413. /** 发送失败 */
  16414. FAILED: Symbol('failed')
  16415. };
  16416. Object.freeze(MessageStatus);
  16417. const rMessageStatus = {
  16418. [MessageStatus.NONE]: true,
  16419. [MessageStatus.SENDING]: true,
  16420. [MessageStatus.SENT]: true,
  16421. [MessageStatus.DELIVERED]: true,
  16422. [MessageStatus.READ]: true,
  16423. [MessageStatus.FAILED]: true
  16424. };
  16425. class Message {
  16426. /**
  16427. * @implements AVMessage
  16428. * @param {Object|String|ArrayBuffer} content 消息内容
  16429. */
  16430. constructor(content) {
  16431. Object.assign(this, {
  16432. content
  16433. }, {
  16434. /**
  16435. * @type {String}
  16436. * @memberof Message#
  16437. */
  16438. id: v4_1(),
  16439. /**
  16440. * 消息所在的 conversation id
  16441. * @memberof Message#
  16442. * @type {String?}
  16443. */
  16444. cid: null,
  16445. /**
  16446. * 消息发送时间
  16447. * @memberof Message#
  16448. * @type {Date}
  16449. */
  16450. timestamp: new Date(),
  16451. /**
  16452. * 消息发送者
  16453. * @memberof Message#
  16454. * @type {String}
  16455. */
  16456. from: undefined,
  16457. /**
  16458. * 消息提及的用户
  16459. * @since 4.0.0
  16460. * @memberof Message#
  16461. * @type {String[]}
  16462. */
  16463. mentionList: [],
  16464. /**
  16465. * 消息是否提及了所有人
  16466. * @since 4.0.0
  16467. * @memberof Message#
  16468. * @type {Boolean}
  16469. */
  16470. mentionedAll: false,
  16471. _mentioned: false
  16472. });
  16473. this._setStatus(MessageStatus.NONE);
  16474. }
  16475. /**
  16476. * 将当前消息的内容序列化为 JSON 对象
  16477. * @private
  16478. * @return {Object}
  16479. */
  16480. getPayload() {
  16481. return this.content;
  16482. }
  16483. _toJSON() {
  16484. const {
  16485. id,
  16486. cid,
  16487. from,
  16488. timestamp,
  16489. deliveredAt,
  16490. updatedAt,
  16491. mentionList,
  16492. mentionedAll,
  16493. mentioned
  16494. } = this;
  16495. return {
  16496. id,
  16497. cid,
  16498. from,
  16499. timestamp,
  16500. deliveredAt,
  16501. updatedAt,
  16502. mentionList,
  16503. mentionedAll,
  16504. mentioned
  16505. };
  16506. }
  16507. /**
  16508. * 返回 JSON 格式的消息
  16509. * @return {Object} 返回值是一个 plain Object
  16510. */
  16511. toJSON() {
  16512. return { ...this._toJSON(),
  16513. data: this.content
  16514. };
  16515. }
  16516. /**
  16517. * 返回 JSON 格式的消息,与 toJSON 不同的是,该对象包含了完整的信息,可以通过 {@link IMClient#parseMessage} 反序列化。
  16518. * @return {Object} 返回值是一个 plain Object
  16519. * @since 4.0.0
  16520. */
  16521. toFullJSON() {
  16522. const {
  16523. content,
  16524. id,
  16525. cid,
  16526. from,
  16527. timestamp,
  16528. deliveredAt,
  16529. _updatedAt,
  16530. mentionList,
  16531. mentionedAll
  16532. } = this;
  16533. return {
  16534. data: content,
  16535. id,
  16536. cid,
  16537. from,
  16538. timestamp: getTime(timestamp),
  16539. deliveredAt: getTime(deliveredAt),
  16540. updatedAt: getTime(_updatedAt),
  16541. mentionList,
  16542. mentionedAll
  16543. };
  16544. }
  16545. /**
  16546. * 消息状态,值为 {@link module:leancloud-realtime.MessageStatus} 之一
  16547. * @type {Symbol}
  16548. * @readonly
  16549. * @since 3.2.0
  16550. */
  16551. get status() {
  16552. return this._status;
  16553. }
  16554. _setStatus(status) {
  16555. if (!rMessageStatus[status]) {
  16556. throw new Error('Invalid message status');
  16557. }
  16558. this._status = status;
  16559. }
  16560. get timestamp() {
  16561. return this._timestamp;
  16562. }
  16563. set timestamp(value) {
  16564. this._timestamp = decodeDate(value);
  16565. }
  16566. /**
  16567. * 消息送达时间
  16568. * @type {?Date}
  16569. */
  16570. get deliveredAt() {
  16571. return this._deliveredAt;
  16572. }
  16573. set deliveredAt(value) {
  16574. this._deliveredAt = decodeDate(value);
  16575. }
  16576. /**
  16577. * 消息修改或撤回时间,可以通过比较其与消息的 timestamp 是否相等判断消息是否被修改过或撤回过。
  16578. * @type {Date}
  16579. * @since 3.5.0
  16580. */
  16581. get updatedAt() {
  16582. return this._updatedAt || this.timestamp;
  16583. }
  16584. set updatedAt(value) {
  16585. this._updatedAt = decodeDate(value);
  16586. }
  16587. /**
  16588. * 当前用户是否在该消息中被提及
  16589. * @type {Boolean}
  16590. * @readonly
  16591. * @since 4.0.0
  16592. */
  16593. get mentioned() {
  16594. return this._mentioned;
  16595. }
  16596. _updateMentioned(client) {
  16597. this._mentioned = this.from !== client && (this.mentionedAll || this.mentionList.indexOf(client) > -1);
  16598. }
  16599. /**
  16600. * 获取提及用户列表
  16601. * @since 4.0.0
  16602. * @return {String[]} 提及用户的 id 列表
  16603. */
  16604. getMentionList() {
  16605. return this.mentionList;
  16606. }
  16607. /**
  16608. * 设置提及用户列表
  16609. * @since 4.0.0
  16610. * @param {String[]} clients 提及用户的 id 列表
  16611. * @return {this} self
  16612. */
  16613. setMentionList(clients) {
  16614. this.mentionList = ensureArray(clients);
  16615. return this;
  16616. }
  16617. /**
  16618. * 设置是否提及所有人
  16619. * @since 4.0.0
  16620. * @param {Boolean} [value=true]
  16621. * @return {this} self
  16622. */
  16623. mentionAll(value = true) {
  16624. this.mentionedAll = Boolean(value);
  16625. return this;
  16626. }
  16627. /**
  16628. * 判断给定的内容是否是有效的 Message,
  16629. * 该方法始终返回 true
  16630. * @private
  16631. * @returns {Boolean}
  16632. * @implements AVMessage.validate
  16633. */
  16634. static validate() {
  16635. return true;
  16636. }
  16637. /**
  16638. * 解析处理消息内容
  16639. * <pre>
  16640. * 如果子类提供了 message,返回该 message
  16641. * 如果没有提供,将 json 作为 content 实例化一个 Message
  16642. * @private
  16643. * @param {Object} json json 格式的消息内容
  16644. * @param {Message} message 子类提供的 message
  16645. * @return {Message}
  16646. * @implements AVMessage.parse
  16647. */
  16648. static parse(json, message) {
  16649. return message || new this(json);
  16650. }
  16651. }
  16652. /* eslint-disable no-param-reassign */
  16653. const messageType = type => {
  16654. if (typeof type !== 'number') {
  16655. throw new TypeError(`${type} is not a Number`);
  16656. }
  16657. return target => {
  16658. target.TYPE = type;
  16659. target.validate = json => json._lctype === type;
  16660. target.prototype._getType = () => ({
  16661. _lctype: type
  16662. });
  16663. };
  16664. }; // documented in ../plugin-im.js
  16665. const messageField = fields => {
  16666. if (typeof fields !== 'string') {
  16667. if (!Array.isArray(fields)) {
  16668. throw new TypeError(`${fields} is not an Array`);
  16669. } else if (fields.some(value => typeof value !== 'string')) {
  16670. throw new TypeError('fields contains non-string typed member');
  16671. }
  16672. }
  16673. return target => {
  16674. // IE10 Hack:
  16675. // static properties in IE10 will not be inherited from super
  16676. // search for parse method and assign it manually
  16677. let originalCustomFields = isIE10 ? getStaticProperty(target, '_customFields') : target._customFields;
  16678. originalCustomFields = Array.isArray(originalCustomFields) ? originalCustomFields : [];
  16679. target._customFields = originalCustomFields.concat(fields);
  16680. };
  16681. }; // IE10 Hack:
  16682. // static properties in IE10 will not be inherited from super
  16683. // search for parse method and assign it manually
  16684. const IE10Compatible = target => {
  16685. if (isIE10) {
  16686. target.parse = getStaticProperty(target, 'parse');
  16687. }
  16688. };
  16689. var _dec, _class$1;
  16690. let // jsdoc-ignore-end
  16691. /**
  16692. * 所有内置的富媒体消息均继承自本类
  16693. * @extends Message
  16694. */
  16695. TypedMessage = (_dec = messageField(['_lctext', '_lcattrs']), _dec(_class$1 = class TypedMessage extends Message {
  16696. /**
  16697. * @type {Number}
  16698. * @readonly
  16699. */
  16700. get type() {
  16701. return this.constructor.TYPE;
  16702. }
  16703. /** @type {String} */
  16704. set text(text) {
  16705. return this.setText(text);
  16706. }
  16707. get text() {
  16708. return this.getText();
  16709. }
  16710. /** @type {Object} */
  16711. set attributes(attributes) {
  16712. return this.setAttributes(attributes);
  16713. }
  16714. get attributes() {
  16715. return this.getAttributes();
  16716. }
  16717. /**
  16718. * 在客户端需要以文本形式展示该消息时显示的文案,
  16719. * 如 <code>[红包] 新春快乐</code>。
  16720. * 默认值为消息的 text。
  16721. * @type {String}
  16722. * @readonly
  16723. */
  16724. get summary() {
  16725. return this.text;
  16726. }
  16727. /**
  16728. * @param {String} text
  16729. * @return {this} self
  16730. */
  16731. setText(text) {
  16732. this._lctext = text;
  16733. return this;
  16734. }
  16735. /**
  16736. * @return {String}
  16737. */
  16738. getText() {
  16739. return this._lctext;
  16740. }
  16741. /**
  16742. * @param {Object} attributes
  16743. * @return {this} self
  16744. */
  16745. setAttributes(attributes) {
  16746. this._lcattrs = attributes;
  16747. return this;
  16748. }
  16749. /**
  16750. * @return {Object}
  16751. */
  16752. getAttributes() {
  16753. return this._lcattrs;
  16754. }
  16755. _getCustomFields() {
  16756. const fields = Array.isArray(this.constructor._customFields) ? this.constructor._customFields : [];
  16757. return fields.reduce((result, field) => {
  16758. if (typeof field !== 'string') return result;
  16759. result[field] = this[field]; // eslint-disable-line no-param-reassign
  16760. return result;
  16761. }, {});
  16762. }
  16763. /* eslint-disable class-methods-use-this */
  16764. _getType() {
  16765. throw new Error('not implemented');
  16766. }
  16767. /* eslint-enable class-methods-use-this */
  16768. getPayload() {
  16769. return compact({
  16770. _lctext: this.getText(),
  16771. _lcattrs: this.getAttributes(),
  16772. ...this._getCustomFields(),
  16773. ...this._getType()
  16774. });
  16775. }
  16776. toJSON() {
  16777. const {
  16778. type,
  16779. text,
  16780. attributes,
  16781. summary
  16782. } = this;
  16783. return { ...super._toJSON(),
  16784. type,
  16785. text,
  16786. attributes,
  16787. summary
  16788. };
  16789. }
  16790. toFullJSON() {
  16791. return { ...super.toFullJSON(),
  16792. data: this.getPayload()
  16793. };
  16794. }
  16795. /**
  16796. * 解析处理消息内容
  16797. * <pre>
  16798. * 为给定的 message 设置 text 与 attributes 属性,返回该 message
  16799. * 如果子类没有提供 message,new this()
  16800. * @protected
  16801. * @param {Object} json json 格式的消息内容
  16802. * @param {TypedMessage} message 子类提供的 message
  16803. * @return {TypedMessage}
  16804. * @implements AVMessage.parse
  16805. */
  16806. static parse(json, message = new this()) {
  16807. message.content = json; // eslint-disable-line no-param-reassign
  16808. const customFields = isIE10 ? getStaticProperty(message.constructor, '_customFields') : message.constructor._customFields;
  16809. let fields = Array.isArray(customFields) ? customFields : [];
  16810. fields = fields.reduce((result, field) => {
  16811. if (typeof field !== 'string') return result;
  16812. result[field] = json[field]; // eslint-disable-line no-param-reassign
  16813. return result;
  16814. }, {});
  16815. Object.assign(message, fields);
  16816. return super.parse(json, message);
  16817. }
  16818. }) || _class$1);
  16819. var _dec$1, _class$2;
  16820. let // jsdoc-ignore-end
  16821. /**
  16822. * 已撤回类型消息,当消息被撤回时,SDK 会使用该类型的消息替代原始消息
  16823. * @extends TypedMessage
  16824. */
  16825. RecalledMessage = (_dec$1 = messageType(-127), _dec$1(_class$2 = IE10Compatible(_class$2 = class RecalledMessage extends TypedMessage {
  16826. /**
  16827. * 在客户端需要以文本形式展示该消息时显示的文案,值为 <code>[该消息已撤回]</code>
  16828. * @type {String}
  16829. * @readonly
  16830. */
  16831. // eslint-disable-next-line class-methods-use-this
  16832. get summary() {
  16833. return '[该消息已撤回]';
  16834. }
  16835. }) || _class$2) || _class$2);
  16836. /* eslint class-methods-use-this: ["error", { "exceptMethods": ["_addMembers", "_removeMembers"] }] */
  16837. const debug$7 = browser('LC:Conversation');
  16838. const serializeMessage = message => {
  16839. const content = message.getPayload();
  16840. let msg;
  16841. let binaryMsg;
  16842. if (content instanceof ArrayBuffer) {
  16843. binaryMsg = content;
  16844. } else if (typeof content !== 'string') {
  16845. msg = JSON.stringify(content);
  16846. } else {
  16847. msg = content;
  16848. }
  16849. return {
  16850. msg,
  16851. binaryMsg
  16852. };
  16853. };
  16854. const {
  16855. NEW,
  16856. OLD
  16857. } = LogsCommand.QueryDirection;
  16858. /**
  16859. * 历史消息查询方向枚举
  16860. * @enum {Number}
  16861. * @since 4.0.0
  16862. * @memberof module:leancloud-realtime
  16863. */
  16864. const MessageQueryDirection = {
  16865. /** 从后向前 */
  16866. NEW_TO_OLD: OLD,
  16867. /** 从前向后 */
  16868. OLD_TO_NEW: NEW
  16869. };
  16870. Object.freeze(MessageQueryDirection);
  16871. class ConversationBase extends eventemitter3 {
  16872. /**
  16873. * @extends EventEmitter
  16874. * @private
  16875. * @abstract
  16876. */
  16877. constructor({
  16878. id,
  16879. lastMessageAt,
  16880. lastMessage,
  16881. lastDeliveredAt,
  16882. lastReadAt,
  16883. unreadMessagesCount = 0,
  16884. members = [],
  16885. mentioned = false,
  16886. ...properties
  16887. }, client) {
  16888. super();
  16889. Object.assign(this, {
  16890. /**
  16891. * 对话 id,对应 _Conversation 表中的 objectId
  16892. * @memberof ConversationBase#
  16893. * @type {String}
  16894. */
  16895. id,
  16896. /**
  16897. * 最后一条消息时间
  16898. * @memberof ConversationBase#
  16899. * @type {?Date}
  16900. */
  16901. lastMessageAt,
  16902. /**
  16903. * 最后一条消息
  16904. * @memberof ConversationBase#
  16905. * @type {?Message}
  16906. */
  16907. lastMessage,
  16908. /**
  16909. * 参与该对话的用户列表
  16910. * @memberof ConversationBase#
  16911. * @type {String[]}
  16912. */
  16913. members,
  16914. // other properties provided by subclasses
  16915. ...properties
  16916. });
  16917. this.members = Array.from(new Set(this.members));
  16918. Object.assign(internal(this), {
  16919. messagesWaitingForReceipt: {},
  16920. lastDeliveredAt,
  16921. lastReadAt,
  16922. unreadMessagesCount,
  16923. mentioned
  16924. });
  16925. this._client = client;
  16926. if (debug$7.enabled) {
  16927. values_1(IMEvent).forEach(event => this.on(event, (...payload) => this._debug(`${event} event emitted. %o`, payload)));
  16928. } // onConversationCreate hook
  16929. applyDecorators(this._client._plugins.onConversationCreate, this);
  16930. }
  16931. /**
  16932. * 当前用户是否在该对话的未读消息中被提及
  16933. * @type {Boolean}
  16934. * @since 4.0.0
  16935. */
  16936. get unreadMessagesMentioned() {
  16937. return internal(this).unreadMessagesMentioned;
  16938. }
  16939. _setUnreadMessagesMentioned(value) {
  16940. internal(this).unreadMessagesMentioned = Boolean(value);
  16941. }
  16942. set unreadMessagesCount(value) {
  16943. if (value !== this.unreadMessagesCount) {
  16944. internal(this).unreadMessagesCount = value;
  16945. this._client.emit(UNREAD_MESSAGES_COUNT_UPDATE, [this]);
  16946. }
  16947. }
  16948. /**
  16949. * 当前用户在该对话的未读消息数
  16950. * @type {Number}
  16951. */
  16952. get unreadMessagesCount() {
  16953. return internal(this).unreadMessagesCount;
  16954. }
  16955. set lastMessageAt(value) {
  16956. const time = decodeDate(value);
  16957. if (time <= this._lastMessageAt) return;
  16958. this._lastMessageAt = time;
  16959. }
  16960. get lastMessageAt() {
  16961. return this._lastMessageAt;
  16962. }
  16963. /**
  16964. * 最后消息送达时间,常用来实现消息的「已送达」标记,可通过 {@link Conversation#fetchReceiptTimestamps} 获取或更新该属性
  16965. * @type {?Date}
  16966. * @since 3.4.0
  16967. */
  16968. get lastDeliveredAt() {
  16969. if (this.members.length !== 2) return null;
  16970. return internal(this).lastDeliveredAt;
  16971. }
  16972. _setLastDeliveredAt(value) {
  16973. const date = decodeDate(value);
  16974. if (!(date < internal(this).lastDeliveredAt)) {
  16975. internal(this).lastDeliveredAt = date;
  16976. /**
  16977. * 最后消息送达时间更新
  16978. * @event ConversationBase#LAST_DELIVERED_AT_UPDATE
  16979. * @since 3.4.0
  16980. */
  16981. this.emit(LAST_DELIVERED_AT_UPDATE);
  16982. }
  16983. }
  16984. /**
  16985. * 最后消息被阅读时间,常用来实现发送消息的「已读」标记,可通过 {@link Conversation#fetchReceiptTimestamps} 获取或更新该属性
  16986. * @type {?Date}
  16987. * @since 3.4.0
  16988. */
  16989. get lastReadAt() {
  16990. if (this.members.length !== 2) return null;
  16991. return internal(this).lastReadAt;
  16992. }
  16993. _setLastReadAt(value) {
  16994. const date = decodeDate(value);
  16995. if (!(date < internal(this).lastReadAt)) {
  16996. internal(this).lastReadAt = date;
  16997. /**
  16998. * 最后消息被阅读时间更新
  16999. * @event ConversationBase#LAST_READ_AT_UPDATE
  17000. * @since 3.4.0
  17001. */
  17002. this.emit(LAST_READ_AT_UPDATE);
  17003. }
  17004. }
  17005. /**
  17006. * 返回 JSON 格式的对话,与 toJSON 不同的是,该对象包含了完整的信息,可以通过 {@link IMClient#parseConversation} 反序列化。
  17007. * @return {Object} 返回值是一个 plain Object
  17008. * @since 4.0.0
  17009. */
  17010. toFullJSON() {
  17011. const {
  17012. id,
  17013. members,
  17014. lastMessageAt,
  17015. lastDeliveredAt,
  17016. lastReadAt,
  17017. lastMessage,
  17018. unreadMessagesCount
  17019. } = this;
  17020. return {
  17021. id,
  17022. members,
  17023. lastMessageAt: getTime(lastMessageAt),
  17024. lastDeliveredAt: getTime(lastDeliveredAt),
  17025. lastReadAt: getTime(lastReadAt),
  17026. lastMessage: lastMessage ? lastMessage.toFullJSON() : undefined,
  17027. unreadMessagesCount
  17028. };
  17029. }
  17030. /**
  17031. * 返回 JSON 格式的对话
  17032. * @return {Object} 返回值是一个 plain Object
  17033. * @since 4.0.0
  17034. */
  17035. toJSON() {
  17036. const {
  17037. id,
  17038. members,
  17039. lastMessageAt,
  17040. lastDeliveredAt,
  17041. lastReadAt,
  17042. lastMessage,
  17043. unreadMessagesCount,
  17044. unreadMessagesMentioned
  17045. } = this;
  17046. return {
  17047. id,
  17048. members,
  17049. lastMessageAt,
  17050. lastDeliveredAt,
  17051. lastReadAt,
  17052. lastMessage: lastMessage ? lastMessage.toJSON() : undefined,
  17053. unreadMessagesCount,
  17054. unreadMessagesMentioned
  17055. };
  17056. }
  17057. _debug(...params) {
  17058. debug$7(...params, `[${this.id}]`);
  17059. }
  17060. _send(command, ...args) {
  17061. /* eslint-disable no-param-reassign */
  17062. if (command.cmd === null) {
  17063. command.cmd = 'conv';
  17064. }
  17065. if (command.cmd === 'conv' && command.convMessage === null) {
  17066. command.convMessage = new ConvCommand();
  17067. }
  17068. if (command.convMessage && command.convMessage.cid === null) {
  17069. command.convMessage.cid = this.id;
  17070. }
  17071. /* eslint-enable no-param-reassign */
  17072. return this._client._send(command, ...args);
  17073. }
  17074. /**
  17075. * 发送消息
  17076. * @param {Message} message 消息,Message 及其子类的实例
  17077. * @param {Object} [options] since v3.3.0,发送选项
  17078. * @param {Boolean} [options.transient] since v3.3.1,是否作为暂态消息发送
  17079. * @param {Boolean} [options.receipt] 是否需要回执,仅在普通对话中有效
  17080. * @param {Boolean} [options.will] since v3.4.0,是否指定该消息作为「掉线消息」发送,
  17081. * 「掉线消息」会延迟到当前用户掉线后发送,常用来实现「下线通知」功能
  17082. * @param {MessagePriority} [options.priority] 消息优先级,仅在暂态对话中有效,
  17083. * see: {@link module:leancloud-realtime.MessagePriority MessagePriority}
  17084. * @param {Object} [options.pushData] 消息对应的离线推送内容,如果消息接收方不在线,会推送指定的内容。其结构说明参见: {@link https://url.leanapp.cn/pushData 推送消息内容}
  17085. * @return {Promise.<Message>} 发送的消息
  17086. */
  17087. async send(message, options) {
  17088. this._debug(message, 'send');
  17089. if (!(message instanceof Message)) {
  17090. throw new TypeError(`${message} is not a Message`);
  17091. }
  17092. const {
  17093. transient,
  17094. receipt,
  17095. priority,
  17096. pushData,
  17097. will
  17098. } = { // support Message static property: sendOptions
  17099. ...message.constructor.sendOptions,
  17100. // support Message static property: getSendOptions
  17101. ...(typeof message.constructor.getSendOptions === 'function' ? message.constructor.getSendOptions(message) : {}),
  17102. ...options
  17103. };
  17104. if (receipt) {
  17105. if (this.transient) {
  17106. console.warn('receipt option is ignored as the conversation is transient.');
  17107. } else if (transient) {
  17108. console.warn('receipt option is ignored as the message is sent transiently.');
  17109. } else if (this.members.length > 2) {
  17110. console.warn('receipt option is recommended to be used in one-on-one conversation.'); // eslint-disable-line max-len
  17111. }
  17112. }
  17113. if (priority && !this.transient) {
  17114. console.warn('priority option is ignored as the conversation is not transient.');
  17115. }
  17116. Object.assign(message, {
  17117. cid: this.id,
  17118. from: this._client.id
  17119. });
  17120. message._setStatus(MessageStatus.SENDING);
  17121. const {
  17122. msg,
  17123. binaryMsg
  17124. } = serializeMessage(message);
  17125. const command = new GenericCommand({
  17126. cmd: 'direct',
  17127. directMessage: new DirectCommand({
  17128. msg,
  17129. binaryMsg,
  17130. cid: this.id,
  17131. r: receipt,
  17132. transient,
  17133. dt: message.id,
  17134. pushData: JSON.stringify(pushData),
  17135. will,
  17136. mentionPids: message.mentionList,
  17137. mentionAll: message.mentionedAll
  17138. }),
  17139. priority
  17140. });
  17141. try {
  17142. const resCommand = await this._send(command);
  17143. const {
  17144. ackMessage: {
  17145. uid,
  17146. t,
  17147. code,
  17148. reason,
  17149. appCode
  17150. }
  17151. } = resCommand;
  17152. if (code !== null) {
  17153. throw createError({
  17154. code,
  17155. reason,
  17156. appCode
  17157. });
  17158. }
  17159. Object.assign(message, {
  17160. id: uid,
  17161. timestamp: t
  17162. });
  17163. if (!transient) {
  17164. this.lastMessage = message;
  17165. this.lastMessageAt = message.timestamp;
  17166. }
  17167. message._setStatus(MessageStatus.SENT);
  17168. if (receipt) {
  17169. internal(this).messagesWaitingForReceipt[message.id] = message;
  17170. }
  17171. return message;
  17172. } catch (error) {
  17173. message._setStatus(MessageStatus.FAILED);
  17174. throw error;
  17175. }
  17176. }
  17177. async _update(message, newMessage, recall) {
  17178. this._debug('patch %O %O %O', message, newMessage, recall);
  17179. if (message instanceof Message) {
  17180. if (message.from !== this._client.id) {
  17181. throw new Error('Updating message from others is not allowed');
  17182. }
  17183. if (message.status !== MessageStatus.SENT && message.status !== MessageStatus.DELIVERED) {
  17184. throw new Error('Message is not sent');
  17185. }
  17186. } else if (!(message.id && message.timestamp)) {
  17187. throw new TypeError(`${message} is not a Message`);
  17188. }
  17189. let msg;
  17190. let binaryMsg;
  17191. if (!recall) {
  17192. const content = serializeMessage(newMessage);
  17193. ({
  17194. msg,
  17195. binaryMsg
  17196. } = content);
  17197. }
  17198. await this._send(new GenericCommand({
  17199. cmd: CommandType.patch,
  17200. op: OpType.modify,
  17201. patchMessage: new PatchCommand({
  17202. patches: [new PatchItem({
  17203. cid: this.id,
  17204. mid: message.id,
  17205. timestamp: Number(message.timestamp),
  17206. recall,
  17207. data: msg,
  17208. binaryMsg,
  17209. mentionPids: newMessage.mentionList,
  17210. mentionAll: newMessage.mentionedAll
  17211. })],
  17212. lastPatchTime: this._client._lastPatchTime
  17213. })
  17214. }));
  17215. const {
  17216. id,
  17217. cid,
  17218. timestamp,
  17219. from,
  17220. _status
  17221. } = message;
  17222. Object.assign(newMessage, {
  17223. id,
  17224. cid,
  17225. timestamp,
  17226. from,
  17227. _status
  17228. });
  17229. if (this.lastMessage && this.lastMessage.id === newMessage.id) {
  17230. this.lastMessage = newMessage;
  17231. }
  17232. return newMessage;
  17233. }
  17234. /**
  17235. * 获取对话人数,或暂态对话的在线人数
  17236. * @return {Promise.<Number>}
  17237. */
  17238. async count() {
  17239. this._debug('count');
  17240. const resCommand = await this._send(new GenericCommand({
  17241. op: 'count'
  17242. }));
  17243. return resCommand.convMessage.count;
  17244. }
  17245. /**
  17246. * 应用增加成员的操作,产生副作用
  17247. * @param {string[]} members
  17248. * @abstract
  17249. * @private
  17250. */
  17251. _addMembers() {}
  17252. /**
  17253. * 应用减少成员的操作,产生副作用
  17254. * @param {string[]} members
  17255. * @abstract
  17256. * @private
  17257. */
  17258. _removeMembers() {}
  17259. /**
  17260. * 修改已发送的消息
  17261. * @param {AVMessage} message 要修改的消息,该消息必须是由当前用户发送的。也可以提供一个包含消息 {id, timestamp} 的对象
  17262. * @param {AVMessage} newMessage 新的消息
  17263. * @return {Promise.<AVMessage>} 更新后的消息
  17264. */
  17265. async update(message, newMessage) {
  17266. if (!(newMessage instanceof Message)) {
  17267. throw new TypeError(`${newMessage} is not a Message`);
  17268. }
  17269. return this._update(message, newMessage, false);
  17270. }
  17271. /**
  17272. * 撤回已发送的消息
  17273. * @param {AVMessage} message 要撤回的消息,该消息必须是由当前用户发送的。也可以提供一个包含消息 {id, timestamp} 的对象
  17274. * @return {Promise.<RecalledMessage>} 一条已撤回的消息
  17275. */
  17276. async recall(message) {
  17277. return this._update(message, new RecalledMessage(), true);
  17278. }
  17279. /**
  17280. * 查询消息记录
  17281. * 如果仅需实现消息向前记录翻页查询需求,建议使用 {@link Conversation#createMessagesIterator}。
  17282. * 不论何种方向,获得的消息都是按照时间升序排列的。
  17283. * startClosed 与 endClosed 用于指定查询区间的开闭。
  17284. *
  17285. * @param {Object} [options]
  17286. * @param {Number} [options.limit] 限制查询结果的数量,目前服务端默认为 20
  17287. * @param {Number} [options.type] 指定查询的富媒体消息类型,不指定则查询所有消息。
  17288. * @param {MessageQueryDirection} [options.direction] 查询的方向。
  17289. * 在不指定的情况下如果 startTime 大于 endTime,则为从新到旧查询,可以实现加载聊天记录等场景。
  17290. * 如果 startTime 小于 endTime,则为从旧到新查询,可以实现弹幕等场景。
  17291. * @param {Date} [options.startTime] 从该时间开始查询,不传则从当前时间开始查询
  17292. * @param {String} [options.startMessageId] 从该消息之前开始查询,需要与 startTime 同时使用,为防止某时刻有重复消息
  17293. * @param {Boolean}[options.startClosed] 指定查询范围是否包括开始的时间点,默认不包括
  17294. * @param {Date} [options.endTime] 查询到该时间为止,不传则查询最早消息为止
  17295. * @param {String} [options.endMessageId] 查询到该消息为止,需要与 endTime 同时使用,为防止某时刻有重复消息
  17296. * @param {Boolean}[options.endClosed] 指定查询范围是否包括结束的时间点,默认不包括
  17297. *
  17298. * @param {Date} [options.beforeTime] DEPRECATED: 使用 startTime 代替。限制查询结果为小于该时间之前的消息,不传则为当前时间
  17299. * @param {String} [options.beforeMessageId] DEPRECATED: 使用 startMessageId 代替。
  17300. * 限制查询结果为该消息之前的消息,需要与 beforeTime 同时使用,为防止某时刻有重复消息
  17301. * @param {Date} [options.afterTime] DEPRECATED: 使用 endTime 代替。限制查询结果为大于该时间之前的消息
  17302. * @param {String} [options.afterMessageId] DEPRECATED: 使用 endMessageId 代替。
  17303. * 限制查询结果为该消息之后的消息,需要与 afterTime 同时使用,为防止某时刻有重复消息
  17304. * @return {Promise.<Message[]>} 消息列表
  17305. */
  17306. async queryMessages(options = {}) {
  17307. this._debug('query messages %O', options);
  17308. const {
  17309. beforeTime,
  17310. beforeMessageId,
  17311. afterTime,
  17312. afterMessageId,
  17313. limit,
  17314. direction,
  17315. type,
  17316. startTime,
  17317. startMessageId,
  17318. startClosed,
  17319. endTime,
  17320. endMessageId,
  17321. endClosed
  17322. } = options;
  17323. if (beforeMessageId || beforeTime || afterMessageId || afterTime) {
  17324. console.warn('DEPRECATION: queryMessages options beforeTime, beforeMessageId, afterTime and afterMessageId are deprecated in favor of startTime, startMessageId, endTime and endMessageId.');
  17325. return this.queryMessages({
  17326. startTime: beforeTime,
  17327. startMessageId: beforeMessageId,
  17328. endTime: afterTime,
  17329. endMessageId: afterMessageId,
  17330. limit
  17331. });
  17332. }
  17333. if (startMessageId && !startTime) {
  17334. throw new Error('query option startMessageId must be used with option startTime');
  17335. }
  17336. if (endMessageId && !endTime) {
  17337. throw new Error('query option endMessageId must be used with option endTime');
  17338. }
  17339. const conditions = {
  17340. t: startTime,
  17341. mid: startMessageId,
  17342. tIncluded: startClosed,
  17343. tt: endTime,
  17344. tmid: endMessageId,
  17345. ttIncluded: endClosed,
  17346. l: limit,
  17347. lctype: type
  17348. };
  17349. if (conditions.t instanceof Date) {
  17350. conditions.t = conditions.t.getTime();
  17351. }
  17352. if (conditions.tt instanceof Date) {
  17353. conditions.tt = conditions.tt.getTime();
  17354. }
  17355. if (direction !== undefined) {
  17356. conditions.direction = direction;
  17357. } else if (conditions.tt > conditions.t) {
  17358. conditions.direction = MessageQueryDirection.OLD_TO_NEW;
  17359. }
  17360. const resCommand = await this._send(new GenericCommand({
  17361. cmd: 'logs',
  17362. logsMessage: new LogsCommand(Object.assign(conditions, {
  17363. cid: this.id
  17364. }))
  17365. }));
  17366. return Promise.all(resCommand.logsMessage.logs.map(async ({
  17367. msgId,
  17368. timestamp,
  17369. patchTimestamp,
  17370. from,
  17371. ackAt,
  17372. readAt,
  17373. data,
  17374. mentionAll,
  17375. mentionPids,
  17376. bin
  17377. }) => {
  17378. const messageData = {
  17379. data,
  17380. bin,
  17381. id: msgId,
  17382. cid: this.id,
  17383. timestamp,
  17384. from,
  17385. deliveredAt: ackAt,
  17386. updatedAt: patchTimestamp,
  17387. mentionList: mentionPids,
  17388. mentionedAll: mentionAll
  17389. };
  17390. const message = await this._client.parseMessage(messageData);
  17391. let status = MessageStatus.SENT;
  17392. if (this.members.length === 2) {
  17393. if (ackAt) status = MessageStatus.DELIVERED;
  17394. if (ackAt) this._setLastDeliveredAt(ackAt);
  17395. if (readAt) this._setLastReadAt(readAt);
  17396. }
  17397. message._setStatus(status);
  17398. return message;
  17399. }));
  17400. }
  17401. /**
  17402. * 获取消息翻页迭代器
  17403. * @param {Object} [options]
  17404. * @param {Date} [options.beforeTime] 限制起始查询结果为小于该时间之前的消息,不传则为当前时间
  17405. * @param {String} [options.beforeMessageId] 限制起始查询结果为该消息之前的消息,需要与 beforeTime 同时使用,为防止某时刻有重复消息
  17406. * @param {Number} [options.limit] 限制每页查询结果的数量,目前服务端默认为 20
  17407. * @return {AsyncIterater.<Promise.<IteratorResult<Message[]>>>} [AsyncIterator]{@link https://github.com/tc39/proposal-async-iteration},调用其 next 方法返回获取下一页消息的 Promise
  17408. * @example
  17409. * var messageIterator = conversation.createMessagesIterator({ limit: 10 });
  17410. * messageIterator.next().then(function(result) {
  17411. * // result: {
  17412. * // value: [message1, ..., message10],
  17413. * // done: false,
  17414. * // }
  17415. * });
  17416. * messageIterator.next().then(function(result) {
  17417. * // result: {
  17418. * // value: [message11, ..., message20],
  17419. * // done: false,
  17420. * // }
  17421. * });
  17422. * messageIterator.next().then(function(result) {
  17423. * // No more messages
  17424. * // result: { value: [], done: true }
  17425. * });
  17426. */
  17427. createMessagesIterator({
  17428. beforeTime,
  17429. beforeMessageId,
  17430. limit
  17431. } = {}) {
  17432. let promise;
  17433. return {
  17434. next: () => {
  17435. if (promise === undefined) {
  17436. // first call
  17437. promise = this.queryMessages({
  17438. limit,
  17439. startTime: beforeTime,
  17440. startMessageId: beforeMessageId
  17441. });
  17442. } else {
  17443. promise = promise.then(prevMessages => {
  17444. if (prevMessages.length === 0 || prevMessages.length < limit) {
  17445. // no more messages
  17446. return [];
  17447. }
  17448. return this.queryMessages({
  17449. startTime: prevMessages[0].timestamp,
  17450. startMessageId: prevMessages[0].id,
  17451. limit
  17452. });
  17453. });
  17454. }
  17455. return promise.then(value => ({
  17456. value: Array.from(value),
  17457. done: value.length === 0 || value.length < limit
  17458. }));
  17459. }
  17460. };
  17461. }
  17462. /**
  17463. * 将该会话标记为已读
  17464. * @return {Promise.<this>} self
  17465. */
  17466. async read() {
  17467. this.unreadMessagesCount = 0;
  17468. this._setUnreadMessagesMentioned(false); // 跳过暂态会话
  17469. if (this.transient) return this;
  17470. const client = this._client;
  17471. if (!internal(client).readConversationsBuffer) {
  17472. internal(client).readConversationsBuffer = new Set();
  17473. }
  17474. internal(client).readConversationsBuffer.add(this);
  17475. client._doSendRead();
  17476. return this;
  17477. }
  17478. _handleReceipt({
  17479. messageId,
  17480. timestamp,
  17481. read
  17482. }) {
  17483. if (read) {
  17484. this._setLastReadAt(timestamp);
  17485. } else {
  17486. this._setLastDeliveredAt(timestamp);
  17487. }
  17488. const {
  17489. messagesWaitingForReceipt
  17490. } = internal(this);
  17491. const message = messagesWaitingForReceipt[messageId];
  17492. if (!message) return;
  17493. message._setStatus(MessageStatus.DELIVERED);
  17494. message.deliveredAt = timestamp;
  17495. delete messagesWaitingForReceipt[messageId];
  17496. }
  17497. /**
  17498. * 更新对话的最新回执时间戳(lastDeliveredAt、lastReadAt)
  17499. * @since 3.4.0
  17500. * @return {Promise.<this>} this
  17501. */
  17502. async fetchReceiptTimestamps() {
  17503. // 暂态/系统会话不支持回执
  17504. if (this.transient || this.system) return this;
  17505. const {
  17506. convMessage: {
  17507. maxReadTimestamp,
  17508. maxAckTimestamp
  17509. }
  17510. } = await this._send(new GenericCommand({
  17511. op: 'max_read'
  17512. }));
  17513. this._setLastDeliveredAt(maxAckTimestamp);
  17514. this._setLastReadAt(maxReadTimestamp);
  17515. return this;
  17516. }
  17517. _fetchAllReceiptTimestamps() {
  17518. // 暂态/系统会话不支持回执
  17519. if (this.transient || this.system) return this;
  17520. const convMessage = new ConvCommand({
  17521. queryAllMembers: true
  17522. });
  17523. return this._send(new GenericCommand({
  17524. op: 'max_read',
  17525. convMessage
  17526. })).then(({
  17527. convMessage: {
  17528. maxReadTuples
  17529. }
  17530. }) => maxReadTuples.filter(maxReadTuple => maxReadTuple.maxAckTimestamp || maxReadTuple.maxReadTimestamp).map(({
  17531. pid,
  17532. maxAckTimestamp,
  17533. maxReadTimestamp
  17534. }) => ({
  17535. pid,
  17536. lastDeliveredAt: decodeDate(maxAckTimestamp),
  17537. lastReadAt: decodeDate(maxReadTimestamp)
  17538. })));
  17539. }
  17540. }
  17541. const debug$8 = browser('LC:SignatureFactoryRunner');
  17542. function _validateSignature(signatureResult = {}) {
  17543. const {
  17544. signature,
  17545. timestamp,
  17546. nonce
  17547. } = signatureResult;
  17548. if (typeof signature !== 'string' || typeof timestamp !== 'number' || typeof nonce !== 'string') {
  17549. throw new Error('malformed signature');
  17550. }
  17551. return {
  17552. signature,
  17553. timestamp,
  17554. nonce
  17555. };
  17556. }
  17557. var runSignatureFactory = ((signatureFactory, params) => Promise.resolve().then(() => {
  17558. debug$8('call signatureFactory with %O', params);
  17559. return signatureFactory(...params);
  17560. }).then(tap(signatureResult => debug$8('sign result %O', signatureResult)), error => {
  17561. // eslint-disable-next-line no-param-reassign
  17562. error.message = `sign error: ${error.message}`;
  17563. debug$8(error);
  17564. throw error;
  17565. }).then(_validateSignature));
  17566. /**
  17567. * 部分失败异常
  17568. * @typedef OperationFailureError
  17569. * @type {Error}
  17570. * @property {string} message 异常信息
  17571. * @property {string[]} clientIds 因为该原因失败的 client id 列表
  17572. * @property {number} [code] 错误码
  17573. * @property {string} [detail] 详细信息
  17574. */
  17575. /**
  17576. * 部分成功的结果
  17577. * @typedef PartiallySuccess
  17578. * @type {Object}
  17579. * @property {string[]} successfulClientIds 成功的 client id 列表
  17580. * @property {OperationFailureError[]} failures 失败的异常列表
  17581. */
  17582. /**
  17583. * 分页查询结果
  17584. * @typedef PagedResults
  17585. * @type {Object}
  17586. * @property {T[]} results 查询结果
  17587. * @property {string} [next] 存在表示还有更多结果,在下次查询中带上可实现翻页。
  17588. */
  17589. const createPartiallySuccess = ({
  17590. allowedPids,
  17591. failedPids
  17592. }) => ({
  17593. successfulClientIds: allowedPids,
  17594. failures: failedPids.map(({
  17595. pids,
  17596. ...error
  17597. }) => Object.assign(createError(error), {
  17598. clientIds: pids
  17599. }))
  17600. });
  17601. /**
  17602. * @extends ConversationBase
  17603. * @private
  17604. * @abstract
  17605. */
  17606. class PersistentConversation extends ConversationBase {
  17607. constructor(data, {
  17608. creator,
  17609. createdAt,
  17610. updatedAt,
  17611. transient = false,
  17612. system = false,
  17613. muted = false,
  17614. mutedMembers = [],
  17615. ...attributes
  17616. }, client) {
  17617. super({ ...data,
  17618. /**
  17619. * 对话创建者
  17620. * @memberof PersistentConversation#
  17621. * @type {String}
  17622. */
  17623. creator,
  17624. /**
  17625. * 对话创建时间
  17626. * @memberof PersistentConversation#
  17627. * @type {Date}
  17628. */
  17629. createdAt,
  17630. /**
  17631. * 对话更新时间
  17632. * @memberof PersistentConversation#
  17633. * @type {Date}
  17634. */
  17635. updatedAt,
  17636. /**
  17637. * 对该对话设置了静音的用户列表
  17638. * @memberof PersistentConversation#
  17639. * @type {?String[]}
  17640. */
  17641. mutedMembers,
  17642. /**
  17643. * 暂态对话标记
  17644. * @memberof PersistentConversation#
  17645. * @type {Boolean}
  17646. */
  17647. transient,
  17648. /**
  17649. * 系统对话标记
  17650. * @memberof PersistentConversation#
  17651. * @type {Boolean}
  17652. * @since 3.3.0
  17653. */
  17654. system,
  17655. /**
  17656. * 当前用户静音该对话标记
  17657. * @memberof PersistentConversation#
  17658. * @type {Boolean}
  17659. */
  17660. muted,
  17661. _attributes: attributes
  17662. }, client);
  17663. this._reset();
  17664. }
  17665. set createdAt(value) {
  17666. this._createdAt = decodeDate(value);
  17667. }
  17668. get createdAt() {
  17669. return this._createdAt;
  17670. }
  17671. set updatedAt(value) {
  17672. this._updatedAt = decodeDate(value);
  17673. }
  17674. get updatedAt() {
  17675. return this._updatedAt;
  17676. }
  17677. /**
  17678. * 对话名字,对应 _Conversation 表中的 name
  17679. * @type {String}
  17680. */
  17681. get name() {
  17682. return this.get('name');
  17683. }
  17684. set name(value) {
  17685. this.set('name', value);
  17686. }
  17687. /**
  17688. * 获取对话的自定义属性
  17689. * @since 3.2.0
  17690. * @param {String} key key 属性的键名,'x' 对应 Conversation 表中的 x 列
  17691. * @return {Any} 属性的值
  17692. */
  17693. get(key) {
  17694. return get_1(internal(this).currentAttributes, key);
  17695. }
  17696. /**
  17697. * 设置对话的自定义属性
  17698. * @since 3.2.0
  17699. * @param {String} key 属性的键名,'x' 对应 Conversation 表中的 x 列,支持使用 'x.y.z' 来修改对象的部分字段。
  17700. * @param {Any} value 属性的值
  17701. * @return {this} self
  17702. * @example
  17703. *
  17704. * // 设置对话的 color 属性
  17705. * conversation.set('color', {
  17706. * text: '#000',
  17707. * background: '#DDD',
  17708. * });
  17709. * // 设置对话的 color.text 属性
  17710. * conversation.set('color.text', '#333');
  17711. */
  17712. set(key, value) {
  17713. this._debug(`set [${key}]: ${value}`);
  17714. const {
  17715. pendingAttributes
  17716. } = internal(this);
  17717. const pendingKeys = Object.keys(pendingAttributes); // suppose pendingAttributes = { 'a.b': {} }
  17718. // set 'a' or 'a.b': delete 'a.b'
  17719. const re = new RegExp(`^${key}`);
  17720. const childKeys = pendingKeys.filter(re.test.bind(re));
  17721. childKeys.forEach(k => {
  17722. delete pendingAttributes[k];
  17723. });
  17724. if (childKeys.length) {
  17725. pendingAttributes[key] = value;
  17726. } else {
  17727. // set 'a.c': nothing to do
  17728. // set 'a.b.c.d': assign c: { d: {} } to 'a.b'
  17729. const parentKey = find_1(pendingKeys, k => key.indexOf(k) === 0); // 'a.b'
  17730. if (parentKey) {
  17731. setValue(pendingAttributes[parentKey], key.slice(parentKey.length + 1), value);
  17732. } else {
  17733. pendingAttributes[key] = value;
  17734. }
  17735. }
  17736. this._buildCurrentAttributes();
  17737. return this;
  17738. }
  17739. _buildCurrentAttributes() {
  17740. const {
  17741. pendingAttributes
  17742. } = internal(this);
  17743. internal(this).currentAttributes = Object.keys(pendingAttributes).reduce((target, k) => setValue(target, k, pendingAttributes[k]), cloneDeep_1(this._attributes));
  17744. }
  17745. _updateServerAttributes(attributes) {
  17746. Object.keys(attributes).forEach(key => setValue(this._attributes, key, attributes[key]));
  17747. this._buildCurrentAttributes();
  17748. }
  17749. _reset() {
  17750. Object.assign(internal(this), {
  17751. pendingAttributes: {},
  17752. currentAttributes: this._attributes
  17753. });
  17754. }
  17755. /**
  17756. * 保存当前对话的属性至服务器
  17757. * @return {Promise.<this>} self
  17758. */
  17759. async save() {
  17760. this._debug('save');
  17761. const attr = internal(this).pendingAttributes;
  17762. if (isEmpty_1(attr)) {
  17763. this._debug('nothing touched, resolve with self');
  17764. return this;
  17765. }
  17766. this._debug('attr: %O', attr);
  17767. const convMessage = new ConvCommand({
  17768. attr: new JsonObjectMessage({
  17769. data: JSON.stringify(encode(attr))
  17770. })
  17771. });
  17772. const resCommand = await this._send(new GenericCommand({
  17773. op: 'update',
  17774. convMessage
  17775. }));
  17776. this.updatedAt = resCommand.convMessage.udate;
  17777. this._attributes = internal(this).currentAttributes;
  17778. internal(this).pendingAttributes = {};
  17779. return this;
  17780. }
  17781. /**
  17782. * 从服务器更新对话的属性
  17783. * @return {Promise.<this>} self
  17784. */
  17785. async fetch() {
  17786. const query = this._client.getQuery().equalTo('objectId', this.id);
  17787. await query.find();
  17788. return this;
  17789. }
  17790. /**
  17791. * 静音,客户端拒绝收到服务器端的离线推送通知
  17792. * @return {Promise.<this>} self
  17793. */
  17794. async mute() {
  17795. this._debug('mute');
  17796. await this._send(new GenericCommand({
  17797. op: 'mute'
  17798. }));
  17799. if (!this.transient) {
  17800. this.muted = true;
  17801. this.mutedMembers = union(this.mutedMembers, [this._client.id]);
  17802. }
  17803. return this;
  17804. }
  17805. /**
  17806. * 取消静音
  17807. * @return {Promise.<this>} self
  17808. */
  17809. async unmute() {
  17810. this._debug('unmute');
  17811. await this._send(new GenericCommand({
  17812. op: 'unmute'
  17813. }));
  17814. if (!this.transient) {
  17815. this.muted = false;
  17816. this.mutedMembers = difference(this.mutedMembers, [this._client.id]);
  17817. }
  17818. return this;
  17819. }
  17820. async _appendConversationSignature(command, action, clientIds) {
  17821. if (this._client.options.conversationSignatureFactory) {
  17822. const params = [this.id, this._client.id, clientIds.sort(), action];
  17823. const signatureResult = await runSignatureFactory(this._client.options.conversationSignatureFactory, params);
  17824. Object.assign(command.convMessage, keyRemap({
  17825. signature: 's',
  17826. timestamp: 't',
  17827. nonce: 'n'
  17828. }, signatureResult));
  17829. }
  17830. }
  17831. async _appendBlacklistSignature(command, action, clientIds) {
  17832. if (this._client.options.blacklistSignatureFactory) {
  17833. const params = [this.id, this._client.id, clientIds.sort(), action];
  17834. const signatureResult = await runSignatureFactory(this._client.options.blacklistSignatureFactory, params);
  17835. Object.assign(command.blacklistMessage, keyRemap({
  17836. signature: 's',
  17837. timestamp: 't',
  17838. nonce: 'n'
  17839. }, signatureResult));
  17840. }
  17841. }
  17842. /**
  17843. * 增加成员
  17844. * @param {String|String[]} clientIds 新增成员 client id
  17845. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  17846. */
  17847. async add(clientIds) {
  17848. this._debug('add', clientIds);
  17849. if (typeof clientIds === 'string') {
  17850. clientIds = [clientIds]; // eslint-disable-line no-param-reassign
  17851. }
  17852. const command = new GenericCommand({
  17853. op: 'add',
  17854. convMessage: new ConvCommand({
  17855. m: clientIds
  17856. })
  17857. });
  17858. await this._appendConversationSignature(command, 'invite', clientIds);
  17859. const {
  17860. convMessage,
  17861. convMessage: {
  17862. allowedPids
  17863. }
  17864. } = await this._send(command);
  17865. this._addMembers(allowedPids);
  17866. return createPartiallySuccess(convMessage);
  17867. }
  17868. /**
  17869. * 剔除成员
  17870. * @param {String|String[]} clientIds 成员 client id
  17871. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  17872. */
  17873. async remove(clientIds) {
  17874. this._debug('remove', clientIds);
  17875. if (typeof clientIds === 'string') {
  17876. clientIds = [clientIds]; // eslint-disable-line no-param-reassign
  17877. }
  17878. const command = new GenericCommand({
  17879. op: 'remove',
  17880. convMessage: new ConvCommand({
  17881. m: clientIds
  17882. })
  17883. });
  17884. await this._appendConversationSignature(command, 'kick', clientIds);
  17885. const {
  17886. convMessage,
  17887. convMessage: {
  17888. allowedPids
  17889. }
  17890. } = await this._send(command);
  17891. this._removeMembers(allowedPids);
  17892. return createPartiallySuccess(convMessage);
  17893. }
  17894. /**
  17895. * (当前用户)加入该对话
  17896. * @return {Promise.<this>} self
  17897. */
  17898. async join() {
  17899. this._debug('join');
  17900. return this.add(this._client.id).then(({
  17901. failures
  17902. }) => {
  17903. if (failures[0]) throw failures[0];
  17904. return this;
  17905. });
  17906. }
  17907. /**
  17908. * (当前用户)退出该对话
  17909. * @return {Promise.<this>} self
  17910. */
  17911. async quit() {
  17912. this._debug('quit');
  17913. return this.remove(this._client.id).then(({
  17914. failures
  17915. }) => {
  17916. if (failures[0]) throw failures[0];
  17917. return this;
  17918. });
  17919. }
  17920. /**
  17921. * 在该对话中禁言成员
  17922. * @param {String|String[]} clientIds 成员 client id
  17923. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  17924. */
  17925. async muteMembers(clientIds) {
  17926. this._debug('mute', clientIds);
  17927. clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
  17928. const command = new GenericCommand({
  17929. op: OpType.add_shutup,
  17930. convMessage: new ConvCommand({
  17931. m: clientIds
  17932. })
  17933. });
  17934. const {
  17935. convMessage
  17936. } = await this._send(command);
  17937. return createPartiallySuccess(convMessage);
  17938. }
  17939. /**
  17940. * 在该对话中解除成员禁言
  17941. * @param {String|String[]} clientIds 成员 client id
  17942. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  17943. */
  17944. async unmuteMembers(clientIds) {
  17945. this._debug('unmute', clientIds);
  17946. clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
  17947. const command = new GenericCommand({
  17948. op: OpType.remove_shutup,
  17949. convMessage: new ConvCommand({
  17950. m: clientIds
  17951. })
  17952. });
  17953. const {
  17954. convMessage
  17955. } = await this._send(command);
  17956. return createPartiallySuccess(convMessage);
  17957. }
  17958. /**
  17959. * 查询该对话禁言成员列表
  17960. * @param {Object} [options]
  17961. * @param {Number} [options.limit] 返回的成员数量,服务器默认值 10
  17962. * @param {String} [options.next] 从指定 next 开始查询,与 limit 一起使用可以完成翻页。
  17963. * @return {PagedResults.<string>} 查询结果。其中的 cureser 存在表示还有更多结果。
  17964. */
  17965. async queryMutedMembers({
  17966. limit,
  17967. next
  17968. } = {}) {
  17969. this._debug('query muted: limit %O, next: %O', limit, next);
  17970. const command = new GenericCommand({
  17971. op: OpType.query_shutup,
  17972. convMessage: new ConvCommand({
  17973. limit,
  17974. next
  17975. })
  17976. });
  17977. const {
  17978. convMessage: {
  17979. m,
  17980. next: newNext
  17981. }
  17982. } = await this._send(command);
  17983. return {
  17984. results: m,
  17985. next: newNext
  17986. };
  17987. }
  17988. /**
  17989. * 将用户加入该对话黑名单
  17990. * @param {String|String[]} clientIds 成员 client id
  17991. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  17992. */
  17993. async blockMembers(clientIds) {
  17994. this._debug('block', clientIds);
  17995. clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
  17996. const command = new GenericCommand({
  17997. cmd: 'blacklist',
  17998. op: OpType.block,
  17999. blacklistMessage: new BlacklistCommand({
  18000. srcCid: this.id,
  18001. toPids: clientIds
  18002. })
  18003. });
  18004. await this._appendBlacklistSignature(command, 'conversation-block-clients', clientIds);
  18005. const {
  18006. blacklistMessage
  18007. } = await this._send(command);
  18008. return createPartiallySuccess(blacklistMessage);
  18009. }
  18010. /**
  18011. * 将用户移出该对话黑名单
  18012. * @param {String|String[]} clientIds 成员 client id
  18013. * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
  18014. */
  18015. async unblockMembers(clientIds) {
  18016. this._debug('unblock', clientIds);
  18017. clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
  18018. const command = new GenericCommand({
  18019. cmd: 'blacklist',
  18020. op: OpType.unblock,
  18021. blacklistMessage: new BlacklistCommand({
  18022. srcCid: this.id,
  18023. toPids: clientIds
  18024. })
  18025. });
  18026. await this._appendBlacklistSignature(command, 'conversation-unblock-clients', clientIds);
  18027. const {
  18028. blacklistMessage
  18029. } = await this._send(command);
  18030. return createPartiallySuccess(blacklistMessage);
  18031. }
  18032. /**
  18033. * 查询该对话黑名单
  18034. * @param {Object} [options]
  18035. * @param {Number} [options.limit] 返回的成员数量,服务器默认值 10
  18036. * @param {String} [options.next] 从指定 next 开始查询,与 limit 一起使用可以完成翻页
  18037. * @return {PagedResults.<string>} 查询结果。其中的 cureser 存在表示还有更多结果。
  18038. */
  18039. async queryBlockedMembers({
  18040. limit,
  18041. next
  18042. } = {}) {
  18043. this._debug('query blocked: limit %O, next: %O', limit, next);
  18044. const command = new GenericCommand({
  18045. cmd: 'blacklist',
  18046. op: OpType.query,
  18047. blacklistMessage: new BlacklistCommand({
  18048. srcCid: this.id,
  18049. limit,
  18050. next
  18051. })
  18052. });
  18053. const {
  18054. blacklistMessage: {
  18055. blockedPids,
  18056. next: newNext
  18057. }
  18058. } = await this._send(command);
  18059. return {
  18060. results: blockedPids,
  18061. next: newNext
  18062. };
  18063. }
  18064. toFullJSON() {
  18065. const {
  18066. creator,
  18067. system,
  18068. transient,
  18069. createdAt,
  18070. updatedAt,
  18071. _attributes
  18072. } = this;
  18073. return { ...super.toFullJSON(),
  18074. creator,
  18075. system,
  18076. transient,
  18077. createdAt: getTime(createdAt),
  18078. updatedAt: getTime(updatedAt),
  18079. ..._attributes
  18080. };
  18081. }
  18082. toJSON() {
  18083. const {
  18084. creator,
  18085. system,
  18086. transient,
  18087. muted,
  18088. mutedMembers,
  18089. createdAt,
  18090. updatedAt,
  18091. _attributes
  18092. } = this;
  18093. return { ...super.toJSON(),
  18094. creator,
  18095. system,
  18096. transient,
  18097. muted,
  18098. mutedMembers,
  18099. createdAt,
  18100. updatedAt,
  18101. ..._attributes
  18102. };
  18103. }
  18104. }
  18105. /**
  18106. * 对话成员角色枚举
  18107. * @enum {String}
  18108. * @since 4.0.0
  18109. * @memberof module:leancloud-realtime
  18110. */
  18111. const ConversationMemberRole = {
  18112. /** 所有者 */
  18113. OWNER: 'Owner',
  18114. /** 管理员 */
  18115. MANAGER: 'Manager',
  18116. /** 成员 */
  18117. MEMBER: 'Member'
  18118. };
  18119. Object.freeze(ConversationMemberRole);
  18120. class ConversationMemberInfo {
  18121. /**
  18122. * 对话成员属性,保存了成员与某个对话相关的属性,对应 _ConversationMemberInfo 表
  18123. * @since 4.0.0
  18124. */
  18125. constructor({
  18126. conversation,
  18127. memberId,
  18128. role
  18129. }) {
  18130. if (!conversation) throw new Error('conversation requried');
  18131. if (!memberId) throw new Error('memberId requried');
  18132. Object.assign(internal(this), {
  18133. conversation,
  18134. memberId,
  18135. role
  18136. });
  18137. }
  18138. /**
  18139. * 对话 Id
  18140. * @type {String}
  18141. * @readonly
  18142. */
  18143. get conversationId() {
  18144. return internal(this).conversation.id;
  18145. }
  18146. /**
  18147. * 成员 Id
  18148. * @type {String}
  18149. * @readonly
  18150. */
  18151. get memberId() {
  18152. return internal(this).memberId;
  18153. }
  18154. /**
  18155. * 角色
  18156. * @type {module:leancloud-realtime.ConversationMemberRole | String}
  18157. * @readonly
  18158. */
  18159. get role() {
  18160. if (this.isOwner) return ConversationMemberRole.OWNER;
  18161. return internal(this).role;
  18162. }
  18163. /**
  18164. * 是否是管理员
  18165. * @type {Boolean}
  18166. * @readonly
  18167. */
  18168. get isOwner() {
  18169. return this.memberId === internal(this).conversation.creator;
  18170. }
  18171. toJSON() {
  18172. const {
  18173. conversationId,
  18174. memberId,
  18175. role,
  18176. isOwner
  18177. } = this;
  18178. return {
  18179. conversationId,
  18180. memberId,
  18181. role,
  18182. isOwner
  18183. };
  18184. }
  18185. }
  18186. /**
  18187. * 普通对话
  18188. *
  18189. * 无法直接实例化,请使用 {@link IMClient#createConversation} 创建新的普通对话。
  18190. * @extends PersistentConversation
  18191. * @public
  18192. */
  18193. class Conversation extends PersistentConversation {
  18194. _addMembers(members) {
  18195. super._addMembers(members);
  18196. this.members = union(this.members, members);
  18197. const {
  18198. memberInfoMap
  18199. } = internal(this);
  18200. if (!memberInfoMap) return;
  18201. members.forEach(memberId => {
  18202. memberInfoMap[memberId] = memberInfoMap[memberId] || new ConversationMemberInfo({
  18203. conversation: this,
  18204. memberId,
  18205. role: ConversationMemberRole.MEMBER
  18206. });
  18207. });
  18208. }
  18209. _removeMembers(members) {
  18210. super._removeMembers(members);
  18211. this.members = difference(this.members, members);
  18212. const {
  18213. memberInfoMap
  18214. } = internal(this);
  18215. if (!memberInfoMap) return;
  18216. members.forEach(memberId => {
  18217. delete memberInfoMap[memberId];
  18218. });
  18219. }
  18220. async _fetchAllMemberInfo() {
  18221. const response = await this._client._requestWithSessionToken({
  18222. method: 'GET',
  18223. path: '/classes/_ConversationMemberInfo',
  18224. query: {
  18225. where: {
  18226. cid: this.id
  18227. }
  18228. }
  18229. });
  18230. const memberInfos = response.results.map(info => new ConversationMemberInfo({
  18231. conversation: this,
  18232. memberId: info.clientId,
  18233. role: info.role
  18234. }));
  18235. const memberInfoMap = {};
  18236. memberInfos.forEach(memberInfo => {
  18237. memberInfoMap[memberInfo.memberId] = memberInfo;
  18238. });
  18239. this.members.forEach(memberId => {
  18240. memberInfoMap[memberId] = memberInfoMap[memberId] || new ConversationMemberInfo({
  18241. conversation: this,
  18242. memberId,
  18243. role: ConversationMemberRole.MEMBER
  18244. });
  18245. });
  18246. internal(this).memberInfoMap = memberInfoMap;
  18247. return memberInfoMap;
  18248. }
  18249. /**
  18250. * 获取所有成员的对话属性
  18251. * @since 4.0.0
  18252. * @return {Promise.<ConversationMemberInfo[]>} 所有成员的对话属性列表
  18253. */
  18254. async getAllMemberInfo({
  18255. noCache = false
  18256. } = {}) {
  18257. let {
  18258. memberInfoMap
  18259. } = internal(this);
  18260. if (!memberInfoMap || noCache) {
  18261. memberInfoMap = await this._fetchAllMemberInfo();
  18262. }
  18263. return this.members.map(memberId => memberInfoMap[memberId]);
  18264. }
  18265. /**
  18266. * 获取指定成员的对话属性
  18267. * @since 4.0.0
  18268. * @param {String} memberId 成员 Id
  18269. * @return {Promise.<ConversationMemberInfo>} 指定成员的对话属性
  18270. */
  18271. async getMemberInfo(memberId) {
  18272. if (this.members.indexOf(memberId) === -1) throw new Error(`${memberId} is not the mumber of conversation[${this.id}]`);
  18273. const {
  18274. memberInfoMap
  18275. } = internal(this);
  18276. if (!(memberInfoMap && memberInfoMap[memberId])) await this.getAllMemberInfo();
  18277. return internal(this).memberInfoMap[memberId];
  18278. }
  18279. /**
  18280. * 更新指定用户的角色
  18281. * @since 4.0.0
  18282. * @param {String} memberId 成员 Id
  18283. * @param {module:leancloud-realtime.ConversationMemberRole | String} role 角色
  18284. * @return {Promise.<this>} self
  18285. */
  18286. async updateMemberRole(memberId, role) {
  18287. this._debug('update member role');
  18288. if (role === ConversationMemberRole.OWNER) throw createError({
  18289. code: ErrorCode.OWNER_PROMOTION_NOT_ALLOWED
  18290. });
  18291. await this._send(new GenericCommand({
  18292. op: OpType.member_info_update,
  18293. convMessage: new ConvCommand({
  18294. targetClientId: memberId,
  18295. info: new ConvMemberInfo({
  18296. pid: memberId,
  18297. role
  18298. })
  18299. })
  18300. }));
  18301. const {
  18302. memberInfos
  18303. } = internal(this);
  18304. if (memberInfos && memberInfos[memberId]) {
  18305. internal(memberInfos[memberId]).role = role;
  18306. }
  18307. return this;
  18308. }
  18309. }
  18310. /**
  18311. * 聊天室。
  18312. *
  18313. * 无法直接实例化,请使用 {@link IMClient#createChatRoom} 创建新的聊天室。
  18314. * @since 4.0.0
  18315. * @extends PersistentConversation
  18316. * @public
  18317. */
  18318. class ChatRoom extends PersistentConversation {}
  18319. /**
  18320. * 服务号。
  18321. *
  18322. * 服务号不支持在客户端创建。
  18323. * @since 4.0.0
  18324. * @extends PersistentConversation
  18325. * @public
  18326. */
  18327. class ServiceConversation extends PersistentConversation {
  18328. /**
  18329. * 订阅该服务号
  18330. * @return {Promise.<this>} self
  18331. */
  18332. async subscribe() {
  18333. return this.join();
  18334. }
  18335. /**
  18336. * 退订该服务号
  18337. * @return {Promise.<this>} self
  18338. */
  18339. async unsubscribe() {
  18340. return this.quit();
  18341. }
  18342. }
  18343. const transformNotFoundError = error => error.code === ErrorCode.CONVERSATION_NOT_FOUND ? createError({
  18344. code: ErrorCode.TEMPORARY_CONVERSATION_EXPIRED
  18345. }) : error;
  18346. /**
  18347. * 临时对话
  18348. * @since 4.0.0
  18349. * @extends ConversationBase
  18350. * @public
  18351. */
  18352. class TemporaryConversation extends ConversationBase {
  18353. /**
  18354. * 无法直接实例化,请使用 {@link IMClient#createTemporaryConversation} 创建新的临时对话。
  18355. */
  18356. constructor(data, {
  18357. expiredAt
  18358. }, client) {
  18359. super({ ...data,
  18360. expiredAt
  18361. }, client);
  18362. }
  18363. /**
  18364. * 对话失效时间
  18365. * @type {Date}
  18366. */
  18367. set expiredAt(value) {
  18368. this._expiredAt = decodeDate(value);
  18369. }
  18370. get expiredAt() {
  18371. return this._expiredAt;
  18372. }
  18373. /**
  18374. * 对话是否已失效
  18375. * @type {Boolean}
  18376. */
  18377. get expired() {
  18378. return this.expiredAt < new Date();
  18379. }
  18380. async _send(...args) {
  18381. if (this.expired) throw createError({
  18382. code: ErrorCode.TEMPORARY_CONVERSATION_EXPIRED
  18383. });
  18384. try {
  18385. return await super._send(...args);
  18386. } catch (error) {
  18387. throw transformNotFoundError(error);
  18388. }
  18389. }
  18390. async send(...args) {
  18391. try {
  18392. return await super.send(...args);
  18393. } catch (error) {
  18394. throw transformNotFoundError(error);
  18395. }
  18396. }
  18397. toFullJSON() {
  18398. const {
  18399. expiredAt
  18400. } = this;
  18401. return { ...super.toFullJSON(),
  18402. expiredAt: getTime(expiredAt)
  18403. };
  18404. }
  18405. toJSON() {
  18406. const {
  18407. expiredAt,
  18408. expired
  18409. } = this;
  18410. return { ...super.toJSON(),
  18411. expiredAt,
  18412. expired
  18413. };
  18414. }
  18415. }
  18416. const debug$9 = browser('LC:ConversationQuery');
  18417. class ConversationQuery {
  18418. static _encode(value) {
  18419. if (value instanceof Date) {
  18420. return {
  18421. __type: 'Date',
  18422. iso: value.toJSON()
  18423. };
  18424. }
  18425. if (value instanceof RegExp) {
  18426. return value.source;
  18427. }
  18428. return value;
  18429. }
  18430. static _quote(s) {
  18431. return `\\Q${s.replace('\\E', '\\E\\\\E\\Q')}\\E`;
  18432. }
  18433. static _calculateFlag(options) {
  18434. return ['withLastMessagesRefreshed', 'compact'].reduce( // eslint-disable-next-line no-bitwise
  18435. (prev, key) => (prev << 1) + Boolean(options[key]), 0);
  18436. }
  18437. /**
  18438. * 构造一个用 AND 连接所有查询的 ConversationQuery
  18439. * @param {...ConversationQuery} queries
  18440. * @return {ConversationQuery}
  18441. */
  18442. static and(...queries) {
  18443. if (queries.length < 2) {
  18444. throw new Error('The queries must contain at least two elements');
  18445. }
  18446. if (!queries.every(q => q instanceof ConversationQuery)) {
  18447. throw new Error('The element of queries must be an instance of ConversationQuery');
  18448. }
  18449. const combined = new ConversationQuery(queries[0]._client);
  18450. combined._where.$and = queries.map(q => q._where);
  18451. return combined;
  18452. }
  18453. /**
  18454. * 构造一个用 OR 连接所有查询的 ConversationQuery
  18455. * @param {...ConversationQuery} queries
  18456. * @return {ConversationQuery}
  18457. */
  18458. static or(...queries) {
  18459. const combined = ConversationQuery.and(...queries);
  18460. combined._where.$or = combined._where.$and;
  18461. delete combined._where.$and;
  18462. return combined;
  18463. }
  18464. /**
  18465. * Create a ConversationQuery
  18466. * @param {IMClient} client
  18467. */
  18468. constructor(client) {
  18469. this._client = client;
  18470. this._where = {};
  18471. this._extraOptions = {};
  18472. }
  18473. _addCondition(key, condition, value) {
  18474. // Check if we already have a condition
  18475. if (!this._where[key]) {
  18476. this._where[key] = {};
  18477. }
  18478. this._where[key][condition] = this.constructor._encode(value);
  18479. return this;
  18480. }
  18481. toJSON() {
  18482. const json = {
  18483. where: this._where,
  18484. flag: this.constructor._calculateFlag(this._extraOptions)
  18485. };
  18486. if (typeof this._skip !== 'undefined') json.skip = this._skip;
  18487. if (typeof this._limit !== 'undefined') json.limit = this._limit;
  18488. if (typeof this._order !== 'undefined') json.sort = this._order;
  18489. debug$9(json);
  18490. return json;
  18491. }
  18492. /**
  18493. * 增加查询条件,指定聊天室的组员包含某些成员即可返回
  18494. * @param {string[]} peerIds - 成员 ID 列表
  18495. * @return {ConversationQuery} self
  18496. */
  18497. containsMembers(peerIds) {
  18498. return this.containsAll('m', peerIds);
  18499. }
  18500. /**
  18501. * 增加查询条件,指定聊天室的组员条件满足条件的才返回
  18502. *
  18503. * @param {string[]} - 成员 ID 列表
  18504. * @param {Boolean} includeSelf - 是否包含自己
  18505. * @return {ConversationQuery} self
  18506. */
  18507. withMembers(peerIds, includeSelf) {
  18508. const peerIdsSet = new Set(peerIds);
  18509. if (includeSelf) {
  18510. peerIdsSet.add(this._client.id);
  18511. }
  18512. this.sizeEqualTo('m', peerIdsSet.size);
  18513. return this.containsMembers(Array.from(peerIdsSet));
  18514. }
  18515. /**
  18516. * 增加查询条件,当 conversation 的属性中对应的字段满足等于条件时即可返回
  18517. *
  18518. * @param {string} key
  18519. * @param value
  18520. * @return {ConversationQuery} self
  18521. */
  18522. equalTo(key, value) {
  18523. this._where[key] = this.constructor._encode(value);
  18524. return this;
  18525. }
  18526. /**
  18527. * 增加查询条件,当 conversation 的属性中对应的字段满足小于条件时即可返回
  18528. * @param {string} key
  18529. * @param value
  18530. * @return {ConversationQuery} self
  18531. */
  18532. lessThan(key, value) {
  18533. return this._addCondition(key, '$lt', value);
  18534. }
  18535. /**
  18536. * 增加查询条件,当 conversation 的属性中对应的字段满足小于等于条件时即可返回
  18537. * @param {string} key
  18538. * @param value
  18539. * @return {ConversationQuery} self
  18540. */
  18541. lessThanOrEqualTo(key, value) {
  18542. return this._addCondition(key, '$lte', value);
  18543. }
  18544. /**
  18545. * 增加查询条件,当 conversation 的属性中对应的字段满足大于条件时即可返回
  18546. *
  18547. * @param {string} key
  18548. * @param value
  18549. * @return {ConversationQuery} self
  18550. */
  18551. greaterThan(key, value) {
  18552. return this._addCondition(key, '$gt', value);
  18553. }
  18554. /**
  18555. * 增加查询条件,当 conversation 的属性中对应的字段满足大于等于条件时即可返回
  18556. *
  18557. * @param {string} key
  18558. * @param value
  18559. * @return {ConversationQuery} self
  18560. */
  18561. greaterThanOrEqualTo(key, value) {
  18562. return this._addCondition(key, '$gte', value);
  18563. }
  18564. /**
  18565. * 增加查询条件,当 conversation 的属性中对应的字段满足不等于条件时即可返回
  18566. *
  18567. * @param {string} key
  18568. * @param value
  18569. * @return {ConversationQuery} self
  18570. */
  18571. notEqualTo(key, value) {
  18572. return this._addCondition(key, '$ne', value);
  18573. }
  18574. /**
  18575. * 增加查询条件,当 conversation 存在指定的字段时即可返回
  18576. *
  18577. * @since 3.5.0
  18578. * @param {string} key
  18579. * @return {ConversationQuery} self
  18580. */
  18581. exists(key) {
  18582. return this._addCondition(key, '$exists', true);
  18583. }
  18584. /**
  18585. * 增加查询条件,当 conversation 不存在指定的字段时即可返回
  18586. *
  18587. * @since 3.5.0
  18588. * @param {string} key
  18589. * @return {ConversationQuery} self
  18590. */
  18591. doesNotExist(key) {
  18592. return this._addCondition(key, '$exists', false);
  18593. }
  18594. /**
  18595. * 增加查询条件,当 conversation 的属性中对应的字段对应的值包含在指定值中时即可返回
  18596. *
  18597. * @param {string} key
  18598. * @param values
  18599. * @return {ConversationQuery} self
  18600. */
  18601. containedIn(key, values) {
  18602. return this._addCondition(key, '$in', values);
  18603. }
  18604. /**
  18605. * 增加查询条件,当 conversation 的属性中对应的字段对应的值不包含在指定值中时即可返回
  18606. *
  18607. * @param {string} key
  18608. * @param values
  18609. * @return {ConversationQuery} self
  18610. */
  18611. notContainsIn(key, values) {
  18612. return this._addCondition(key, '$nin', values);
  18613. }
  18614. /**
  18615. * 增加查询条件,当conversation的属性中对应的字段中的元素包含所有的值才可返回
  18616. *
  18617. * @param {string} key
  18618. * @param values
  18619. * @return {ConversationQuery} self
  18620. */
  18621. containsAll(key, values) {
  18622. return this._addCondition(key, '$all', values);
  18623. }
  18624. /**
  18625. * 增加查询条件,当 conversation 的属性中对应的字段对应的值包含此字符串即可返回
  18626. *
  18627. * @param {string} key
  18628. * @param {string} subString
  18629. * @return {ConversationQuery} self
  18630. */
  18631. contains(key, subString) {
  18632. return this._addCondition(key, '$regex', ConversationQuery._quote(subString));
  18633. }
  18634. /**
  18635. * 增加查询条件,当 conversation 的属性中对应的字段对应的值以此字符串起始即可返回
  18636. *
  18637. * @param {string} key
  18638. * @param {string} prefix
  18639. * @return {ConversationQuery} self
  18640. */
  18641. startsWith(key, prefix) {
  18642. return this._addCondition(key, '$regex', `^${ConversationQuery._quote(prefix)}`);
  18643. }
  18644. /**
  18645. * 增加查询条件,当 conversation 的属性中对应的字段对应的值以此字符串结束即可返回
  18646. *
  18647. * @param {string} key
  18648. * @param {string} suffix
  18649. * @return {ConversationQuery} self
  18650. */
  18651. endsWith(key, suffix) {
  18652. return this._addCondition(key, '$regex', `${ConversationQuery._quote(suffix)}$`);
  18653. }
  18654. /**
  18655. * 增加查询条件,当 conversation 的属性中对应的字段对应的值满足提供的正则表达式即可返回
  18656. *
  18657. * @param {string} key
  18658. * @param {RegExp} regex
  18659. * @return {ConversationQuery} self
  18660. */
  18661. matches(key, regex) {
  18662. this._addCondition(key, '$regex', regex); // Javascript regex options support mig as inline options but store them
  18663. // as properties of the object. We support mi & should migrate them to
  18664. // modifiers
  18665. let _modifiers = '';
  18666. if (regex.ignoreCase) {
  18667. _modifiers += 'i';
  18668. }
  18669. if (regex.multiline) {
  18670. _modifiers += 'm';
  18671. }
  18672. if (_modifiers && _modifiers.length) {
  18673. this._addCondition(key, '$options', _modifiers);
  18674. }
  18675. return this;
  18676. }
  18677. /**
  18678. * 添加查询约束条件,查找 key 类型是数组,该数组的长度匹配提供的数值
  18679. *
  18680. * @param {string} key
  18681. * @param {Number} length
  18682. * @return {ConversationQuery} self
  18683. */
  18684. sizeEqualTo(key, length) {
  18685. return this._addCondition(key, '$size', length);
  18686. }
  18687. /**
  18688. * 设置返回集合的大小上限
  18689. *
  18690. * @param {Number} limit - 上限
  18691. * @return {ConversationQuery} self
  18692. */
  18693. limit(limit) {
  18694. this._limit = limit;
  18695. return this;
  18696. }
  18697. /**
  18698. * 设置返回集合的起始位置,一般用于分页
  18699. *
  18700. * @param {Number} skip - 起始位置跳过几个对象
  18701. * @return {ConversationQuery} self
  18702. */
  18703. skip(skip) {
  18704. this._skip = skip;
  18705. return this;
  18706. }
  18707. /**
  18708. * 设置返回集合按照指定key进行增序排列
  18709. *
  18710. * @param {string} key
  18711. * @return {ConversationQuery} self
  18712. */
  18713. ascending(key) {
  18714. this._order = key;
  18715. return this;
  18716. }
  18717. /**
  18718. * 设置返回集合按照指定key进行增序排列,如果已设置其他排序,原排序的优先级较高
  18719. *
  18720. * @param {string} key
  18721. * @return {ConversationQuery} self
  18722. */
  18723. addAscending(key) {
  18724. if (this._order) {
  18725. this._order += `,${key}`;
  18726. } else {
  18727. this._order = key;
  18728. }
  18729. return this;
  18730. }
  18731. /**
  18732. * 设置返回集合按照指定 key 进行降序排列
  18733. *
  18734. * @param {string} key
  18735. * @return {ConversationQuery} self
  18736. */
  18737. descending(key) {
  18738. this._order = `-${key}`;
  18739. return this;
  18740. }
  18741. /**
  18742. * 设置返回集合按照指定 key 进行降序排列,如果已设置其他排序,原排序的优先级较高
  18743. *
  18744. * @param {string} key
  18745. * @return {ConversationQuery} self
  18746. */
  18747. addDescending(key) {
  18748. if (this._order) {
  18749. this._order += `,-${key}`;
  18750. } else {
  18751. this._order = `-${key}`;
  18752. }
  18753. return this;
  18754. }
  18755. /**
  18756. * 设置返回的 conversations 刷新最后一条消息
  18757. * @param {Boolean} [enabled=true]
  18758. * @return {ConversationQuery} self
  18759. */
  18760. withLastMessagesRefreshed(enabled = true) {
  18761. this._extraOptions.withLastMessagesRefreshed = enabled;
  18762. return this;
  18763. }
  18764. /**
  18765. * 设置返回的 conversations 为精简模式,即不含成员列表
  18766. * @param {Boolean} [enabled=true]
  18767. * @return {ConversationQuery} self
  18768. */
  18769. compact(enabled = true) {
  18770. this._extraOptions.compact = enabled;
  18771. return this;
  18772. }
  18773. /**
  18774. * 执行查询
  18775. * @return {Promise.<ConversationBase[]>}
  18776. */
  18777. async find() {
  18778. return this._client._executeQuery(this);
  18779. }
  18780. /**
  18781. * 返回符合条件的第一个结果
  18782. * @return {Promise.<ConversationBase>}
  18783. */
  18784. async first() {
  18785. return (await this.limit(1).find())[0];
  18786. }
  18787. }
  18788. const debug$a = browser('LC:SessionManager');
  18789. class SessionManager {
  18790. constructor({
  18791. refresh,
  18792. onBeforeGetSessionToken
  18793. } = {}) {
  18794. this.refresh = refresh;
  18795. this._onBeforeGetSessionToken = onBeforeGetSessionToken;
  18796. this.setSessionToken(null, 0);
  18797. }
  18798. setSessionToken(token, ttl) {
  18799. debug$a('set session token', token, ttl);
  18800. const sessionToken = new Expirable(token, ttl * 1000);
  18801. this._sessionToken = sessionToken;
  18802. delete this._pendingSessionTokenPromise;
  18803. return sessionToken;
  18804. }
  18805. async setSessionTokenAsync(promise) {
  18806. const currentSessionToken = this._sessionToken;
  18807. this._pendingSessionTokenPromise = promise.catch(error => {
  18808. // revert, otherwise the following getSessionToken calls
  18809. // will all be rejected
  18810. this._sessionToken = currentSessionToken;
  18811. throw error;
  18812. });
  18813. return this.setSessionToken(...(await this._pendingSessionTokenPromise));
  18814. }
  18815. async getSessionToken({
  18816. autoRefresh = true
  18817. } = {}) {
  18818. debug$a('get session token');
  18819. if (this._onBeforeGetSessionToken) {
  18820. this._onBeforeGetSessionToken(this);
  18821. }
  18822. const {
  18823. value,
  18824. originalValue
  18825. } = this._sessionToken || (await this._pendingSessionTokenPromise);
  18826. if (value === Expirable.EXPIRED && autoRefresh && this.refresh) {
  18827. debug$a('refresh expired session token');
  18828. const {
  18829. value: newValue
  18830. } = await this.setSessionTokenAsync(this.refresh(this, originalValue));
  18831. debug$a('session token', newValue);
  18832. return newValue;
  18833. }
  18834. debug$a('session token', value);
  18835. return value;
  18836. }
  18837. revoke() {
  18838. if (this._sessionToken) this._sessionToken.expiredAt = -1;
  18839. }
  18840. }
  18841. var _dec$2, _dec2, _class$3;
  18842. const debug$b = browser('LC:IMClient');
  18843. const {
  18844. INVITED: INVITED$1,
  18845. KICKED: KICKED$1,
  18846. MEMBERS_JOINED: MEMBERS_JOINED$1,
  18847. MEMBERS_LEFT: MEMBERS_LEFT$1,
  18848. MEMBER_INFO_UPDATED: MEMBER_INFO_UPDATED$1,
  18849. BLOCKED: BLOCKED$1,
  18850. UNBLOCKED: UNBLOCKED$1,
  18851. MEMBERS_BLOCKED: MEMBERS_BLOCKED$1,
  18852. MEMBERS_UNBLOCKED: MEMBERS_UNBLOCKED$1,
  18853. MUTED: MUTED$1,
  18854. UNMUTED: UNMUTED$1,
  18855. MEMBERS_MUTED: MEMBERS_MUTED$1,
  18856. MEMBERS_UNMUTED: MEMBERS_UNMUTED$1,
  18857. MESSAGE: MESSAGE$2,
  18858. UNREAD_MESSAGES_COUNT_UPDATE: UNREAD_MESSAGES_COUNT_UPDATE$1,
  18859. CLOSE: CLOSE$1,
  18860. CONFLICT: CONFLICT$1,
  18861. UNHANDLED_MESSAGE: UNHANDLED_MESSAGE$1,
  18862. CONVERSATION_INFO_UPDATED: CONVERSATION_INFO_UPDATED$1,
  18863. MESSAGE_RECALL: MESSAGE_RECALL$1,
  18864. MESSAGE_UPDATE: MESSAGE_UPDATE$1,
  18865. INFO_UPDATED: INFO_UPDATED$1
  18866. } = IMEvent;
  18867. const isTemporaryConversatrionId = id => /^_tmp:/.test(id);
  18868. /**
  18869. * 1 patch-msg
  18870. * 1 temp-conv-msg
  18871. * 0 auto-bind-deviceid-and-installation
  18872. * 1 transient-msg-ack
  18873. * 1 keep-notification
  18874. * 1 partial-failed-msg
  18875. * 0 group-chat-rcp
  18876. * 1 omit-peer-id
  18877. * @ignore
  18878. */
  18879. const configBitmap = 0b10111011;
  18880. let IMClient = (_dec$2 = throttle(1000), _dec2 = throttle(1000), (_class$3 = class IMClient extends eventemitter3 {
  18881. /**
  18882. * 无法直接实例化,请使用 {@link Realtime#createIMClient} 创建新的 IMClient。
  18883. *
  18884. * @extends EventEmitter
  18885. */
  18886. constructor(id, options = {}, props) {
  18887. if (!(id === undefined || typeof id === 'string')) {
  18888. throw new TypeError(`Client id [${id}] is not a String`);
  18889. }
  18890. super();
  18891. Object.assign(this, {
  18892. /**
  18893. * @var id {String} 客户端 id
  18894. * @memberof IMClient#
  18895. */
  18896. id,
  18897. options
  18898. }, props);
  18899. if (!this._messageParser) {
  18900. throw new Error('IMClient must be initialized with a MessageParser');
  18901. }
  18902. this._conversationCache = new Cache(`client:${this.id}`);
  18903. this._ackMessageBuffer = {};
  18904. internal(this).lastPatchTime = Date.now();
  18905. internal(this).lastNotificationTime = undefined;
  18906. internal(this)._eventemitter = new eventemitter3();
  18907. if (debug$b.enabled) {
  18908. values_1(IMEvent).forEach(event => this.on(event, (...payload) => this._debug(`${event} event emitted. %o`, payload)));
  18909. } // onIMClientCreate hook
  18910. applyDecorators(this._plugins.onIMClientCreate, this);
  18911. }
  18912. _debug(...params) {
  18913. debug$b(...params, `[${this.id}]`);
  18914. }
  18915. /**
  18916. * @override
  18917. * @private
  18918. */
  18919. async _dispatchCommand(command) {
  18920. this._debug(trim(command), 'received');
  18921. if (command.serverTs && command.notificationType === 1) {
  18922. internal(this).lastNotificationTime = getTime(decodeDate(command.serverTs));
  18923. }
  18924. switch (command.cmd) {
  18925. case CommandType.conv:
  18926. return this._dispatchConvMessage(command);
  18927. case CommandType.direct:
  18928. return this._dispatchDirectMessage(command);
  18929. case CommandType.session:
  18930. return this._dispatchSessionMessage(command);
  18931. case CommandType.unread:
  18932. return this._dispatchUnreadMessage(command);
  18933. case CommandType.rcp:
  18934. return this._dispatchRcpMessage(command);
  18935. case CommandType.patch:
  18936. return this._dispatchPatchMessage(command);
  18937. default:
  18938. return this.emit(UNHANDLED_MESSAGE$1, command);
  18939. }
  18940. }
  18941. async _dispatchSessionMessage(message) {
  18942. const {
  18943. sessionMessage: {
  18944. code,
  18945. reason
  18946. }
  18947. } = message;
  18948. switch (message.op) {
  18949. case OpType.closed:
  18950. {
  18951. internal(this)._eventemitter.emit('close');
  18952. if (code === ErrorCode.SESSION_CONFLICT) {
  18953. /**
  18954. * 用户在其他客户端登录,当前客户端被服务端强行下线。详见文档「单点登录」章节。
  18955. * @event IMClient#CONFLICT
  18956. * @param {Object} payload
  18957. * @param {string} payload.reason 原因
  18958. */
  18959. return this.emit(CONFLICT$1, {
  18960. reason
  18961. });
  18962. }
  18963. /**
  18964. * 当前客户端被服务端强行下线
  18965. * @event IMClient#CLOSE
  18966. * @param {Object} payload
  18967. * @param {Number} payload.code 错误码
  18968. * @param {String} payload.reason 原因
  18969. */
  18970. return this.emit(CLOSE$1, {
  18971. code,
  18972. reason
  18973. });
  18974. }
  18975. default:
  18976. this.emit(UNHANDLED_MESSAGE$1, message);
  18977. throw new Error('Unrecognized session command');
  18978. }
  18979. }
  18980. _dispatchUnreadMessage({
  18981. unreadMessage: {
  18982. convs,
  18983. notifTime
  18984. }
  18985. }) {
  18986. internal(this).lastUnreadNotifTime = notifTime; // ensure all converstions are cached
  18987. return this.getConversations(convs.map(conv => conv.cid)).then(() => // update conversations data
  18988. Promise.all(convs.map(({
  18989. cid,
  18990. unread,
  18991. mid,
  18992. timestamp: ts,
  18993. from,
  18994. data,
  18995. binaryMsg,
  18996. patchTimestamp,
  18997. mentioned
  18998. }) => {
  18999. const conversation = this._conversationCache.get(cid); // deleted conversation
  19000. if (!conversation) return null;
  19001. let timestamp;
  19002. if (ts) {
  19003. timestamp = decodeDate(ts);
  19004. conversation.lastMessageAt = timestamp; // eslint-disable-line no-param-reassign
  19005. }
  19006. return (mid ? this._messageParser.parse(binaryMsg || data).then(message => {
  19007. const messageProps = {
  19008. id: mid,
  19009. cid,
  19010. timestamp,
  19011. updatedAt: patchTimestamp,
  19012. from
  19013. };
  19014. Object.assign(message, messageProps);
  19015. conversation.lastMessage = message; // eslint-disable-line no-param-reassign
  19016. }) : Promise.resolve()).then(() => {
  19017. conversation._setUnreadMessagesMentioned(mentioned);
  19018. const countNotUpdated = unread === internal(conversation).unreadMessagesCount;
  19019. if (countNotUpdated) return null; // to be filtered
  19020. // manipulate internal property directly to skip unreadmessagescountupdate event
  19021. internal(conversation).unreadMessagesCount = unread;
  19022. return conversation;
  19023. }); // filter conversations without unread count update
  19024. })).then(conversations => conversations.filter(conversation => conversation))).then(conversations => {
  19025. if (conversations.length) {
  19026. /**
  19027. * 未读消息数目更新
  19028. * @event IMClient#UNREAD_MESSAGES_COUNT_UPDATE
  19029. * @since 3.4.0
  19030. * @param {Conversation[]} conversations 未读消息数目有更新的对话列表
  19031. */
  19032. this.emit(UNREAD_MESSAGES_COUNT_UPDATE$1, conversations);
  19033. }
  19034. });
  19035. }
  19036. async _dispatchRcpMessage(message) {
  19037. const {
  19038. rcpMessage,
  19039. rcpMessage: {
  19040. read
  19041. }
  19042. } = message;
  19043. const conversationId = rcpMessage.cid;
  19044. const messageId = rcpMessage.id;
  19045. const timestamp = decodeDate(rcpMessage.t);
  19046. const conversation = this._conversationCache.get(conversationId); // conversation not cached means the client does not send the message
  19047. // during this session
  19048. if (!conversation) return;
  19049. conversation._handleReceipt({
  19050. messageId,
  19051. timestamp,
  19052. read
  19053. });
  19054. }
  19055. _dispatchPatchMessage({
  19056. patchMessage: {
  19057. patches
  19058. }
  19059. }) {
  19060. // ensure all converstions are cached
  19061. return this.getConversations(patches.map(patch => patch.cid)).then(() => Promise.all(patches.map(({
  19062. cid,
  19063. mid,
  19064. timestamp,
  19065. recall,
  19066. data,
  19067. patchTimestamp,
  19068. from,
  19069. binaryMsg,
  19070. mentionAll,
  19071. mentionPids,
  19072. patchCode,
  19073. patchReason
  19074. }) => {
  19075. const conversation = this._conversationCache.get(cid); // deleted conversation
  19076. if (!conversation) return null;
  19077. return this._messageParser.parse(binaryMsg || data).then(message => {
  19078. const patchTime = getTime(decodeDate(patchTimestamp));
  19079. const messageProps = {
  19080. id: mid,
  19081. cid,
  19082. timestamp,
  19083. updatedAt: patchTime,
  19084. from,
  19085. mentionList: mentionPids,
  19086. mentionedAll: mentionAll
  19087. };
  19088. Object.assign(message, messageProps);
  19089. message._setStatus(MessageStatus.SENT);
  19090. message._updateMentioned(this.id);
  19091. if (internal(this).lastPatchTime < patchTime) {
  19092. internal(this).lastPatchTime = patchTime;
  19093. } // update conversation lastMessage
  19094. if (conversation.lastMessage && conversation.lastMessage.id === mid) {
  19095. conversation.lastMessage = message; // eslint-disable-line no-param-reassign
  19096. }
  19097. let reason;
  19098. if (patchCode) {
  19099. reason = {
  19100. code: patchCode.toNumber(),
  19101. detail: patchReason
  19102. };
  19103. }
  19104. if (recall) {
  19105. /**
  19106. * 消息被撤回
  19107. * @event IMClient#MESSAGE_RECALL
  19108. * @param {AVMessage} message 被撤回的消息
  19109. * @param {ConversationBase} conversation 消息所在的会话
  19110. * @param {PatchReason} [reason] 撤回的原因,不存在代表是发送者主动撤回
  19111. */
  19112. this.emit(MESSAGE_RECALL$1, message, conversation, reason);
  19113. /**
  19114. * 消息被撤回
  19115. * @event ConversationBase#MESSAGE_RECALL
  19116. * @param {AVMessage} message 被撤回的消息
  19117. * @param {PatchReason} [reason] 撤回的原因,不存在代表是发送者主动撤回
  19118. */
  19119. conversation.emit(MESSAGE_RECALL$1, message, reason);
  19120. } else {
  19121. /**
  19122. * 消息被修改
  19123. * @event IMClient#MESSAGE_UPDATE
  19124. * @param {AVMessage} message 被修改的消息
  19125. * @param {ConversationBase} conversation 消息所在的会话
  19126. * @param {PatchReason} [reason] 修改的原因,不存在代表是发送者主动修改
  19127. */
  19128. this.emit(MESSAGE_UPDATE$1, message, conversation, reason);
  19129. /**
  19130. * 消息被修改
  19131. * @event ConversationBase#MESSAGE_UPDATE
  19132. * @param {AVMessage} message 被修改的消息
  19133. * @param {PatchReason} [reason] 修改的原因,不存在代表是发送者主动修改
  19134. */
  19135. conversation.emit(MESSAGE_UPDATE$1, message, reason);
  19136. }
  19137. });
  19138. })));
  19139. }
  19140. async _dispatchConvMessage(message) {
  19141. const {
  19142. convMessage,
  19143. convMessage: {
  19144. initBy,
  19145. m,
  19146. info,
  19147. attr
  19148. }
  19149. } = message;
  19150. const conversation = await this.getConversation(convMessage.cid);
  19151. switch (message.op) {
  19152. case OpType.joined:
  19153. {
  19154. conversation._addMembers([this.id]);
  19155. const payload = {
  19156. invitedBy: initBy
  19157. };
  19158. /**
  19159. * 当前用户被添加至某个对话
  19160. * @event IMClient#INVITED
  19161. * @param {Object} payload
  19162. * @param {String} payload.invitedBy 邀请者 id
  19163. * @param {ConversationBase} conversation
  19164. */
  19165. this.emit(INVITED$1, payload, conversation);
  19166. /**
  19167. * 当前用户被添加至当前对话
  19168. * @event ConversationBase#INVITED
  19169. * @param {Object} payload
  19170. * @param {String} payload.invitedBy 该移除操作的发起者 id
  19171. */
  19172. conversation.emit(INVITED$1, payload);
  19173. return;
  19174. }
  19175. case OpType.left:
  19176. {
  19177. conversation._removeMembers([this.id]);
  19178. const payload = {
  19179. kickedBy: initBy
  19180. };
  19181. /**
  19182. * 当前用户被从某个对话中移除
  19183. * @event IMClient#KICKED
  19184. * @param {Object} payload
  19185. * @param {String} payload.kickedBy 该移除操作的发起者 id
  19186. * @param {ConversationBase} conversation
  19187. */
  19188. this.emit(KICKED$1, payload, conversation);
  19189. /**
  19190. * 当前用户被从当前对话中移除
  19191. * @event ConversationBase#KICKED
  19192. * @param {Object} payload
  19193. * @param {String} payload.kickedBy 该移除操作的发起者 id
  19194. */
  19195. conversation.emit(KICKED$1, payload);
  19196. return;
  19197. }
  19198. case OpType.members_joined:
  19199. {
  19200. conversation._addMembers(m);
  19201. const payload = {
  19202. invitedBy: initBy,
  19203. members: m
  19204. };
  19205. /**
  19206. * 有用户被添加至某个对话
  19207. * @event IMClient#MEMBERS_JOINED
  19208. * @param {Object} payload
  19209. * @param {String[]} payload.members 被添加的用户 id 列表
  19210. * @param {String} payload.invitedBy 邀请者 id
  19211. * @param {ConversationBase} conversation
  19212. */
  19213. this.emit(MEMBERS_JOINED$1, payload, conversation);
  19214. /**
  19215. * 有成员被添加至当前对话
  19216. * @event ConversationBase#MEMBERS_JOINED
  19217. * @param {Object} payload
  19218. * @param {String[]} payload.members 被添加的成员 id 列表
  19219. * @param {String} payload.invitedBy 邀请者 id
  19220. */
  19221. conversation.emit(MEMBERS_JOINED$1, payload);
  19222. return;
  19223. }
  19224. case OpType.members_left:
  19225. {
  19226. conversation._removeMembers(m);
  19227. const payload = {
  19228. kickedBy: initBy,
  19229. members: m
  19230. };
  19231. /**
  19232. * 有成员被从某个对话中移除
  19233. * @event IMClient#MEMBERS_LEFT
  19234. * @param {Object} payload
  19235. * @param {String[]} payload.members 被移除的成员 id 列表
  19236. * @param {String} payload.kickedBy 该移除操作的发起者 id
  19237. * @param {ConversationBase} conversation
  19238. */
  19239. this.emit(MEMBERS_LEFT$1, payload, conversation);
  19240. /**
  19241. * 有成员被从当前对话中移除
  19242. * @event ConversationBase#MEMBERS_LEFT
  19243. * @param {Object} payload
  19244. * @param {String[]} payload.members 被移除的成员 id 列表
  19245. * @param {String} payload.kickedBy 该移除操作的发起者 id
  19246. */
  19247. conversation.emit(MEMBERS_LEFT$1, payload);
  19248. return;
  19249. }
  19250. case OpType.members_blocked:
  19251. {
  19252. const payload = {
  19253. blockedBy: initBy,
  19254. members: m
  19255. };
  19256. /**
  19257. * 有成员被加入某个对话的黑名单
  19258. * @event IMClient#MEMBERS_BLOCKED
  19259. * @param {Object} payload
  19260. * @param {String[]} payload.members 成员 id 列表
  19261. * @param {String} payload.blockedBy 该操作的发起者 id
  19262. * @param {ConversationBase} conversation
  19263. */
  19264. this.emit(MEMBERS_BLOCKED$1, payload, conversation);
  19265. /**
  19266. * 有成员被加入当前对话的黑名单
  19267. * @event ConversationBase#MEMBERS_BLOCKED
  19268. * @param {Object} payload
  19269. * @param {String[]} payload.members 成员 id 列表
  19270. * @param {String} payload.blockedBy 该操作的发起者 id
  19271. */
  19272. conversation.emit(MEMBERS_BLOCKED$1, payload);
  19273. return;
  19274. }
  19275. case OpType.members_unblocked:
  19276. {
  19277. const payload = {
  19278. unblockedBy: initBy,
  19279. members: m
  19280. };
  19281. /**
  19282. * 有成员被移出某个对话的黑名单
  19283. * @event IMClient#MEMBERS_UNBLOCKED
  19284. * @param {Object} payload
  19285. * @param {String[]} payload.members 成员 id 列表
  19286. * @param {String} payload.unblockedBy 该操作的发起者 id
  19287. * @param {ConversationBase} conversation
  19288. */
  19289. this.emit(MEMBERS_UNBLOCKED$1, payload, conversation);
  19290. /**
  19291. * 有成员被移出当前对话的黑名单
  19292. * @event ConversationBase#MEMBERS_UNBLOCKED
  19293. * @param {Object} payload
  19294. * @param {String[]} payload.members 成员 id 列表
  19295. * @param {String} payload.unblockedBy 该操作的发起者 id
  19296. */
  19297. conversation.emit(MEMBERS_UNBLOCKED$1, payload);
  19298. return;
  19299. }
  19300. case OpType.blocked:
  19301. {
  19302. const payload = {
  19303. blockedBy: initBy
  19304. };
  19305. /**
  19306. * 当前用户被加入某个对话的黑名单
  19307. * @event IMClient#BLOCKED
  19308. * @param {Object} payload
  19309. * @param {String} payload.blockedBy 该操作的发起者 id
  19310. * @param {ConversationBase} conversation
  19311. */
  19312. this.emit(BLOCKED$1, payload, conversation);
  19313. /**
  19314. * 当前用户被加入当前对话的黑名单
  19315. * @event ConversationBase#BLOCKED
  19316. * @param {Object} payload
  19317. * @param {String} payload.blockedBy 该操作的发起者 id
  19318. */
  19319. conversation.emit(BLOCKED$1, payload);
  19320. return;
  19321. }
  19322. case OpType.unblocked:
  19323. {
  19324. const payload = {
  19325. unblockedBy: initBy
  19326. };
  19327. /**
  19328. * 当前用户被移出某个对话的黑名单
  19329. * @event IMClient#UNBLOCKED
  19330. * @param {Object} payload
  19331. * @param {String} payload.unblockedBy 该操作的发起者 id
  19332. * @param {ConversationBase} conversation
  19333. */
  19334. this.emit(UNBLOCKED$1, payload, conversation);
  19335. /**
  19336. * 当前用户被移出当前对话的黑名单
  19337. * @event ConversationBase#UNBLOCKED
  19338. * @param {Object} payload
  19339. * @param {String} payload.unblockedBy 该操作的发起者 id
  19340. */
  19341. conversation.emit(UNBLOCKED$1, payload);
  19342. return;
  19343. }
  19344. case OpType.members_shutuped:
  19345. {
  19346. const payload = {
  19347. mutedBy: initBy,
  19348. members: m
  19349. };
  19350. /**
  19351. * 有成员在某个对话中被禁言
  19352. * @event IMClient#MEMBERS_MUTED
  19353. * @param {Object} payload
  19354. * @param {String[]} payload.members 成员 id 列表
  19355. * @param {String} payload.mutedBy 该操作的发起者 id
  19356. * @param {ConversationBase} conversation
  19357. */
  19358. this.emit(MEMBERS_MUTED$1, payload, conversation);
  19359. /**
  19360. * 有成员在当前对话中被禁言
  19361. * @event ConversationBase#MEMBERS_MUTED
  19362. * @param {Object} payload
  19363. * @param {String[]} payload.members 成员 id 列表
  19364. * @param {String} payload.mutedBy 该操作的发起者 id
  19365. */
  19366. conversation.emit(MEMBERS_MUTED$1, payload);
  19367. return;
  19368. }
  19369. case OpType.members_unshutuped:
  19370. {
  19371. const payload = {
  19372. unmutedBy: initBy,
  19373. members: m
  19374. };
  19375. /**
  19376. * 有成员在某个对话中被解除禁言
  19377. * @event IMClient#MEMBERS_UNMUTED
  19378. * @param {Object} payload
  19379. * @param {String[]} payload.members 成员 id 列表
  19380. * @param {String} payload.unmutedBy 该操作的发起者 id
  19381. * @param {ConversationBase} conversation
  19382. */
  19383. this.emit(MEMBERS_UNMUTED$1, payload, conversation);
  19384. /**
  19385. * 有成员在当前对话中被解除禁言
  19386. * @event ConversationBase#MEMBERS_UNMUTED
  19387. * @param {Object} payload
  19388. * @param {String[]} payload.members 成员 id 列表
  19389. * @param {String} payload.unmutedBy 该操作的发起者 id
  19390. */
  19391. conversation.emit(MEMBERS_UNMUTED$1, payload);
  19392. return;
  19393. }
  19394. case OpType.shutuped:
  19395. {
  19396. const payload = {
  19397. mutedBy: initBy
  19398. };
  19399. /**
  19400. * 有成员在某个对话中被禁言
  19401. * @event IMClient#MUTED
  19402. * @param {Object} payload
  19403. * @param {String} payload.mutedBy 该操作的发起者 id
  19404. * @param {ConversationBase} conversation
  19405. */
  19406. this.emit(MUTED$1, payload, conversation);
  19407. /**
  19408. * 有成员在当前对话中被禁言
  19409. * @event ConversationBase#MUTED
  19410. * @param {Object} payload
  19411. * @param {String} payload.mutedBy 该操作的发起者 id
  19412. */
  19413. conversation.emit(MUTED$1, payload);
  19414. return;
  19415. }
  19416. case OpType.unshutuped:
  19417. {
  19418. const payload = {
  19419. unmutedBy: initBy
  19420. };
  19421. /**
  19422. * 有成员在某个对话中被解除禁言
  19423. * @event IMClient#UNMUTED
  19424. * @param {Object} payload
  19425. * @param {String} payload.unmutedBy 该操作的发起者 id
  19426. * @param {ConversationBase} conversation
  19427. */
  19428. this.emit(UNMUTED$1, payload, conversation);
  19429. /**
  19430. * 有成员在当前对话中被解除禁言
  19431. * @event ConversationBase#UNMUTED
  19432. * @param {Object} payload
  19433. * @param {String} payload.unmutedBy 该操作的发起者 id
  19434. */
  19435. conversation.emit(UNMUTED$1, payload);
  19436. return;
  19437. }
  19438. case OpType.member_info_changed:
  19439. {
  19440. const {
  19441. pid,
  19442. role
  19443. } = info;
  19444. const {
  19445. memberInfoMap
  19446. } = internal(conversation); // 如果不存在缓存,且不是 role 的更新,则不通知
  19447. if (!memberInfoMap && !role) return;
  19448. const memberInfo = await conversation.getMemberInfo(pid);
  19449. internal(memberInfo).role = role;
  19450. const payload = {
  19451. member: pid,
  19452. memberInfo,
  19453. updatedBy: initBy
  19454. };
  19455. /**
  19456. * 有成员的对话信息被更新
  19457. * @event IMClient#MEMBER_INFO_UPDATED
  19458. * @param {Object} payload
  19459. * @param {String} payload.member 被更新对话信息的成员 id
  19460. * @param {ConversationMumberInfo} payload.memberInfo 被更新的成员对话信息
  19461. * @param {String} payload.updatedBy 该操作的发起者 id
  19462. * @param {ConversationBase} conversation
  19463. */
  19464. this.emit(MEMBER_INFO_UPDATED$1, payload, conversation);
  19465. /**
  19466. * 有成员的对话信息被更新
  19467. * @event ConversationBase#MEMBER_INFO_UPDATED
  19468. * @param {Object} payload
  19469. * @param {String} payload.member 被更新对话信息的成员 id
  19470. * @param {ConversationMumberInfo} payload.memberInfo 被更新的成员对话信息
  19471. * @param {String} payload.updatedBy 该操作的发起者 id
  19472. */
  19473. conversation.emit(MEMBER_INFO_UPDATED$1, payload);
  19474. return;
  19475. }
  19476. case OpType.updated:
  19477. {
  19478. const attributes = decode(JSON.parse(attr.data));
  19479. conversation._updateServerAttributes(attributes);
  19480. const payload = {
  19481. attributes,
  19482. updatedBy: initBy
  19483. };
  19484. /**
  19485. * 该对话信息被更新
  19486. * @event IMClient#CONVERSATION_INFO_UPDATED
  19487. * @param {Object} payload
  19488. * @param {Object} payload.attributes 被更新的属性
  19489. * @param {String} payload.updatedBy 该操作的发起者 id
  19490. * @param {ConversationBase} conversation
  19491. */
  19492. this.emit(CONVERSATION_INFO_UPDATED$1, payload, conversation);
  19493. /**
  19494. * 有对话信息被更新
  19495. * @event ConversationBase#INFO_UPDATED
  19496. * @param {Object} payload
  19497. * @param {Object} payload.attributes 被更新的属性
  19498. * @param {String} payload.updatedBy 该操作的发起者 id
  19499. */
  19500. conversation.emit(INFO_UPDATED$1, payload);
  19501. return;
  19502. }
  19503. default:
  19504. this.emit(UNHANDLED_MESSAGE$1, message);
  19505. throw new Error('Unrecognized conversation command');
  19506. }
  19507. }
  19508. _dispatchDirectMessage(originalMessage) {
  19509. const {
  19510. directMessage,
  19511. directMessage: {
  19512. id,
  19513. cid,
  19514. fromPeerId,
  19515. timestamp,
  19516. transient,
  19517. patchTimestamp,
  19518. mentionPids,
  19519. mentionAll,
  19520. binaryMsg,
  19521. msg
  19522. }
  19523. } = originalMessage;
  19524. const content = binaryMsg ? binaryMsg.toArrayBuffer() : msg;
  19525. return Promise.all([this.getConversation(directMessage.cid), this._messageParser.parse(content)]).then(([conversation, message]) => {
  19526. // deleted conversation
  19527. if (!conversation) return undefined;
  19528. const messageProps = {
  19529. id,
  19530. cid,
  19531. timestamp,
  19532. updatedAt: patchTimestamp,
  19533. from: fromPeerId,
  19534. mentionList: mentionPids,
  19535. mentionedAll: mentionAll
  19536. };
  19537. Object.assign(message, messageProps);
  19538. message._updateMentioned(this.id);
  19539. message._setStatus(MessageStatus.SENT); // filter outgoing message sent from another device
  19540. if (message.from !== this.id) {
  19541. if (!(transient || conversation.transient)) {
  19542. this._sendAck(message);
  19543. }
  19544. }
  19545. return this._dispatchParsedMessage(message, conversation);
  19546. });
  19547. }
  19548. _dispatchParsedMessage(message, conversation) {
  19549. // beforeMessageDispatch hook
  19550. return applyDispatcher(this._plugins.beforeMessageDispatch, [message, conversation]).then(shouldDispatch => {
  19551. if (shouldDispatch === false) return;
  19552. conversation.lastMessage = message; // eslint-disable-line no-param-reassign
  19553. conversation.lastMessageAt = message.timestamp; // eslint-disable-line no-param-reassign
  19554. // filter outgoing message sent from another device
  19555. if (message.from !== this.id) {
  19556. conversation.unreadMessagesCount += 1; // eslint-disable-line no-param-reassign
  19557. if (message.mentioned) conversation._setUnreadMessagesMentioned(true);
  19558. }
  19559. /**
  19560. * 当前用户收到消息
  19561. * @event IMClient#MESSAGE
  19562. * @param {Message} message
  19563. * @param {ConversationBase} conversation 收到消息的对话
  19564. */
  19565. this.emit(MESSAGE$2, message, conversation);
  19566. /**
  19567. * 当前对话收到消息
  19568. * @event ConversationBase#MESSAGE
  19569. * @param {Message} message
  19570. */
  19571. conversation.emit(MESSAGE$2, message);
  19572. });
  19573. }
  19574. _sendAck(message) {
  19575. this._debug('send ack for %O', message);
  19576. const {
  19577. cid
  19578. } = message;
  19579. if (!cid) {
  19580. throw new Error('missing cid');
  19581. }
  19582. if (!this._ackMessageBuffer[cid]) {
  19583. this._ackMessageBuffer[cid] = [];
  19584. }
  19585. this._ackMessageBuffer[cid].push(message);
  19586. return this._doSendAck();
  19587. } // jsdoc-ignore-start
  19588. // jsdoc-ignore-end
  19589. _doSendAck() {
  19590. // if not connected, just skip everything
  19591. if (!this._connection.is('connected')) return;
  19592. this._debug('do send ack %O', this._ackMessageBuffer);
  19593. Promise.all(Object.keys(this._ackMessageBuffer).map(cid => {
  19594. const convAckMessages = this._ackMessageBuffer[cid];
  19595. const timestamps = convAckMessages.map(message => message.timestamp);
  19596. const command = new GenericCommand({
  19597. cmd: 'ack',
  19598. ackMessage: new AckCommand({
  19599. cid,
  19600. fromts: Math.min.apply(null, timestamps),
  19601. tots: Math.max.apply(null, timestamps)
  19602. })
  19603. });
  19604. delete this._ackMessageBuffer[cid];
  19605. return this._send(command, false).catch(error => {
  19606. this._debug('send ack failed: %O', error);
  19607. this._ackMessageBuffer[cid] = convAckMessages;
  19608. });
  19609. }));
  19610. }
  19611. _omitPeerId(value) {
  19612. internal(this).peerIdOmittable = value;
  19613. }
  19614. _send(cmd, ...args) {
  19615. const command = cmd;
  19616. if (!internal(this).peerIdOmittable && this.id) {
  19617. command.peerId = this.id;
  19618. }
  19619. return this._connection.send(command, ...args);
  19620. }
  19621. async _open(appId, tag, deviceId, isReconnect = false) {
  19622. this._debug('open session');
  19623. const {
  19624. lastUnreadNotifTime,
  19625. lastPatchTime,
  19626. lastNotificationTime
  19627. } = internal(this);
  19628. const command = new GenericCommand({
  19629. cmd: 'session',
  19630. op: 'open',
  19631. appId,
  19632. peerId: this.id,
  19633. sessionMessage: new SessionCommand({
  19634. ua: `js/${version}`,
  19635. r: isReconnect,
  19636. lastUnreadNotifTime,
  19637. lastPatchTime,
  19638. configBitmap
  19639. })
  19640. });
  19641. if (!isReconnect) {
  19642. Object.assign(command.sessionMessage, trim({
  19643. tag,
  19644. deviceId
  19645. }));
  19646. if (this.options.signatureFactory) {
  19647. const signatureResult = await runSignatureFactory(this.options.signatureFactory, [this._identity]);
  19648. Object.assign(command.sessionMessage, keyRemap({
  19649. signature: 's',
  19650. timestamp: 't',
  19651. nonce: 'n'
  19652. }, signatureResult));
  19653. }
  19654. } else {
  19655. const sessionToken = await this._sessionManager.getSessionToken({
  19656. autoRefresh: false
  19657. });
  19658. if (sessionToken && sessionToken !== Expirable.EXPIRED) {
  19659. Object.assign(command.sessionMessage, {
  19660. st: sessionToken
  19661. });
  19662. }
  19663. }
  19664. let resCommand;
  19665. try {
  19666. resCommand = await this._send(command);
  19667. } catch (error) {
  19668. if (error.code === ErrorCode.SESSION_TOKEN_EXPIRED) {
  19669. if (!this._sessionManager) {
  19670. // let it fail if sessoinToken not cached but command rejected as token expired
  19671. // to prevent session openning flood
  19672. throw new Error('Unexpected session expiration');
  19673. }
  19674. debug$b('Session token expired, reopening');
  19675. this._sessionManager.revoke();
  19676. return this._open(appId, tag, deviceId, isReconnect);
  19677. }
  19678. throw error;
  19679. }
  19680. const {
  19681. peerId,
  19682. sessionMessage,
  19683. sessionMessage: {
  19684. st: token,
  19685. stTtl: tokenTTL,
  19686. code
  19687. },
  19688. serverTs
  19689. } = resCommand;
  19690. if (code) {
  19691. throw createError(sessionMessage);
  19692. }
  19693. if (peerId) {
  19694. this.id = peerId;
  19695. if (!this._identity) this._identity = peerId;
  19696. if (token) {
  19697. this._sessionManager = this._sessionManager || this._createSessionManager();
  19698. this._sessionManager.setSessionToken(token, tokenTTL);
  19699. }
  19700. const serverTime = getTime(decodeDate(serverTs));
  19701. if (serverTs) {
  19702. internal(this).lastPatchTime = serverTime;
  19703. }
  19704. if (lastNotificationTime) {
  19705. // Do not await for it as this is failable
  19706. this._syncNotifications(lastNotificationTime).catch(error => console.warn('Syncing notifications failed:', error));
  19707. } else {
  19708. // Set timestamp to now for next reconnection
  19709. internal(this).lastNotificationTime = serverTime;
  19710. }
  19711. } else {
  19712. console.warn('Unexpected session opened without peerId.');
  19713. }
  19714. return undefined;
  19715. }
  19716. async _syncNotifications(timestamp) {
  19717. const {
  19718. hasMore,
  19719. notifications
  19720. } = await this._fetchNotifications(timestamp);
  19721. notifications.forEach(notification => {
  19722. const {
  19723. cmd,
  19724. op,
  19725. serverTs,
  19726. notificationType,
  19727. ...payload
  19728. } = notification;
  19729. this._dispatchCommand({
  19730. cmd: CommandType[cmd],
  19731. op: OpType[op],
  19732. serverTs,
  19733. notificationType,
  19734. [`${cmd}Message`]: payload
  19735. });
  19736. });
  19737. if (hasMore) {
  19738. return this._syncNotifications(internal(this).lastNotificationTime);
  19739. }
  19740. return undefined;
  19741. }
  19742. async _fetchNotifications(timestamp) {
  19743. return this._requestWithSessionToken({
  19744. method: 'GET',
  19745. path: '/rtm/notifications',
  19746. query: {
  19747. start_ts: timestamp,
  19748. notification_type: 'permanent'
  19749. }
  19750. });
  19751. }
  19752. _createSessionManager() {
  19753. debug$b('create SessionManager');
  19754. return new SessionManager({
  19755. onBeforeGetSessionToken: this._connection.checkConnectionAvailability.bind(this._connection),
  19756. refresh: (manager, expiredSessionToken) => manager.setSessionTokenAsync(Promise.resolve(new GenericCommand({
  19757. cmd: 'session',
  19758. op: 'refresh',
  19759. sessionMessage: new SessionCommand({
  19760. ua: `js/${version}`,
  19761. st: expiredSessionToken
  19762. })
  19763. })).then(async command => {
  19764. if (this.options.signatureFactory) {
  19765. const signatureResult = await runSignatureFactory(this.options.signatureFactory, [this._identity]);
  19766. Object.assign(command.sessionMessage, keyRemap({
  19767. signature: 's',
  19768. timestamp: 't',
  19769. nonce: 'n'
  19770. }, signatureResult));
  19771. }
  19772. return command;
  19773. }).then(this._send.bind(this)).then(({
  19774. sessionMessage: {
  19775. st: token,
  19776. stTtl: ttl
  19777. }
  19778. }) => [token, ttl]))
  19779. });
  19780. }
  19781. async _requestWithSessionToken({
  19782. headers,
  19783. query,
  19784. ...params
  19785. }) {
  19786. const sessionToken = await this._sessionManager.getSessionToken();
  19787. return this._request({
  19788. headers: {
  19789. 'X-LC-IM-Session-Token': sessionToken,
  19790. ...headers
  19791. },
  19792. query: {
  19793. client_id: this.id,
  19794. ...query
  19795. },
  19796. ...params
  19797. });
  19798. }
  19799. /**
  19800. * 关闭客户端
  19801. * @return {Promise}
  19802. */
  19803. async close() {
  19804. this._debug('close session');
  19805. const _ee = internal(this)._eventemitter;
  19806. _ee.emit('beforeclose');
  19807. if (this._connection.is('connected')) {
  19808. const command = new GenericCommand({
  19809. cmd: 'session',
  19810. op: 'close'
  19811. });
  19812. await this._send(command);
  19813. }
  19814. _ee.emit('close');
  19815. this.emit(CLOSE$1, {
  19816. code: 0
  19817. });
  19818. }
  19819. /**
  19820. * 获取 client 列表中在线的 client,每次查询最多 20 个 clientId,超出部分会被忽略
  19821. * @param {String[]} clientIds 要查询的 client ids
  19822. * @return {Primse.<String[]>} 在线的 client ids
  19823. */
  19824. async ping(clientIds) {
  19825. this._debug('ping');
  19826. if (!(clientIds instanceof Array)) {
  19827. throw new TypeError(`clientIds ${clientIds} is not an Array`);
  19828. }
  19829. if (!clientIds.length) {
  19830. return Promise.resolve([]);
  19831. }
  19832. const command = new GenericCommand({
  19833. cmd: 'session',
  19834. op: 'query',
  19835. sessionMessage: new SessionCommand({
  19836. sessionPeerIds: clientIds
  19837. })
  19838. });
  19839. const resCommand = await this._send(command);
  19840. return resCommand.sessionMessage.onlineSessionPeerIds;
  19841. }
  19842. /**
  19843. * 获取某个特定的对话
  19844. * @param {String} id 对话 id,对应 _Conversation 表中的 objectId
  19845. * @param {Boolean} [noCache=false] 强制不从缓存中获取
  19846. * @return {Promise.<ConversationBase>} 如果 id 对应的对话不存在则返回 null
  19847. */
  19848. async getConversation(id, noCache = false) {
  19849. if (typeof id !== 'string') {
  19850. throw new TypeError(`${id} is not a String`);
  19851. }
  19852. if (!noCache) {
  19853. const cachedConversation = this._conversationCache.get(id);
  19854. if (cachedConversation) {
  19855. return cachedConversation;
  19856. }
  19857. }
  19858. if (isTemporaryConversatrionId(id)) {
  19859. return (await this._getTemporaryConversations([id]))[0] || null;
  19860. }
  19861. return this.getQuery().equalTo('objectId', id).find().then(conversations => conversations[0] || null);
  19862. }
  19863. /**
  19864. * 通过 id 批量获取某个特定的对话
  19865. * @since 3.4.0
  19866. * @param {String[]} ids 对话 id 列表,对应 _Conversation 表中的 objectId
  19867. * @param {Boolean} [noCache=false] 强制不从缓存中获取
  19868. * @return {Promise.<ConversationBase[]>} 如果 id 对应的对话不存在则返回 null
  19869. */
  19870. async getConversations(ids, noCache = false) {
  19871. const remoteConversationIds = noCache ? ids : ids.filter(id => this._conversationCache.get(id) === null);
  19872. if (remoteConversationIds.length) {
  19873. const remoteTemporaryConversationIds = remove_1(remoteConversationIds, isTemporaryConversatrionId);
  19874. const query = [];
  19875. if (remoteConversationIds.length) {
  19876. query.push(this.getQuery().containedIn('objectId', remoteConversationIds).limit(999).find());
  19877. }
  19878. if (remoteTemporaryConversationIds.length) {
  19879. const remoteTemporaryConversationsPromise = remoteTemporaryConversationIds.map(this._getTemporaryConversations.bind(this));
  19880. query.push(...remoteTemporaryConversationsPromise);
  19881. }
  19882. await Promise.all(query);
  19883. }
  19884. return ids.map(id => this._conversationCache.get(id));
  19885. }
  19886. async _getTemporaryConversations(ids) {
  19887. const command = new GenericCommand({
  19888. cmd: 'conv',
  19889. op: 'query',
  19890. convMessage: new ConvCommand({
  19891. tempConvIds: ids
  19892. })
  19893. });
  19894. const resCommand = await this._send(command);
  19895. return this._handleQueryResults(resCommand);
  19896. }
  19897. /**
  19898. * 构造一个 ConversationQuery 来查询对话
  19899. * @return {ConversationQuery.<PersistentConversation>}
  19900. */
  19901. getQuery() {
  19902. return new ConversationQuery(this);
  19903. }
  19904. /**
  19905. * 构造一个 ConversationQuery 来查询聊天室
  19906. * @return {ConversationQuery.<ChatRoom>}
  19907. */
  19908. getChatRoomQuery() {
  19909. return this.getQuery().equalTo('tr', true);
  19910. }
  19911. /**
  19912. * 构造一个 ConversationQuery 来查询服务号
  19913. * @return {ConversationQuery.<ServiceConversation>}
  19914. */
  19915. getServiceConversationQuery() {
  19916. return this.getQuery().equalTo('sys', true);
  19917. }
  19918. async _executeQuery(query) {
  19919. const queryJSON = query.toJSON();
  19920. queryJSON.where = new JsonObjectMessage({
  19921. data: JSON.stringify(encode(queryJSON.where))
  19922. });
  19923. const command = new GenericCommand({
  19924. cmd: 'conv',
  19925. op: 'query',
  19926. convMessage: new ConvCommand(queryJSON)
  19927. });
  19928. const resCommand = await this._send(command);
  19929. return this._handleQueryResults(resCommand);
  19930. }
  19931. async _handleQueryResults(resCommand) {
  19932. let conversations;
  19933. try {
  19934. conversations = decode(JSON.parse(resCommand.convMessage.results.data));
  19935. } catch (error) {
  19936. const commandString = JSON.stringify(trim(resCommand));
  19937. throw new Error(`Parse query result failed: ${error.message}. Command: ${commandString}`);
  19938. }
  19939. conversations = await Promise.all(conversations.map(this._parseConversationFromRawData.bind(this)));
  19940. return conversations.map(this._upsertConversationToCache.bind(this));
  19941. }
  19942. _upsertConversationToCache(fetchedConversation) {
  19943. let conversation = this._conversationCache.get(fetchedConversation.id);
  19944. if (!conversation) {
  19945. conversation = fetchedConversation;
  19946. this._debug('no match, set cache');
  19947. this._conversationCache.set(fetchedConversation.id, fetchedConversation);
  19948. } else {
  19949. this._debug('update cached conversation');
  19950. ['creator', 'createdAt', 'updatedAt', 'lastMessageAt', 'lastMessage', 'mutedMembers', 'members', '_attributes', 'transient', 'muted'].forEach(key => {
  19951. const value = fetchedConversation[key];
  19952. if (value !== undefined) conversation[key] = value;
  19953. });
  19954. if (conversation._reset) conversation._reset();
  19955. }
  19956. return conversation;
  19957. }
  19958. /**
  19959. * 反序列化消息,与 {@link Message#toFullJSON} 相对。
  19960. * @param {Object}
  19961. * @return {AVMessage} 解析后的消息
  19962. * @since 4.0.0
  19963. */
  19964. async parseMessage({
  19965. data,
  19966. bin = false,
  19967. ...properties
  19968. }) {
  19969. const content = bin ? base64Arraybuffer_2(data) : data;
  19970. const message = await this._messageParser.parse(content);
  19971. Object.assign(message, properties);
  19972. message._updateMentioned(this.id);
  19973. return message;
  19974. }
  19975. /**
  19976. * 反序列化对话,与 {@link Conversation#toFullJSON} 相对。
  19977. * @param {Object}
  19978. * @return {ConversationBase} 解析后的对话
  19979. * @since 4.0.0
  19980. */
  19981. async parseConversation({
  19982. id,
  19983. lastMessageAt,
  19984. lastMessage,
  19985. lastDeliveredAt,
  19986. lastReadAt,
  19987. unreadMessagesCount,
  19988. members,
  19989. mentioned,
  19990. ...properties
  19991. }) {
  19992. const conversationData = {
  19993. id,
  19994. lastMessageAt,
  19995. lastMessage,
  19996. lastDeliveredAt,
  19997. lastReadAt,
  19998. unreadMessagesCount,
  19999. members,
  20000. mentioned
  20001. };
  20002. if (lastMessage) {
  20003. conversationData.lastMessage = await this.parseMessage(lastMessage);
  20004. conversationData.lastMessage._setStatus(MessageStatus.SENT);
  20005. }
  20006. const {
  20007. transient,
  20008. system,
  20009. expiredAt
  20010. } = properties;
  20011. if (transient) return new ChatRoom(conversationData, properties, this);
  20012. if (system) return new ServiceConversation(conversationData, properties, this);
  20013. if (expiredAt || isTemporaryConversatrionId(id)) {
  20014. return new TemporaryConversation(conversationData, {
  20015. expiredAt
  20016. }, this);
  20017. }
  20018. return new Conversation(conversationData, properties, this);
  20019. }
  20020. async _parseConversationFromRawData(rawData) {
  20021. const data = keyRemap({
  20022. objectId: 'id',
  20023. lm: 'lastMessageAt',
  20024. m: 'members',
  20025. tr: 'transient',
  20026. sys: 'system',
  20027. c: 'creator',
  20028. mu: 'mutedMembers'
  20029. }, rawData);
  20030. if (data.msg) {
  20031. data.lastMessage = {
  20032. data: data.msg,
  20033. bin: data.bin,
  20034. from: data.msg_from,
  20035. id: data.msg_mid,
  20036. timestamp: data.msg_timestamp,
  20037. updatedAt: data.patch_timestamp
  20038. };
  20039. delete data.lastMessageFrom;
  20040. delete data.lastMessageId;
  20041. delete data.lastMessageTimestamp;
  20042. delete data.lastMessagePatchTimestamp;
  20043. }
  20044. const {
  20045. ttl
  20046. } = data;
  20047. if (ttl) data.expiredAt = Date.now() + ttl * 1000;
  20048. return this.parseConversation(data);
  20049. }
  20050. /**
  20051. * 创建一个对话
  20052. * @param {Object} options 除了下列字段外的其他字段将被视为对话的自定义属性
  20053. * @param {String[]} options.members 对话的初始成员列表,默认包含当前 client
  20054. * @param {String} [options.name] 对话的名字
  20055. * @param {Boolean} [options.unique=true] 唯一对话,当其为 true 时,如果当前已经有相同成员的对话存在则返回该对话,否则会创建新的对话
  20056. * @return {Promise.<Conversation>}
  20057. */
  20058. async createConversation({
  20059. members: m,
  20060. name,
  20061. transient,
  20062. unique = true,
  20063. _tempConv: tempConv,
  20064. _tempConvTTL: tempConvTTL,
  20065. ...properties
  20066. } = {}) {
  20067. if (!(transient || Array.isArray(m))) {
  20068. throw new TypeError(`conversation members ${m} is not an array`);
  20069. }
  20070. let members = new Set(m);
  20071. members.add(this.id);
  20072. members = Array.from(members).sort();
  20073. let attr = properties || {};
  20074. if (name) {
  20075. if (typeof name !== 'string') {
  20076. throw new TypeError(`conversation name ${name} is not a string`);
  20077. }
  20078. attr.name = name;
  20079. }
  20080. attr = new JsonObjectMessage({
  20081. data: JSON.stringify(encode(attr))
  20082. });
  20083. const startCommandJson = {
  20084. m: members,
  20085. attr,
  20086. transient,
  20087. unique,
  20088. tempConv,
  20089. tempConvTTL
  20090. };
  20091. const command = new GenericCommand({
  20092. cmd: 'conv',
  20093. op: 'start',
  20094. convMessage: new ConvCommand(startCommandJson)
  20095. });
  20096. if (this.options.conversationSignatureFactory) {
  20097. const params = [null, this._identity, members, 'create'];
  20098. const signatureResult = await runSignatureFactory(this.options.conversationSignatureFactory, params);
  20099. Object.assign(command.convMessage, keyRemap({
  20100. signature: 's',
  20101. timestamp: 't',
  20102. nonce: 'n'
  20103. }, signatureResult));
  20104. }
  20105. const {
  20106. convMessage: {
  20107. cid,
  20108. cdate,
  20109. tempConvTTL: ttl
  20110. }
  20111. } = await this._send(command);
  20112. const data = {
  20113. name,
  20114. transient,
  20115. unique,
  20116. id: cid,
  20117. createdAt: cdate,
  20118. updatedAt: cdate,
  20119. lastMessageAt: null,
  20120. creator: this.id,
  20121. members: transient ? [] : members,
  20122. ...properties
  20123. };
  20124. if (ttl) data.expiredAt = Date.now() + ttl * 1000;
  20125. const conversation = await this.parseConversation(data);
  20126. return this._upsertConversationToCache(conversation);
  20127. }
  20128. /**
  20129. * 创建一个聊天室
  20130. * @since 4.0.0
  20131. * @param {Object} options 除了下列字段外的其他字段将被视为对话的自定义属性
  20132. * @param {String} [options.name] 对话的名字
  20133. * @return {Promise.<ChatRoom>}
  20134. */
  20135. async createChatRoom(param) {
  20136. return this.createConversation({ ...param,
  20137. transient: true,
  20138. members: null,
  20139. unique: false,
  20140. _tempConv: false
  20141. });
  20142. }
  20143. /**
  20144. * 创建一个临时对话
  20145. * @since 4.0.0
  20146. * @param {Object} options
  20147. * @param {String[]} options.members 对话的初始成员列表,默认包含当前 client
  20148. * @param {String} [options.ttl] 对话存在时间,单位为秒,最大值与默认值均为 86400(一天),过期后该对话不再可用。
  20149. * @return {Promise.<TemporaryConversation>}
  20150. */
  20151. async createTemporaryConversation({
  20152. ttl: _tempConvTTL,
  20153. ...param
  20154. }) {
  20155. return this.createConversation({ ...param,
  20156. _tempConv: true,
  20157. _tempConvTTL
  20158. });
  20159. } // jsdoc-ignore-start
  20160. // jsdoc-ignore-end
  20161. _doSendRead() {
  20162. // if not connected, just skip everything
  20163. if (!this._connection.is('connected')) return;
  20164. const buffer = internal(this).readConversationsBuffer;
  20165. const conversations = Array.from(buffer);
  20166. if (!conversations.length) return;
  20167. const ids = conversations.map(conversation => {
  20168. if (!(conversation instanceof ConversationBase)) {
  20169. throw new TypeError(`${conversation} is not a Conversation`);
  20170. }
  20171. return conversation.id;
  20172. });
  20173. this._debug(`mark [${ids}] as read`);
  20174. buffer.clear();
  20175. this._sendReadCommand(conversations).catch(error => {
  20176. this._debug('send read failed: %O', error);
  20177. conversations.forEach(buffer.add.bind(buffer));
  20178. });
  20179. }
  20180. _sendReadCommand(conversations) {
  20181. return this._send(new GenericCommand({
  20182. cmd: 'read',
  20183. readMessage: new ReadCommand({
  20184. convs: conversations.map(conversation => new ReadTuple({
  20185. cid: conversation.id,
  20186. mid: conversation.lastMessage && conversation.lastMessage.from !== this.id ? conversation.lastMessage.id : undefined,
  20187. timestamp: (conversation.lastMessageAt || new Date()).getTime()
  20188. }))
  20189. })
  20190. }), false);
  20191. }
  20192. }, (_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));
  20193. /**
  20194. * 修改、撤回消息的原因
  20195. * @typedef PatchReason
  20196. * @type {Object}
  20197. * @property {number} code 负数为内置 code,正数为开发者在 hook 中自定义的 code。比如因为敏感词过滤被修改的 code 为 -4408。
  20198. * @property {string} [detail] 具体的原因说明。
  20199. */
  20200. const RECONNECT_ERROR = 'reconnecterror';
  20201. var CoreEvent = /*#__PURE__*/Object.freeze({
  20202. __proto__: null,
  20203. RECONNECT_ERROR: RECONNECT_ERROR,
  20204. DISCONNECT: DISCONNECT,
  20205. RECONNECT: RECONNECT,
  20206. RETRY: RETRY,
  20207. SCHEDULE: SCHEDULE,
  20208. OFFLINE: OFFLINE,
  20209. ONLINE: ONLINE
  20210. });
  20211. var _class$4;
  20212. let // jsdoc-ignore-end
  20213. BinaryMessage = IE10Compatible(_class$4 = class BinaryMessage extends Message {
  20214. /**
  20215. * 二进制消息
  20216. * @extends Message
  20217. * @param {ArrayBuffer} buffer
  20218. * @since 4.0.0
  20219. */
  20220. constructor(buffer) {
  20221. if (!(buffer instanceof ArrayBuffer)) {
  20222. throw new TypeError(`${buffer} is not an ArrayBuffer`);
  20223. }
  20224. super(buffer);
  20225. }
  20226. /**
  20227. * @type ArrayBuffer
  20228. */
  20229. get buffer() {
  20230. return this.content;
  20231. }
  20232. set buffer(buffer) {
  20233. this.content = buffer;
  20234. }
  20235. static validate(target) {
  20236. return target instanceof ArrayBuffer;
  20237. }
  20238. toJSON() {
  20239. return { ...super._toJSON(),
  20240. data: base64Arraybuffer_1(this.content)
  20241. };
  20242. }
  20243. toFullJSON() {
  20244. return { ...super.toFullJSON(),
  20245. bin: true,
  20246. data: base64Arraybuffer_1(this.content)
  20247. };
  20248. }
  20249. }) || _class$4;
  20250. var _dec$3, _class$5;
  20251. let // jsdoc-ignore-end
  20252. TextMessage = (_dec$3 = messageType(-1), _dec$3(_class$5 = IE10Compatible(_class$5 = class TextMessage extends TypedMessage {
  20253. /**
  20254. * 文类类型消息
  20255. * @extends TypedMessage
  20256. * @param {String} [text='']
  20257. * @throws {TypeError} text 不是 String 类型
  20258. */
  20259. constructor(text = '') {
  20260. if (typeof text !== 'string') {
  20261. throw new TypeError(`${text} is not a string`);
  20262. }
  20263. super();
  20264. this.setText(text);
  20265. }
  20266. }) || _class$5) || _class$5);
  20267. /**
  20268. * @name TYPE
  20269. * @memberof TextMessage
  20270. * @type Number
  20271. * @static
  20272. * @const
  20273. */
  20274. var _class$6;
  20275. const debug$c = browser('LC:MessageParser');
  20276. const tryParseJson = (target, key, descriptor) => {
  20277. const fn = descriptor.value; // eslint-disable-next-line no-param-reassign
  20278. descriptor.value = function wrapper(param) {
  20279. let content;
  20280. if (typeof param !== 'string') {
  20281. content = param;
  20282. } else {
  20283. try {
  20284. content = JSON.parse(param);
  20285. } catch (error) {
  20286. content = param;
  20287. }
  20288. }
  20289. return fn.call(this, content);
  20290. };
  20291. };
  20292. const applyPlugins = (target, key, descriptor) => {
  20293. const fn = descriptor.value; // eslint-disable-next-line no-param-reassign
  20294. descriptor.value = function wrapper(json) {
  20295. return Promise.resolve(json).then(applyMiddlewares(this._plugins.beforeMessageParse)).then(decoratedJson => fn.call(this, decoratedJson)).then(applyMiddlewares(this._plugins.afterMessageParse));
  20296. };
  20297. };
  20298. let MessageParser = (_class$6 = class MessageParser {
  20299. /**
  20300. * 消息解析器
  20301. * @param {Object} plugins 插件,插件的 messageClasses 会自动被注册,在解析时 beforeMessageParse 与 afterMessageParse Middleware 会被应用。
  20302. */
  20303. constructor(plugins = {}) {
  20304. this._plugins = plugins;
  20305. this._messageClasses = [];
  20306. this.register(plugins.messageClasses);
  20307. }
  20308. /**
  20309. * 注册消息类
  20310. *
  20311. * @param {Function | Function[]} messageClass 消息类,需要实现 {@link AVMessage} 接口,
  20312. * 建议继承自 {@link TypedMessage},也可以传入一个消息类数组。
  20313. * @throws {TypeError} 如果 messageClass 没有实现 {@link AVMessage} 接口则抛出异常
  20314. */
  20315. register(messageClasses) {
  20316. ensureArray(messageClasses).map(klass => this._register(klass));
  20317. }
  20318. _register(messageClass) {
  20319. if (messageClass && messageClass.parse && messageClass.prototype && messageClass.prototype.getPayload) {
  20320. this._messageClasses.unshift(messageClass);
  20321. } else {
  20322. throw new TypeError('Invalid messageClass');
  20323. }
  20324. } // jsdoc-ignore-start
  20325. // jsdoc-ignore-end
  20326. /**
  20327. * 解析消息内容
  20328. * @param {Object | string | any} target 消息内容,如果是字符串会尝试 parse 为 JSON。
  20329. * @return {AVMessage} 解析后的消息
  20330. * @throws {Error} 如果不匹配任何注册的消息则抛出异常
  20331. */
  20332. parse(content) {
  20333. debug$c('parsing message: %O', content); // eslint-disable-next-line
  20334. for (const Klass of this._messageClasses) {
  20335. const contentCopy = isPlainObject_1(content) ? { ...content
  20336. } : content;
  20337. let valid;
  20338. let result;
  20339. try {
  20340. valid = Klass.validate(contentCopy);
  20341. } catch (error) {// eslint-disable-line no-empty
  20342. }
  20343. if (valid) {
  20344. try {
  20345. result = Klass.parse(contentCopy);
  20346. } catch (error) {
  20347. console.warn('parsing a valid message content error', {
  20348. error,
  20349. Klass,
  20350. content: contentCopy
  20351. });
  20352. }
  20353. if (result !== undefined) {
  20354. debug$c('parse result: %O', result);
  20355. return result;
  20356. }
  20357. }
  20358. }
  20359. throw new Error('No Message Class matched');
  20360. }
  20361. }, (_applyDecoratedDescriptor(_class$6.prototype, "parse", [tryParseJson, applyPlugins], Object.getOwnPropertyDescriptor(_class$6.prototype, "parse"), _class$6.prototype)), _class$6);
  20362. /** @module leancloud-realtime */
  20363. const debug$d = browser('LC:IMPlugin');
  20364. /**
  20365. * 消息优先级枚举
  20366. * @enum {Number}
  20367. * @since 3.3.0
  20368. */
  20369. const MessagePriority = {
  20370. /** 高 */
  20371. HIGH: 1,
  20372. /** 普通 */
  20373. NORMAL: 2,
  20374. /** 低 */
  20375. LOW: 3
  20376. };
  20377. Object.freeze(MessagePriority);
  20378. /**
  20379. * 为 Conversation 定义一个新属性
  20380. * @param {String} prop 属性名
  20381. * @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
  20382. * @returns void
  20383. * @example
  20384. *
  20385. * conversation.get('type');
  20386. * conversation.set('type', 1);
  20387. *
  20388. * // equals to
  20389. * defineConversationProperty('type');
  20390. * conversation.type;
  20391. * conversation.type = 1;
  20392. */
  20393. const defineConversationProperty = (prop, descriptor = {
  20394. get() {
  20395. return this.get(prop);
  20396. },
  20397. set(value) {
  20398. this.set(prop, value);
  20399. }
  20400. }) => {
  20401. Object.defineProperty(Conversation.prototype, prop, descriptor);
  20402. };
  20403. const onRealtimeCreate = realtime => {
  20404. /* eslint-disable no-param-reassign */
  20405. const deviceId = v4_1();
  20406. realtime._IMClients = {};
  20407. realtime._IMClientsCreationCount = 0;
  20408. const messageParser = new MessageParser(realtime._plugins);
  20409. realtime._messageParser = messageParser;
  20410. const signAVUser = async user => realtime._request({
  20411. method: 'POST',
  20412. path: '/rtm/sign',
  20413. data: {
  20414. session_token: user.getSessionToken()
  20415. }
  20416. });
  20417. /**
  20418. * 注册消息类
  20419. *
  20420. * 在接收消息、查询消息时,会按照消息类注册顺序的逆序依次尝试解析消息内容
  20421. *
  20422. * @memberof Realtime
  20423. * @instance
  20424. * @param {Function | Function[]} messageClass 消息类,需要实现 {@link AVMessage} 接口,
  20425. * 建议继承自 {@link TypedMessage}
  20426. * @throws {TypeError} 如果 messageClass 没有实现 {@link AVMessage} 接口则抛出异常
  20427. */
  20428. const register = messageParser.register.bind(messageParser);
  20429. /**
  20430. * 创建一个即时通讯客户端,多次创建相同 id 的客户端会返回同一个实例
  20431. * @memberof Realtime
  20432. * @instance
  20433. * @param {String|AV.User} [identity] 客户端 identity,如果不指定该参数,服务端会随机生成一个字符串作为 identity,
  20434. * 如果传入一个已登录的 AV.User,则会使用该用户的 id 作为客户端 identity 登录。
  20435. * @param {Object} [options]
  20436. * @param {Function} [options.signatureFactory] open session 时的签名方法 // TODO need details
  20437. * @param {Function} [options.conversationSignatureFactory] 对话创建、增减成员操作时的签名方法
  20438. * @param {Function} [options.blacklistSignatureFactory] 黑名单操作时的签名方法
  20439. * @param {String} [options.tag] 客户端类型标记,以支持单点登录功能
  20440. * @param {String} [options.isReconnect=false] 单点登录时标记该次登录是不是应用启动时自动重新登录
  20441. * @return {Promise.<IMClient>}
  20442. */
  20443. const createIMClient = async (identity, {
  20444. tag,
  20445. isReconnect,
  20446. ...clientOptions
  20447. } = {}, lagecyTag) => {
  20448. let id;
  20449. const buildinOptions = {};
  20450. if (identity) {
  20451. if (typeof identity === 'string') {
  20452. id = identity;
  20453. } else if (identity.id && identity.getSessionToken) {
  20454. ({
  20455. id
  20456. } = identity);
  20457. const sessionToken = identity.getSessionToken();
  20458. if (!sessionToken) {
  20459. throw new Error('User must be authenticated');
  20460. }
  20461. buildinOptions.signatureFactory = signAVUser;
  20462. } else {
  20463. throw new TypeError('Identity must be a String or an AV.User');
  20464. }
  20465. if (realtime._IMClients[id] !== undefined) {
  20466. return realtime._IMClients[id];
  20467. }
  20468. }
  20469. if (lagecyTag) {
  20470. console.warn('DEPRECATION createIMClient tag param: Use options.tag instead.');
  20471. }
  20472. const _tag = tag || lagecyTag;
  20473. const promise = realtime._open().then(connection => {
  20474. const client = new IMClient(id, { ...buildinOptions,
  20475. ...clientOptions
  20476. }, {
  20477. _connection: connection,
  20478. _request: realtime._request.bind(realtime),
  20479. _messageParser: messageParser,
  20480. _plugins: realtime._plugins,
  20481. _identity: identity
  20482. });
  20483. connection.on(RECONNECT, () => client._open(realtime._options.appId, _tag, deviceId, true)
  20484. /**
  20485. * 客户端连接恢复正常,该事件通常在 {@link Realtime#event:RECONNECT} 之后发生
  20486. * @event IMClient#RECONNECT
  20487. * @see Realtime#event:RECONNECT
  20488. * @since 3.2.0
  20489. */
  20490. /**
  20491. * 客户端重新登录发生错误(网络连接已恢复,但重新登录错误)
  20492. * @event IMClient#RECONNECT_ERROR
  20493. * @since 3.2.0
  20494. */
  20495. .then(() => client.emit(RECONNECT), error => client.emit(RECONNECT_ERROR, error)));
  20496. internal(client)._eventemitter.on('beforeclose', () => {
  20497. delete realtime._IMClients[client.id];
  20498. if (realtime._firstIMClient === client) {
  20499. delete realtime._firstIMClient;
  20500. }
  20501. }, realtime);
  20502. internal(client)._eventemitter.on('close', () => {
  20503. realtime._deregister(client);
  20504. }, realtime);
  20505. return client._open(realtime._options.appId, _tag, deviceId, isReconnect).then(() => {
  20506. realtime._IMClients[client.id] = client;
  20507. realtime._IMClientsCreationCount += 1;
  20508. if (realtime._IMClientsCreationCount === 1) {
  20509. client._omitPeerId(true);
  20510. realtime._firstIMClient = client;
  20511. } else if (realtime._IMClientsCreationCount > 1 && realtime._firstIMClient) {
  20512. realtime._firstIMClient._omitPeerId(false);
  20513. }
  20514. realtime._register(client);
  20515. return client;
  20516. }).catch(error => {
  20517. delete realtime._IMClients[client.id];
  20518. throw error;
  20519. });
  20520. }).then(...finalize(() => {
  20521. realtime._deregisterPending(promise);
  20522. })).catch(error => {
  20523. delete realtime._IMClients[id];
  20524. throw error;
  20525. });
  20526. if (identity) {
  20527. realtime._IMClients[id] = promise;
  20528. }
  20529. realtime._registerPending(promise);
  20530. return promise;
  20531. };
  20532. Object.assign(realtime, {
  20533. register,
  20534. createIMClient
  20535. });
  20536. /* eslint-enable no-param-reassign */
  20537. };
  20538. const beforeCommandDispatch = (command, realtime) => {
  20539. const isIMCommand = command.service === null || command.service === 2;
  20540. if (!isIMCommand) return true;
  20541. const targetClient = command.peerId ? realtime._IMClients[command.peerId] : realtime._firstIMClient;
  20542. if (targetClient) {
  20543. Promise.resolve(targetClient).then(client => client._dispatchCommand(command)).catch(debug$d);
  20544. } else {
  20545. debug$d('[WARN] Unexpected message received without any live client match: %O', trim(command));
  20546. }
  20547. return false;
  20548. };
  20549. const IMPlugin = {
  20550. name: 'leancloud-realtime-plugin-im',
  20551. onRealtimeCreate,
  20552. beforeCommandDispatch,
  20553. messageClasses: [Message, BinaryMessage, RecalledMessage, TextMessage]
  20554. };
  20555. /** @module leancloud-realtime */
  20556. Realtime.defineConversationProperty = defineConversationProperty;
  20557. Realtime.__preRegisteredPlugins = [IMPlugin];
  20558. const Event = { ...CoreEvent,
  20559. ...IMEvent
  20560. };
  20561. exports.BinaryMessage = BinaryMessage;
  20562. exports.ChatRoom = ChatRoom;
  20563. exports.Conversation = Conversation;
  20564. exports.ConversationMemberRole = ConversationMemberRole;
  20565. exports.ConversationQuery = ConversationQuery;
  20566. exports.ErrorCode = ErrorCode;
  20567. exports.Event = Event;
  20568. exports.EventEmitter = eventemitter3;
  20569. exports.IE10Compatible = IE10Compatible;
  20570. exports.IMPlugin = IMPlugin;
  20571. exports.Message = Message;
  20572. exports.MessageParser = MessageParser;
  20573. exports.MessagePriority = MessagePriority;
  20574. exports.MessageQueryDirection = MessageQueryDirection;
  20575. exports.MessageStatus = MessageStatus;
  20576. exports.Promise = polyfilledPromise;
  20577. exports.Protocals = message;
  20578. exports.Protocols = message;
  20579. exports.Realtime = Realtime;
  20580. exports.RecalledMessage = RecalledMessage;
  20581. exports.ServiceConversation = ServiceConversation;
  20582. exports.TemporaryConversation = TemporaryConversation;
  20583. exports.TextMessage = TextMessage;
  20584. exports.TypedMessage = TypedMessage;
  20585. exports.debug = debug$2;
  20586. exports.defineConversationProperty = defineConversationProperty;
  20587. exports.getAdapter = getAdapter;
  20588. exports.messageField = messageField;
  20589. exports.messageType = messageType;
  20590. exports.setAdapters = setAdapters;
  20591. Object.defineProperty(exports, '__esModule', { value: true });
  20592. })));
  20593. //# sourceMappingURL=im.js.map