123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283 |
- /* webim javascript SDK
- * VER 1.7.2
- */
- (function(global, factory) {
- global['Long'] = factory();
- })(window, function() {
- 'use strict';
-
- function Long(low, high, unsigned) {
- this.low = low | 0;
- this.high = high | 0;
- this.unsigned = !!unsigned;
- }
- Long.prototype.__isLong__;
-
- Object.defineProperty(Long.prototype, '__isLong__', {
- value: true,
- enumerable: false,
- configurable: false
- });
-
- function isLong(obj) {
- return (obj && obj['__isLong__']) === true;
- }
- Long.isLong = isLong;
- var INT_CACHE = {};
- var UINT_CACHE = {};
-
- function fromInt(value, unsigned) {
- var obj, cachedObj, cache;
- if (unsigned) {
- value >>>= 0;
- if ((cache = 0 <= value && value < 256)) {
- cachedObj = UINT_CACHE[value];
- if (cachedObj) return cachedObj;
- }
- obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true);
- if (cache) UINT_CACHE[value] = obj;
- return obj;
- } else {
- value |= 0;
- if ((cache = -128 <= value && value < 128)) {
- cachedObj = INT_CACHE[value];
- if (cachedObj) return cachedObj;
- }
- obj = fromBits(value, value < 0 ? -1 : 0, false);
- if (cache) INT_CACHE[value] = obj;
- return obj;
- }
- }
- Long.fromInt = fromInt;
-
- function fromNumber(value, unsigned) {
- if (isNaN(value) || !isFinite(value)) return unsigned ? UZERO : ZERO;
- if (unsigned) {
- if (value < 0) return UZERO;
- if (value >= TWO_PWR_64_DBL) return MAX_UNSIGNED_VALUE;
- } else {
- if (value <= -TWO_PWR_63_DBL) return MIN_VALUE;
- if (value + 1 >= TWO_PWR_63_DBL) return MAX_VALUE;
- }
- if (value < 0) return fromNumber(-value, unsigned).neg();
- return fromBits(value % TWO_PWR_32_DBL | 0, (value / TWO_PWR_32_DBL) | 0, unsigned);
- }
- Long.fromNumber = fromNumber;
-
- function fromBits(lowBits, highBits, unsigned) {
- return new Long(lowBits, highBits, unsigned);
- }
- Long.fromBits = fromBits;
- var pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4)
-
- function fromString(str, unsigned, radix) {
- if (str.length === 0) throw Error('empty string');
- if (str === 'NaN' || str === 'Infinity' || str === '+Infinity' || str === '-Infinity') return ZERO;
- if (typeof unsigned === 'number') {
- // For goog.math.long compatibility
- (radix = unsigned), (unsigned = false);
- } else {
- unsigned = !!unsigned;
- }
- radix = radix || 10;
- if (radix < 2 || 36 < radix) throw RangeError('radix');
-
- var p;
- if ((p = str.indexOf('-')) > 0) throw Error('interior hyphen');
- else if (p === 0) {
- return fromString(str.substring(1), unsigned, radix).neg();
- }
- var radixToPower = fromNumber(pow_dbl(radix, 8));
-
- var result = ZERO;
- for (var i = 0; i < str.length; i += 8) {
- var size = Math.min(8, str.length - i),
- value = parseInt(str.substring(i, i + size), radix);
- if (size < 8) {
- var power = fromNumber(pow_dbl(radix, size));
- result = result.mul(power).add(fromNumber(value));
- } else {
- result = result.mul(radixToPower);
- result = result.add(fromNumber(value));
- }
- }
- result.unsigned = unsigned;
- return result;
- }
- Long.fromString = fromString;
-
- function fromValue(val) {
- if (val /* is compatible */ instanceof Long) return val;
- if (typeof val === 'number') return fromNumber(val);
- if (typeof val === 'string') return fromString(val);
- // Throws for non-objects, converts non-instanceof Long:
- return fromBits(val.low, val.high, val.unsigned);
- }
- Long.fromValue = fromValue;
- var TWO_PWR_16_DBL = 1 << 16;
- var TWO_PWR_24_DBL = 1 << 24;
- var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;
- var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;
- var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;
- var TWO_PWR_24 = fromInt(TWO_PWR_24_DBL);
- var ZERO = fromInt(0);
- Long.ZERO = ZERO;
- var UZERO = fromInt(0, true);
- Long.UZERO = UZERO;
- var ONE = fromInt(1);
- Long.ONE = ONE;
- var UONE = fromInt(1, true);
- Long.UONE = UONE;
- var NEG_ONE = fromInt(-1);
- Long.NEG_ONE = NEG_ONE;
- var MAX_VALUE = fromBits(0xffffffff | 0, 0x7fffffff | 0, false);
- Long.MAX_VALUE = MAX_VALUE;
- var MAX_UNSIGNED_VALUE = fromBits(0xffffffff | 0, 0xffffffff | 0, true);
- Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE;
- var MIN_VALUE = fromBits(0, 0x80000000 | 0, false);
- Long.MIN_VALUE = MIN_VALUE;
- var LongPrototype = Long.prototype;
- LongPrototype.toInt = function toInt() {
- return this.unsigned ? this.low >>> 0 : this.low;
- };
- LongPrototype.toNumber = function toNumber() {
- if (this.unsigned) return (this.high >>> 0) * TWO_PWR_32_DBL + (this.low >>> 0);
- return this.high * TWO_PWR_32_DBL + (this.low >>> 0);
- };
-
- LongPrototype.toString = function toString(radix) {
- radix = radix || 10;
- if (radix < 2 || 36 < radix) throw RangeError('radix');
- if (this.isZero()) return '0';
- if (this.isNegative()) {
- // Unsigned Longs are never negative
- if (this.eq(MIN_VALUE)) {
- // We need to change the Long value before it can be negated, so we remove
- // the bottom-most digit in this base and then recurse to do the rest.
- var radixLong = fromNumber(radix),
- div = this.div(radixLong),
- rem1 = div.mul(radixLong).sub(this);
- return div.toString(radix) + rem1.toInt().toString(radix);
- } else return '-' + this.neg().toString(radix);
- }
- var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned),
- rem = this;
- var result = '';
- while (true) {
- var remDiv = rem.div(radixToPower),
- intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0,
- digits = intval.toString(radix);
- rem = remDiv;
- if (rem.isZero()) return digits + result;
- else {
- while (digits.length < 6) digits = '0' + digits;
- result = '' + digits + result;
- }
- }
- };
- LongPrototype.getHighBits = function getHighBits() {
- return this.high;
- };
- LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() {
- return this.high >>> 0;
- };
- LongPrototype.getLowBits = function getLowBits() {
- return this.low;
- };
- LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() {
- return this.low >>> 0;
- };
- LongPrototype.getNumBitsAbs = function getNumBitsAbs() {
- if (this.isNegative())
- // Unsigned Longs are never negative
- return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs();
- var val = this.high != 0 ? this.high : this.low;
- for (var bit = 31; bit > 0; bit--) if ((val & (1 << bit)) != 0) break;
- return this.high != 0 ? bit + 33 : bit + 1;
- };
- LongPrototype.isZero = function isZero() {
- return this.high === 0 && this.low === 0;
- };
- LongPrototype.isNegative = function isNegative() {
- return !this.unsigned && this.high < 0;
- };
- LongPrototype.isPositive = function isPositive() {
- return this.unsigned || this.high >= 0;
- };
- LongPrototype.isOdd = function isOdd() {
- return (this.low & 1) === 1;
- };
- LongPrototype.isEven = function isEven() {
- return (this.low & 1) === 0;
- };
- LongPrototype.equals = function equals(other) {
- if (!isLong(other)) other = fromValue(other);
- if (this.unsigned !== other.unsigned && this.high >>> 31 === 1 && other.high >>> 31 === 1) return false;
- return this.high === other.high && this.low === other.low;
- };
- LongPrototype.eq = LongPrototype.equals;
- LongPrototype.notEquals = function notEquals(other) {
- return !this.eq(/* validates */ other);
- };
- LongPrototype.neq = LongPrototype.notEquals;
-
- /**
- * Tests if this Long's value is less than the specified's.
- * @param {!Long|number|string} other Other value
- * @returns {boolean}
- */
- LongPrototype.lessThan = function lessThan(other) {
- return this.comp(/* validates */ other) < 0;
- };
-
- /**
- * Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}.
- * @function
- * @param {!Long|number|string} other Other value
- * @returns {boolean}
- */
- LongPrototype.lt = LongPrototype.lessThan;
-
- /**
- * Tests if this Long's value is less than or equal the specified's.
- * @param {!Long|number|string} other Other value
- * @returns {boolean}
- */
- LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) {
- return this.comp(/* validates */ other) <= 0;
- };
-
- /**
- * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.
- * @function
- * @param {!Long|number|string} other Other value
- * @returns {boolean}
- */
- LongPrototype.lte = LongPrototype.lessThanOrEqual;
-
- /**
- * Tests if this Long's value is greater than the specified's.
- * @param {!Long|number|string} other Other value
- * @returns {boolean}
- */
- LongPrototype.greaterThan = function greaterThan(other) {
- return this.comp(/* validates */ other) > 0;
- };
-
- /**
- * Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}.
- * @function
- * @param {!Long|number|string} other Other value
- * @returns {boolean}
- */
- LongPrototype.gt = LongPrototype.greaterThan;
-
- /**
- * Tests if this Long's value is greater than or equal the specified's.
- * @param {!Long|number|string} other Other value
- * @returns {boolean}
- */
- LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) {
- return this.comp(/* validates */ other) >= 0;
- };
-
- /**
- * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.
- * @function
- * @param {!Long|number|string} other Other value
- * @returns {boolean}
- */
- LongPrototype.gte = LongPrototype.greaterThanOrEqual;
-
- /**
- * Compares this Long's value with the specified's.
- * @param {!Long|number|string} other Other value
- * @returns {number} 0 if they are the same, 1 if the this is greater and -1
- * if the given one is greater
- */
- LongPrototype.compare = function compare(other) {
- if (!isLong(other)) other = fromValue(other);
- if (this.eq(other)) return 0;
- var thisNeg = this.isNegative(),
- otherNeg = other.isNegative();
- if (thisNeg && !otherNeg) return -1;
- if (!thisNeg && otherNeg) return 1;
- // At this point the sign bits are the same
- if (!this.unsigned) return this.sub(other).isNegative() ? -1 : 1;
- // Both are positive if at least one is unsigned
- return other.high >>> 0 > this.high >>> 0 || (other.high === this.high && other.low >>> 0 > this.low >>> 0) ? -1 : 1;
- };
-
- /**
- * Compares this Long's value with the specified's. This is an alias of {@link Long#compare}.
- * @function
- * @param {!Long|number|string} other Other value
- * @returns {number} 0 if they are the same, 1 if the this is greater and -1
- * if the given one is greater
- */
- LongPrototype.comp = LongPrototype.compare;
-
- /**
- * Negates this Long's value.
- * @returns {!Long} Negated Long
- */
- LongPrototype.negate = function negate() {
- if (!this.unsigned && this.eq(MIN_VALUE)) return MIN_VALUE;
- return this.not().add(ONE);
- };
-
- /**
- * Negates this Long's value. This is an alias of {@link Long#negate}.
- * @function
- * @returns {!Long} Negated Long
- */
- LongPrototype.neg = LongPrototype.negate;
-
- /**
- * Returns the sum of this and the specified Long.
- * @param {!Long|number|string} addend Addend
- * @returns {!Long} Sum
- */
- LongPrototype.add = function add(addend) {
- if (!isLong(addend)) addend = fromValue(addend);
-
- // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
-
- var a48 = this.high >>> 16;
- var a32 = this.high & 0xffff;
- var a16 = this.low >>> 16;
- var a00 = this.low & 0xffff;
-
- var b48 = addend.high >>> 16;
- var b32 = addend.high & 0xffff;
- var b16 = addend.low >>> 16;
- var b00 = addend.low & 0xffff;
-
- var c48 = 0,
- c32 = 0,
- c16 = 0,
- c00 = 0;
- c00 += a00 + b00;
- c16 += c00 >>> 16;
- c00 &= 0xffff;
- c16 += a16 + b16;
- c32 += c16 >>> 16;
- c16 &= 0xffff;
- c32 += a32 + b32;
- c48 += c32 >>> 16;
- c32 &= 0xffff;
- c48 += a48 + b48;
- c48 &= 0xffff;
- return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
- };
-
- /**
- * Returns the difference of this and the specified Long.
- * @param {!Long|number|string} subtrahend Subtrahend
- * @returns {!Long} Difference
- */
- LongPrototype.subtract = function subtract(subtrahend) {
- if (!isLong(subtrahend)) subtrahend = fromValue(subtrahend);
- return this.add(subtrahend.neg());
- };
-
- /**
- * Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}.
- * @function
- * @param {!Long|number|string} subtrahend Subtrahend
- * @returns {!Long} Difference
- */
- LongPrototype.sub = LongPrototype.subtract;
-
- /**
- * Returns the product of this and the specified Long.
- * @param {!Long|number|string} multiplier Multiplier
- * @returns {!Long} Product
- */
- LongPrototype.multiply = function multiply(multiplier) {
- if (this.isZero()) return ZERO;
- if (!isLong(multiplier)) multiplier = fromValue(multiplier);
- if (multiplier.isZero()) return ZERO;
- if (this.eq(MIN_VALUE)) return multiplier.isOdd() ? MIN_VALUE : ZERO;
- if (multiplier.eq(MIN_VALUE)) return this.isOdd() ? MIN_VALUE : ZERO;
-
- if (this.isNegative()) {
- if (multiplier.isNegative()) return this.neg().mul(multiplier.neg());
- else
- return this.neg()
- .mul(multiplier)
- .neg();
- } else if (multiplier.isNegative()) return this.mul(multiplier.neg()).neg();
-
- // If both longs are small, use float multiplication
- if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24)) return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned);
-
- // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
- // We can skip products that would overflow.
-
- var a48 = this.high >>> 16;
- var a32 = this.high & 0xffff;
- var a16 = this.low >>> 16;
- var a00 = this.low & 0xffff;
-
- var b48 = multiplier.high >>> 16;
- var b32 = multiplier.high & 0xffff;
- var b16 = multiplier.low >>> 16;
- var b00 = multiplier.low & 0xffff;
-
- var c48 = 0,
- c32 = 0,
- c16 = 0,
- c00 = 0;
- c00 += a00 * b00;
- c16 += c00 >>> 16;
- c00 &= 0xffff;
- c16 += a16 * b00;
- c32 += c16 >>> 16;
- c16 &= 0xffff;
- c16 += a00 * b16;
- c32 += c16 >>> 16;
- c16 &= 0xffff;
- c32 += a32 * b00;
- c48 += c32 >>> 16;
- c32 &= 0xffff;
- c32 += a16 * b16;
- c48 += c32 >>> 16;
- c32 &= 0xffff;
- c32 += a00 * b32;
- c48 += c32 >>> 16;
- c32 &= 0xffff;
- c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
- c48 &= 0xffff;
- return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
- };
-
- /**
- * Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}.
- * @function
- * @param {!Long|number|string} multiplier Multiplier
- * @returns {!Long} Product
- */
- LongPrototype.mul = LongPrototype.multiply;
-
- /**
- * Returns this Long divided by the specified. The result is signed if this Long is signed or
- * unsigned if this Long is unsigned.
- * @param {!Long|number|string} divisor Divisor
- * @returns {!Long} Quotient
- */
- LongPrototype.divide = function divide(divisor) {
- if (!isLong(divisor)) divisor = fromValue(divisor);
- if (divisor.isZero()) throw Error('division by zero');
- if (this.isZero()) return this.unsigned ? UZERO : ZERO;
- var approx, rem, res;
- if (!this.unsigned) {
- // This section is only relevant for signed longs and is derived from the
- // closure library as a whole.
- if (this.eq(MIN_VALUE)) {
- if (divisor.eq(ONE) || divisor.eq(NEG_ONE)) return MIN_VALUE;
- // recall that -MIN_VALUE == MIN_VALUE
- else if (divisor.eq(MIN_VALUE)) return ONE;
- else {
- // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
- var halfThis = this.shr(1);
- approx = halfThis.div(divisor).shl(1);
- if (approx.eq(ZERO)) {
- return divisor.isNegative() ? ONE : NEG_ONE;
- } else {
- rem = this.sub(divisor.mul(approx));
- res = approx.add(rem.div(divisor));
- return res;
- }
- }
- } else if (divisor.eq(MIN_VALUE)) return this.unsigned ? UZERO : ZERO;
- if (this.isNegative()) {
- if (divisor.isNegative()) return this.neg().div(divisor.neg());
- return this.neg()
- .div(divisor)
- .neg();
- } else if (divisor.isNegative()) return this.div(divisor.neg()).neg();
- res = ZERO;
- } else {
- // The algorithm below has not been made for unsigned longs. It's therefore
- // required to take special care of the MSB prior to running it.
- if (!divisor.unsigned) divisor = divisor.toUnsigned();
- if (divisor.gt(this)) return UZERO;
- if (divisor.gt(this.shru(1)))
- // 15 >>> 1 = 7 ; with divisor = 8 ; true
- return UONE;
- res = UZERO;
- }
-
- // Repeat the following until the remainder is less than other: find a
- // floating-point that approximates remainder / other *from below*, add this
- // into the result, and subtract it from the remainder. It is critical that
- // the approximate value is less than or equal to the real value so that the
- // remainder never becomes negative.
- rem = this;
- while (rem.gte(divisor)) {
- // Approximate the result of division. This may be a little greater or
- // smaller than the actual value.
- approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber()));
-
- // We will tweak the approximate result by changing it in the 48-th digit or
- // the smallest non-fractional digit, whichever is larger.
- var log2 = Math.ceil(Math.log(approx) / Math.LN2),
- delta = log2 <= 48 ? 1 : pow_dbl(2, log2 - 48),
- // Decrease the approximation until it is smaller than the remainder. Note
- // that if it is too large, the product overflows and is negative.
- approxRes = fromNumber(approx),
- approxRem = approxRes.mul(divisor);
- while (approxRem.isNegative() || approxRem.gt(rem)) {
- approx -= delta;
- approxRes = fromNumber(approx, this.unsigned);
- approxRem = approxRes.mul(divisor);
- }
-
- // We know the answer can't be zero... and actually, zero would cause
- // infinite recursion since we would make no progress.
- if (approxRes.isZero()) approxRes = ONE;
-
- res = res.add(approxRes);
- rem = rem.sub(approxRem);
- }
- return res;
- };
-
- /**
- * Returns this Long divided by the specified. This is an alias of {@link Long#divide}.
- * @function
- * @param {!Long|number|string} divisor Divisor
- * @returns {!Long} Quotient
- */
- LongPrototype.div = LongPrototype.divide;
-
- /**
- * Returns this Long modulo the specified.
- * @param {!Long|number|string} divisor Divisor
- * @returns {!Long} Remainder
- */
- LongPrototype.modulo = function modulo(divisor) {
- if (!isLong(divisor)) divisor = fromValue(divisor);
- return this.sub(this.div(divisor).mul(divisor));
- };
-
- /**
- * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.
- * @function
- * @param {!Long|number|string} divisor Divisor
- * @returns {!Long} Remainder
- */
- LongPrototype.mod = LongPrototype.modulo;
-
- /**
- * Returns the bitwise NOT of this Long.
- * @returns {!Long}
- */
- LongPrototype.not = function not() {
- return fromBits(~this.low, ~this.high, this.unsigned);
- };
-
- /**
- * Returns the bitwise AND of this Long and the specified.
- * @param {!Long|number|string} other Other Long
- * @returns {!Long}
- */
- LongPrototype.and = function and(other) {
- if (!isLong(other)) other = fromValue(other);
- return fromBits(this.low & other.low, this.high & other.high, this.unsigned);
- };
-
- /**
- * Returns the bitwise OR of this Long and the specified.
- * @param {!Long|number|string} other Other Long
- * @returns {!Long}
- */
- LongPrototype.or = function or(other) {
- if (!isLong(other)) other = fromValue(other);
- return fromBits(this.low | other.low, this.high | other.high, this.unsigned);
- };
-
- /**
- * Returns the bitwise XOR of this Long and the given one.
- * @param {!Long|number|string} other Other Long
- * @returns {!Long}
- */
- LongPrototype.xor = function xor(other) {
- if (!isLong(other)) other = fromValue(other);
- return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned);
- };
-
- /**
- * Returns this Long with bits shifted to the left by the given amount.
- * @param {number|!Long} numBits Number of bits
- * @returns {!Long} Shifted Long
- */
- LongPrototype.shiftLeft = function shiftLeft(numBits) {
- if (isLong(numBits)) numBits = numBits.toInt();
- if ((numBits &= 63) === 0) return this;
- else if (numBits < 32) return fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned);
- else return fromBits(0, this.low << (numBits - 32), this.unsigned);
- };
-
- /**
- * Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}.
- * @function
- * @param {number|!Long} numBits Number of bits
- * @returns {!Long} Shifted Long
- */
- LongPrototype.shl = LongPrototype.shiftLeft;
-
- /**
- * Returns this Long with bits arithmetically shifted to the right by the given amount.
- * @param {number|!Long} numBits Number of bits
- * @returns {!Long} Shifted Long
- */
- LongPrototype.shiftRight = function shiftRight(numBits) {
- if (isLong(numBits)) numBits = numBits.toInt();
- if ((numBits &= 63) === 0) return this;
- else if (numBits < 32) return fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned);
- else return fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned);
- };
-
- /**
- * Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}.
- * @function
- * @param {number|!Long} numBits Number of bits
- * @returns {!Long} Shifted Long
- */
- LongPrototype.shr = LongPrototype.shiftRight;
-
- /**
- * Returns this Long with bits logically shifted to the right by the given amount.
- * @param {number|!Long} numBits Number of bits
- * @returns {!Long} Shifted Long
- */
- LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) {
- if (isLong(numBits)) numBits = numBits.toInt();
- numBits &= 63;
- if (numBits === 0) return this;
- else {
- var high = this.high;
- if (numBits < 32) {
- var low = this.low;
- return fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned);
- } else if (numBits === 32) return fromBits(high, 0, this.unsigned);
- else return fromBits(high >>> (numBits - 32), 0, this.unsigned);
- }
- };
-
- /**
- * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.
- * @function
- * @param {number|!Long} numBits Number of bits
- * @returns {!Long} Shifted Long
- */
- LongPrototype.shru = LongPrototype.shiftRightUnsigned;
-
- /**
- * Converts this Long to signed.
- * @returns {!Long} Signed long
- */
- LongPrototype.toSigned = function toSigned() {
- if (!this.unsigned) return this;
- return fromBits(this.low, this.high, false);
- };
-
- /**
- * Converts this Long to unsigned.
- * @returns {!Long} Unsigned long
- */
- LongPrototype.toUnsigned = function toUnsigned() {
- if (this.unsigned) return this;
- return fromBits(this.low, this.high, true);
- };
-
- /**
- * Converts this Long to its byte representation.
- * @param {boolean=} le Whether little or big endian, defaults to big endian
- * @returns {!Array.<number>} Byte representation
- */
- LongPrototype.toBytes = function(le) {
- return le ? this.toBytesLE() : this.toBytesBE();
- };
-
- /**
- * Converts this Long to its little endian byte representation.
- * @returns {!Array.<number>} Little endian byte representation
- */
- LongPrototype.toBytesLE = function() {
- var hi = this.high,
- lo = this.low;
- return [lo & 0xff, (lo >>> 8) & 0xff, (lo >>> 16) & 0xff, (lo >>> 24) & 0xff, hi & 0xff, (hi >>> 8) & 0xff, (hi >>> 16) & 0xff, (hi >>> 24) & 0xff];
- };
-
- /**
- * Converts this Long to its big endian byte representation.
- * @returns {!Array.<number>} Big endian byte representation
- */
- LongPrototype.toBytesBE = function() {
- var hi = this.high,
- lo = this.low;
- return [(hi >>> 24) & 0xff, (hi >>> 16) & 0xff, (hi >>> 8) & 0xff, hi & 0xff, (lo >>> 24) & 0xff, (lo >>> 16) & 0xff, (lo >>> 8) & 0xff, lo & 0xff];
- };
-
- return Long;
- });
-
- (function (factory) {
- global['SparkMD5'] = factory();
- }(function (undefined) {
-
- 'use strict';
-
- /*
- * Fastest md5 implementation around (JKM md5).
- * Credits: Joseph Myers
- *
- * @see http://www.myersdaily.org/joseph/javascript/md5-text.html
- * @see http://jsperf.com/md5-shootout/7
- */
-
- /* this function is much faster,
- so if possible we use it. Some IEs
- are the only ones I know of that
- need the idiotic second function,
- generated by an if clause. */
- var add32 = function (a, b) {
- return (a + b) & 0xFFFFFFFF;
- },
- hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
-
-
- function cmn(q, a, b, x, s, t) {
- a = add32(add32(a, q), add32(x, t));
- return add32((a << s) | (a >>> (32 - s)), b);
- }
-
- function md5cycle(x, k) {
- var a = x[0],
- b = x[1],
- c = x[2],
- d = x[3];
-
- a += (b & c | ~b & d) + k[0] - 680876936 | 0;
- a = (a << 7 | a >>> 25) + b | 0;
- d += (a & b | ~a & c) + k[1] - 389564586 | 0;
- d = (d << 12 | d >>> 20) + a | 0;
- c += (d & a | ~d & b) + k[2] + 606105819 | 0;
- c = (c << 17 | c >>> 15) + d | 0;
- b += (c & d | ~c & a) + k[3] - 1044525330 | 0;
- b = (b << 22 | b >>> 10) + c | 0;
- a += (b & c | ~b & d) + k[4] - 176418897 | 0;
- a = (a << 7 | a >>> 25) + b | 0;
- d += (a & b | ~a & c) + k[5] + 1200080426 | 0;
- d = (d << 12 | d >>> 20) + a | 0;
- c += (d & a | ~d & b) + k[6] - 1473231341 | 0;
- c = (c << 17 | c >>> 15) + d | 0;
- b += (c & d | ~c & a) + k[7] - 45705983 | 0;
- b = (b << 22 | b >>> 10) + c | 0;
- a += (b & c | ~b & d) + k[8] + 1770035416 | 0;
- a = (a << 7 | a >>> 25) + b | 0;
- d += (a & b | ~a & c) + k[9] - 1958414417 | 0;
- d = (d << 12 | d >>> 20) + a | 0;
- c += (d & a | ~d & b) + k[10] - 42063 | 0;
- c = (c << 17 | c >>> 15) + d | 0;
- b += (c & d | ~c & a) + k[11] - 1990404162 | 0;
- b = (b << 22 | b >>> 10) + c | 0;
- a += (b & c | ~b & d) + k[12] + 1804603682 | 0;
- a = (a << 7 | a >>> 25) + b | 0;
- d += (a & b | ~a & c) + k[13] - 40341101 | 0;
- d = (d << 12 | d >>> 20) + a | 0;
- c += (d & a | ~d & b) + k[14] - 1502002290 | 0;
- c = (c << 17 | c >>> 15) + d | 0;
- b += (c & d | ~c & a) + k[15] + 1236535329 | 0;
- b = (b << 22 | b >>> 10) + c | 0;
-
- a += (b & d | c & ~d) + k[1] - 165796510 | 0;
- a = (a << 5 | a >>> 27) + b | 0;
- d += (a & c | b & ~c) + k[6] - 1069501632 | 0;
- d = (d << 9 | d >>> 23) + a | 0;
- c += (d & b | a & ~b) + k[11] + 643717713 | 0;
- c = (c << 14 | c >>> 18) + d | 0;
- b += (c & a | d & ~a) + k[0] - 373897302 | 0;
- b = (b << 20 | b >>> 12) + c | 0;
- a += (b & d | c & ~d) + k[5] - 701558691 | 0;
- a = (a << 5 | a >>> 27) + b | 0;
- d += (a & c | b & ~c) + k[10] + 38016083 | 0;
- d = (d << 9 | d >>> 23) + a | 0;
- c += (d & b | a & ~b) + k[15] - 660478335 | 0;
- c = (c << 14 | c >>> 18) + d | 0;
- b += (c & a | d & ~a) + k[4] - 405537848 | 0;
- b = (b << 20 | b >>> 12) + c | 0;
- a += (b & d | c & ~d) + k[9] + 568446438 | 0;
- a = (a << 5 | a >>> 27) + b | 0;
- d += (a & c | b & ~c) + k[14] - 1019803690 | 0;
- d = (d << 9 | d >>> 23) + a | 0;
- c += (d & b | a & ~b) + k[3] - 187363961 | 0;
- c = (c << 14 | c >>> 18) + d | 0;
- b += (c & a | d & ~a) + k[8] + 1163531501 | 0;
- b = (b << 20 | b >>> 12) + c | 0;
- a += (b & d | c & ~d) + k[13] - 1444681467 | 0;
- a = (a << 5 | a >>> 27) + b | 0;
- d += (a & c | b & ~c) + k[2] - 51403784 | 0;
- d = (d << 9 | d >>> 23) + a | 0;
- c += (d & b | a & ~b) + k[7] + 1735328473 | 0;
- c = (c << 14 | c >>> 18) + d | 0;
- b += (c & a | d & ~a) + k[12] - 1926607734 | 0;
- b = (b << 20 | b >>> 12) + c | 0;
-
- a += (b ^ c ^ d) + k[5] - 378558 | 0;
- a = (a << 4 | a >>> 28) + b | 0;
- d += (a ^ b ^ c) + k[8] - 2022574463 | 0;
- d = (d << 11 | d >>> 21) + a | 0;
- c += (d ^ a ^ b) + k[11] + 1839030562 | 0;
- c = (c << 16 | c >>> 16) + d | 0;
- b += (c ^ d ^ a) + k[14] - 35309556 | 0;
- b = (b << 23 | b >>> 9) + c | 0;
- a += (b ^ c ^ d) + k[1] - 1530992060 | 0;
- a = (a << 4 | a >>> 28) + b | 0;
- d += (a ^ b ^ c) + k[4] + 1272893353 | 0;
- d = (d << 11 | d >>> 21) + a | 0;
- c += (d ^ a ^ b) + k[7] - 155497632 | 0;
- c = (c << 16 | c >>> 16) + d | 0;
- b += (c ^ d ^ a) + k[10] - 1094730640 | 0;
- b = (b << 23 | b >>> 9) + c | 0;
- a += (b ^ c ^ d) + k[13] + 681279174 | 0;
- a = (a << 4 | a >>> 28) + b | 0;
- d += (a ^ b ^ c) + k[0] - 358537222 | 0;
- d = (d << 11 | d >>> 21) + a | 0;
- c += (d ^ a ^ b) + k[3] - 722521979 | 0;
- c = (c << 16 | c >>> 16) + d | 0;
- b += (c ^ d ^ a) + k[6] + 76029189 | 0;
- b = (b << 23 | b >>> 9) + c | 0;
- a += (b ^ c ^ d) + k[9] - 640364487 | 0;
- a = (a << 4 | a >>> 28) + b | 0;
- d += (a ^ b ^ c) + k[12] - 421815835 | 0;
- d = (d << 11 | d >>> 21) + a | 0;
- c += (d ^ a ^ b) + k[15] + 530742520 | 0;
- c = (c << 16 | c >>> 16) + d | 0;
- b += (c ^ d ^ a) + k[2] - 995338651 | 0;
- b = (b << 23 | b >>> 9) + c | 0;
-
- a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;
- a = (a << 6 | a >>> 26) + b | 0;
- d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;
- d = (d << 10 | d >>> 22) + a | 0;
- c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;
- c = (c << 15 | c >>> 17) + d | 0;
- b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;
- b = (b << 21 |b >>> 11) + c | 0;
- a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;
- a = (a << 6 | a >>> 26) + b | 0;
- d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;
- d = (d << 10 | d >>> 22) + a | 0;
- c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;
- c = (c << 15 | c >>> 17) + d | 0;
- b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;
- b = (b << 21 |b >>> 11) + c | 0;
- a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;
- a = (a << 6 | a >>> 26) + b | 0;
- d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;
- d = (d << 10 | d >>> 22) + a | 0;
- c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;
- c = (c << 15 | c >>> 17) + d | 0;
- b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;
- b = (b << 21 |b >>> 11) + c | 0;
- a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;
- a = (a << 6 | a >>> 26) + b | 0;
- d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;
- d = (d << 10 | d >>> 22) + a | 0;
- c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;
- c = (c << 15 | c >>> 17) + d | 0;
- b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;
- b = (b << 21 | b >>> 11) + c | 0;
-
- x[0] = a + x[0] | 0;
- x[1] = b + x[1] | 0;
- x[2] = c + x[2] | 0;
- x[3] = d + x[3] | 0;
- }
-
- function md5blk(s) {
- var md5blks = [],
- i; /* Andy King said do it this way. */
-
- for (i = 0; i < 64; i += 4) {
- md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
- }
- return md5blks;
- }
-
- function md5blk_array(a) {
- var md5blks = [],
- i; /* Andy King said do it this way. */
-
- for (i = 0; i < 64; i += 4) {
- md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
- }
- return md5blks;
- }
-
- function md51(s) {
- var n = s.length,
- state = [1732584193, -271733879, -1732584194, 271733878],
- i,
- length,
- tail,
- tmp,
- lo,
- hi;
-
- for (i = 64; i <= n; i += 64) {
- md5cycle(state, md5blk(s.substring(i - 64, i)));
- }
- s = s.substring(i - 64);
- length = s.length;
- tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
- for (i = 0; i < length; i += 1) {
- tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
- }
- tail[i >> 2] |= 0x80 << ((i % 4) << 3);
- if (i > 55) {
- md5cycle(state, tail);
- for (i = 0; i < 16; i += 1) {
- tail[i] = 0;
- }
- }
-
- // Beware that the final length might not fit in 32 bits so we take care of that
- tmp = n * 8;
- tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
- lo = parseInt(tmp[2], 16);
- hi = parseInt(tmp[1], 16) || 0;
-
- tail[14] = lo;
- tail[15] = hi;
-
- md5cycle(state, tail);
- return state;
- }
-
- function md51_array(a) {
- var n = a.length,
- state = [1732584193, -271733879, -1732584194, 271733878],
- i,
- length,
- tail,
- tmp,
- lo,
- hi;
-
- for (i = 64; i <= n; i += 64) {
- md5cycle(state, md5blk_array(a.subarray(i - 64, i)));
- }
-
- // Not sure if it is a bug, however IE10 will always produce a sub array of length 1
- // containing the last element of the parent array if the sub array specified starts
- // beyond the length of the parent array - weird.
- // https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue
- a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0);
-
- length = a.length;
- tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
- for (i = 0; i < length; i += 1) {
- tail[i >> 2] |= a[i] << ((i % 4) << 3);
- }
-
- tail[i >> 2] |= 0x80 << ((i % 4) << 3);
- if (i > 55) {
- md5cycle(state, tail);
- for (i = 0; i < 16; i += 1) {
- tail[i] = 0;
- }
- }
-
- // Beware that the final length might not fit in 32 bits so we take care of that
- tmp = n * 8;
- tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
- lo = parseInt(tmp[2], 16);
- hi = parseInt(tmp[1], 16) || 0;
-
- tail[14] = lo;
- tail[15] = hi;
-
- md5cycle(state, tail);
-
- return state;
- }
-
- function rhex(n) {
- var s = '',
- j;
- for (j = 0; j < 4; j += 1) {
- s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
- }
- return s;
- }
-
- function hex(x) {
- var i;
- for (i = 0; i < x.length; i += 1) {
- x[i] = rhex(x[i]);
- }
- return x.join('');
- }
-
- // In some cases the fast add32 function cannot be used..
- if (hex(md51('hello')) !== '5d41402abc4b2a76b9719d911017c592') {
- add32 = function (x, y) {
- var lsw = (x & 0xFFFF) + (y & 0xFFFF),
- msw = (x >> 16) + (y >> 16) + (lsw >> 16);
- return (msw << 16) | (lsw & 0xFFFF);
- };
- }
-
- // ---------------------------------------------------
-
- /**
- * ArrayBuffer slice polyfill.
- *
- * @see https://github.com/ttaubert/node-arraybuffer-slice
- */
-
- if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
- (function () {
- function clamp(val, length) {
- val = (val | 0) || 0;
-
- if (val < 0) {
- return Math.max(val + length, 0);
- }
-
- return Math.min(val, length);
- }
-
- ArrayBuffer.prototype.slice = function (from, to) {
- var length = this.byteLength,
- begin = clamp(from, length),
- end = length,
- num,
- target,
- targetArray,
- sourceArray;
-
- if (to !== undefined) {
- end = clamp(to, length);
- }
-
- if (begin > end) {
- return new ArrayBuffer(0);
- }
-
- num = end - begin;
- target = new ArrayBuffer(num);
- targetArray = new Uint8Array(target);
-
- sourceArray = new Uint8Array(this, begin, num);
- targetArray.set(sourceArray);
-
- return target;
- };
- })();
- }
-
- // ---------------------------------------------------
-
- /**
- * Helpers.
- */
-
- function toUtf8(str) {
- if (/[\u0080-\uFFFF]/.test(str)) {
- str = unescape(encodeURIComponent(str));
- }
-
- return str;
- }
-
- function utf8Str2ArrayBuffer(str, returnUInt8Array) {
- var length = str.length,
- buff = new ArrayBuffer(length),
- arr = new Uint8Array(buff),
- i;
-
- for (i = 0; i < length; i += 1) {
- arr[i] = str.charCodeAt(i);
- }
-
- return returnUInt8Array ? arr : buff;
- }
-
- function arrayBuffer2Utf8Str(buff) {
- return String.fromCharCode.apply(null, new Uint8Array(buff));
- }
-
- function concatenateArrayBuffers(first, second, returnUInt8Array) {
- var result = new Uint8Array(first.byteLength + second.byteLength);
-
- result.set(new Uint8Array(first));
- result.set(new Uint8Array(second), first.byteLength);
-
- return returnUInt8Array ? result : result.buffer;
- }
-
- function hexToBinaryString(hex) {
- var bytes = [],
- length = hex.length,
- x;
-
- for (x = 0; x < length - 1; x += 2) {
- bytes.push(parseInt(hex.substr(x, 2), 16));
- }
-
- return String.fromCharCode.apply(String, bytes);
- }
-
- // ---------------------------------------------------
-
- /**
- * SparkMD5 OOP implementation.
- *
- * Use this class to perform an incremental md5, otherwise use the
- * static methods instead.
- */
-
- function SparkMD5() {
- // call reset to init the instance
- this.reset();
- }
-
- /**
- * Appends a string.
- * A conversion will be applied if an utf8 string is detected.
- *
- * @param {String} str The string to be appended
- *
- * @return {SparkMD5} The instance itself
- */
- SparkMD5.prototype.append = function (str) {
- // Converts the string to utf8 bytes if necessary
- // Then append as binary
- this.appendBinary(toUtf8(str));
-
- return this;
- };
-
- /**
- * Appends a binary string.
- *
- * @param {String} contents The binary string to be appended
- *
- * @return {SparkMD5} The instance itself
- */
- SparkMD5.prototype.appendBinary = function (contents) {
- this._buff += contents;
- this._length += contents.length;
-
- var length = this._buff.length,
- i;
-
- for (i = 64; i <= length; i += 64) {
- md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)));
- }
-
- this._buff = this._buff.substring(i - 64);
-
- return this;
- };
-
- /**
- * Finishes the incremental computation, reseting the internal state and
- * returning the result.
- *
- * @param {Boolean} raw True to get the raw string, false to get the hex string
- *
- * @return {String} The result
- */
- SparkMD5.prototype.end = function (raw) {
- var buff = this._buff,
- length = buff.length,
- i,
- tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- ret;
-
- for (i = 0; i < length; i += 1) {
- tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3);
- }
-
- this._finish(tail, length);
- ret = hex(this._hash);
-
- if (raw) {
- ret = hexToBinaryString(ret);
- }
-
- this.reset();
-
- return ret;
- };
-
- /**
- * Resets the internal state of the computation.
- *
- * @return {SparkMD5} The instance itself
- */
- SparkMD5.prototype.reset = function () {
- this._buff = '';
- this._length = 0;
- this._hash = [1732584193, -271733879, -1732584194, 271733878];
-
- return this;
- };
-
- /**
- * Gets the internal state of the computation.
- *
- * @return {Object} The state
- */
- SparkMD5.prototype.getState = function () {
- return {
- buff: this._buff,
- length: this._length,
- hash: this._hash
- };
- };
-
- /**
- * Gets the internal state of the computation.
- *
- * @param {Object} state The state
- *
- * @return {SparkMD5} The instance itself
- */
- SparkMD5.prototype.setState = function (state) {
- this._buff = state.buff;
- this._length = state.length;
- this._hash = state.hash;
-
- return this;
- };
-
- /**
- * Releases memory used by the incremental buffer and other additional
- * resources. If you plan to use the instance again, use reset instead.
- */
- SparkMD5.prototype.destroy = function () {
- delete this._hash;
- delete this._buff;
- delete this._length;
- };
-
- /**
- * Finish the final calculation based on the tail.
- *
- * @param {Array} tail The tail (will be modified)
- * @param {Number} length The length of the remaining buffer
- */
- SparkMD5.prototype._finish = function (tail, length) {
- var i = length,
- tmp,
- lo,
- hi;
-
- tail[i >> 2] |= 0x80 << ((i % 4) << 3);
- if (i > 55) {
- md5cycle(this._hash, tail);
- for (i = 0; i < 16; i += 1) {
- tail[i] = 0;
- }
- }
-
- // Do the final computation based on the tail and length
- // Beware that the final length may not fit in 32 bits so we take care of that
- tmp = this._length * 8;
- tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
- lo = parseInt(tmp[2], 16);
- hi = parseInt(tmp[1], 16) || 0;
-
- tail[14] = lo;
- tail[15] = hi;
- md5cycle(this._hash, tail);
- };
-
- /**
- * Performs the md5 hash on a string.
- * A conversion will be applied if utf8 string is detected.
- *
- * @param {String} str The string
- * @param {Boolean} raw True to get the raw string, false to get the hex string
- *
- * @return {String} The result
- */
- SparkMD5.hash = function (str, raw) {
- // Converts the string to utf8 bytes if necessary
- // Then compute it using the binary function
- return SparkMD5.hashBinary(toUtf8(str), raw);
- };
-
- /**
- * Performs the md5 hash on a binary string.
- *
- * @param {String} content The binary string
- * @param {Boolean} raw True to get the raw string, false to get the hex string
- *
- * @return {String} The result
- */
- SparkMD5.hashBinary = function (content, raw) {
- var hash = md51(content),
- ret = hex(hash);
-
- return raw ? hexToBinaryString(ret) : ret;
- };
-
- // ---------------------------------------------------
-
- /**
- * SparkMD5 OOP implementation for array buffers.
- *
- * Use this class to perform an incremental md5 ONLY for array buffers.
- */
- SparkMD5.ArrayBuffer = function () {
- // call reset to init the instance
- this.reset();
- };
-
- /**
- * Appends an array buffer.
- *
- * @param {ArrayBuffer} arr The array to be appended
- *
- * @return {SparkMD5.ArrayBuffer} The instance itself
- */
- SparkMD5.ArrayBuffer.prototype.append = function (arr) {
- var buff = concatenateArrayBuffers(this._buff.buffer, arr, true),
- length = buff.length,
- i;
-
- this._length += arr.byteLength;
-
- for (i = 64; i <= length; i += 64) {
- md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)));
- }
-
- this._buff = (i - 64) < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);
-
- return this;
- };
-
- /**
- * Finishes the incremental computation, reseting the internal state and
- * returning the result.
- *
- * @param {Boolean} raw True to get the raw string, false to get the hex string
- *
- * @return {String} The result
- */
- SparkMD5.ArrayBuffer.prototype.end = function (raw) {
- var buff = this._buff,
- length = buff.length,
- tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
- i,
- ret;
-
- for (i = 0; i < length; i += 1) {
- tail[i >> 2] |= buff[i] << ((i % 4) << 3);
- }
-
- this._finish(tail, length);
- ret = hex(this._hash);
-
- if (raw) {
- ret = hexToBinaryString(ret);
- }
-
- this.reset();
-
- return ret;
- };
-
- /**
- * Resets the internal state of the computation.
- *
- * @return {SparkMD5.ArrayBuffer} The instance itself
- */
- SparkMD5.ArrayBuffer.prototype.reset = function () {
- this._buff = new Uint8Array(0);
- this._length = 0;
- this._hash = [1732584193, -271733879, -1732584194, 271733878];
-
- return this;
- };
-
- /**
- * Gets the internal state of the computation.
- *
- * @return {Object} The state
- */
- SparkMD5.ArrayBuffer.prototype.getState = function () {
- var state = SparkMD5.prototype.getState.call(this);
-
- // Convert buffer to a string
- state.buff = arrayBuffer2Utf8Str(state.buff);
-
- return state;
- };
-
- /**
- * Gets the internal state of the computation.
- *
- * @param {Object} state The state
- *
- * @return {SparkMD5.ArrayBuffer} The instance itself
- */
- SparkMD5.ArrayBuffer.prototype.setState = function (state) {
- // Convert string to buffer
- state.buff = utf8Str2ArrayBuffer(state.buff, true);
-
- return SparkMD5.prototype.setState.call(this, state);
- };
-
- SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
-
- SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
-
- /**
- * Performs the md5 hash on an array buffer.
- *
- * @param {ArrayBuffer} arr The array buffer
- * @param {Boolean} raw True to get the raw string, false to get the hex one
- *
- * @return {String} The result
- */
- SparkMD5.ArrayBuffer.hash = function (arr, raw) {
- var hash = md51_array(new Uint8Array(arr)),
- ret = hex(hash);
-
- return raw ? hexToBinaryString(ret) : ret;
- };
-
- return SparkMD5;
- }));
-
- if (typeof Array.prototype.forEach != 'function') {
- Array.prototype.forEach = function(callback) {
- for (var i = 0; i < this.length; i++) {
- callback.apply(this, [this[i], i, this]);
- }
- };
- }
-
- /* webim API definitions
- */
- var msgCache = {};
- var webim = {
- // namespace object webim
-
- /* function init
- * sdk登录
- * params:
- * loginInfo - Object, 登录身份相关参数集合,详见下面
- * {
- * sdkAppID - String, 用户标识接入SDK的应用ID,必填
- * accountType - int, 账号类型,必填
- * identifier - String, 用户帐号,必须是字符串类型,必填
- * identifierNick - String, 用户昵称,选填
- * userSig - String, 鉴权Token,必须是字符串类型,必填
- * }
- * listeners - Object, 事件回调函数集合, 详见下面
- * {
- * onConnNotify - function(connInfo), 用于收到连接状态相关通知的回调函数,目前未使用
- * jsonpCallback -function(rspData),//IE9(含)以下浏览器用到的jsonp回调函数
- * onMsgNotify - function(newMsgList), 用于收到消息通知的回调函数,
- * newMsgList为新消息数组,格式为[Msg对象]
- * 使用方有两种处理回调: 1)处理newMsgList中的增量消息,2)直接访问webim.MsgStore获取最新的消息
- * onGroupInfoChangeNotify - function(groupInfo), 用于监听群组资料变更的回调函数,
- * groupInfo为新的群组资料信息
- * onGroupSystemNotifys - Object, 用于监听(多终端同步)群系统消息的回调函数对象
- *
- * }
- * options - Object, 其它选项, 目前未使用
- * return:
- * (无)
- */
- login: function(loginInfo, listeners, options) {},
-
- /* function syncMsgs
- * 拉取最新C2C消息
- * 一般不需要使用方直接调用, SDK底层会自动同步最新消息并通知使用方, 一种有用的调用场景是用户手动触发刷新消息
- * params:
- * cbOk - function(msgList)类型, 当同步消息成功时的回调函数, msgList为新消息数组,格式为[Msg对象],
- * 如果此参数为null或undefined则同步消息成功后会像自动同步那样回调cbNotify
- * cbErr - function(err)类型, 当同步消息失败时的回调函数, err为错误对象
- * return:
- * (无)
- */
- syncMsgs: function(cbOk, cbErr) {},
-
- /* function getC2CHistoryMsgs
- * 拉取C2C漫游消息
- * params:
- * options - 请求参数
- * cbOk - function(msgList)类型, 成功时的回调函数, msgList为消息数组,格式为[Msg对象],
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- getC2CHistoryMsgs: function(options, cbOk, cbErr) {},
-
- /* function syncGroupMsgs
- * 拉取群漫游消息
- * params:
- * options - 请求参数
- * cbOk - function(msgList)类型, 成功时的回调函数, msgList为消息数组,格式为[Msg对象],
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- syncGroupMsgs: function(options, cbOk, cbErr) {},
-
- /* function sendMsg
- * 发送一条消息
- * params:
- * msg - webim.Msg类型, 要发送的消息对象
- * cbOk - function()类型, 当发送消息成功时的回调函数
- * cbErr - function(err)类型, 当发送消息失败时的回调函数, err为错误对象
- * return:
- * (无)
- */
- sendMsg: function(msg, cbOk, cbErr) {},
-
- /* function logout
- * sdk登出
- * params:
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- logout: function(cbOk, cbErr) {},
-
- /* function setAutoRead
- * 设置会话自动已读上报标志
- * params:
- * selSess - webim.Session类型, 当前会话
- * isOn - boolean, 将selSess的自动已读消息标志改为isOn,同时是否上报当前会话已读消息
- * isResetAll - boolean,是否重置所有会话的自动已读标志
- * return:
- * (无)
- */
- setAutoRead: function(selSess, isOn, isResetAll) {},
-
- /* function getProfilePortrait
- * 拉取资料(搜索用户)
- * params:
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- getProfilePortrait: function(options, cbOk, cbErr) {},
-
- /* function setProfilePortrait
- * 设置个人资料
- * params:
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- setProfilePortrait: function(options, cbOk, cbErr) {},
-
- /* function applyAddFriend
- * 申请添加好友
- * params:
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- applyAddFriend: function(options, cbOk, cbErr) {},
-
- /* function getPendency
- * 拉取好友申请
- * params:
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- getPendency: function(options, cbOk, cbErr) {},
-
- /* function deletePendency
- * 删除好友申请
- * params:
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- deletePendency: function(options, cbOk, cbErr) {},
-
- /* function responseFriend
- * 响应好友申请
- * params:
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- responseFriend: function(options, cbOk, cbErr) {},
-
- /* function getAllFriend
- * 拉取我的好友
- * params:
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- getAllFriend: function(options, cbOk, cbErr) {},
-
- /* function deleteFriend
- * 删除好友
- * params:
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- deleteFriend: function(options, cbOk, cbErr) {},
-
- /* function addBlackList
- * 增加黑名单
- * params:
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- addBlackList: function(options, cbOk, cbErr) {},
-
- /* function getBlackList
- * 删除黑名单
- * params:
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- getBlackList: function(options, cbOk, cbErr) {},
-
- /* function deleteBlackList
- * 我的黑名单
- * params:
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- deleteBlackList: function(options, cbOk, cbErr) {},
-
- /* function uploadPic
- * 上传图片
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- uploadPic: function(options, cbOk, cbErr) {},
-
- /* function createGroup
- * 创建群
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- createGroup: function(options, cbOk, cbErr) {},
-
- /* function applyJoinGroup
- * 申请加群
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- applyJoinGroup: function(options, cbOk, cbErr) {},
-
- /* function handleApplyJoinGroup
- * 处理申请加群(同意或拒绝)
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- handleApplyJoinGroup: function(options, cbOk, cbErr) {},
-
- /* function deleteApplyJoinGroupPendency
- * 删除加群申请
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- deleteApplyJoinGroupPendency: function(options, cbOk, cbErr) {},
-
- /* function quitGroup
- * 主动退群
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- quitGroup: function(options, cbOk, cbErr) {},
-
- /* function getGroupPublicInfo
- * 读取群公开资料-高级接口
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- getGroupPublicInfo: function(options, cbOk, cbErr) {},
-
- /* function getGroupInfo
- * 读取群详细资料-高级接口
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- getGroupInfo: function(options, cbOk, cbErr) {},
-
- /* function modifyGroupBaseInfo
- * 修改群基本资料
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- modifyGroupBaseInfo: function(options, cbOk, cbErr) {},
-
- /* function destroyGroup
- * 解散群
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- destroyGroup: function(options, cbOk, cbErr) {},
-
- /* function getJoinedGroupListHigh
- * 获取我的群组-高级接口
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- getJoinedGroupListHigh: function(options, cbOk, cbErr) {},
-
- /* function getGroupMemberInfo
- * 获取群组成员列表
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- getGroupMemberInfo: function(options, cbOk, cbErr) {},
-
- /* function addGroupMember
- * 邀请好友加群
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- addGroupMember: function(options, cbOk, cbErr) {},
-
- /* function modifyGroupMember
- * 修改群成员资料(角色或者群消息提类型示)
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- modifyGroupMember: function(options, cbOk, cbErr) {},
-
- /* function forbidSendMsg
- * 设置群成员禁言时间
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- forbidSendMsg: function(options, cbOk, cbErr) {},
-
- /* function deleteGroupMember
- * 删除群成员
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- deleteGroupMember: function(options, cbOk, cbErr) {},
-
- /* function getPendencyGroup
- * 获取群组未决列表
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- getPendencyGroup: function(options, cbOk, cbErr) {},
-
- /* function getPendencyReport
- * 好友未决已读上报
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- getPendencyReport: function(options, cbOk, cbErr) {},
-
- /* function getPendencyGroupRead
- * 群组未决已读上报
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- getPendencyGroupRead: function(options, cbOk, cbErr) {},
-
- /* function sendCustomGroupNotify
- * 发送自定义群通知
- * params:
- * options - 请求参数,详见api文档
- * cbOk - function()类型, 成功时回调函数
- * cbErr - function(err)类型, 失败时回调函数, err为错误对象
- * return:
- * (无)
- */
- sendCustomGroupNotify: function(options, cbOk, cbErr) {},
-
- /* class webim.Msg
- * 一条消息的描述类, 消息发送、接收的API中都会涉及此类型的对象
- * properties:
- * sess - Session object-ref, 消息所属的会话(e.g:我与好友A的C2C会话,我与群组G的GROUP会话)
- * isSend - Boolean, true表示是我发出消息, false表示是发给我的消息)
- * seq - Integer, 消息序列号, 用于判断消息是否同一条
- * random - Integer, 消息随机数,用于判断消息是否同一条
- * time - Integer, 消息时间戳, 为unix timestamp
- * fromAccount -String, 消息发送者帐号
- * subType -Integer, 消息子类型,c2c消息时,0-表示普通消息;群消息时,0-普通消息,1-点赞消息,2-提示消息
- * fromAccountNick -String, 消息发送者昵称
- * elems - Array of webim.Msg.Elem, 描述消息内容的元素列表
- * constructor:
- * Msg(sess, isSend, seq,random time,fromAccount) - 构造函数, 参数定义同上面properties中定义
- * methods:
- * addText(text) - 向elems中添加一个TEXT元素
- * addFace(face) - 向elems中添加一个FACE元素
- * toHtml() - 转成可展示的html String
- *addFace
- * sub-class webim.Msg.Elem
- * 消息中一个组成元素的描述类, 一条消息的内容被抽象描述为N个元素的有序列表
- * properties:
- * type - 元素类型, 目前有TEXT(文本)、FACE(表情)、IMAGE(图片)等
- * content- 元素内容体, 当TEXT时为String, 当PIC时为UrlString
- * constructor:
- * Elem(type, content) - 构造函数, 参数定义同上面properties中定义
- *
- * sub-class webim.Msg.Elem.TextElem
- * 文本
- * properties:
- * text - String 内容
- * constructor:
- * TextElem(text) - 构造函数, 参数定义同上面properties中定义
- *
- * sub-class webim.Msg.Elem.FaceElem
- * 表情
- * properties:
- * index - Integer 表情索引, 用户自定义
- * data - String 额外数据,用户自定义
- * constructor:
- * FaceElem(index,data) - 构造函数, 参数定义同上面properties中定义
- *
- *
- */
- Msg: function(sess, isSend, seq, random, time, fromAccount, subType, fromAccountNick, fromAccountHeadurl) {
- /*Class constructor*/
- },
-
- /* singleton object MsgStore
- * webim.MsgStore是消息数据的Model对象(参考MVC概念), 它提供接口访问当前存储的会话和消息数据
- * 下面说明下会话数据类型: Session
- *
- * class Session
- * 一个Session对象描述一个会话,会话可简单理解为最近会话列表的一个条目,它由两个字段唯一标识:
- * type - String, 会话类型(如"C2C", "GROUP", ...)
- * id - String, 会话ID(如C2C类型中为对方帐号,"C2C"时为好友ID,"GROUP"时为群ID)
- * properties:
- * (Session对象未对外暴露任何属性字段, 所有访问通过下面的getter方法进行)
- * methods:
- * type() - String, 返回会话类型,"C2C"表示与好友私聊,"GROUP"表示群聊
- * id() - String, 返回会话ID
- * name() - String, 返回会话标题(如C2C类型中为对方的昵称,暂不支持)
- * icon() - String, 返回会话图标(对C2C类型中为对方的头像URL,暂不支持)
- * unread() - Integer, 返回会话未读条数
- * time() - Integer, 返回会话最后活跃时间, 为unix timestamp
- * curMaxMsgSeq() - Integer, 返回会话最大消息序列号
- * msgCount() - Integer, 返回会话中所有消息条数
- * msg(index) - webim.Msg, 返回会话中第index条消息
- */
- MsgStore: {
- /* function sessMap
- * 获取所有会话
- * return:
- * 所有会话对象
- */
- sessMap: function() {
- return {
- /*Object*/
- };
- },
- /* function sessCount
- * 获取当前会话的个数
- * return:
- * Integer, 会话个数
- */
- sessCount: function() {
- return 0;
- },
-
- /* function sessByTypeId
- * 根据会话类型和会话ID取得相应会话
- * params:
- * type - String, 会话类型(如"C2C", "GROUP", ...)
- * id - String, 会话ID(如对方ID)
- * return:
- * Session, 会话对象(说明见上面)
- */
- sessByTypeId: function(type, id) {
- return {
- /*Session Object*/
- };
- },
- /* function delSessByTypeId
- * 根据会话类型和会话ID删除相应会话
- * params:
- * type - String, 会话类型(如"C2C", "GROUP", ...)
- * id - String, 会话ID(如对方ID)
- * return:
- * Boolean, 布尔类型
- */
- delSessByTypeId: function(type, id) {
- return true;
- },
-
- /* function resetCookieAndSyncFlag
- * 重置上一次读取新c2c消息Cookie和是否继续拉取标记
- * return:
- *
- */
- resetCookieAndSyncFlag: function() {},
-
- downloadMap: {}
- }
- };
-
- /* webim API implementation
- */
- (function(webim) {
- //sdk版本
- var SDK = {
- VERSION: '1.7.2', //sdk版本号
- APPID: '537048168', //web im sdk 版本 APPID
- PLAATFORM: '10' //发送请求时判断其是来自web端的请求
- };
-
- //是否启用正式环境,默认启用
- var isAccessFormaEnvironment = true;
- // var isAccessFormaEnvironment = false;
-
- //后台接口主机
- var SRV_HOST = {
- FORMAL: {
- COMMON: 'https://webim.tim.qq.com',
- PIC: 'https://pic.tim.qq.com'
- },
- TEST: {
- COMMON: 'https://test.tim.qq.com',
- PIC: 'https://pic.tim.qq.com'
- }
- };
-
- //浏览器版本信息
- var BROWSER_INFO = {};
- //是否为ie9(含)以下
- var lowerBR = false;
-
- //服务名称
- var SRV_NAME = {
- OPEN_IM: 'openim', //私聊(拉取未读c2c消息,长轮询,c2c消息已读上报等)服务名
- GROUP: 'group_open_http_svc', //群组管理(拉取群消息,创建群,群成员管理,群消息已读上报等)服务名
- FRIEND: 'sns', //关系链管理(好友管理,黑名单管理等)服务名
- PROFILE: 'profile', //资料管理(查询,设置个人资料等)服务名
- RECENT_CONTACT: 'recentcontact', //最近联系人服务名
- PIC: 'openpic', //图片(或文件)服务名
- BIG_GROUP: 'group_open_http_noauth_svc', //直播大群 群组管理(申请加大群)服务名
- BIG_GROUP_LONG_POLLING: 'group_open_long_polling_http_noauth_svc', //直播大群 长轮询(拉取消息等)服务名
- IM_OPEN_STAT: 'imopenstat', //质量上报,统计接口错误率
- DEL_CHAT: 'recentcontact', //删除会话
- WEB_IM: 'webim'
- };
-
- //不同服务对应的版本号
- var SRV_NAME_VER = {
- openim: 'v4',
- group_open_http_svc: 'v4',
- sns: 'v4',
- profile: 'v4',
- recentcontact: 'v4',
- openpic: 'v4',
- group_open_http_noauth_svc: 'v1',
- group_open_long_polling_http_noauth_svc: 'v1',
- imopenstat: 'v4',
- webim: 'v3'
- };
-
- //不同的命令名对应的上报类型ID,用于接口质量上报
- var CMD_EVENT_ID_MAP = {
- login: 1, //登录
- pic_up: 3, //上传图片
- apply_join_group: 9, //申请加入群组
- create_group: 10, //创建群组
- longpolling: 18, //普通长轮询
- send_group_msg: 19, //群聊
- sendmsg: 20 //私聊
- };
-
- //聊天类型
- var SESSION_TYPE = {
- C2C: 'C2C', //私聊
- GROUP: 'GROUP' //群聊
- };
-
- //最近联系人类型
- var RECENT_CONTACT_TYPE = {
- C2C: 1, //好友
- GROUP: 2 //群
- };
-
- //消息最大长度(字节)
- var MSG_MAX_LENGTH = {
- C2C: 12000, //私聊消息
- GROUP: 8898 //群聊
- };
-
- //后台接口返回类型
- var ACTION_STATUS = {
- OK: 'OK', //成功
- FAIL: 'FAIL' //失败
- };
-
- var ERROR_CODE_CUSTOM = 99999; //自定义后台接口返回错误码
-
- //消息元素类型
- var MSG_ELEMENT_TYPE = {
- TEXT: 'TIMTextElem', //文本
- FACE: 'TIMFaceElem', //表情
- IMAGE: 'TIMImageElem', //图片
- CUSTOM: 'TIMCustomElem', //自定义
- SOUND: 'TIMSoundElem', //语音,只支持显示
- FILE: 'TIMFileElem', //文件,只支持显示
- LOCATION: 'TIMLocationElem', //地理位置
- GROUP_TIP: 'TIMGroupTipElem' //群提示消息,只支持显示
- };
-
- //图片类型
- var IMAGE_TYPE = {
- ORIGIN: 1, //原图
- LARGE: 2, //缩略大图
- SMALL: 3 //缩略小图
- };
- //图片格式
- var IMAGE_FORMAT = {
- JPG: 0x1,
- JPEG: 0x1,
- GIF: 0x2,
- PNG: 0x3,
- BMP: 0x4,
- UNKNOWN: 0xff
- };
-
- //上传资源包类型
- var UPLOAD_RES_PKG_FLAG = {
- RAW_DATA: 0, //原始数据
- BASE64_DATA: 1 //base64编码数据
- };
-
- //下载文件配置
- var DOWNLOAD_FILE = {
- BUSSINESS_ID: '10001', //下载文件业务ID
- AUTH_KEY: '617574686b6579', //下载文件authkey
- SERVER_IP: '182.140.186.147' //下载文件服务器IP
- };
-
- //下载文件类型
- var DOWNLOAD_FILE_TYPE = {
- SOUND: 2106, //语音
- FILE: 2107 //普通文件
- };
-
- //上传资源类型
- var UPLOAD_RES_TYPE = {
- IMAGE: 1, //图片
- FILE: 2, //文件
- SHORT_VIDEO: 3, //短视频
- SOUND: 4 //语音,PTT
- };
-
- //版本号,用于上传图片或文件接口
- var VERSION_INFO = {
- APP_VERSION: '2.1', //应用版本号
- SERVER_VERSION: 1 //服务端版本号
- };
-
- //长轮询消息类型
- var LONG_POLLINNG_EVENT_TYPE = {
- C2C: 1, //新的c2c消息通知
- GROUP_COMMON: 3, //新的群普通消息
- GROUP_TIP: 4, //新的群提示消息
- GROUP_SYSTEM: 5, //新的群系统消息
- GROUP_TIP2: 6, //新的群提示消息2
- FRIEND_NOTICE: 7, //好友系统通知
- PROFILE_NOTICE: 8, //资料系统通知
- C2C_COMMON: 9, //新的C2C消息
- C2C_EVENT: 10
- };
-
- //c2c消息子类型
- var C2C_MSG_SUB_TYPE = {
- COMMON: 0 //普通消息
- };
- //c2c消息子类型
- var C2C_EVENT_SUB_TYPE = {
- READED: 92, //已读消息同步
- KICKEDOUT: 96
- };
-
- //群消息子类型
- var GROUP_MSG_SUB_TYPE = {
- COMMON: 0, //普通消息
- LOVEMSG: 1, //点赞消息
- TIP: 2, //提示消息
- REDPACKET: 3 //红包消息
- };
-
- //群消息优先级类型
- var GROUP_MSG_PRIORITY_TYPE = {
- REDPACKET: 1, //红包消息
- COMMON: 2, //普通消息
- LOVEMSG: 3 //点赞消息
- };
-
- //群提示消息类型
- var GROUP_TIP_TYPE = {
- JOIN: 1, //加入群组
- QUIT: 2, //退出群组
- KICK: 3, //被踢出群组
- SET_ADMIN: 4, //被设置为管理员
- CANCEL_ADMIN: 5, //被取消管理员
- MODIFY_GROUP_INFO: 6, //修改群资料
- MODIFY_MEMBER_INFO: 7 //修改群成员信息
- };
-
- //群提示消息-群资料变更类型
- var GROUP_TIP_MODIFY_GROUP_INFO_TYPE = {
- FACE_URL: 1, //修改群头像URL
- NAME: 2, //修改群名称
- OWNER: 3, //修改群主
- NOTIFICATION: 4, //修改群公告
- INTRODUCTION: 5 //修改群简介
- };
-
- //群系统消息类型
- var GROUP_SYSTEM_TYPE = {
- JOIN_GROUP_REQUEST: 1, //申请加群请求(只有管理员会收到)
- JOIN_GROUP_ACCEPT: 2, //申请加群被同意(只有申请人能够收到)
- JOIN_GROUP_REFUSE: 3, //申请加群被拒绝(只有申请人能够收到)
- KICK: 4, //被管理员踢出群(只有被踢者接收到)
- DESTORY: 5, //群被解散(全员接收)
- CREATE: 6, //创建群(创建者接收, 不展示)
- INVITED_JOIN_GROUP_REQUEST: 7, //邀请加群(被邀请者接收)
- QUIT: 8, //主动退群(主动退出者接收, 不展示)
- SET_ADMIN: 9, //设置管理员(被设置者接收)
- CANCEL_ADMIN: 10, //取消管理员(被取消者接收)
- REVOKE: 11, //群已被回收(全员接收, 不展示)
- READED: 15, //群消息已读同步
- CUSTOM: 255, //用户自定义通知(默认全员接收)
- INVITED_JOIN_GROUP_REQUEST_AGREE: 12 //邀请加群(被邀请者需同意)
- };
-
- //好友系统通知子类型
- var FRIEND_NOTICE_TYPE = {
- FRIEND_ADD: 1, //好友表增加
- FRIEND_DELETE: 2, //好友表删除
- PENDENCY_ADD: 3, //未决增加
- PENDENCY_DELETE: 4, //未决删除
- BLACK_LIST_ADD: 5, //黑名单增加
- BLACK_LIST_DELETE: 6, //黑名单删除
- PENDENCY_REPORT: 7, //未决已读上报
- FRIEND_UPDATE: 8 //好友数据更新
- };
-
- //资料系统通知子类型
- var PROFILE_NOTICE_TYPE = {
- PROFILE_MODIFY: 1 //资料修改
- };
-
- //腾讯登录服务错误码(用于托管模式)
- var TLS_ERROR_CODE = {
- OK: 0, //成功
- SIGNATURE_EXPIRATION: 11 //用户身份凭证过期
- };
-
- //长轮询连接状态
- var CONNECTION_STATUS = {
- INIT: -1, //初始化
- ON: 0, //连接正常
- RECONNECT: 1, //连接恢复正常
- OFF: 9999 //连接已断开,可能是用户网络问题,或者长轮询接口报错引起的
- };
-
- var UPLOAD_PIC_BUSSINESS_TYPE = {
- //图片业务类型
- GROUP_MSG: 1, //私聊图片
- C2C_MSG: 2, //群聊图片
- USER_HEAD: 3, //用户头像
- GROUP_HEAD: 4 //群头像
- };
-
- var FRIEND_WRITE_MSG_ACTION = {
- //好友输入消息状态
- ING: 14, //正在输入
- STOP: 15 //停止输入
- };
-
- //ajax默认超时时间,单位:毫秒
- var ajaxDefaultTimeOut = 15000;
-
- //大群长轮询接口返回正常时,延时一定时间再发起下一次请求
- var OK_DELAY_TIME = 1000;
-
- //大群长轮询接口发生错误时,延时一定时间再发起下一次请求
- var ERROR_DELAY_TIME = 5000;
-
- //群提示消息最多显示人数
- var GROUP_TIP_MAX_USER_COUNT = 10;
-
- //长轮询连接状态
- var curLongPollingStatus = CONNECTION_STATUS.INIT;
-
- //当长轮询连接断开后,是否已经回调过
- var longPollingOffCallbackFlag = false;
-
- //当前长轮询返回错误次数
- var curLongPollingRetErrorCount = 0;
-
- //长轮询默认超时时间,单位:毫秒
- var longPollingDefaultTimeOut = 60000;
-
- //长轮询返回错误次数达到一定值后,发起新的长轮询请求间隔时间,单位:毫秒
- var longPollingIntervalTime = 5000;
-
- //没有新消息时,长轮询返回60008错误码是正常的
- var longPollingTimeOutErrorCode = 60008;
-
- //多实例登录被kick的错误码
- var longPollingKickedErrorCode = 91101;
-
- var longPollingPackageTooLargeErrorCode = 10018;
-
- var LongPollingId = null;
-
- //当前大群长轮询返回错误次数
- var curBigGroupLongPollingRetErrorCount = 0;
-
- //最大允许长轮询返回错误次数
- var LONG_POLLING_MAX_RET_ERROR_COUNT = 10;
-
- //上传重试累计
- var Upload_Retry_Times = 0;
- //最大上传重试
- var Upload_Retry_Max_Times = 20;
-
- //ie7/8/9采用jsonp方法解决ajax跨域限制
- var jsonpRequestId = 0; //jsonp请求id
- //最新jsonp请求返回的json数据
- var jsonpLastRspData = null;
- //兼容ie7/8/9,jsonp回调函数
- var jsonpCallback = null;
-
- var uploadResultIframeId = 0; //用于上传图片的iframe id
-
- var ipList = []; //文件下载地址
- var authkey = null; //文件下载票据
- var expireTime = null; //文件下载票据超时时间
-
- //错误码
- var ERROR = {};
- //当前登录用户
- var ctx = {
- sdkAppID: null,
- appIDAt3rd: null,
- accountType: null,
- identifier: null,
- tinyid: null,
- identifierNick: null,
- userSig: null,
- a2: null,
- contentType: 'json',
- apn: 1
- };
- var opt = {};
- var xmlHttpObjSeq = 0; //ajax请求id
- var xmlHttpObjMap = {}; //发起的ajax请求
- var curSeq = 0; //消息seq
- var tempC2CMsgList = []; //新c2c消息临时缓存
- var tempC2CHistoryMsgList = []; //漫游c2c消息临时缓存
-
- var maxApiReportItemCount = 20; //一次最多上报条数
- var apiReportItems = []; //暂存api接口质量上报数据
- var onLongPullingNotify = null;
-
- var Resources = {
- downloadMap: {}
- };
-
- //表情标识字符和索引映射关系对象,用户可以自定义
- var emotionDataIndexs = {
- '[惊讶]': 0,
- '[撇嘴]': 1,
- '[色]': 2,
- '[发呆]': 3,
- '[得意]': 4,
- '[流泪]': 5,
- '[害羞]': 6,
- '[闭嘴]': 7,
- '[睡]': 8,
- '[大哭]': 9,
- '[尴尬]': 10,
- '[发怒]': 11,
- '[调皮]': 12,
- '[龇牙]': 13,
- '[微笑]': 14,
- '[难过]': 15,
- '[酷]': 16,
- '[冷汗]': 17,
- '[抓狂]': 18,
- '[吐]': 19,
- '[偷笑]': 20,
- '[可爱]': 21,
- '[白眼]': 22,
- '[傲慢]': 23,
- '[饿]': 24,
- '[困]': 25,
- '[惊恐]': 26,
- '[流汗]': 27,
- '[憨笑]': 28,
- '[大兵]': 29,
- '[奋斗]': 30,
- '[咒骂]': 31,
- '[疑问]': 32,
- '[嘘]': 33,
- '[晕]': 34
- };
-
- //表情对象,用户可以自定义
-
- var emotions = {
- "0": ["[惊讶]", "data:image/gif;base64,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"],
- "1": ["[撇嘴]", "data:image/gif;base64,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"],
- "2": ["[色]", "data:image/gif;base64,R0lGODlhGAAYAPf/ALeCR+jl4t2cHP+5Esurhc6EDv/9sv+0h/nFPf79/P3RZ//SLtM1AOpFAP/2eNs6APyYaPK+OP/oTPenI+u5U+Xh3vCjC9aiatulQ//DHfTGW9eOEf/hQsYsAPncm//5mP3dQv/LJv/89v/7lf20EMOJPv/ePIIxAP2xDKhhEf/wXP/p3dnUz//+0P/EH//FH//9uP/mSP/5h/VNAP/cOv/1bf3gSs0xAP/y6v+1D/SoDP/UMf/7oP+6E//bOe5IAP/PK+VCAOOZHf/tV8RxGv/xX/tRAMB3J/+/GcqMS//AGv379///z+OXCvW+Jf/pTv7dPv/dPdqOC/jGMf/9yPzZPvFKAP/8m/zPNPbLNv/4e+umFvfGKt+TG+afEP/xYP/gVP/bSO28gP/PLPCsWfqxKPCmN+ymGtfRzP9UAP9gANfSzf/+x+Pf3PHbxPv6+ubCm/fr3t3Y1NzX0/NMAP/3eOpYAO24S7NvGv2ESuWmJu2+WPW5M+65N/PesN/a1rd7MvTy8eG/jP//18CXZ/yshf346+rn5L1/Lufe0Ml5Dcx4Cf/WNPvTPf3XOa5mD/GsEqxtJeKyUtKWM+auLvfBRfXBS/W3KenIkbmIU9iVFfDu7MyLIsJ8FPZRAvry5/vhpfzw1vzlr7FzK6hdCciQPpw7APrML+A+APfIW/jKX9mwbN+4b713FM6ACsWebdGVVPbYmdLFuPfKZ+rj3OGgIceCFsuJGvvLMNmYIcivlunNrr9UAP/uV9xVAOjXzOaqH/+XWcRuCf7hR/mzE97Z1eG7kuGAHOGPXf3MRdqkX/q2MvyzO/3HQvvQefzSh//WwvquMu21h/XGM/3URf68IfaZIPi3G/v48/7VYP3cP/atRruRZfi4Gv/rUPrIfvrYQ+1HAP/Lsf/ePv/JqN/JsaE9AK5wLPHAgP/DnuaqIPdOAPuvDNincv+7Fd1hANjAp8ZxB8ZzCcx3COCVEfv38v/8oN62ist9CO+8k//7n/2xC4czAL9iAP///////yH/C05FVFNDQVBFMi4wAwEAAAAh+QQFFAD/ACwAAAAAGAAYAAAI/wD/CRxIsKDBgwgTKhQhSlWlS3wszfIQSuFAUAgagQDBAYojLFP2+FmYysawGBKeSIjBgYYPXH0oIEyggVoabw3AfFExJEwaEw2qTZN00AM4T4Ua/AiipU4NpEqDvKDEqqChCNqM5Jnx48GHETK0zgj3IMQ1DIkIxsoSo1mDBze+wTBgT8HbG2WAZNiy6s3AO1UkqMjW4RmbFmwMjCCMwMSCF8QmBRioZ5yEIlquwGgxqAWMK1q+PHH8YsCtOQNrRRHsYIQBNkwSj3CgQoJjFwNsrRkowEeMXjVk6DMwl4eMGr1i+NCboxOagbkYcVDUr7r16/1chUBCotVzgRi40LboB8dNHH/o0cdxA6ffC3c6EO0WiEndjn788uvff6KfkhxSvCLHQJ9wcsp9/JhihxoM2mEOP/1k0IMFgMhyCEGCCLDAAv3I8w6DarwTT4Q9oPAIIX/4NVACpWgyRggbLGLdPPQo0QM7rgCwxoUGlbCBExm8IGQGSLiTQxMpZIJGGwkRgEcBXkAyAAk6NIHPObqwUIFFtBAAwCikpBAJANygUUwgFgmUwCZtyIEGC3NUwGOadBIUEAAh+QQFFAD/ACwDAAUAEgAQAAAIqgD/bTNCJ1qaBsz+JUtjZYKRBtb+SUwDDcKPdXRQ/UsjDkI4jAwk/jMCgc6PBkFCkjSJ8kY3ictQonrAAN0/ZzJpThD5zwwDBjeQMZFI5meHYyKjPPlHoYMYnv80dOgzTqQJiXUkUmkhMqvIF/9o8OQh0h5Psf8GQF3Ltq3bf8DeyuUZ7J8vXr+IuFUm7cAKHNiW+DPmbu4/Yf787epi+J8Qf7AaS4R1hGdAACH5BAUUAP8ALAMABQARABEAAAibAP9poJbGWwMwRf71CpPGRINq0/79A+epUIMfQbT8q1HxYpAXErUZyTPjx4MP/2SMnBHuQYhr/2I0a/DgxjcY/+wpoHmjDBCJ/1Rk6/CMTQuJI4YiiAJUopYrMJj8k/pPS5EnJiQybcqGalOgPv4NkWjvK1izaNOqXcu27dcBadNJrNd0X9OfbtUqOfPP3xG3QvzByvsPVhKgAQEAIfkEBRQA/wAsAwAFABEAEgAACJwA/20zQidamgbM/iVLY2WCkQbW/v1LAw3Cj3V0UE0UByEcRgYSjUCg86NBEJAiSZq80e3fMpOoHjBA988ZTJkTJP4zw4DBDWRMJJLp2eHYPxc6KXQQ0+Jf038aOkQYJ9GEzqtYs/aSyENnV500soodS7as2bNYe2AlsiofOYnYdPZAgdYsUolIdCap+89fCbRC/F0ohxZeu3s6AwIAOw=="],
- "3": ["[发呆]", "data:image/gif;base64,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"],
- "4": ["[得意]", "data:image/gif;base64,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"],
- "5": ["[流泪]", "data:image/gif;base64,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"],
- "6": ["[害羞]", "data:image/gif;base64,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"],
- "7": ["[闭嘴]", "data:image/gif;base64,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"],
- "8": ["[睡]", "data:image/gif;base64,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"],
- "9": ["[大哭]", "data:image/gif;base64,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"],
- "10": ["[尴尬]", "data:image/gif;base64,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"],
- "11": ["[发怒]", "data:image/gif;base64,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"],
- "12": ["[调皮]", "data:image/gif;base64,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"],
- "13": ["[龇牙]", "data:image/gif;base64,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"],
- "14": ["[微笑]", "data:image/gif;base64,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"],
- "15": ["[难过]", "data:image/gif;base64,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"],
- "16": ["[酷]", "data:image/gif;base64,R0lGODlhGAAYAPf/ANWiOtWkVP60Dv/89v/cOvjGMP+5E//XNf/1beXEav/wXdnUz//VMbhrEv/wX2loS/+7FDIsDf/GIOSXCv/aOf/DHf/tV//pT//9sf/ePf/AGv/FIP/+0P/6lf/KJf/4e//5iP/3eP/3d//dPf/EH//9uQ4LA9ShMtSfLP7hRf/gQf3dQ/7dP97bgv/TLv/PK//LKdXHSvfGK/y1Ef2xDPGsEtSmRvCjC9ilGdqOC5+SM7+HEnJuNmZjLmZaGxgUBdfRzP/fRf/lR6WclKpSBr5pCdfSzf/sU//RLf/qUP/mSL2Xdern5OPf3NzX0/////v6+t3Y1I5lQf/iQv/LJv/oTP/pTf/oTf+3EP/xX//uV8t+CPe8N9LFuFdXR65wLPncnOG/jOrj3NOYEPWyEs2sg+fe0P+/GcKKPlpZNv/ePr13FKxtJfbEL/XBS5SMhffIW8iQPvry50g4CYV+ePW3KeGgIe24SyQiDLiESfzw1suJGqdgEMyLIu7CUntvI86ACP/7mzkyDqhdCf/hQrSAR/jbmrd7MvPesOC0N++zMPjKX/fKZ/3XOcivltiVFf/TMOnIkfOpDYczAPTy8bmIU5OQTruRZcCXZ/Du7PbGWczHbdmYIZyTOv38/P79/Pi3GvnEJfvhpfzlr65mD//MJ+afELFzK+HZZuWmJvvLMPrNN/zPNP346/C/JMJ8FP/+x+ro5cWebdWOEfbYmfHIWG9tRv//197Z1d/a1v7IJXVwMmZeIPfBReCfJMeCFvuvDP7nT+jl4t2cH/3fRMmphu65Nu3HU/W5M/SnC/CwH86EDr1/Lv/2dGZgJrNvGtixa+Tg3ebi3//+/PzfQf/qUY13Hf/rUfPRNtmkQtylRKpjE9KWM7eCRbVpHeC3PTw4Nfz3k3p0bv/rU//8mtejTdKUINKYJeaqH+XFW+aqIP/3e/OyGO7YbeCoJOC7T7hsGO7Zgfn4woRzIMaHK92bGN2cGMaJNf/XNP/7n9ahQbVpGf/RLv/SLQAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQFFAD/ACwAAAAAGAAYAAAI/wD/CRxIsKDBgwgTKhwwalGvOsjcMAKjR+FAUVxWrUhBiEUjVgVqIVoIp0CwK1esWFFCiAADVcb8IJymqcC4JFoUZFGgJYmQDAx0KTt20FCbC4lOIBDx4R2CLEfOueO3wVeCgq0UEUuSBZ6NDuTugWh2ogEhfFRAZTNDkJYJf3h2bQpAJIG3eEQAxPgTwZ+/HdCgDLzzw6/fB3RhEdHHw7DfMdyEDUwlyPASKV5ucSiRxp+UJYbJ7HEy0M48y08c+30C2t8cA7+MDByGra/jBxhsqf6BA8srIAM54aOmw1kPSy0CdQCBqhMvH9ZcnRGwBrhAbTIICDmSBUGIdSKeHrYRQgCJBAjJmMkWGEkdgwxCruXc2fMnAyoasOSQFWWgnD6hUEDAFEpUYcUVSgThUikVGHDDIV3EQlAY9VBxAD4UjKBGEUUEgQQVFUBAAymY5CLYQJ/E8YgEkLyARD9FTBKEBBoYAAwgeRjBxEFozMIODCRsEEQQZ0CAxQTbVAJEEwmV8cwyptRgwAySTLDFF44sII1FYhTTzSmD8MFGIZcAgQslFgnkSSZNRAHEAk5Es2OadBYUEAAh+QQFFAD/ACwDAAMAEQARAAAIhAD/CRwoUAXBgwQvVPm3cArCgYlQDPxmodo/c+4QHmkAQCC9fw5QNCCABGGzf0TS7WtH5F8Shw/zlSOCgQgABA+HgBMoj8M/DOEGihsy8M0QojmHvCFIBynCIXQeSp1K9Z+Ghx9CHOwnEN1UiyP+eZh6oUgRqfYGEqj60AXbgRsGXj0YEAA7"],
- "17": ["[冷汗]", "data:image/gif;base64,R0lGODlhGAAYAPf/APzjqm0pAPymN//rXf+0S+WnJv/4h93Y1Ojj3f7TNf7dRPjGMfx6Rfz16cOaappFA//wXdaDFfvNeeqYKvjamv/qUPu0ErBqFv96a7dlDf/ubdubKfuuDf/oTf/lSvfKZ/+ZMdLFufbm0P/+x9y1bf/6nODEVv7aOf/2df7VYern5NuZIP+5E//8suCoIteZM7aCR//89vSVF8+hMP/DHbl3TtfRzMOKPcurhf7ZQPa7NenTxv/SPP/+0f79/J07AP/RLs6CC/+/UMitlf/IMfOfMP/dPf/6lcSIJv/SUvbicLuQZv9rTqhhEsN8FP+XTf+1YfbLNf+bJeumFvfLX/+SYvflmKlbCf+mKf/3eNulQ/+DN/fIW/qwLu24S6FIBf9ZXMmDG/CwH/6MK/+PXP/FIP/1bf/MOP+LRv+8PP/gQtnUzv/LJ9ChiL51E+LGtOSXCv/cTv+hXf+/Gv/OTf/7oP/dUfrUeP9zU8t+Cf/NL//OK/+yGKFTD/6jG//lR//FXP/9uPnCJv/CKP+5Iv/uV/22Mv2rEf/nTP+tUvfBRchaHP+wPP+wJv+JU6tYJP/HS8eCFuK9jOC1MfKqD//FKP/BIf/jTf+iQt+gIfbeW+C8Pva8Jv+nc7t4NeafEP+rTv9zXf/mXtGPGPOxGP9fZf+2D//pWP97Xv/aXP/TTu3SrOPf3Pv6+axtJa5wLPbEL/Ty8enIkfDu7O+zMPXBS+msLfW3KciQPvzw1vXGWbeBMO2+WLFzK7d9IfvIK/nFL7mHVP/FQPPesOm4Uv/4e9CFJ/9gaPaAVuKyUv+vR9qymuje0L5/LsuJGv/xX//jRv/rU923obBjELJrQPm6Ke3Cb+WFRe2jS+fIqLlQEOnTvO3IcNWqka5mO/bmsLJmJ/LEMP+xWv/DOPNxOPvjff/bOd6HEP++Mf/LR+JaN+2WNOihJPO/KP/0lP/RYOa6MP+3cdnOx8SVgf+oZLlPFblXC/rDJv6nF+2AO/+qHP+kSf37+oczAP///////yH/C05FVFNDQVBFMi4wAwEAAAAh+QQFCAD/ACwAAAAAGAAYAAAI/wD/CRxIsKDBgwgTKowBgIqiWzpqfaCQS+FAADqAJThh5ASQX5x4DVvIBZiCDhVSIoKm5sQ9W8QQ+tC1oEK0QhCeQShU4U9LIGKSHaQAK9qmfv12Fcti5pkvpC4SZCJRsAEtDzP6mTBwpMQRAyieVZjUb5QgLcwIUojioZAZA3VaBGpRx4CZQn/M7aExhUSrgV5ydICQ5UiLET1GtDiSBUIHI0DKWHiBYGABNR2eZSkRqIfnQCWKPXsc2YKzAwMzGfEwAIW7w4kXoxhwKYceGiwi2UjNI06qaRKsULjSosS0FKkUTUNHyIKT3QJXnIEkBNuXAH24fdX1APs6AVgOucWB/k9LNQKg6NGDIqFcFg2iACV68gSEHxnNyMtil0ZZInGAvCMKBKfYkQ4BmIBg3zkOoCZQA8ZUM44w6agSxyUd/KEAD+MY0og+MngSggoESVJAJXpslIMRHSUARCVz8MHBNA3+NZAPuLhQBht7AAEEUmyUMQcLHAQBgw0kGnRDJqTQUAZSSLFgChxNBGMDKwnhgEQQn1DCggWUwJHHK0OsUZlCCOAAQy9XNOEKDEvYcEAsFgnkwyysHGDDGgewkmSdgBIUEAAh+QQFCAD/ACwCAAQAEwAOAAAIngD/Cfy3QM3ADgMTKly4UA9DhSgeSpw48A9FDxQzDoQgEQKihZdEfRkZ4IHAkQ9K/rP0b8U/VUkubPMXIINAN8xoZjDUiM+/cQTkXLvy5Z81gcmIXsmHRgq+f132OUKFoUq8OwJTiCODBw+DMQInMHpChgw9QCkExiHwxBGDLVIGdklDQAgkVXb+YUxniBEWPwuJ6OGhcM8/Qv8OCQwIACH5BAUIAP8ALAMABQASAA0AAAiTAP8JHEiQIJCCCLMgXMiwocM/DiMOfEYFSZ8m3wSWC9OnD7x/NFgMDCMiwL8wAkmaDENkIB1AYVb9W4XypEyajASmAUUG2YUHFyQIpPLzAgMGIPwIeBKq1DEMnSSg+PdOTigwYJhsEYjJESpUVaC8E5gkkSM8TBiMiSCQkTICQpIMzCGMkQAQUggO+ncGoZ69BAMCACH5BAUIAP8ALAYABAAMABAAAAhKAIEp+EeQ4J+CCBMW1KOwocOCmjZEeGGFoBKJK6KEEREgQBiCGzuGyeCvYwaCJE2S9Ofv5L+VLRXWeUizZsEUNePY3MnzHwuCAQEAIfkECRAA/wAsBAADABQADgAACFcA/wkcSHDglzYFBS5QUxCaQEH/vjxCmLCiQCBOutXoZtHijx3+MuzomPCHP387fvDzQFJgOJEof7RqOTDTxwzz/iGiKXDUDzfyeAoVWGKo0aNIW9rhGRAAIfkECRAA/wAsAAAAABgAGAAACP8A/wkcSLCgwYMIEypcyBCADmAJThg5AeQXJ17DFMbgskBNhwoVOiCCpubEPVvGWiHUtaBCtEIQnkEoVOFPST0/mvE7CCvapn79dhXLYuaZL6AuMv14pMKghxn9TBg4UuKIARTPKkzql+HNmx8G/xTStCHCCyst6igpuyLKD3/+li3xQbADhDAiAgQIM6IFXr1h3sJ9tHNgh2cZ/OnN0CNQ4sWC/YEleElUYrgZ+l72l2HUj2w/lhSkAyjMKn+rwrQoYRp1GEYZfmSwURAUGWQXHlyQYJVK7gsMGIDw44Y2wSehSh3D0EkCCg3v5IQCA4bJFhnNjA/E5AgVqipQUkA0OJUkkSM8TBiMieDgQMEujJQREJIkTgcPOYQxEgBCigxPITTF0IAEFpiQKQYmqOCCDBIYEAAh+QQFEAD/ACwAAAAAGAAYAAAI/wD/CRxIsKDBgwgTKowBgIqiWzpqfaCQS+FAADqAJThh5ASQX5x4DVvIBZiaCig7IIKm5sQ9W8QQ+tC1oEK0QhCeQShU4U9LIGKSHaQAK9qmfv12Fcti5pkvpC4SZCJRsAEtDzP6mTBwpMQRAyieVZjUb5SYL28IUojyp5CmDRFeWGlRRwncFVH25JEGrtVALzk6QAgjIkCAMCNaEDYcpt0Pfz/WDCygpsOzDP4MZ+gRCLNmN8v8LasxMJORS6Iw+/OXIbFq1o9X/xi4ggcdQGFW+VsVpkWJ3LvDxIZMOw0oMsguPLgg4SsV5RcY1Hvj7423gVoEPAlV6hiGThJQaLl4JycUGDDqtP34MmSgrAmYHKFCVQVKCginkiRyhIcJgzEROHDAQA0Y0wUjyhAgRBJxdOBBDsIwIgAIUsjgSQgqECRJAYMQcQYPORjRUQJ6DEIIH4dMI6BfA/mAiwtlsLEHEEAgxUYZc7DAQRAw2JChQTdkQgoNZSCFFAumwNFEMDawkhAOSATxCSUsWEAJHHm8MsQaCFiEAA4w9HJFE67AsIQNB8RikUA+zMLKATascQArP65pJ0EBAQAh+QQFEAD/ACwEAAQAEwAOAAAIYAD//Vvwr4PACv/+CFzIsKHDhxAjSlwIgaEgLcz+eZi4kMYUEhwXAilj4QWCkP+AkPri5ABKInmkXbGBssiPfz9CoFy07N+yGih/+Bt6M6RQoijtvfH3hhrKc19+UHsTEAAh+QQJEAD/ACwLAAQADAARAAAIWAA7/IP2r6DBgwgTKlz4bKHDhxALlmHhzKElFpEWMmrEx4kNhQzGPHDzMSGTRdL6lERI7se/HyEUZlj2b1mwf+YQ/vDH02XCnT0V9nnj700NhUOo/ajxJiAAIfkEBTIA/wAsAAAAABgAGAAACPoA/wkcSLCgwYMIEypcyLChQ4EdEEFTc+KeLWIP/0EoVOEPRSBikj3MYuaZr379XCTIRMLhEQMonlWY1G+UIC3MDP4x2KKOkg0RVkTZQ2MKiVYMR7QIIyJAgDBAylh4gYBhj0AZ/DnNAIQGC2cHkrbI6s9fBiKWWESywbBFiTCr/K0Kw6gRHydsF76kcuHBBQYMQPhxk1chCg3v5IQCA4bJFhnNCieEcCpJIkd4mDAYE8FBWIV2OkDLIYyRABBSZHgKoYKhkRMJ9AwixOfQNM9IF6JkU2YOCw5BYNhozRBlPxam4DQJZoOVQxYWKMHJ82rImqoZs2vfXjAgADs="],
- "18": ["[抓狂]", "data:image/gif;base64,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"],
- "19": ["[吐]", "data:image/gif;base64,R0lGODlhGAAYAPf/ALViCf+IcOrdzaNOC7NwKnzq1P+4FP6qbmnL6YnatlS01/zKNiDi6c3z+vq3JeS1kEqw54dPEP/wXovo0f71bcN5FNavbv/+0v7aRfz7+//rUa7X+fjCSf/6lreESnnk5OSNM/TJWf/8s5Gur/enCm6uz93Y1P/cO//3d9OeU9ulQ4zR1GW08KXLlv/9yOu5Nf/kSLVpGIvgrYf7+P/TM9XFj9SsLunn5PStFPvjqf7hQ9p6Tf/BHOSjJ/a6Nv/nZdfSzduZHNu5mseabPLs5kCk9FLOt+zVu/Pl1MuFGPjbmu24SPz26eXEk//oTf/5h+6IAdeZIvzRPJ50R4Hz5v/FIGy2teebFej1/WXI2+3EU//PLP/uWF2/2Vbl0/vvlHrb1eXg3f+Wf//RVXfUyPeaBviUQG3Y4PrLYmHGuOPHrGzcy9PFtummGIDVsvn18qzk8v/ALP/teP/cZsDUgVTK6P/89nbC1867p//7n//kUfaDVf/UhdWNFUfaw4Lt4//RLrx9MmPJzv3mh/jcedOXMpfe9KpcDq2qavyVX/P6/n3aqseGJe2xKPTy8f66Wv6uH9XBW/OlOIvbnb9tDcKKPLnG1fPesP+DiufFSea2UOOXC/2yD9a1hO3WVJzX4H3Kylq9xX/C98uqg+bDaVrTxf/KJ/+KmH7juujEhV3asH7W8X+037tgJ//Ar//IcqLQeOC8cufPucHh/HbNqduLCc6ADf7kW9Orip3K7YnI6P+zRLePZ+WoUzXI5vfFL5bO+/98gtfOzHLVn4Dv9V7q5MqQQG3Su/zv06PhxFXez96oNv/tsOa/OuOvSueaPJHx3HXMujvY3FwjAOKXWe7WZu/WfvuiR/XapO7Sof7NsFDLz/+2nv/r82jKre+NVf/qQvHORemOe/W8I/+gEIczAE+f2savmfOGTq1lFP7XNv/3Utzh0/emU6ThrNXebd/sic+THdi7QODsg/+gjt7w/fDPjfzOoP7fUMfU3/PzYf+fo8y0mdCplP///////yH/C05FVFNDQVBFMi4wAwEAAAAh+QQFFAD/ACwAAAAAGAAYAAAI/wD/CRxIsKDBgwgTKrSTAw0HBz44oFGCTOHAHD4W2Iigo5k6Kb9CXFoY4leEk/KANItwIkKUF1oQ+gvRKIqtKOEkWOAiD8bGkzENKmmU4oidIylCoKAgQYOOE4Cq9CBVkEmjJEf8lSt3hFGHJ56SVKgQZJwDFQIIKvkFIIPWaRlioKhG6cjWJpTatLGQYeASKZRk+Rt8hMA8RoKnlfMnAACOQjcG9jjRzINgWR4QtfAw5M1gJEMoGUhiQvIJDc1iDEinucXm1auj8BgNZGCQEzDWrdP3jo5v3+88rQMHaHaF2gKjqNOhQQIFFEv1SV/HBZw6Uzw4VRA2UMUv3OzOPbJ/srQpjBNDqhggEQj5vyZt1J2wMISLhPtcNMBooM4fKQO1DFGaQEwwUsUJJ+hAyQsvULLgfFs0MAV7bEQ2UBNBmKKOOs04yAUXeW3BAy9TpMOLCX0NZIcxQVQByAkfArIFiG0YgIMtHgBhYUGV9IGDKVUEyQMPXJiySTo5hpHQKDHYcgUOBnBCwia2EHAOEEoqdMMoHhBwyCEEeMALECY4YpFAGRARhglAkBnGjmfGOVBAACH5BAUUAP8ALAMAAgATABIAAAjoAP8JHEjwXwQLBRP+06Hj34l/USJIVPgPhrx/TiI4AfKPxgKFvyRGuJjpn4VwQWz1uULwlxMNEiigQCEQn60mdpBY6DNQB4ZlSSokISWwUJNy5fy9oTQwXIUHb5Ba0ISCkYBp//z5C8RSoBqB5aYRiTGvUiet/94cGshoyJGsdnARaAFrgJAMApMQlFfh36EBUwS2QBTD778qFAm++6eP4hCBFBJq0MHuXEF/sSQIpFnQQoqCDaZoUHiChikeLXkFhuGEYCNKpw1QPNGIIKVmDXhwEsgOr0AabZgO5ELDwu7ZmgcakF0wIAAh+QQFFAD/ACwEAAIAEwATAAAI7QD/CRxIEI0SgggH2ojwr9k/Kb9CXEooMAJDeUCaMYwQhWKjKLaihPtn4Z88GAstEmyU4oidIylCCJSgQccJQFV6DExyxF+5ckcYCfSUpEKFIOMcDASQwee0DDFQVKN0pNy/JpTatBkoS6C/IwTmMZLlb5pVAQAGNvPQVZYHRC08DHnjz59ASgSbxfiXDq5ADwPS8aVIkc4/T4Q1CESRkMs/daYGAvkHg905gU8Igvs3pArCExaGUGygzh8pglXUnfhH6QVB0FsaTCHcDO/ANqaq8Jr9zwRBQCccD8xqAAfhf1t4EOQS+bjz3gQDAgAh+QQFFAD/ACwBAAIAFwAUAAAI/wD/CRz4r1MEgggTEozA8J+6EycARYinRWHCE06caMgIw8Y/hposKpTwD0MUW30ajQspEuGtCk3sILEQ5EUshC8qKFQhpFw5f0woQXKGcNc/JBkGAhDBSMC0f/6QBJLUA+GjVjEOBVIjK5ALYw+O8DrU6lAiMwgPiDl1SlyrQE0u5BiQjpoYTJgCJBqI7N+jA/T2cdMW14UIa4ReqRWT6FofNv/sNRqDBg0fPsyYiRCR54mcOWge7doFadOQN87G0cBw64ccOR3ydHiCgksjDFLiCCxT6UaUKoAEOrmVBEC1fwDCAZBCY4tATiQqmFDhwBQNdRgw+PABoAcAAI3ixHDhYeAfpzKBgKRqw+OfqQULGgHgMp8+pPuc/pGoNcQEkhRXGBCHAw5QwsUJ/5ygDg+1kENOGWXUEggeN/wjgAWU1EKgKYAE514VBjxIySG84BHGGwI5UuE/4/BQBUEGlCeQMEDcgKJCQbSko0jCKBQQACH5BAkUAP8ALAEAAwAXABMAAAhpAP8JHEhQII2CCBMqXMiwocOHEAU6iEhRoZCKA10ovOYQWUQpA5XkEEFRHcIOAzXgi/gjBKV/lJphcAjohEAML8PBjMPwyj9TAxdwATCQZ8Q4NLgUJcdwSAVbBv4ZjfiGYBWMWCkCSRgQACH5BAkUAP8ALAAAAAAYABgAAAj/AP8JHEiwoMGDBNlEQMhwYISHKQhGsNCQYA4fv2ioO3ECUJSHCxnaWdLHVpBwGpw4CRckSZ8gmhD6c5biSIYjKTJJwFehiR0kFmAeVFLhiL9y5Y4kQVGoCVJ/byi9iFWQiaQYSOyUm5YhRgdGAqaV84ck0LNeAggqaRej1aFAao4QEGFMyBFjh9wmMmMhw8AlB8ScOiWulYcHLpQMSEdNDCZMAcwUuiEQWY9HB+jt46atyYULIqwRehVYTKJrSdgItDduDJpXfJQwQ3bBhYgOcuagebRrF6QrFt78c/ZLHYxbcp58EcE8zxM5evBJWcCDE4lKlKOYUqdDA5cfctBQwOpAKRM+DOpomKpOooKJ4eMAndCBD98cSgCqAaC0IM6C9QZYFwgQ/6TShilb0CDFglwAAAAXXMThgAOQcGJdLUO8h0wKbfAQx4cLYAAhDDosAAkk5KRYSyB4UPaPAMYEMWEcNHDEkTqA8JBiGW/hEYZwAr1RSRBbIAjIkUVWwUOAtngAhAlAElRJH+PwUMWVPCxpwCbpOBkGQ6PEEMQVOARIwia2EHAOEF82dMMoHhBwyCEEeMDLk45UpOeefA4UEAAh+QQJMgD/ACwAAAAAGAAYAAAI/wD/CRxIsKDBgwgTJvQ3JUIKDg58cEgRIcIUfwqPFLLVZ5y6Eyd+9UnSJ1bGFEfsHEnRzAmGCk3eILFQCGGGCkf8lSt3hJGEKE12+mNCqVcGg/cAIMlQbpodACgYCZhWzh+SQM8sFGTSrlWMQ4HUyCLQwVinI7wOtTqUiJoAgkoSiTl1SlwrD7FEDBqQjpoYTMECfLNwVOCLRwfo0eOmrckFFyKsEXp1QIyYRNfi3RCIrdEYNK/4KGGG7MIFEXnkzEHzaNcuSJs6CXRm6oSeH3K+MHPBW0QHObf0YFgQxwAJY0T+9dhyAgYXCnIGWaMkgpKWWxgwqNvCwwCnCib+RdIxpU4HjFs/flACQAgApQVSFpiqwoMTiQpA/qkYt0Vd9jFjcAEAAFxIAFEcDjjACSdlBJJfNvGMY8oCFEqhBxcYaqCOA5BAQsKHMYwS3j9NJJFgHAtg4MSKMOhwwgKQkENOGTEMAURyAnUSBCCAfAQSSOoAYkp3nKRjI44CZWBMEFuYsgWPgDRJn3e2eADEZgZV0lEVXNLXnQGbpGNlGAmNEkMQV+DgHQmb2ELAOUCQqdANo3hAwCGHEOABL0CY4IhCA2VARBgmANFnGFgCqqhBAQEAIfkECQAA/wAsAAAAABgAGAAACP8A/wkcSLCgwYMD7eRAw8GBDw5olCBDSNBfDh8LMOjQcUKdlF8hLvlDmKEfgR749DhZCYMjjR7lBmTIYLDbARARymn6IUECFyfNypV79uxAN4PcEtGj960cATkoKMQo1+tAgADfcBVkkkjMqVP0uCnJ0+GJnDkHxGAKFkCcAIJK2h1Yyu0eMxEi8ph9lVZMIjMWaAp8AfEVHyXMXFxwIaLDWTSPdu2CFO+GQGzjMOj5IedL4gsX8sq5hQ/DgjgGNnUSqOnXCScSUHz5Yo+SC0qkfpQ+AaiKARLGiPxz5hqGBs6DKAFQAoDSmAVSAJni8buSiX/ZGtE4gQ/fmDlcAAC64MJFSpzz1DnVGnX9XyFT0KVIGcOTCwUJGHxA2g+JRCBhwv3TRBumxAGdHj35pAEMNDgACTkk1DJEe/8wwYhrJ+iwEksubUGdf2xYNlAqQZiijjonpJiiOtKll86EggmUgTFBVEHDFoDkuIUpVaRniwdAiFhQJX3gwGMVPVKXWjpAhkHRKDEkcQUOBnBCwia2EHBOkBQJFMYoHhBwyCEEeMALECY40uVAGRARhglAoBmGkGvWaeedAgUEACH5BAkAAP8ALAAAAAAYABgAAAj/AP8JHEiwoMGDA+3kQMPBgQ8OaJQgQ1gwh48FGHToOKFOyq8Qlyj+sxPilxMNTlLC2EhjwQstCP2VRMlFgk0uGmCcoFGlEUyDShgFavaDAoqjFCRowPei3IAopArakcShV4RypL506PAERaZy5Z7tkkRNAEEl7Q7QoyeuHAEXIvIQKNfrgBgxicxYyDBwid1Tp/a5QuICbgdC3MRgwhTATKEbApH1eKSWHjdtyC5ciDvolV2815KoEZhq3Bg0r/goycHsgmE5c9A82rUL0pUhb/4tM6UO360fgwbZoySCkpY5GKRIWcDDAAlGkFVUUadDz+85lAAQAkBpgXdTcXhwuyIRyMS/VI22qMPAfowEAAC4cFngI44DAwY41RpiHkmhRqZ4t4AUesjHhRMYQKIgJORsUgEekP1zRBIOxBEHRik5sdIJpjBYRhkE8GNCbqQFwZs6J6SYojqAmFJFfunw5whBGRgTRBWA5JjjFi42x4ktHgARYUGV9IGDi1VUwUNzBmySTpBhUDRKDElcgUN+JGxiCwHnCCnSP2GM4gEBhxxCgAe8AGHCjF/+kwERYZgAhJphDNnmnXjeGRAAIfkECQoA/wAsAAAAABgAGAAACP8A/wkc+M9ODjQcHPjggEYJMoIQCebwIQWGHicwdEhZEOJSRIJ2QizQwEWCSS4aYJyQ8kLLx3/+RJakgKImBQkpT2xp5DKikl8aJKB40iFPhycocOpQZ6oHKYhMGsHgQuFJHhFY8zyhwEXllnEqBBD86URohxoRLrgQ0SGCPCcnAFVpYyHDwCVSgkbYW+PCBRF5Iu2NIJdToRsDe5woi6KDCBdq2SaFK9dAEhMDgwDYzBlADBFfOndOAiQzADX+UvsTEuhoDNSqhVCqUFpglB4DhLwhgutQNRQUMuXejWvAlQrCBqpo963VgAEEQpx0siTG81bozASq/a/JtwCYMInVOTDmIgwMHA4ECBYswI4hmAUy2ZHoAJT7+PPfD7BnBxvEAz0AAgDuzGCggX9IA4ECDALQCnx2DZSBMbYUaCA0ExRQhwLmMFiBB8IASJA/lVg4AzQyDJMGgwpAAGIYH6U2wokTyDDJMKEwaA4rJsD4UT0NfDLDGWAkMIw3oUBQBI+OROTPPxuwIoqQHxRJSxpJmrPjQE9CpMgsVBbpBpLmQGDmQBuYs8E/wKwp0CfAdHFHAm6sqKWWAgFTAp4bNGCXP3CKoksyyawAyp3m/KPIBrrcAUdAACH5BAkKAP8ALAAAAAAYABgAAAj/AP8JHPjPTg40HBz44IBGCTKCEAnm8CEFhh4nMHRIWRDiUkSCdkIs0MBFgkkuGmCckPJCy8d//kSWpICiJgUJKU9saeQyopJfGiSgeNIhT4cnKHDqUGeqBymITBrB4ELhSR4RWPM8ocBF5ZZxKgQQ/BkURYcaES64ENEhgjwnJwBVaWMhw8AlUoJG2FvjwgUReSLtjSCXU6EbA3uccCK0gwgXatkmhSvXQBITA4MA2MwZQAwRXzp3TgIkMwA1/lL7ExLoaAzUqoVQqlBaYJQeA4S8IYLrUDUUFDLl3o1rwJUKwgaquPat1YABBEKcdLIkxvNW6MwEqv2vybcAmDCJ0zkw5iIMDBwOBAgWLMCOIZgFMtmR6ACU+/jz3w+wZwcbxAM9AAIAuxRAxQcFFFBCEQwyCEAr8Nk1UAbG2JIAAgj8kSAYXUDQYAUeCAMgQf5UUgAECFCRYAFgrJFFF0XwIkwYL9WTRRYfqLjhMccgsIolNNZYxATQIFjAjd5EA0E+b+TiT0T+1ANMFjJMYGQdXSigAASzbFDEBhApUo8oEExQpY4FnMEgCwyKIspAWNQzCwsKdHHHBH+g+QECbDIIEQts3gHGoAYWk6AXXnTRZxEQBQQAIfkECQoA/wAsAAAAABgAGAAACP8A/wkc+M9ODjQcHPjggEYJMoIQCebwIQWGHicwdEhZEOJSRIJ2QizQwEWCSS4aYJyQ8kLLx3/+RJakgKImBQkpT2xp5DKikl8aJKB40iFPhycocOpQZ6oHKYhMGunhQuFJHhFY8zyhwEXllnEqBBD86URohxoRLrgQ0SGCPCc6q7SxkGHgEilBI+itceGCiDyR9EYAVIVToRsDe5woi6KDCBdq2SaFS9hAEhMDgwDYzBlADBFfOndOAiQzADX+UvsTEuhoDNSqhVCqUFpglB4DhLwhgutQNRQUMuXejWvAlQrCBqpo963VgAEEQpx0siTd81bozASq/a/JtwCYMInjOTDmIgwMHA4ECBYswI4hmAUy2ZHoAJT7+PPfD7BnBxvEAz0AAgAjuDNBAWAIksYxgrBQQgkAtAJfXQNlYIwtI9wBSjTHrOFhgw9W4IEwABKUAS8ZWjEMKgUUsMY2Do4wYhgRZTBLLm64sYgMLFKxBogjmBAGFrNAZCMLoLgzCY8FUFEAjCWwwoQiG7AAkSJwICnDJJP0WAyMrKzwTwbAQDCQP4o0sAqSCSy5CCpUFCMNC3fUM2YDGwhUTwOGsIDkHXdE4wYqLHoBIwtFQlQECwiAQQYogJKhoyqq+AGjKBQSFBAAIfkECQoA/wAsAAAAABgAGAAACP8A/wkc+M9ODjQcHPjggEYJMoIQCebwIQWGHicwdEhZEOJSRIJ2QizQwEWCSS4aYJyQ8kLLx3/+RJakgKImBQkpT2xp5DKikl8aJKB40iFPhycocOpQZ6oHKYhMGsHgQuFJHhFY8zyhwEXllnEqBBD86URohxoRLrgQ0SGCPCc6q7SxkGHgEilBI+itceGCiDyR9EYAVIVToRsDe5woi6KDCBdq2SaFS9hAEhMDgwDYzBlADBFfOndOAiQzADX+UvsTEuhoDNSqhVCqUFpglB4DhLwhgutQNRQUMuXejWvAlQrCBqpo963VgAEEQpx0siTd81bozASq/a/JtwCYMInOOTDmIgwMHA4ECBYswI4hmAUy2ZHoAJT7+PPfD7BnBxvEAz0AAgB+MGDggQx4YaA0ALQCX10DZWCMLUZIIw2C0nijCgO+VOCBMAAS5E8lFV6IoB8F+jKCJfF9VIo0aWyjjDJeeIGKgr6UkM9LAp1RSjRrrEGjF2ukqMAGWEAY0RqlHFMKjRdaqEopXbAAzCwvgWGEG8es4UUxxaxByyTugCKKKMB8hMUZ25DRZQFwLjIJLLRAsIGSBIlyRxeClGIEiiiqMsmgbtyB5gb/BAQAIfkECQoA/wAsAAAAABgAGAAACP8A/wkc+M9ODjQcHPjggEYJMoIQCebwIQWGHicwdEhZEOJSRIJ2QizQwEWCSS4aYJyQ8kLLx3/+RJakgKImBQkpT2xp5DKikl8aJKB40iFPhycocOpQZ6oHKYhMGunhQuFJHhFY8zyhwEXllnEqBBD86URohxoRLrgQ0SGCPCcnAFVpYyHDwCVSgkbYW+PCBRF5Iu2NIJdToRsDe5woi6KDCBdq2SaFK9dAEhMDgwDYzBlADBFfOndOAiQzADX+UvsTEuhoDNSqhVCqUFpglB4DhLwhgutQNRQUMuXejWvAlQrCBqq49q3VgAEEQpx0siTG81bozASq/a/JtwCYMInfOTDmIgwMHA4ECBYswI4hmAUy2ZHoAJT7+PPfD7BnBxvEAz0AggfQzGDgDFRQcUYdvoSCSAytwGfXQBlUkkKB0GQ4QQFnlKKAFYhU4IEwABLkDyITzADNBDIsMow3aYRixRS8CBPGS1iswKIMkwwzTBoxKjACEDe+VI8hYCSQQI8/hqIABEUUMZAiWECEhSEfJOCGG7R4E4qTEEBgzkC5sELQLBt8kKSWXcYYCgJwTPgPmhtsgMUshtTRxR1KahlkmFAisMpAs8yiyCzA1MGCLsk0msAKTj5ZhC9RInpHQAAh+QQJCgD/ACwAAAAAGAAYAAAI/wD/CRz4z04ONBwc+OCARgkyghAJ5vAhBYYeJzB0SFkQ4lJEgnZCLNDARYJJLhpgnJDyQsvHf/5ElqSAoiYFCSlPbGnkMqKSXxokoHjSIU+HJyhw6lBnqgcpiEwaweBC4UkeEVjzPKHAReWWcSoEEPzpRGiHGhEuuBDRIYI8JycAVWljIcPAJVKCRthb48IFEXki7Y0gl1OhGwN7nCiLooMIF2rZJoUr10ASEwODANjMGUAMEV86d04CJDMANf5S+xMS6GgM1KqFUKpQWmCUHgOEvCGC61A1FBQy5d6Na8CVCsIGqmj3rdWAAQRCnNSzJMbzVujMBKr9r8m3AJgwie05MOYiDAwcDgQIFizAjiGYBTLZkegAlPv4898PsGcHG8QDPQACAAkkQwwxMyQ4AzHSdGEFAK3AZ9dAGRhjSwIJnPHBH9BAQ8UHdVhhRQUeCAMgQf5UkgAoZ4BRwAQwFiCIiB4AEcZL/oxghSCCuOHOJKisIUgoVphwI0Sz1PNPPatkwaMbGKJCRh0lWEEEEf4oQhArutSjiCFOtgjjMaFsc4cV/zjiTy4ElcAKMIYYsiAVCM5wTBqhOPhPBqyIAlE9hqyCQBddIPABNB98EIoCEECwwT8bsInkKl2w0IUouiSzAhmfiCjiHZ9MGBAAIfkECQoA/wAsAAAAABgAGAAACP8A/wkc+M9ODjQcHPjggEYJMoIQCebwIQWGHicwdEhZEOJSRIJ2QizQwEWCSS4aYJyg8ULLx3/+RJakgKImBQkpT2xp5DKikl8aJKB40iFPhycocOpQZ6oHKYhMGunhQuFJHhFY8zyhwEXllnEqBBD86URohxoRLrgQ0SGCPCcnAFVpYyHDwCVSgkbYW+PCBRF5Iu2NIJdToRsDe5woi6KDCBdq2SaFK9dAEhMDgwDYzBlADBFfOndOAiQzADX+UvsTEuhoDNSqhVCqUFpglB4DhLwhgutQNRQUMuXejWvAlQrCBqpo963VgAEEQpzUsyTd81bozASq/a/JtwCYMInYOTDmIgwMHA4ECBYswI4hmAUy2ZHoAJT7+PPfD7BnBxvEAz0AAgB3/PHHDAgSU4wvvpRQAgCtwGfXQBkYYwsrZ3zwBzTQEHNGHRAoYEUFHggDIEH+VDJCFmdsOMEfZ3ShAATmlBjGS/+AggACCcggAyprhKKAAqGscONLWKyCQBZuTJIAGYLIKEiROPozyypdCEJGAqgcIwgEdZyxygovKdKAIauckeEfExwjZBfEGEJmRFjAscoqxOSJ4B9uKrBNnLlgEdGaMxCT5gfQ/EHGkArkeQYrBAUEACH5BAUKAP8ALAAAAAAYABgAAAj/AP8JHPjPTg40HBz44IBGCTKCEAnm8CEFhh4nMHRIWRDiUkSCdkIs0MBFgkkuGmCckPJCy8d//kSWpICiJgUJKU9saeQyopJfGiSgeNIhT4cnKHDqUGeqBymITBrp4ULhSR4RWPM8ocBF5ZZxKgQQ/OlEaIcaES64ENEhgjwnJwBVaWMhw8AlUoJG2FvjwgUReSLtjSCXU6EbA3ucKIuigwgXatkmhSvXQBITA4MA2MwZQAwRXzp3TgIkMwA1/lL7ExLoaAzUqoVQqlBaYJQeA4S8IYLrUDUUFDLl3o1rwJUKwgaqaPet1YABBEKc1LMk3fNW6MwEqv2vybcAmDCJ3Tkw5iIMDBwOBAgWLMCOIZgFMtmR6ACU+/jz3w+wZwcbxAM9AAIAfxQABhiCpKHgMYKUYA4ArcBn10AZGFPJHdEcQ8YaHHJYShddWOGBMAAO5I8iI5QwzCKoFFBAgWuUIgiIwoQRUQa53OGGDKigQkUBVBT4oQJdhFHPLBGJAooMi/AIJBU/DtnFP8CwAFEDotwhwyROQgmlHzNOCQwEJjaQRZZbNtmil9KQAeI/s2wgEBYNIMDCHXi64UaPLroojQJEQsQCCwiQQQYoWSyiqCqq+OGHNNv4AsGUBAUEADs="],
- "20": ["[偷笑]", "data:image/gif;base64,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"],
- "21": ["[可爱]", "data:image/gif;base64,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"],
- "22": ["[白眼]", "data:image/gif;base64,R0lGODlhGAAYAPfPAP/LJvbBSP/vWu7HOd7Z1beCR92cItfRzMmFGP/SLf/WNNKPKujl4tKJFv/3eNixa//oTP/9ss6BCv/iQvW5KMyVQPa6NffamsurheSrJvGjC+Xh3vCwH//7lqlhEf/wXf/5h//1bf+2D/uuC9CfSv+4Ev/DHemvJv/qUPfHWvjGLP/ePdefRKpeC//+yNqkQ9qOC//GIP20D//cOteZIdKNHf/VMeSXCs2KJP/uV//kR9nUz//wX//+0P/9uP/FH7ySZf/mSP+7FP/7mv7TNOrJkf/7oP/PKv/3d//dPOCmIu65S/2xDLFzLLh8Mt+eJP/AGv/2dLqJU9KMGf/+x+29WPSoDP/+/PnEJeKyUv/pTf7ZOMWebct9B/3RMvbLNvjHMf346/PesPry5/zZPv/qUfnCJufe0O7Yme7SWf/fPv/4e+7Vb9GsdMJ8FL13FOulFv/lR9edLdKWM/3ZO/GsEv/gQvrIK//8m6xtJf+/GfmyFOafEPyrBv+vCPOhBf3aO//QK////10jAMp7EPbm0KdRBHwtANXGvf/bOePf3Pv6+tzX0//sU9eeNf38/PTy8e7AL///19LFuP7kS+rj3P/89+rn5P/xX9GGEvvhpdOzgtO7n9XEtfDu7Oq4UsKKPv79/MiQPq5mEa5wLN2hH9+4b8ivluG/jO+zMOerH5hDBr1/LsOIJsCXZ+GgIeanJt2cH//nS/OyF//bOv/nTPmzFP/8oL2BLuCpRuTDjLFpENKPI8ePQMGNUOm2UdCvhO+uH++oEf/3e/bEL8eNKMGYZ+SkIsqxlvzTN/C1MYczAM+VKs6UHP/XNP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFZADPACwAAAAAGAAYAAAI/wCfCRxIsKDBgwIRDRqEiKBChggJDuq0aVAAChYCDGrDaVDEgZosgEkGaMYWL3coVBHz0VKKEw0ITRmAIsiAmJkM/EJ4JQWYKYMOFarxIQdQoQ2CZTl4gVgjQocECSKEJARUqYSIPDFVMIwySigISZ3aAYRYrADMvDhD8MKXODlqFBJUaEGEW7zmFmpwxAScB4sGLiED4UMaRzhYoKESgY2cGjQiJfhhaw6DgbDsQMC0ZoiPHpJ6+BiyBhMENZOFIGA08FiSwkg6RKDSg3EHJB8grJhcAsGBga9mBMkRAoSRCD4iGAERIkeQGX1LuPkt0ICCCSgwRQHRYUjZKJhQTNBwBgCKjDfUn+VSMSNOI0whkAyriqlRnBkJYgixgit9EVU2JBEHCjl8gElRKOiwgg3liQADFwQMNAYvWNgwwwRBQKCFFkFMMAODJpSggROTXEKQLicAkIAziazgYiLOJACACUIwsYsxBAQ20BUVZBADAIEkIGQgAMQARQkjSFDAASYa1IsSs5jwgwCGGCKAECLcMIoUBygSETDFZCIMlVYm2QQyO2zw0TOVYCCBBn708UcXQBxAACRrCvSIL0204EEeSzaZ50CKEHDADoyoeVBAACH5BAUUAM8ALAMAAwASABAAAAhrAJ8JHPiMDsGDBMHYgYAChRZZOuxsMZMBYZlGOT5gEogijkQvCFusGtnCwTORJBEKXIaQpcqXMBG6gDlBy7NhKnFqWfEsRgmeMQUmGUiL4K2gIoIqfWZS6QodKuMshQBhqdWDRwZmHchkYEAAIfkECWQAzwAsAwADABIAFQAACGsAnwkcKDAJwYMDTzQgNGWAwAELMxlAOKXQoUE1BFa82AAhIUGCDhFC8uxjSEIIBQpCuPJgkJQwY8bcY0fgGjwycw50IHCFzlsEE+lMqecgj2dI1vCUmSQOTIM5tQwVOKNg1alYs2rdyjVrQAAh+QQFPADPACwAAAAAGAAYAAAI/wCfCRxIsKDBgwgTKlzIUJMFMMnorNji5Q6FKmIUWkpxogGhKQO0yBrgMdOTTwivpAAzZdChQjU+5Gj5sgGHLAcvEGtE6JAgQYQchOj5kxCRJ6YMpqKEgtBPoB1AOC0KwMwLg1+C5KhRSFChBRFu8epaqMERE3AMkoHwIY0jHCzQUInARk4NGpES/LBl0I4WTMOG+OghqYePIWswaVGTIEaJgq9WsHXQIQKVHnM7IPkAIYnexwRjJdIaAsStCD4iGAERIkeQRGdFFKShYAIKTFFAdBgSNQomFBOcAdAjo+ALFTPiNOIRwsEaJCEwNdIxo7EQK6wKqrKxIg6KHB8wyZREESeJDQBQRMAwiAOLjRkTgkDQAiHIhBnnTZTQ4MQgqgwAJOBMIisUmIgzCQBgghBMjOKKQaGIokQMAByRgACGGCJADFCUMIIEBRyAECilzGLCDxhqKIQIN3ggxQGKJIRBK5nwUUcJMlhxQxeknLLDBgtVgkEBTbTgQR4FAHEAAZAw9MwjnihCwAE7MLLBJU5mSVBAACH5BAkUAM8ALAMAAQAQABEAAAhXAJ8JHEiwoMGDCBMqfIYiiMJCzwYRhCixoKBnhwhezLjwYJyDRjoKdHFwgsA1B4cJXEEQCUGSzxwQnIHwFsIyBPEQxGkQk8eCSUQehHBQSEFaSdQENRgQACH5BAUUAM8ALAAAAAAYABgAAAj/AJ8JHEiwoMGDCBMmRDRoEIkAFCwEINEQkUKBg5jRGEQnyRYvg5pVGKTQUooTDQhNGaBF1oCUmZ58QnglBZgpgw4VqvEhB06dDTggvECsEaFDggQRchDiaFJCRBCmooSCUFKlHUBYfQoA4ZcgOWoUElRoQYRbvMYWanAEIRkIH9I4wsECDZUIbOTUoBEpAUI7WjANG+Kjh6QePoaswaRFjd+DK+A66BCBSo+7HZB8gJDkscFEYEOAuBXBRwQjIELkCJKo7UEFE1BgigKiw5CsUTChmOCs60EVM+I04hHCwRokITA10jEjQQyEqmysiIMixwdMPVHESWIDABSEOLDYLpgxIQgELRCCTJjR3UQJhKgyAEjgLNGK+4mcJQBgQgiTiwAGKOCABBZo4IECBgQAIfkECRQAzwAsAwABABIAEwAACGwAnwlENGgQIoEDCx5EKHBQp02DGA5qwykiw2eaLIBJBmiFwDsUqoi5SBJFEJIkCz2zKFAly4uCnh16hkRgzJkoc+rcSVILz58MhzH8ISTJTgdABd5K+gxPTigXMaGMw1Sgx6o8Z2Dd+swEz4AAIfkEBRQAzwAsAAAAABgAGAAACP8AnwkcSLCgwYMIEyZENGgQiQAULAQg0RCRQoGDmNEYRGfFFi+DmlUYpNBSihMNCE0ZoEXWgJSZnnxCeCUFmCmDDhWq8SEHTp0NOGQ5eIFYI0KHBAki5CAEUqWEiDwxZTAVJRSElC7tACIrVABmXhj8EiRHjUKCCi2IcIsX2kINjpiAY5AMhA9pHOFggYZKBDZyatCIlOCHLYN2tGAaNsRHD0k9fAxZg0mLmgQxShhccddBhwhUevjtgOQDhCSFNRdMVDYEiFsRfEQwAiJEjiCJ5IowqGACCkxRQHQYwjUKJhQTnAHQI8OgihlxGvEI4WANkhCYGumYgVmIFYOqbKxxiIMixwdMPVHESWIDABQRMAziwGJjxoQgELRACDJhRnsTJWjghEGoZABAAs4kssKCiTiTAAAmCMHEKK4YFIooSsQAwBEJCGCIIQLEAEUJI0hQwAEIgVLKLCb84CGIQohwgwdSHKDIRTjmqOOOPPb4TEAAIfkEBRQAzwAsAwABABIAEQAACGsAnwlENGgQIoEDCx5EKHBQp02DGA5qwykiw2eaLIBJxvAOhSpiLopEEUSkyELPLApEqfKioGeHGL6MabKmzZs4cyJcg0dnEoFIbq5gGMfkLZMlcpZBCOUiJoHDHCAsqhPhUJ1UcdJCuNVkQAA7"],
- "23": ["[傲慢]", "data:image/gif;base64,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"],
- "24": ["[饿]", "data:image/gif;base64,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"],
- "25": ["[困]", "data:image/gif;base64,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"],
- "26": ["[惊恐]", "data:image/gif;base64,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"],
- "27": ["[流汗]", "data:image/gif;base64,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"],
- "28": ["[憨笑]", "data:image/gif;base64,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"],
- "29": ["[大兵]", "data:image/gif;base64,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"],
- "30": ["[奋斗]", "data:image/gif;base64,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"],
- "31": ["[咒骂]", "data:image/gif;base64,R0lGODlhGAAYAPf/AP7fQ/a6KMurhc6CC/a7NffGKv/hQv/9stqlQ//LJsJ8FciQPv/VMf61EPCjC+Tg3f/7leSsJf/3eP/1bdmYIa1kDv/oTP+4EvDu6//qUNiod/KrFP/kRo06AuXMtcp9CPncm7x+Lf/89v/DHfCwH7WBRtuyRKRUA//ePf/wXf/xX//tV//+0P3tXf/aOV0jAP/cOv/FIKxkE/2xDNqNCv74htjTzv/EH/60DvfFMKldCdq1UtCTHf/9uNinN//+x+mrLOSXCv/dPP/XNP/7mv/mSP+6E/35nf/rU//PKv/7oM+iM//5h/2+Gf7TNPnDJpxKA712FP/3d/v6+tCeKv7ZOKpbBpNHCv/SLpRIDf/2dMeCFv3RMv/lR9WZG/SoDP/AGvnEJbpsDP7QL//sU6J+Of/pTq9uGPzZPv/4e/uvDPOxF//+yP/+z/3ZO7J2Hq5hBfmzE/bLNt2hH//QKv35tf/pULVkB285CP/8muulFv/xYP73h+afEK6GJuHFV//qTvzTN/3aO7+EH7R6I8WDHP/fP5NEBvmzFLtxCf/XM+fCOv2wDP/vWtfRzP///9fSzf/SLa6NPNzX093Y1Orn5P9gAP/RLePf3K6QWa5wLOKyUv/+/Pzlr7mIU+CnIvfKZ+rj3Mivlu24S7iESe+zMOCfJN7Z1dLFuOq4Uu2+WOfe0P//1/38/P79/OWmJvPesLd7MtGWM/346/vhpffIW/nFMPbYmf7kS//nS+GgIadgEPry59ixa9+4b/XBS7uRZfbGWaxtJfjKX8yLIsuJGsCXZ8WebcOIJunIkfzw1uG/jN/a1vfBRf/uV+ro5d2cH+jl4tlhAIldIepYAHdFE/vIK8KKPrFzK/Ty8ffr3pw7AOaqH59YEdS1o7d2F+HAR8eUK+fWzP/bOfzUOP/8oOTij8yhccpZAN+wMta0jPzrW+C7Zubi3+fp59aVGNCfcfHbxPfAIrBiCbdqBsuQK//0VP/2c/+7Ff/jRv3uW/7UNP7PL/vILIczAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQFHgD/ACwAAAAAGAAYAAAI/wD/CRxIsKDBgwgTKhTRaVizAAR+gQKhTOFAWgRsBXIjpAoXawFUwVpYyxYACxkymMmVz5CLJ0BSIeQULEcGJCtSqEjhLEMXA1XGkNh0EEQOf/72TJCQRsIEFWQ4IN1nylfBWaVwZVDhjwkEIhCYaOFqYEiCJwhWEbwlp8uKCUz8HehxoFxcZ0VgJBmhp9eUgaPQWEgh6UUmfyx+HPBX2A+KSDEQyYo28JUBMypeaGbBikWPPJpfoMASw0ixSQN1oRhcONOPxAcgNEZxKcaFLZAGQhtXxBnccnPrMpmwosu4vRcUOBpIYYiBDHu0eAUrVkWGsgnA4IiyXCCCAuO6kL5RsfQP0iVkusCAjO9LiNwCk3FjIKRLBmfg/Nmzd2aREAbZNUDDMZQMxAsxYTAAgwGLvGEPFeHYAwOAIxjhQCyoPEPQMhEkEMkQ46AgIgyKXJJAhYxUYAwzfw3kygKfxJBAEpFgEUkSCcQAhhFqDEAKJJUcdM0ca4wQQww3jAAGPg0EIYMnjmCSkADIDNDHBhc08EUQH2giig3tWBSKACVgo8MuwpQAjCOnZGORQK1ggAkljtgwyQNBvqlnQQEBACH5BAUFAP8ALAMAAwASABEAAAh8AP8JHEhuoMGDCAdySDgQyT9nCV3wS6jinxSLA7sIdMKwo8EiEA8qMTiOjkeGN+L8s4CwzT8iCC8IOSlQSKR/RkQidFaEIs2BMA7uuHLFBM0VKa6IE3eFAwqPRRr5e/TIX6OTMBod8ubt0FWBMxg28uLP37uvJxupRWswIAAh+QQFBQD/ACwEAAMAEQARAAAIcAD/CRwoaGC/gQgHmknIcGCGfysa/hsjUaCEihj3YMSYZGNCLP8QLfQokU0bhigu/btAEgZJj1LSSJigYqDKgSgEOvun4sqVRl2EYLRg4Yq/Ri4lKvonBECjRgBu4mtI5xKWS0kSxFiJMcaNEWAaBgQAIfkEBQUA/wAsBwADAA4AEgAACHAA/wkc+M8awYEWDv6rorChQH4HJfyT4rDhvYoKV3TBSFBIpBhxBLb5x4Ljj5INbwgs53AcHY4NJey4csXEwEgKr4gTd4UDioaN/D165K/RwAsCh4xrdMibt0NG/xk52MiLP3/vjE5V2Khr1IpbGwYEACH5BAUFAP8ALAUAAwAPABIAAAhzAP8J/BdooMGD/8wgdBHGIJJ/zv7tOVhljMGJUhBqPKhFxcEVCMsJjLhRIwqELDQaKqkxBsuXCBVpTCNhgseDQi5eudKoS06NFsxc8dcIxkAjAi8JRAGgUSMAWATiO5jkEpZLSRK4LBkjxggw/y6wFKsxIAAh+QQFBQD/ACwDAAMAEgASAAAIcQD/CRxIzs3AgwgTInyiUOAKhS4aqmjYcE/CexSdUfxXZKNANgkv3UCUsI1CFAKNoPT4T0hDJQNhsqQ4ZOOOK1dMUFwp8Io4cVc48GzYyN+jR/4abVT0r9Ehb94OKfXYyIs/f++UXqDaqOu/BjONUAwIACH5BAUFAP8ALAMABAASABEAAAh9AP8JFGhhoMGDAzP8c/ZPxcEq/BAOlGAQycB9Bx0e1CLxX5eOAleANPhDYow4Hdt0vCDkIBuJKCL9MwKy3MEkI3MelJJGygSHHP5dGqniypVGXVoKvICwiwUzV/w1ggEy0pB/QgA0agQAi85IWC4lSRBD578YMUaAMbsUZEAAIfkEBQUA/wAsBAADABAAEQAACHEA/wkUGGigwYMCzSBciGQhB4FjFkoZuIfMQCcLMwosslCJQGf/YGhcGCkji5EDf/xjk7HLwHIoEeZB2fCfhB1Xrpj459KgEINXxIm78nBgg4ON/D165K/RyEaHvHk75PSfkYWNvPjz966qxkZgvQ4MCAAh+QQFBQD/ACwDAAMAEgARAAAIdQD/CRxITtDAgwgTKlyYsAvDgRIGqnhIMeEKhhfHVUx46R+ihCz+tfmXZ2NFGEUu/lNiEiGRgXsEKkpIZmAaKRMmCoyEEIXAiyquXGnUxSfDIhYsXPHXCAbDjv9QAGjUCABUfE+xREqSIMY/Iw9vxIgxAozCgAAh+QQFBQD/ACwDAAMAEgARAAAIegD/CRz4zw3BgwgTKlwo0AVDKQwV5hF4b6EzhOUEOusCg07Eg0IExmFIZKAhgUYU/kB46d+Fcf8uHlQicMU/GAkrHlQhcAjDHVeumBjYkmDImP+uiBN3hcPHRv4ePfLXiKGif40OefN2qGrERl78+XvnlWGMRmjLEgwIACH5BAUFAP8ALAMABAASABEAAAiBAP8JFGhBIKCBCBNmIJOwocN/Eh5KRKhl4sQi45JIbNMQBUILexKy+JdnoMd/F04OZPMw0j8jEssJdPZvXMM9FS06lJJGwgQVSARiachh4J4rVxp1EWLRgpkr/hrBGHih4ZB/QgA0agTg0kBGD7FgiZQkQQyd/2LEGAEGrUCYDwMCACH5BAkKAP8ALAQAAwARABQAAAjhAP8JHChoYL+BCAeaEbhQoJt5MhAWCockocBB33gg7PaGUMJ1S87AwILQTgsqWf4R+cfnT5YyFlf8KwMuS51/R7JMe4HnHx2E0/7h+cGCzT8I1YQKvPFvYVI8bQYSSVPGjKGEEsoc+IFQij4L/y79u4CwXEIfYrZESKgCrQJZCOrN0+ZBg453CKlA8dfhnAdt2vwJ9jcPoZXBiBGfQLgX8T/EHawwFryNGjVLlh5ZknZiBsJHULahk4YZMxR6Gz4LTATn0YkTcD4IfGRRIJBHF+IkpG3xnLra7mr/a1d7isCAACH5BAUKAP8ALAAAAAAYABgAAAj/AP8JHEiwoMGDCBMqXMiQFgFb5NwIqcLFWgBVsBSKqGULgJkMGczk4mDIzTwZqRIGKxQOibMUKlKsyNBl0DceJDYhzNHtDaEJEtJImLBuyRkYkZyY8nUQl50WVLJAIAKBz58sZQwMSfAEwcEiziaUAZelzoEjWaa9wDMuyQg9By2kUIvnB4sfByBUW4si0o04B83s2YuHBSsWPYikKWMGBZYYF+KmkFLmgF02eaWksCAkEuSDXcIyUXKgB7tCJiY4K9J2RGSDBjKo0MIEwg4rGsSsy6A1ARgcB2F0IaNigpQo8R6dSNcFxqUY+L4cZCCky6NHje7489fhkTkGj8A0haBxMAwDGAasa+/gL9b1EUYcxDoYIUEkReOyS7NEzYo8+DNUYMxBC3wSQwJJNOLFNtRIo0ATF6gxACmQIHTNHGuMEEMjJ3RwQiMNBCGDJ45gkpAAyAzQxwaNtEjDB5qIYkM7C4UiQAnY6LCLMCUA48gp2TD0TysYYEKJIzZM8kAlQjZJUEAAIfkECQoA/wAsAwAEABIAEwAACKkA/wkUaGGgwYMIBzpLmFAKw4cDa0CcKJAOxYOXYgxUkTAPQiNCBEoQyObfj4H6/qEwWGRgOYEHyjHxIWZLhIQ0FchCUG+eNg8adLw7SAWKvw7nPGjT5q+pv3kHrTj1J3CqvxMHjTr9R9VpBytZm26jRu2fpUeWpGE9+AjKNnTSLMm1BIXeBrYCE8F59O8EnA8C+TIE8uhCnC9BBgpGeE5dQncP2yWcIjAgACH5BAUKAP8ALAAAAAAYABgAAAj/AP8JHEiwoMGDCBMqXMiwYUIRtWwBMJMhg5lcHAy5mScjFUJOwQqFQ+IshYoUzjJ0GfSNB4lNB0Hk6PaG0AQJaaRMWLfkDIxLTkz5MlgKl50WVLJAyAOBz58sZQwMSfAEgUE5RZxNKAMuS50DR7JMe4FnXJIRegyisZBiLJ4fLH4cgFCNLIpIN+IYNGBmT108LFix6EEkTRkzKLDEuGAQBVspZQ7AZTNXSgoLQiItNjiui1YmSg70YFfIxARnRcyOYFxwiIEMKrQwgbDDigYx6zJITQAGh8ECMLqQUTFBSpR4j06k6/IzBr4vBrkxENLl0aNGd/z56/DIHINHYBrQhzBILAwDGAaqZ+/gL5b1EUYcxDK4LEKCSIrGYZdmiZoVefDNUIExBrmywCcxJJBEI15sQ400CjRxgRoDkAIJQtfMscYIMTRyQgcnNNJAEDJ44ggmCQmAzAB9bNDIizR8oIkoNrSzUCgClICNDrsIUwIwjpySTUOtYIAJJY7YMMkDlTjkpEABAQAh+QQJCgD/ACwDAAMAEgAUAAAIpgD/CRz4TxDBgwgTKlzIsCGWfQuJNJwokA7FgzEGqmBowRDDNgT1/UNx6Z8RGEVWHDxQjokPMVsiJHypQBaCevO0edCg491BKlD8dTjnQZs2f0j9zSOIwkpSfwKf+jtxMGjSf1CTdrBSFek2atT+WXpkSRrVg4+gbEMnzZJbS1DobUArMBGcR/9OwPmA4x9ehUAeXYjzJcjAvwjPqUvobmG7hFMEBgQAIfkEBQoA/wAsAAAAABgAGAAACP8A/wkcSLCgwYMIEypcyJAWAVvk3AipwsVaAFWwFIqoZQuAmQwZzOTiYMjNPBmpEHIKVigcEmcpVKRYkaHLoG88SGw6CCJHtzeEJkhII2HCuiVnYERyYsqXwVK47LSgkgUCEQh8/mQpY2BIgicIDMop4mxCGXBZ6hw4kmXaCzzjkozQYxCNhRRu8fxg8eMAhGpvUUS6EcegATN7AONhwYpFDyJpyphBgSXGBYMo7kopc2AvG79SUlgQEsmywXFdyjJRcqAHu0ImJjgrEnfE5YJDDGRQoYUJhB1WNIhZl6FrAjA4DBaA0YWMiglSosR7dCJdFxiXYuD7YpAbAyFdHj2XanTHn78Oj8wxeASmAQ2DxMIwgGEgfPkO/mKJH2HEQSyDy0SQQCSKjEOeNJZQY4U8/M1QgTEGubLAJzEkkEQjXmxDjTQKNHGBGgOQAglC18yxxggxNHJCByc00kAQMnjiCCYJCYDMAH1s0MiONHygiSg2tLNQKAKUgI0OuwhTAjCOnJINQ/+0ggEmlDhiwyQPVALllgQFBAAh+QQJCgD/ACwEAAQAEAATAAAIrQD/CRxoRmC+gQgTKlyIUArCcZcY5lGoSGAXhgnpKGSzUMilGP9UYBRoCKEEhD8EStAnMGKRgeUEHijHxIeYLRES2lQgC0G9edo8aNDxbiAVKP46nPOgTZu/p/7mCURhBao/gVb9nRiIFOq/q1A7WOH6dBs1av8sPbIkbevAR1C2oZNmqa4lKPQ2vBWYCM6jfyfgfMDx769CII8uxPkSZG/Cc+oWulvYbuGUfwEBACH5BAUKAP8ALAAAAAAYABgAAAj/AP8JHEiwoMGDCBMqXMiwYUIRtWwBMJMhg5lcHAy5mScjVcJghcIhcZZCRYoVGboM+saDxCaEObq9ITRBQhoJE9YtOQMjkhNTCHHZaUElCwQiEPj8yVLGwJAETxAWcTahDLgsdQ4cyTLtBZ5xSUYgtJCiK54fLH4cgFDNK4pINxCa2dMWDwtWLHoQSVPGDAosMcamkFLmAFo2a6WksCAkUuCDXagyUXKgB7tCJiY4KwJW7EEDGVRoYQJhhxUNYtZlcJoADEIYXciomCAlSrxHJ9J1gXEpBj6EDIR0efSo0R1//jo8MsfgEZgGCMMwgGFg+PEO/mIRH2HEAcIICSIpZhpnXJolalbkcZ9RAeGCTzESJGnkZRs1aQqaXFAzgFTCa3OsMUIMjZzQwQmNNBCEDJ44opAAyAzQxwaNVEjDB5qIYkM7C4UiQAnY6LCLMCUA48gp2TTUCgaYUOKIDZM8UIlDNAoUEAAh+QQJCgD/ACwDAAMAEgAUAAAIqgD/CRz4TxDBgwgP5kvI8J+zhg1bDLwEsaLFiwmFXIoxUMXBNgcNDRSS8MdAfQKx/DPyrwjCA0qY+BCzJQIdhDMVyEJQb542Dxp0vDtIBYq/Duc8aNPmr6m/eQRRWHHqTyBVfycOGnX6r6rTDla0Nt1Gjdo/S48sSct68BGUbeikWZprCQq9DW0FJoLz6N8JOB8E9mUI5NGFOF+CDByM8Jy6hO4atks4RWBAACH5BAUKAP8ALAAAAAAYABgAAAj/AP8JHEiwoMGDCBMqXMiQFgFb5NwIqcLFWgBVsBSKqGULgJkMGczk4mDIzTwZqRByClYoHBJnKVSkWJGhy6BvPEhsOggiR7c3hCZISCNhwrolZ2BEcmLKl8FSuOy0oJIFAhEIfP5kKWNgSIInCAzKKeJsQhlwWeocOJJl2gs845KM0GMQjYUUbvH8YPHjAIRqb1FEuhHHoAEzewDjYcGKRQ8iacqYQYElxgWDKO5KKXNgLxu/UlJYEBLJssFxXcoyUXKgB7tCJiY4KxJ3xOWCQwxkUKGFCYQdVjSIWZehawIwOAwWgNGFjIoJUqLEe3QiXRcYl2Lg+2KQGwMhXR49l2p0x5+/Do/MMXgEpgENg8TCMIBhIHz5Dv5iiR9hxEEsg8tEkEAkioxDnjSWUGOFPPzNUIExBrmywCcxJJBEI15sQ400CjRxgRoDkAIJQtfMscYIMTRyQgcnNNJAEDJ44ggmCQmAzAB9bNDIjjR8oIkoNrSzUCgClICNDrsIUwIwjpySDUP/tIIBJpQ4YsMkD1QC5ZYEBQQAOw=="],
- "32": ["[疑问]", "data:image/gif;base64,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"],
- "33": ["[嘘]", "data:image/gif;base64,R0lGODlhGAAYAPfPAPW5KPu9HP/3d/2yDP/vWuSmJvTIWv/lSP/KJfbBSN7Z1daaIvzVOe+1Mu3YmtfRzOjl4raCR//SLd2cHNPFuu7FU//VMfa7Nf/qUMurhOXDav/9svvNM/+4Es6CC/CjC//FIPfamv/7m/61D//iQt+5ONqOC+bi3//oTN/GbP/7lcyDFaVVAf/3eP/5h//bOf/XNNulQ/CwH9OzgtCfSvzdRP/wXf/DHf/1baliEtGhKf/cOtmxa+7Skf/pTv/ePPbWROzMT8t9CMaCFvXZUeulFtnUz//EH8iQPv/89uOXCv/9uPGrEvi4Gv/uV/jGMf/8oP/+x//PKv/kR//AGsyLIu7NVf/wX+7QaP+6E7FzK//dPP7nT//+0P7gRO7GPd/DWP/ePvSoDP7dPvuvDP/4e+69Lv/TL/+8FeafEfSxGNWOEfmyE/nEJffGKvTCLv/LJ8SGGf/QK8SJH9+/RvbPOb5wDV0jAP///4czAHErAO7SqrZlDbNhBL92DrFeAvv6+uPf3P/0fsFsBdzX0//sU6VhCdS/smUmAPvhpbd7Murj3P/+/OnIkcCXZ+rn5MuJGuG/i7NvGsivlv3468J8FO24S//xX9KWM/79/Ofe0LmIU71/LvTy8diVFcKKPuGgI/PesPry5/bGWfbEL65mD8Webb13FP38/PDu7KhdCaxtJa5wLLuRZf7yeeaqH///16t2R+bCjuivLu7SjPvw19GsdKxoDMyFGPzgWuaqIP/2dPmzE+7OXu7RfeysJufZxPngT9fHsPnYP9GJEfvsb+rDf92gHfnCIvnfTO6tGu+yHuumH/vlVPm0E////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgDPACwAAAAAGAAYAAAI/wCfCRxIsKDBgwLvKKRAkILCOwgLJplxJwGACwnu2KoVkWCiCxxqePHygwGHJwZCdUxiAAAuOyuAoDhQZwXMWRUQMhr1xM4ePHvs2HDiE6gdGTkNhiDlow+ep3wE4ODzFE8fEKA0FKTUoAYGp3r08FHhgmrYPnCaxNBEMMQbFERl6UFkZwMUn3PtSLlRhAeggZYY+LBhhUUeFrSibMBimIUZCSB4YYIwsMAYH1fKiFjSBVaXJSLKXPLx4wyIDpAIDQS1BYUNASo2ROmiWIUAGyi2QO4w5MHACTsOOMHhAsqGJXZd4HBy4MXeDpV8C1xggQSGS7tcpLDD3Q4dDCRgwMShMuKU9Gcx3AQvdInAnzzw8/whsANyFjGczjd6ZeHHAQwEzDEICywMEgcBFiBAngmmKDCQKFW08cIOJBxAwIUYWgDHDVl8oAgFjxAUyQQIwADDCz+k+AIMEiDA4QClOKLAXwNlgoQnIJwhhQQ8SgEHCFR0QIYHETwQokGfrKHGjyCAcAMVWYygRA6bPBBIRBlI4kEaTEQphhJCsDKJESd09MwiGUSghSo5rBJBKw8o0ImZAqGSSiAKPGAEIYEcSeefBAUEACH5BAUKAM8ALAAAAAAYABgAAAj/AJ8JHEiwoMGDCBMmvMOQRgIAFxLQYHhHocBEF3Tc8eJlDIM7CwyEUpjEwBMuPlCkPEBihwUODSogZDTqCRBcdnARseEEyAo7KwDIkGkwBCkfdvbg2WNHAI6kS+2AAKWhIKUGNTD00XMIDx8VLvhwxdMHTpMYmgiGeIPCyVY9XjdAEQu3j5QbRXgAGmiJgQ8bdmIdYhplQ+DBdiSA4IUJwsACP3xcssIiD4seXZZgqczCjOIOkAgNBPUDhY0WKjZE6VJYhQAbKH58HvJg4IQXB5zgcAFlwxK5LnA4OfDibodKtQUusEACw6VdLlSIALvrEgYSMOBQGXEq+bMYbnYcvyh0CUeLMk4vFTqwQzEaMZy8N3plYcsBDE5s0LFjp8SBHxYgsJ0JpigwkChVtPHCDiQcQMAfeeTxBwEWwHFDFh8oQsEjBEUyAQIwwPACAUMMMsgQBCBw4QClOKLAXgNlgoQnIJwhhQQE5EgACFRkQYYHETzAoUGfrKEGHCCAcMQNPY6gRA6bPBBIQhlI4kEaTHQwghhKCMHKJEacYNEiGUSghSo5rBJBKw8o0IlFAqGSSiAKPGAEIYEMCeeeBAUEACH5BAkKAM8ALAUAAgAQABIAAAiUAJ8JHEiwoMGDB1EgLFgIgxMblwRiOLDFAgKChS7hEFBG4KVCB3ZIIHhplwsVIgTuuoSBBIyBLFjkycPCl8BeMmmyGChAxYYoXQSqEGADxQ+CZUQs6QJLoIgyl3yEOcNzodWrBVPYsQPG4ICCf2b+QThFIIGwef4QuFpi0KASVnf8IECXwEirEiRIgYP1GYiBHQoGBAAh+QQJCgDPACwAAAAAGAAYAAAI/wCfCRxIsKDBgwLvKKRAkILCOwgLJplxJwGACwnu2KoVkWCiCxxqeCExhgGHJwZCdXxmAAAuOyuAoDhQZwXMWRU6PrGzB88eOzac8PRpR0ZOhD764FnKpwUOPkvx9AEBSgNCDEr16OGjwgVUrX3gNImBUKgsPYjsbIDCE60dKTeKILRhhUUeFrSibMBil4UZCSB4GQzz7FIZEUu6wOqyRESZSz7CAO5gcMszGy1UbIjSRa8KATZQ/JBwhPJBJzhcQNmwZK0LHE4OvIBr2iCGS7tS2NnNuwQJGHCojDj44kAhJ3/yKF/+hwBgNGIM6nq25QCBOYNYaGcxaA4BBMJNIFV8sYMEgfPoz8O5keWDIoQIYMB4sSXMjx0wJKzPMqCUI4SegHCGFBIUKAccIFCRBRkeRPAAQp+soQaCIIBwAxVojKBEDps8EMhKA2UB4ogklmgiiQEBACH5BAkKAM8ALAAAAAAYABgAAAj/AJ8JHEiwoMGDCBMmvMOQRgIAFxLQYHhHocBEF3Tc8UJiDIM7CwyEUpjEwBMuPlCkPEBihwUODSogZDTqCRBcdnARseEEyAo7KwDIkGkwBCkfdvbg2WNHAI6kS+2AAKWhIKUGNTD00XMIDx8VLvhwxdMHTpMYmgiGeIPCyVY9XjdAEQu3j5QbRXgAGmiJgQ8bdmIdYhplQ+DBdiSA4IUJwsACW3xcssIiD4seXZZgqczCjOIOkAgNBPUDhY0WKjZE6VJYhQAbKH4ozjLkwcAJLw44weECyoYlcl3gcHLghZwbHSrZFrjAAgkMl3a5UCEC7K5LGEjAgENlxKnlz2K4w9lxoNAlHALKtMBxqdCUHYrRiOEEvpEuCz8OYHBig44dOyUcsIUF3I1ggikKDCRKFW28sAMJBxDwRx55/EEAgTdk8YEiFDxCUCQTIAADDC8QMMQggwxBAAIZDlCKIwrsNVAmSHgCwhlSSEDAjgSAQEUWZHgQwQMeGvTJGmrAAQIIR9xABRojKJHDJg8EklAGkniQBhNZjCCGEkKwMokRJ1i0SAYRaKFKDqtE0MoDCnRikUCopBKIAg8YQUggRc7pJ0EBAQAh+QQJCgDPACwAAAAAGAAYAAAI/wCfCRxIsKDBgwLvKKRAkILCOwgLJplxJwGACwnu2KoVkWCiCxxqePEyhgGHJwZCdUxiAAAuOyuAoDhQZwXMWRUQMhr1xM4ePHvs2HDiE6gdGTkNhiDlow+ep3xa4ODzFE8fEKA0FKTUoAYGp3r08FHhgmrYPnCaxNBEMMQbFERl6UFkZwMUn3PtSLlRhAeggZYY+LBhhUUeFrSibMBimIUZCSDYYIIwsMAYFJfKiFjSBVaXJSLKXPLx4wyIDpAIDQT1A4UNASo2ROmiWEULGyi2QO4w5MHACTsOOMHhAsqGJXZd4HBy4MXeDpV8C1xggQSGS7tS2NnOvQQJGHCojMA4Jf1ZDDfBCzn5k6e9+z8EIKMRw6l8I10WfkwhMGcQi/8sDDIHAQiIZ4IpCgwkShVtvLADCQREKGGEcNyQxQeKUPAIQZFMgAAMMLywxQ9bvACDBAhYOEApjijw10CZIOEJCGdIIcEZEsgBBwhUZEGGBxE8sKFBn6yhxo4ggHADFWiMoEQOmzwQSEQZSOJBGkxkMYIYSgjByiRGnNDRM4tkEIEWquSwSgStPKBAJ2MKhEoqgSjwgBGEBDJknHwSFBAAIfkEBQoAzwAsAAAAABgAGAAACP8AnwkcSLCgwYMIEya8w5BGAgAXEtBgeEehwEQXdNzx4mUMgzsLDIRSmMTAEy4oUPhAcYDEDgscGlRAyGjUk0IYnNi4ZMMJhgNbLCCQMdNgCFI+Cl3CIaCMAByXCh3YIQEEKA0FKTWogeHSLhcqRKhwsesSBhIw4DSJoYlgiDcoWLDIk4eFrw1Qes2ty+JGER6ABlpi4MOGABUbonSJskGFABsoflTlhQnCwAI/fFwqI2JJF1hdlogoc8lHmDMgOkAiNBDUDxSGEStm7Biy5NRDHgyc8OKAExwuoGxYgtcFDicHXki50aGSboELLJDo+lVFCjt2wJhFC4fKgFPPn8W7cLPjgFIcLf7Q/SOVKgg0YjiFb/TKwpYpOQmoz/OHwA+hVIxggikKDCRKFW28sAMJBxBQwiCDlECABXDckMUHilDwCEGRTIAADDDs8AMBJBIgAQIWDlCKIwoENlAmSHgCwhlSSGCjFHCAQEUWZHgQwQMbGvTJGmrkCAIIN+zYgRI5bPJAIAllIIkHaTDRwQhiKCEEK5MYcYJFi2QQgRaq5LBKBK08oEAnFgmESiqBKPCAEYQEEmSbeBIUEAAh+QQFCgDPACwDAAMAEgASAAAIngCfCRwokEQYgggTPvOhECEQXHZwEREIZIWdFQAS2tmDZ48dgRs7fkTYR88hPHwE8jGJpw9CJyX1oFSpR2YfKQjtxDrkEeTOngIPXrHCIg+LHgKxFGVhRmCWhgNbEDzybAfUqwhFqHCxK+EIhWVa4LgE9ccBgTbo2LFT4izWZ3/y5Pnz9gWBOIMGDSEARyAZqAQCE3g7kKrAr2+fNgwIACH5BAkAAM8ALAMAAgASABYAAAiTAJ8JHEiwoEGDYw4a9PEMBQqFECMqbCFRIB48BS9C1EiQ40FZehAR3BNyIBuBlwSWJLiyIsEtz0A8e+EyYgo7OO3QKTigIIE/eYLm+UNgYBaDBOYMYsFiUJyiEgl88UOVA4KIP374CRLE0LIAEOU8k+BHkCBDRZxVLHs2jUu2hohpWWvWEBJhdM/yAJbXkLFaBAMCACH5BAVkAM8ALAAAAAAYABgAAAj/AJ8JHEiwoMGDAu8opECQgsI7CAsmmXEnAYALCe7YqhWRYKILHGp4ITGGAYcnBkJ1TGIAAC47K4CgOFBnBcxZFRAyGvXEzh48e+zYcOITqB0ZOQ2GIOWjD56nfFrg4PMUTx8QoDQYbFADg1M9eviocEEVbB84TWIYfIOCqCw9iOxsgOITrh0pN4oYZODDhhUWeVjQirIBC2AWZiSA4GUwjI9LZUQs6QLLgR8/xQj4CHMGRAeDW1DYEKBiQ5QufoIYItIMxRYJRz4XfHHACQ4XUDYs8SPI0JdkB17glU3QAgkMl3a5UCGCt2+RMOBQGWHQzY4Dha7gIADGeYFhOxSjmBFj8JWFHwcwOCHwx7mfYBYQTDdhsEqbFztIHCAQxzmxYHDckMUHihgUyQQIwADDC1sQ4NwXyAg4QCmOGJQJEp6AcIYcEvgxhyB+KNNEFmR4EMEDCH2yhhrH+PGLK64w4wcZSuSwyQOBRJSBJC7CmAsDt3igxSRGnNDRM4v44SMDANyChDAKdHKkQEr+CIAat0QCzJRcGhQQADs="],
- "34": ["[晕]", "data:image/gif;base64,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"]
- };
- //工具类
- var tool = new function() {
- //格式化时间戳
- //format格式如下:
- //yyyy-MM-dd hh:mm:ss 年月日时分秒(默认格式)
- //yyyy-MM-dd 年月日
- //hh:mm:ss 时分秒
- this.formatTimeStamp = function(timestamp, format) {
- if (!timestamp) {
- return 0;
- }
- var formatTime;
- format = format || 'yyyy-MM-dd hh:mm:ss';
- var date = new Date(timestamp * 1000);
- var o = {
- 'M+': date.getMonth() + 1, //月份
- 'd+': date.getDate(), //日
- 'h+': date.getHours(), //小时
- 'm+': date.getMinutes(), //分
- 's+': date.getSeconds() //秒
- };
- if (/(y+)/.test(format)) {
- formatTime = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
- } else {
- formatTime = format;
- }
- for (var k in o) {
- if (new RegExp('(' + k + ')').test(formatTime))
- formatTime = formatTime.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));
- }
- return formatTime;
- };
-
- //根据群类型英文名转换成中文名
- this.groupTypeEn2Ch = function(type_en) {
- var type_ch = null;
- switch (type_en) {
- case 'Public':
- type_ch = '公开群';
- break;
- case 'ChatRoom':
- type_ch = '聊天室';
- break;
- case 'Private':
- type_ch = '私有群'; //即讨论组
- break;
- case 'AVChatRoom':
- type_ch = '直播聊天室';
- break;
- default:
- type_ch = type_en;
- break;
- }
- return type_ch;
- };
- //根据群类型中文名转换成英文名
- this.groupTypeCh2En = function(type_ch) {
- var type_en = null;
- switch (type_ch) {
- case '公开群':
- type_en = 'Public';
- break;
- case '聊天室':
- type_en = 'ChatRoom';
- break;
- case '私有群': //即讨论组
- type_en = 'Private';
- break;
- case '直播聊天室':
- type_en = 'AVChatRoom';
- break;
- default:
- type_en = type_ch;
- break;
- }
- return type_en;
- };
- //根据群身份英文名转换成群身份中文名
- this.groupRoleEn2Ch = function(role_en) {
- var role_ch = null;
- switch (role_en) {
- case 'Member':
- role_ch = '成员';
- break;
- case 'Admin':
- role_ch = '管理员';
- break;
- case 'Owner':
- role_ch = '群主';
- break;
- default:
- role_ch = role_en;
- break;
- }
- return role_ch;
- };
- //根据群身份中文名转换成群身份英文名
- this.groupRoleCh2En = function(role_ch) {
- var role_en = null;
- switch (role_ch) {
- case '成员':
- role_en = 'Member';
- break;
- case '管理员':
- role_en = 'Admin';
- break;
- case '群主':
- role_en = 'Owner';
- break;
- default:
- role_en = role_ch;
- break;
- }
- return role_en;
- };
- //根据群消息提示类型英文转换中文
- this.groupMsgFlagEn2Ch = function(msg_flag_en) {
- var msg_flag_ch = null;
- switch (msg_flag_en) {
- case 'AcceptAndNotify':
- msg_flag_ch = '接收并提示';
- break;
- case 'AcceptNotNotify':
- msg_flag_ch = '接收不提示';
- break;
- case 'Discard':
- msg_flag_ch = '屏蔽';
- break;
- default:
- msg_flag_ch = msg_flag_en;
- break;
- }
- return msg_flag_ch;
- };
- //根据群消息提示类型中文名转换英文名
- this.groupMsgFlagCh2En = function(msg_flag_ch) {
- var msg_flag_en = null;
- switch (msg_flag_ch) {
- case '接收并提示':
- msg_flag_en = 'AcceptAndNotify';
- break;
- case '接收不提示':
- msg_flag_en = 'AcceptNotNotify';
- break;
- case '屏蔽':
- msg_flag_en = 'Discard';
- break;
- default:
- msg_flag_en = msg_flag_ch;
- break;
- }
- return msg_flag_en;
- };
- //将空格和换行符转换成HTML标签
- this.formatText2Html = function(text) {
- var html = text;
- if (html) {
- html = this.xssFilter(html); //用户昵称或群名称等字段会出现脚本字符串
- html = html.replace(/ /g, ' ');
- html = html.replace(/\n/g, '<br/>');
- }
- return html;
- };
- //将HTML标签转换成空格和换行符
- this.formatHtml2Text = function(html) {
- var text = html;
- if (text) {
- text = text.replace(/ /g, ' ');
- text = text.replace(/<br\/>/g, '\n');
- }
- return text;
- };
- //获取字符串(UTF-8编码)所占字节数
- //参考:http://zh.wikipedia.org/zh-cn/UTF-8
- this.getStrBytes = function(str) {
- if (str == null || str === undefined) return 0;
- if (typeof str != 'string') {
- return 0;
- }
- var total = 0,
- charCode,
- i,
- len;
- for (i = 0, len = str.length; i < len; i++) {
- charCode = str.charCodeAt(i);
- if (charCode <= 0x007f) {
- total += 1; //字符代码在000000 – 00007F之间的,用一个字节编码
- } else if (charCode <= 0x07ff) {
- total += 2; //000080 – 0007FF之间的字符用两个字节
- } else if (charCode <= 0xffff) {
- total += 3; //000800 – 00D7FF 和 00E000 – 00FFFF之间的用三个字节,注: Unicode在范围 D800-DFFF 中不存在任何字符
- } else {
- total += 4; //010000 – 10FFFF之间的用4个字节
- }
- }
- return total;
- };
-
- //防止XSS攻击
- this.xssFilter = function(val) {
- val = val.toString();
- val = val.replace(/[<]/g, '<');
- val = val.replace(/[>]/g, '>');
- val = val.replace(/"/g, '"');
- //val = val.replace(/'/g, "'");
- return val;
- };
-
- //去掉头尾空白符
- this.trimStr = function(str) {
- if (!str) return '';
- str = str.toString();
- return str.replace(/(^\s*)|(\s*$)/g, '');
- };
- //判断是否为8位整数
- this.validNumber = function(str) {
- str = str.toString();
- return str.match(/(^\d{1,8}$)/g);
- };
- this.getReturnError = function(errorInfo, errorCode) {
- if (!errorCode) {
- errorCode = -100;
- }
- var error = {
- ActionStatus: ACTION_STATUS.FAIL,
- ErrorCode: errorCode,
- ErrorInfo: errorInfo + '[' + errorCode + ']'
- };
- return error;
- };
- //设置cookie
- //name 名字
- //value 值
- //expires 有效期(单位:秒)
- //path
- //domain 作用域
- this.setCookie = function(name, value, expires, path, domain) {
- var exp = new Date();
- exp.setTime(exp.getTime() + expires * 1000);
- document.cookie = name + '=' + escape(value) + ';expires=' + exp.toGMTString();
- };
- //获取cookie
- this.getCookie = function(name) {
- var result = document.cookie.match(new RegExp('(^| )' + name + '=([^;]*)(;|$)'));
- if (result != null) {
- return unescape(result[2]);
- }
- return null;
- };
- //删除cookie
- this.delCookie = function(name) {
- var exp = new Date();
- exp.setTime(exp.getTime() - 1);
- var value = this.getCookie(name);
- if (value != null) document.cookie = name + '=' + escape(value) + ';expires=' + exp.toGMTString();
- };
- //根据名字获取url参数值
- this.getQueryString = function(name) {
- var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
- var r = window.location.search.substr(1).match(reg);
- if (r != null) return unescape(r[2]);
- return null;
- };
- //判断IE版本号,ver表示版本号
- this.isIE = function(ver) {
- var b = document.createElement('b');
- b.innerHTML = '<!--[if IE ' + ver + ']><i></i><![endif]-->';
- return b.getElementsByTagName('i').length === 1;
- };
- //判断浏览器版本
- this.getBrowserInfo = function() {
- var Sys = {};
- var ua = navigator.userAgent.toLowerCase();
- log.info('navigator.userAgent=' + ua);
- var s;
- (s = ua.match(/msie ([\d.]+)/))
- ? (Sys.ie = s[1])
- : (s = ua.match(/firefox\/([\d.]+)/))
- ? (Sys.firefox = s[1])
- : (s = ua.match(/chrome\/([\d.]+)/))
- ? (Sys.chrome = s[1])
- : (s = ua.match(/opera.([\d.]+)/))
- ? (Sys.opera = s[1])
- : (s = ua.match(/version\/([\d.]+).*safari/))
- ? (Sys.safari = s[1])
- : 0;
- if (Sys.ie) {
- //Js判断为IE浏览器
- //ie10的判断这里有个问题
- // Mozilla/5.0 (compatible; MSIE 9.0; qdesk 2.5.1277.202; Windows NT 6.1; WOW64; Trident/6.0)
- // 是IE10 而不是IE9
- if (ua.match(/trident\/(\d)\./) && ua.match(/trident\/(\d)\./)[1] == 6) {
- Sys.ie = 10;
- }
- return {
- type: 'ie',
- ver: Sys.ie
- };
- }
- if (Sys.firefox) {
- //Js判断为火狐(firefox)浏览器
- return {
- type: 'firefox',
- ver: Sys.firefox
- };
- }
- if (Sys.chrome) {
- //Js判断为谷歌chrome浏览器
- return {
- type: 'chrome',
- ver: Sys.chrome
- };
- }
- if (Sys.opera) {
- //Js判断为opera浏览器
- return {
- type: 'opera',
- ver: Sys.opera
- };
- }
- if (Sys.safari) {
- //Js判断为苹果safari浏览器
- return {
- type: 'safari',
- ver: Sys.safari
- };
- }
- return {
- type: 'unknow',
- ver: -1
- };
- };
-
- this.replaceObject = function(keyMap, json) {
- for (var a in json) {
- if (keyMap[a]) {
- json[keyMap[a]] = json[a];
- delete json[a];
- if (json[keyMap[a]] instanceof Array) {
- var len = json[keyMap[a]].length;
- for (var i = 0; i < len; i++) {
- json[keyMap[a]][i] = this.replaceObject(keyMap, json[keyMap[a]][i]);
- }
- } else if (typeof json[keyMap[a]] === 'object') {
- json[keyMap[a]] = this.replaceObject(keyMap, json[keyMap[a]]);
- }
- }
- }
- return json;
- };
- }();
-
- //日志对象
- var log = new function() {
- var on = true;
-
- this.setOn = function(onFlag) {
- on = onFlag;
- };
-
- this.getOn = function() {
- return on;
- };
-
- this.error = function(logStr) {
- try {
- on && console.error(logStr);
- } catch (e) {}
- };
- this.warn = function(logStr) {
- try {
- on && console.warn(logStr);
- } catch (e) {}
- };
- this.info = function(logStr) {
- try {
- on && console.info(logStr);
- } catch (e) {}
- };
- this.debug = function(logStr) {
- try {
- on && console.debug(logStr);
- } catch (e) {}
- };
- }();
- //获取unix时间戳
- var unixtime = function(d) {
- if (!d) d = new Date();
- return Math.round(d.getTime() / 1000);
- };
- //时间戳转日期
- var fromunixtime = function(t) {
- return new Date(t * 1000);
- };
- //获取下一个消息序号
- var nextSeq = function() {
- if (curSeq) {
- curSeq = curSeq + 1;
- } else {
- curSeq = Math.round(Math.random() * 10000000);
- }
- return curSeq;
- };
- //产生随机数
- var createRandom = function() {
- return Math.round(Math.random() * 4294967296);
- };
-
- //获取ajax请求对象
- var getXmlHttp = function() {
- var xmlhttp = null;
- if (window.XMLHttpRequest) {
- xmlhttp = new XMLHttpRequest();
- } else {
- try {
- xmlhttp = new ActiveXObject('Msxml2.XMLHTTP');
- } catch (e) {
- try {
- xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
- } catch (e) {
- return null;
- }
- }
- }
- return xmlhttp;
- };
- //发起ajax请求
- var ajaxRequest = function(meth, url, req, timeout, content_type, isLongPolling, cbOk, cbErr) {
- var xmlHttpObj = getXmlHttp();
-
- var error, errInfo;
- if (!xmlHttpObj) {
- errInfo = '创建请求失败';
- var error = tool.getReturnError(errInfo, -1);
- log.error(errInfo);
- if (cbErr) cbErr(error);
- return;
- }
- //保存ajax请求对象
- xmlHttpObjSeq++;
- xmlHttpObjMap[xmlHttpObjSeq] = xmlHttpObj;
-
- xmlHttpObj.open(meth, url, true);
- xmlHttpObj.onreadystatechange = function() {
- if (xmlHttpObj.readyState == 4) {
- xmlHttpObjMap[xmlHttpObjSeq] = null; //清空
- if (xmlHttpObj.status == 200) {
- if (cbOk) cbOk(xmlHttpObj.responseText);
- xmlHttpObj = null;
- curLongPollingRetErrorCount = curBigGroupLongPollingRetErrorCount = 0;
- } else {
- xmlHttpObj = null;
- //避免刷新的时候,由于abord ajax引起的错误回调
- setTimeout(function() {
- var errInfo = '请求服务器失败,请检查你的网络是否正常';
- var error = tool.getReturnError(errInfo, -2);
- //if (!isLongPolling && cbErr) cbErr(error);
- if (isLongPolling && onLongPullingNotify) {
- onLongPullingNotify(error);
- }
- if (cbErr) cbErr(error);
- }, 16);
- }
- }
- };
- xmlHttpObj.setRequestHeader('Content-Type', content_type);
- //设置超时时间
- if (!timeout) {
- timeout = ajaxDefaultTimeOut; //设置ajax默认超时时间
- }
- if (timeout) {
- xmlHttpObj.timeout = timeout;
- xmlHttpObj.ontimeout = function(event) {
- xmlHttpObj = null;
- //var errInfo = "请求服务器超时";
- //var error = tool.getReturnError(errInfo, -3);
- //if (cbErr) cbErr(error);
- };
- }
- //
- if (xmlHttpObj.overrideMimeType) {
- // xmlHttpObj.overrideMimeType("application/json;charset=utf-8");
- }
-
- xmlHttpObj.send(req);
- };
- //发起ajax请求(json格式数据)
- var ajaxRequestJson = function(meth, url, req, timeout, content_type, isLongPolling, cbOk, cbErr) {
- ajaxRequest(
- meth,
- url,
- JSON.stringify(req),
- timeout,
- content_type,
- isLongPolling,
- function(resp) {
- var json = null;
- if (resp) json = JSON.parse(resp); //将返回的json字符串转换成json对象
- if (isLongPolling && onLongPullingNotify) {
- onLongPullingNotify(json);
- }
- if (cbOk) cbOk(json);
- },
- cbErr
- );
- };
- //判断用户是否已登录
- var isLogin = function() {
- return ctx.sdkAppID && ctx.identifier;
- };
- //检查是否登录
- var checkLogin = function(cbErr, isNeedCallBack) {
- if (!isLogin()) {
- if (isNeedCallBack) {
- var errInfo = '请登录';
- var error = tool.getReturnError(errInfo, -4);
-
- if (cbErr) cbErr(error);
- }
- return false;
- }
- return true;
- };
-
- //检查是否访问正式环境
- var isAccessFormalEnv = function() {
- return isAccessFormaEnvironment;
- };
-
- //根据不同的服务名和命令,获取对应的接口地址
- var getApiUrl = function(srvName, cmd, cbOk, cbErr) {
- var srvHost = SRV_HOST;
- if (isAccessFormalEnv()) {
- srvHost = SRV_HOST.FORMAL.COMMON;
- } else {
- srvHost = SRV_HOST.TEST.COMMON;
- }
-
- //if (srvName == SRV_NAME.RECENT_CONTACT) {
- // srvHost = SRV_HOST.TEST.COMMON;
- //}
-
- if (srvName == SRV_NAME.PIC) {
- if (isAccessFormalEnv()) {
- srvHost = SRV_HOST.FORMAL.PIC;
- } else {
- srvHost = SRV_HOST.TEST.PIC;
- }
- }
-
- var url =
- srvHost +
- '/' +
- SRV_NAME_VER[srvName] +
- '/' +
- srvName +
- '/' +
- cmd +
- '?websdkappid=' +
- SDK.APPID +
- '&v=' +
- SDK.VERSION +
- '&platform=' +
- SDK.PLAATFORM;
-
- if (isLogin()) {
- if (cmd == 'login' || cmd == 'accesslayer') {
- url += '&identifier=' + encodeURIComponent(ctx.identifier) + '&usersig=' + ctx.userSig;
- } else {
- if (ctx.tinyid && ctx.a2) {
- url += '&tinyid=' + ctx.tinyid + '&a2=' + ctx.a2;
- } else {
- if (cbErr) {
- log.error('tinyid或a2为空[' + srvName + '][' + cmd + ']');
- cbErr(tool.getReturnError('tinyid或a2为空[' + srvName + '][' + cmd + ']', -5));
- return false;
- }
- }
- }
- url += '&contenttype=' + ctx.contentType;
- }
- url += '&sdkappid=' + ctx.sdkAppID + '&accounttype=' + ctx.accountType + '&apn=' + ctx.apn + '&reqtime=' + unixtime();
- return url;
- };
-
- //获取语音下载url
- var getSoundDownUrl = function(uuid, senderId) {
- var soundUrl = null;
- if (authkey && ipList[0]) {
- soundUrl =
- 'http://' +
- ipList[0] +
- '/asn.com/stddownload_common_file?authkey=' +
- authkey +
- '&bid=' +
- DOWNLOAD_FILE.BUSSINESS_ID +
- '&subbid=' +
- ctx.sdkAppID +
- '&fileid=' +
- uuid +
- '&filetype=' +
- DOWNLOAD_FILE_TYPE.SOUND +
- '&openid=' +
- senderId +
- '&ver=0';
- } else {
- log.error('拼接语音下载url不报错:ip或者authkey为空');
- }
- return soundUrl;
- };
-
- //获取文件下载地址
- var getFileDownUrl = function(uuid, senderId, fileName) {
- var fileUrl = null;
- if (authkey && ipList[0]) {
- fileUrl =
- 'http://' +
- ipList[0] +
- '/asn.com/stddownload_common_file?authkey=' +
- authkey +
- '&bid=' +
- DOWNLOAD_FILE.BUSSINESS_ID +
- '&subbid=' +
- ctx.sdkAppID +
- '&fileid=' +
- uuid +
- '&filetype=' +
- DOWNLOAD_FILE_TYPE.FILE +
- '&openid=' +
- senderId +
- '&ver=0&filename=' +
- encodeURIComponent(fileName);
- } else {
- log.error('拼接文件下载url不报错:ip或者authkey为空');
- }
- Resources.downloadMap['uuid_' + uuid] = fileUrl;
- return fileUrl;
- };
-
- //获取文件下载地址
- var getFileDownUrlV2 = function(uuid, senderId, fileName, downFlag, receiverId, busiId, type) {
- var options = {
- From_Account: senderId, //"identifer_0", // 类型: String, 发送者tinyid
- To_Account: receiverId, //"identifer_1", // 类型: String, 接收者tinyid
- os_platform: 10, // 类型: Number, 终端的类型 1(android) 2(ios) 3(windows) 10(others...)
- Timestamp: unixtime().toString(), // 类型: Number, 时间戳
- Random: createRandom().toString(), // 类型: Number, 随机值
- request_info: [
- // 类型: Array
- {
- busi_id: busiId, // 类型: Number, 群(1) C2C(2) 其他请联系sdk开发者分配
- download_flag: downFlag, // 类型: Number, 申请下载地址标识 0(申请架平下载地址) 1(申请COS平台下载地址) 2(不需要申请, 直接拿url下载(这里应该不会为2))
- type: type, // 类型: Number, 0(短视频缩略图), 1(文件), 2(短视频), 3(ptt), 其他待分配
- uuid: uuid, // 类型: Number, 唯一标识一个文件的uuid
- version: VERSION_INFO.SERVER_VERSION, // 类型: Number, 架平server版本
- auth_key: authkey, // 类型: String, 认证签名
- ip: ipList[0] // 类型: Number, 架平IP
- }
- ]
- };
- //获取下载地址
- proto_applyDownload(
- options,
- function(resp) {
- if (resp.error_code == 0 && resp.response_info) {
- Resources.downloadMap['uuid_' + options.uuid] = resp.response_info.url;
- }
- if (onAppliedDownloadUrl) {
- onAppliedDownloadUrl({
- uuid: options.uuid,
- url: resp.response_info.url,
- maps: Resources.downloadMap
- });
- }
- },
- function(resp) {
- log.error('获取下载地址失败', options.uuid);
- }
- );
- };
-
- //重置ajax请求
- var clearXmlHttpObjMap = function() {
- //遍历xmlHttpObjMap{}
- for (var seq in xmlHttpObjMap) {
- var xmlHttpObj = xmlHttpObjMap[seq];
- if (xmlHttpObj) {
- xmlHttpObj.abort(); //中断ajax请求(长轮询)
- xmlHttpObjMap[xmlHttpObjSeq] = null; //清空
- }
- }
- xmlHttpObjSeq = 0;
- xmlHttpObjMap = {};
- };
-
- //重置sdk全局变量
- var clearSdk = function() {
- clearXmlHttpObjMap();
-
- //当前登录用户
- ctx = {
- sdkAppID: null,
- appIDAt3rd: null,
- accountType: null,
- identifier: null,
- identifierNick: null,
- userSig: null,
- contentType: 'json',
- apn: 1
- };
- opt = {};
-
- curSeq = 0;
-
- //ie8,9采用jsonp方法解决ajax跨域限制
- jsonpRequestId = 0; //jsonp请求id
- //最新jsonp请求返回的json数据
- jsonpLastRspData = null;
-
- apiReportItems = [];
-
- MsgManager.clear();
- MsgStore.clear();
-
- //重置longpollingId
- LongPollingId = null;
- };
-
- //登录
- var _login = function(loginInfo, listeners, options, cbOk, cbErr) {
- clearSdk();
-
- if (options) opt = options;
- if (opt.isAccessFormalEnv == false) {
- log.error('请切换为正式环境!!!!');
- isAccessFormaEnvironment = opt.isAccessFormalEnv;
- }
- if (opt.isLogOn == false) {
- log.setOn(opt.isLogOn);
- }
- /*
- if(opt.emotions){
- emotions=opt.emotions;
- webim.Emotions= emotions;
- }
- if(opt.emotionDataIndexs){
- emotionDataIndexs=opt.emotionDataIndexs;
- webim.EmotionDataIndexs= emotionDataIndexs;
- }*/
-
- if (!loginInfo) {
- if (cbErr) {
- cbErr(tool.getReturnError('loginInfo is empty', -6));
- return;
- }
- }
- if (!loginInfo.sdkAppID) {
- if (cbErr) {
- cbErr(tool.getReturnError('loginInfo.sdkAppID is empty', -7));
- return;
- }
- }
- if (!loginInfo.accountType) {
- if (cbErr) {
- cbErr(tool.getReturnError('loginInfo.accountType is empty', -8));
- return;
- }
- }
-
- if (loginInfo.identifier) {
- ctx.identifier = loginInfo.identifier.toString();
- }
- if (loginInfo.identifier && !loginInfo.userSig) {
- if (cbErr) {
- cbErr(tool.getReturnError('loginInfo.userSig is empty', -9));
- return;
- }
- }
- if (loginInfo.userSig) {
- ctx.userSig = loginInfo.userSig.toString();
- }
- ctx.sdkAppID = loginInfo.sdkAppID;
- ctx.accountType = loginInfo.accountType;
-
- if (ctx.identifier && ctx.userSig) {
- //带登录态
- proto_accesslayer(function() {
- //登录
- proto_login(function(identifierNick, headurl) {
- MsgManager.init(
- listeners,
- function(mmInitResp) {
- if (cbOk) {
- mmInitResp.identifierNick = identifierNick;
- mmInitResp.headurl = headurl;
- cbOk(mmInitResp);
- }
- },
- cbErr
- );
- }, cbErr);
- });
- } else {
- //不带登录态,进入直播场景sdk
- MsgManager.init(listeners, cbOk, cbErr);
- }
- };
-
- //初始化浏览器信息
- var initBrowserInfo = function() {
- //初始化浏览器类型
- BROWSER_INFO = tool.getBrowserInfo();
- log.info('BROWSER_INFO: type=' + BROWSER_INFO.type + ', ver=' + BROWSER_INFO.ver);
- if (BROWSER_INFO.type == 'ie') {
- if (parseInt(BROWSER_INFO.ver) < 10) {
- lowerBR = true;
- }
- }
- };
-
- //接口质量上报
- var reportApiQuality = function(cmd, errorCode, errorInfo) {
- if (cmd == 'longpolling' && (errorCode == longPollingTimeOutErrorCode || errorCode == longPollingKickedErrorCode)) {
- //longpolling 返回60008错误可以视为正常,可以不上报
- return;
- }
- var eventId = CMD_EVENT_ID_MAP[cmd];
- if (eventId) {
- var reportTime = unixtime();
- var uniqKey = null;
- var msgCmdErrorCode = {
- Code: errorCode,
- ErrMsg: errorInfo
- };
- if (ctx.a2) {
- uniqKey = ctx.a2.substring(0, 10) + '_' + reportTime + '_' + createRandom();
- } else if (ctx.userSig) {
- uniqKey = ctx.userSig.substring(0, 10) + '_' + reportTime + '_' + createRandom();
- }
-
- if (uniqKey) {
- var rptEvtItem = {
- UniqKey: uniqKey,
- EventId: eventId,
- ReportTime: reportTime,
- MsgCmdErrorCode: msgCmdErrorCode
- };
-
- if (cmd == 'login') {
- var loginApiReportItems = [];
- loginApiReportItems.push(rptEvtItem);
- var loginReportOpt = {
- EvtItems: loginApiReportItems,
- MainVersion: SDK.VERSION,
- Version: '0'
- };
- proto_reportApiQuality(
- loginReportOpt,
- function(resp) {
- loginApiReportItems = null; //
- },
- function(err) {
- loginApiReportItems = null; //
- }
- );
- } else {
- apiReportItems.push(rptEvtItem);
- if (apiReportItems.length >= maxApiReportItemCount) {
- //累计一定条数再上报
- var reportOpt = {
- EvtItems: apiReportItems,
- MainVersion: SDK.VERSION,
- Version: '0'
- };
- proto_reportApiQuality(
- reportOpt,
- function(resp) {
- apiReportItems = []; //清空
- },
- function(err) {
- apiReportItems = []; //清空
- }
- );
- }
- }
- }
- }
- };
-
- var proto_accesslayer = function(callback) {
- ConnManager.apiCall(
- SRV_NAME.WEB_IM,
- 'accesslayer',
- {},
- function(data) {
- if (data.ErrorCode === 0 && data.WebImAccessLayer === 1) {
- SRV_HOST.FORMAL.COMMON = 'https://events.tim.qq.com';
- }
- callback();
- },
- function() {
- callback();
- }
- );
- };
- // REST API calls
- //上线
- var proto_login = function(cbOk, cbErr) {
- ConnManager.apiCall(
- SRV_NAME.OPEN_IM,
- 'login',
- {
- State: 'Online'
- },
- function(loginResp) {
- if (loginResp.TinyId) {
- ctx.tinyid = loginResp.TinyId;
- } else {
- if (cbErr) {
- cbErr(tool.getReturnError('TinyId is empty', -10));
- return;
- }
- }
- if (loginResp.A2Key) {
- ctx.a2 = loginResp.A2Key;
- } else {
- if (cbErr) {
- cbErr(tool.getReturnError('A2Key is empty', -11));
- return;
- }
- }
- var tag_list = ['Tag_Profile_IM_Nick', 'Tag_Profile_IM_Image'];
- var options = {
- From_Account: ctx.identifier,
- To_Account: [ctx.identifier],
- LastStandardSequence: 0,
- TagList: tag_list
- };
- proto_getProfilePortrait(
- options,
- function(resp) {
- var nick, image;
- if (resp.UserProfileItem && resp.UserProfileItem.length > 0) {
- for (var i in resp.UserProfileItem) {
- for (var j in resp.UserProfileItem[i].ProfileItem) {
- switch (resp.UserProfileItem[i].ProfileItem[j].Tag) {
- case 'Tag_Profile_IM_Nick':
- nick = resp.UserProfileItem[i].ProfileItem[j].Value;
- if (nick) ctx.identifierNick = nick;
- break;
- case 'Tag_Profile_IM_Image':
- image = resp.UserProfileItem[i].ProfileItem[j].Value;
- if (image) ctx.headurl = image;
- break;
- }
- }
- }
- }
- if (cbOk) cbOk(ctx.identifierNick, ctx.headurl); //回传当前用户昵称
- },
- cbErr
- );
- },
- cbErr
- );
- };
- //下线
- var proto_logout = function(type, cbOk, cbErr) {
- if (!checkLogin(cbErr, false)) {
- //不带登录态
- clearSdk();
- if (cbOk)
- cbOk({
- ActionStatus: ACTION_STATUS.OK,
- ErrorCode: 0,
- ErrorInfo: 'logout success'
- });
- return;
- }
- if (type == 'all') {
- ConnManager.apiCall(
- SRV_NAME.OPEN_IM,
- 'logout',
- {},
- function(resp) {
- clearSdk();
- if (cbOk) cbOk(resp);
- },
- cbErr
- );
- } else {
- ConnManager.apiCall(
- SRV_NAME.OPEN_IM,
- 'longpollinglogout',
- {
- LongPollingId: LongPollingId
- },
- function(resp) {
- clearSdk();
- if (cbOk) cbOk(resp);
- },
- cbErr
- );
- }
- };
- //发送消息,包括私聊和群聊
- var proto_sendMsg = function(msg, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- var msgInfo = null;
-
- switch (msg.sess.type()) {
- case SESSION_TYPE.C2C:
- msgInfo = {
- From_Account: ctx.identifier,
- To_Account: msg.sess.id().toString(),
- MsgTimeStamp: msg.time,
- MsgSeq: msg.seq,
- MsgRandom: msg.random,
- MsgBody: [],
- OfflinePushInfo: msg.offlinePushInfo
- };
- break;
- case SESSION_TYPE.GROUP:
- var subType = msg.getSubType();
- msgInfo = {
- GroupId: msg.sess.id().toString(),
- From_Account: ctx.identifier,
- Random: msg.random,
- MsgBody: []
- };
- switch (subType) {
- case GROUP_MSG_SUB_TYPE.COMMON:
- msgInfo.MsgPriority = 'COMMON';
- break;
- case GROUP_MSG_SUB_TYPE.REDPACKET:
- msgInfo.MsgPriority = 'REDPACKET';
- break;
- case GROUP_MSG_SUB_TYPE.LOVEMSG:
- msgInfo.MsgPriority = 'LOVEMSG';
- break;
- case GROUP_MSG_SUB_TYPE.TIP:
- log.error('不能主动发送群提示消息,subType=' + subType);
- break;
- default:
- log.error('发送群消息时,出现未知子消息类型:subType=' + subType);
- return;
- break;
- }
- break;
- default:
- break;
- }
-
- for (var i in msg.elems) {
- var elem = msg.elems[i];
- var msgContent = null;
- var msgType = elem.type;
- switch (msgType) {
- case MSG_ELEMENT_TYPE.TEXT: //文本
- msgContent = {
- Text: elem.content.text
- };
- break;
- case MSG_ELEMENT_TYPE.FACE: //表情
- msgContent = {
- Index: elem.content.index,
- Data: elem.content.data
- };
- break;
- case MSG_ELEMENT_TYPE.IMAGE: //图片
- var ImageInfoArray = [];
- for (var j in elem.content.ImageInfoArray) {
- ImageInfoArray.push({
- Type: elem.content.ImageInfoArray[j].type,
- Size: elem.content.ImageInfoArray[j].size,
- Width: elem.content.ImageInfoArray[j].width,
- Height: elem.content.ImageInfoArray[j].height,
- URL: elem.content.ImageInfoArray[j].url
- });
- }
- msgContent = {
- ImageFormat: elem.content.ImageFormat,
- UUID: elem.content.UUID,
- ImageInfoArray: ImageInfoArray
- };
- break;
- case MSG_ELEMENT_TYPE.SOUND: //
- log.warn('web端暂不支持发送语音消息');
- continue;
- break;
- case MSG_ELEMENT_TYPE.LOCATION: //
- log.warn('web端暂不支持发送地理位置消息');
- continue;
- break;
- case MSG_ELEMENT_TYPE.FILE: //
- msgContent = {
- UUID: elem.content.uuid,
- FileName: elem.content.name,
- FileSize: elem.content.size,
- DownloadFlag: elem.content.downFlag
- };
- break;
- case MSG_ELEMENT_TYPE.CUSTOM: //
- msgContent = {
- Data: elem.content.data,
- Desc: elem.content.desc,
- Ext: elem.content.ext
- };
- msgType = MSG_ELEMENT_TYPE.CUSTOM;
- break;
- default:
- log.warn('web端暂不支持发送' + elem.type + '消息');
- continue;
- break;
- }
-
- if (msg.PushInfoBoolean) {
- msgInfo.OfflinePushInfo = msg.PushInfo; //当android终端进程被杀掉时才走push,IOS退到后台即可
- }
-
- msgInfo.MsgBody.push({
- MsgType: msgType,
- MsgContent: msgContent
- });
- }
- if (msg.sess.type() == SESSION_TYPE.C2C) {
- //私聊
- ConnManager.apiCall(SRV_NAME.OPEN_IM, 'sendmsg', msgInfo, cbOk, cbErr);
- } else if (msg.sess.type() == SESSION_TYPE.GROUP) {
- //群聊
- ConnManager.apiCall(SRV_NAME.GROUP, 'send_group_msg', msgInfo, cbOk, cbErr);
- }
- };
- //长轮询接口
- var proto_longPolling = function(options, cbOk, cbErr) {
- if (!isAccessFormaEnvironment && typeof stopPolling != 'undefined' && stopPolling == true) {
- return;
- }
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(SRV_NAME.OPEN_IM, 'longpolling', options, cbOk, cbErr, longPollingDefaultTimeOut, true);
- };
-
- //长轮询接口(拉取直播聊天室新消息)
- var proto_bigGroupLongPolling = function(options, cbOk, cbErr, timeout) {
- ConnManager.apiCall(SRV_NAME.BIG_GROUP_LONG_POLLING, 'get_msg', options, cbOk, cbErr, timeout);
- };
-
- //拉取未读c2c消息接口
- var proto_getMsgs = function(cookie, syncFlag, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.OPEN_IM,
- 'getmsg',
- {
- Cookie: cookie,
- SyncFlag: syncFlag
- },
- function(resp) {
- if (resp.MsgList && resp.MsgList.length) {
- for (var i in resp.MsgList) {
- tempC2CMsgList.push(resp.MsgList[i]);
- }
- }
- if (resp.SyncFlag == 1) {
- proto_getMsgs(resp.Cookie, resp.SyncFlag, cbOk, cbErr);
- } else {
- resp.MsgList = tempC2CMsgList;
- tempC2CMsgList = [];
- if (cbOk) cbOk(resp);
- }
- },
- cbErr
- );
- };
- //C2C消息已读上报接口
- var proto_c2CMsgReaded = function(cookie, c2CMsgReadedItem, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- var tmpC2CMsgReadedItem = [];
- for (var i in c2CMsgReadedItem) {
- var item = {
- To_Account: c2CMsgReadedItem[i].toAccount,
- LastedMsgTime: c2CMsgReadedItem[i].lastedMsgTime
- };
- tmpC2CMsgReadedItem.push(item);
- }
- ConnManager.apiCall(
- SRV_NAME.OPEN_IM,
- 'msgreaded',
- {
- C2CMsgReaded: {
- Cookie: cookie,
- C2CMsgReadedItem: tmpC2CMsgReadedItem
- }
- },
- cbOk,
- cbErr
- );
- };
-
- //删除c2c消息
- var proto_deleteC2CMsg = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- ConnManager.apiCall(SRV_NAME.OPEN_IM, 'deletemsg', options, cbOk, cbErr);
- };
-
- //拉取c2c历史消息接口
- var proto_getC2CHistoryMsgs = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.OPEN_IM,
- 'getroammsg',
- options,
- function(resp) {
- var reqMsgCount = options.MaxCnt;
- var complete = resp.Complete;
- var rspMsgCount = resp.MaxCnt;
- var msgKey = resp.MsgKey;
- var lastMsgTime = resp.LastMsgTime;
-
- if (resp.MsgList && resp.MsgList.length) {
- for (var i in resp.MsgList) {
- tempC2CHistoryMsgList.push(resp.MsgList[i]);
- }
- }
- var netxOptions = null;
- if (complete == 0) {
- //还有历史消息可拉取
- if (rspMsgCount < reqMsgCount) {
- netxOptions = {
- Peer_Account: options.Peer_Account,
- MaxCnt: reqMsgCount - rspMsgCount,
- LastMsgTime: lastMsgTime,
- MsgKey: msgKey
- };
- }
- }
-
- if (netxOptions) {
- //继续拉取
- proto_getC2CHistoryMsgs(netxOptions, cbOk, cbErr);
- } else {
- resp.MsgList = tempC2CHistoryMsgList;
- tempC2CHistoryMsgList = [];
- if (cbOk) cbOk(resp);
- }
- },
- cbErr
- );
- };
-
- //群组接口
- //创建群组
- //协议参考:https://www.qcloud.com/doc/product/269/1615
- var proto_createGroup = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- var opt = {
- //必填 群组形态,包括Public(公开群),Private(私有群),ChatRoom(聊天室),AVChatRoom(互动直播聊天室)。
- Type: options.Type,
- //必填 群名称,最长30字节。
- Name: options.Name
- };
- var member_list = [];
-
- //Array 选填 初始群成员列表,最多500个。成员信息字段详情参见:群成员资料。
- for (var i = 0; i < options.MemberList.length; i++) {
- member_list.push({
- Member_Account: options.MemberList[i]
- });
- }
- opt.MemberList = member_list;
- //选填 为了使得群组ID更加简单,便于记忆传播,腾讯云支持APP在通过REST API创建群组时自定义群组ID。详情参见:自定义群组ID。
- if (options.GroupId) {
- opt.GroupId = options.GroupId;
- }
- //选填 群主id,自动添加到群成员中。如果不填,群没有群主。
- if (options.Owner_Account) {
- opt.Owner_Account = options.Owner_Account;
- }
- //选填 群简介,最长240字节。
- if (options.Introduction) {
- opt.Introduction = options.Introduction;
- }
- //选填 群公告,最长300字节。
- if (options.Notification) {
- opt.Notification = options.Notification;
- }
- //选填 最大群成员数量,最大为10000,不填默认为2000个。
- if (options.MaxMemberCount) {
- opt.MaxMemberCount = options.MaxMemberCount;
- }
- //选填 申请加群处理方式。包含FreeAccess(自由加入),NeedPermission(需要验证),DisableApply(禁止加群),不填默认为NeedPermission(需要验证)。
- if (options.ApplyJoinOption) {
- //
- opt.ApplyJoinOption = options.ApplyJoinOption;
- }
- //Array 选填 群组维度的自定义字段,默认情况是没有的,需要开通,详情参见:自定义字段。
- if (options.AppDefinedData) {
- opt.AppDefinedData = options.AppDefinedData;
- }
- //选填 群头像URL,最长100字节。
- if (options.FaceUrl) {
- opt.FaceUrl = options.FaceUrl;
- }
- ConnManager.apiCall(SRV_NAME.GROUP, 'create_group', opt, cbOk, cbErr);
- };
-
- //创建群组-高级接口
- //协议参考:https://www.qcloud.com/doc/product/269/1615
- var proto_createGroupHigh = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(SRV_NAME.GROUP, 'create_group', options, cbOk, cbErr);
- };
-
- //修改群组基本资料
- //协议参考:https://www.qcloud.com/doc/product/269/1620
- var proto_modifyGroupBaseInfo = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- ConnManager.apiCall(SRV_NAME.GROUP, 'modify_group_base_info', options, cbOk, cbErr);
- };
-
- //申请加群
- var proto_applyJoinGroup = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- options.GroupId = String(options.GroupId);
- ConnManager.apiCall(
- SRV_NAME.GROUP,
- 'apply_join_group',
- {
- GroupId: options.GroupId,
- ApplyMsg: options.ApplyMsg,
- UserDefinedField: options.UserDefinedField
- },
- cbOk,
- cbErr
- );
- };
-
- //申请加入大群
- var BigGroupId;
- var proto_applyJoinBigGroup = function(options, cbOk, cbErr) {
- options.GroupId = String(options.GroupId);
- BigGroupId = options.GroupId;
- var srvName;
- if (!checkLogin(cbErr, false)) {
- //未登录
- srvName = SRV_NAME.BIG_GROUP;
- } else {
- //已登录
- srvName = SRV_NAME.GROUP;
- }
- ConnManager.apiCall(
- srvName,
- 'apply_join_group',
- {
- GroupId: options.GroupId,
- ApplyMsg: options.ApplyMsg,
- UserDefinedField: options.UserDefinedField
- },
- function(resp) {
- if (resp.JoinedStatus && resp.JoinedStatus == 'JoinedSuccess') {
- if (resp.LongPollingKey) {
- MsgManager.setBigGroupLongPollingOn(true); //开启长轮询
- MsgManager.setBigGroupLongPollingKey(resp.LongPollingKey); //更新大群长轮询key
- MsgManager.setBigGroupLongPollingMsgMap(options.GroupId, 0); //收到的群消息置0
- MsgManager.bigGroupLongPolling(); //开启长轮询
- } else {
- //没有返回LongPollingKey,说明申请加的群不是直播聊天室(AVChatRoom)
- cbErr && cbErr(tool.getReturnError('Join Group succeed; But the type of group is not AVChatRoom: groupid=' + options.GroupId, -12));
- return;
- }
- }
- if (cbOk) cbOk(resp);
- },
- function(err) {
- if (cbErr) cbErr(err);
- }
- );
- };
-
- //处理加群申请(同意或拒绝)
- var proto_handleApplyJoinGroupPendency = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- ConnManager.apiCall(
- SRV_NAME.GROUP,
- 'handle_apply_join_group',
- {
- GroupId: options.GroupId,
- Applicant_Account: options.Applicant_Account,
- HandleMsg: options.HandleMsg,
- Authentication: options.Authentication,
- MsgKey: options.MsgKey,
- ApprovalMsg: options.ApprovalMsg,
- UserDefinedField: options.UserDefinedField
- },
- cbOk,
- function(err) {
- if (err.ErrorCode == 10024) {
- //apply has be handled
- if (cbOk) {
- var resp = {
- ActionStatus: ACTION_STATUS.OK,
- ErrorCode: 0,
- ErrorInfo: '该申请已经被处理过'
- };
- cbOk(resp);
- }
- } else {
- if (cbErr) cbErr(err);
- }
- }
- );
- };
-
- //获取群组未决列表
- var proto_getPendencyGroup = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- ConnManager.apiCall(
- SRV_NAME.GROUP,
- 'get_pendency',
- {
- StartTime: options.StartTime,
- Limit: options.Limit,
- Handle_Account: ctx.identifier
- },
- cbOk,
- function(err) {}
- );
- };
-
- //群组未决已经上报
- var proto_getPendencyGroupRead = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- ConnManager.apiCall(
- SRV_NAME.GROUP,
- 'report_pendency',
- {
- ReportTime: options.ReportTime,
- From_Account: ctx.identifier
- },
- cbOk,
- function(err) {}
- );
- };
-
- //处理被邀请进群申请(同意或拒绝)
- var proto_handleInviteJoinGroupRequest = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- ConnManager.apiCall(
- SRV_NAME.GROUP,
- 'handle_invite_join_group',
- {
- GroupId: options.GroupId,
- Inviter_Account: options.Inviter_Account,
- HandleMsg: options.HandleMsg,
- Authentication: options.Authentication,
- MsgKey: options.MsgKey,
- ApprovalMsg: options.ApprovalMsg,
- UserDefinedField: options.UserDefinedField
- },
- cbOk,
- function(err) {}
- );
- };
-
- //主动退群
- var proto_quitGroup = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- ConnManager.apiCall(
- SRV_NAME.GROUP,
- 'quit_group',
- {
- GroupId: options.GroupId
- },
- cbOk,
- cbErr
- );
- };
-
- //退出大群
- var proto_quitBigGroup = function(options, cbOk, cbErr) {
- var srvName;
- if (!checkLogin(cbErr, false)) {
- //未登录
- srvName = SRV_NAME.BIG_GROUP;
- } else {
- //已登录
- srvName = SRV_NAME.GROUP;
- }
- MsgManager.resetBigGroupLongPollingInfo();
- ConnManager.apiCall(
- srvName,
- 'quit_group',
- {
- GroupId: options.GroupId
- },
- function(resp) {
- MsgStore.delSessByTypeId(SESSION_TYPE.GROUP, options.GroupId);
- //重置当前再请求中的ajax
- //clearXmlHttpObjMap();
- //退出大群成功之后需要重置长轮询信息
- // MsgManager.resetBigGroupLongPollingInfo();
- if (cbOk) cbOk(resp);
- },
- cbErr
- );
- };
- //查找群(按名称)
- var proto_searchGroupByName = function(options, cbOk, cbErr) {
- ConnManager.apiCall(SRV_NAME.GROUP, 'search_group', options, cbOk, cbErr);
- };
-
- //获取群组公开资料
- var proto_getGroupPublicInfo = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- ConnManager.apiCall(
- SRV_NAME.GROUP,
- 'get_group_public_info',
- {
- GroupIdList: options.GroupIdList,
- ResponseFilter: {
- GroupBasePublicInfoFilter: options.GroupBasePublicInfoFilter
- }
- },
- function(resp) {
- resp.ErrorInfo = '';
- if (resp.GroupInfo) {
- for (var i in resp.GroupInfo) {
- var errorCode = resp.GroupInfo[i].ErrorCode;
- if (errorCode > 0) {
- resp.ActionStatus = ACTION_STATUS.FAIL;
- resp.GroupInfo[i].ErrorInfo = '[' + errorCode + ']' + resp.GroupInfo[i].ErrorInfo;
- resp.ErrorInfo += resp.GroupInfo[i].ErrorInfo + '\n';
- }
- }
- }
- if (resp.ActionStatus == ACTION_STATUS.FAIL) {
- if (cbErr) {
- cbErr(resp);
- }
- } else if (cbOk) {
- cbOk(resp);
- }
- },
- cbErr
- );
- };
-
- //获取群组详细资料--高级
- //请求协议参考:https://www.qcloud.com/doc/product/269/1616
- var proto_getGroupInfo = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- var opt = {
- GroupIdList: options.GroupIdList,
- ResponseFilter: {
- GroupBaseInfoFilter: options.GroupBaseInfoFilter,
- MemberInfoFilter: options.MemberInfoFilter
- }
- };
- if (options.AppDefinedDataFilter_Group) {
- opt.ResponseFilter.AppDefinedDataFilter_Group = options.AppDefinedDataFilter_Group;
- }
- if (options.AppDefinedDataFilter_GroupMember) {
- opt.ResponseFilter.AppDefinedDataFilter_GroupMember = options.AppDefinedDataFilter_GroupMember;
- }
- ConnManager.apiCall(SRV_NAME.GROUP, 'get_group_info', opt, cbOk, cbErr);
- };
-
- //获取群组成员-高级接口
- //协议参考:https://www.qcloud.com/doc/product/269/1617
- var proto_getGroupMemberInfo = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- ConnManager.apiCall(
- SRV_NAME.GROUP,
- 'get_group_member_info',
- {
- GroupId: options.GroupId,
- Offset: options.Offset,
- Limit: options.Limit,
- MemberInfoFilter: options.MemberInfoFilter,
- MemberRoleFilter: options.MemberRoleFilter,
- AppDefinedDataFilter_GroupMember: options.AppDefinedDataFilter_GroupMember
- },
- cbOk,
- cbErr
- );
- };
-
- //增加群组成员
- //协议参考:https://www.qcloud.com/doc/product/269/1621
- var proto_addGroupMember = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- ConnManager.apiCall(
- SRV_NAME.GROUP,
- 'add_group_member',
- {
- GroupId: options.GroupId,
- Silence: options.Silence,
- MemberList: options.MemberList
- },
- cbOk,
- cbErr
- );
- };
- //修改群组成员资料
- //协议参考:https://www.qcloud.com/doc/product/269/1623
- var proto_modifyGroupMember = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- var opt = {};
- if (options.GroupId) {
- opt.GroupId = options.GroupId;
- }
- if (options.Member_Account) {
- opt.Member_Account = options.Member_Account;
- }
- //Admin或者Member
- if (options.Role) {
- opt.Role = options.Role;
- }
- // AcceptAndNotify代表解收并提示消息,Discard代表不接收也不提示消息,AcceptNotNotify代表接收消息但不提示
- if (options.MsgFlag) {
- opt.MsgFlag = options.MsgFlag;
- }
- if (options.ShutUpTime) {
- //禁言时间
- opt.ShutUpTime = options.ShutUpTime;
- }
- if (options.NameCard) {
- //群名片,最大不超过50个字节
- opt.NameCard = options.NameCard;
- }
- if (options.AppMemberDefinedData) {
- //群成员维度的自定义字段,默认情况是没有的,需要开通
- opt.AppMemberDefinedData = options.AppMemberDefinedData;
- }
- ConnManager.apiCall(SRV_NAME.GROUP, 'modify_group_member_info', opt, cbOk, cbErr);
- };
- //删除群组成员
- //协议参考:https://www.qcloud.com/doc/product/269/1622
- var proto_deleteGroupMember = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- ConnManager.apiCall(
- SRV_NAME.GROUP,
- 'delete_group_member',
- {
- GroupId: options.GroupId,
- Silence: options.Silence,
- MemberToDel_Account: options.MemberToDel_Account,
- Reason: options.Reason
- },
- cbOk,
- cbErr
- );
- };
- //解散群组
- //协议参考:https://www.qcloud.com/doc/product/269/1624
- var proto_destroyGroup = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- ConnManager.apiCall(
- SRV_NAME.GROUP,
- 'destroy_group',
- {
- GroupId: options.GroupId
- },
- cbOk,
- cbErr
- );
- };
- //转让群组
- //协议参考:https://www.qcloud.com/doc/product/269/1633
- var proto_changeGroupOwner = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(SRV_NAME.GROUP, 'change_group_owner', options, cbOk, cbErr);
- };
- //获取用户所加入的群组-高级接口
- //协议参考:https://www.qcloud.com/doc/product/269/1625
- var proto_getJoinedGroupListHigh = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- ConnManager.apiCall(
- SRV_NAME.GROUP,
- 'get_joined_group_list',
- {
- Member_Account: options.Member_Account,
- Limit: options.Limit,
- Offset: options.Offset,
- GroupType: options.GroupType,
- ResponseFilter: {
- GroupBaseInfoFilter: options.GroupBaseInfoFilter,
- SelfInfoFilter: options.SelfInfoFilter
- }
- },
- cbOk,
- cbErr
- );
- };
- //查询一组UserId在群中的身份
- //协议参考:https://www.qcloud.com/doc/product/269/1626
- var proto_getRoleInGroup = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- ConnManager.apiCall(
- SRV_NAME.GROUP,
- 'get_role_in_group',
- {
- GroupId: options.GroupId,
- User_Account: options.User_Account
- },
- cbOk,
- cbErr
- );
- };
- //设置取消成员禁言时间
- //协议参考:https://www.qcloud.com/doc/product/269/1627
- var proto_forbidSendMsg = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- ConnManager.apiCall(
- SRV_NAME.GROUP,
- 'forbid_send_msg',
- {
- GroupId: options.GroupId,
- Members_Account: options.Members_Account,
- ShutUpTime: options.ShutUpTime //单位为秒,为0时表示取消禁言
- },
- cbOk,
- cbErr
- );
- };
-
- //发送自定义群系统通知
- var proto_sendCustomGroupNotify = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(SRV_NAME.GROUP, 'send_group_system_notification', options, cbOk, cbErr);
- };
-
- //拉取群消息接口
- var proto_getGroupMsgs = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.GROUP,
- 'group_msg_get',
- {
- GroupId: options.GroupId,
- ReqMsgSeq: options.ReqMsgSeq,
- ReqMsgNumber: options.ReqMsgNumber
- },
- cbOk,
- cbErr
- );
- };
- //群消息已读上报接口
- var proto_groupMsgReaded = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.GROUP,
- 'msg_read_report',
- {
- GroupId: options.GroupId,
- MsgReadedSeq: options.MsgReadedSeq
- },
- cbOk,
- cbErr
- );
- };
- //end
-
- //好友接口
- //处理好友接口返回的错误码
- var convertErrorEn2ZhFriend = function(resp) {
- var errorAccount = [];
- if (resp.Fail_Account && resp.Fail_Account.length) {
- errorAccount = resp.Fail_Account;
- }
- if (resp.Invalid_Account && resp.Invalid_Account.length) {
- for (var k in resp.Invalid_Account) {
- errorAccount.push(resp.Invalid_Account[k]);
- }
- }
- if (errorAccount.length) {
- resp.ActionStatus = ACTION_STATUS.FAIL;
- resp.ErrorCode = ERROR_CODE_CUSTOM;
- resp.ErrorInfo = '';
- for (var i in errorAccount) {
- var failCount = errorAccount[i];
- for (var j in resp.ResultItem) {
- if (resp.ResultItem[j].To_Account == failCount) {
- var resultCode = resp.ResultItem[j].ResultCode;
- resp.ResultItem[j].ResultInfo = '[' + resultCode + ']' + resp.ResultItem[j].ResultInfo;
- resp.ErrorInfo += resp.ResultItem[j].ResultInfo + '\n';
- break;
- }
- }
- }
- }
- return resp;
- };
- //添加好友
- var proto_applyAddFriend = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.FRIEND,
- 'friend_add',
- {
- From_Account: ctx.identifier,
- AddFriendItem: options.AddFriendItem
- },
- function(resp) {
- var newResp = convertErrorEn2ZhFriend(resp);
- if (newResp.ActionStatus == ACTION_STATUS.FAIL) {
- if (cbErr) cbErr(newResp);
- } else if (cbOk) {
- cbOk(newResp);
- }
- },
- cbErr
- );
- };
- //删除好友
- var proto_deleteFriend = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.FRIEND,
- 'friend_delete',
- {
- From_Account: ctx.identifier,
- To_Account: options.To_Account,
- DeleteType: options.DeleteType
- },
- function(resp) {
- var newResp = convertErrorEn2ZhFriend(resp);
- if (newResp.ActionStatus == ACTION_STATUS.FAIL) {
- if (cbErr) cbErr(newResp);
- } else if (cbOk) {
- cbOk(newResp);
- }
- },
- cbErr
- );
- };
- //删除会话
- var proto_deleteChat = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
-
- if (options.chatType == 1) {
- ConnManager.apiCall(
- SRV_NAME.DEL_CHAT,
- 'delete',
- {
- From_Account: ctx.identifier,
- Type: options.chatType,
- To_Account: options.To_Account
- },
- cbOk,
- cbErr
- );
- } else {
- ConnManager.apiCall(
- SRV_NAME.DEL_CHAT,
- 'delete',
- {
- From_Account: ctx.identifier,
- Type: options.chatType,
- ToGroupid: options.To_Account
- },
- cbOk,
- cbErr
- );
- }
- };
- //获取好友申请
- var proto_getPendency = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.FRIEND,
- 'pendency_get',
- {
- From_Account: ctx.identifier,
- PendencyType: options.PendencyType,
- StartTime: options.StartTime,
- MaxLimited: options.MaxLimited,
- LastSequence: options.LastSequence
- },
- cbOk,
- cbErr
- );
- };
- //好友申请已读上报
- var proto_getPendencyReport = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.FRIEND,
- 'PendencyReport',
- {
- From_Account: ctx.identifier,
- LatestPendencyTimeStamp: options.LatestPendencyTimeStamp
- },
- cbOk,
- cbErr
- );
- };
- //删除好友申请
- var proto_deletePendency = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.FRIEND,
- 'pendency_delete',
- {
- From_Account: ctx.identifier,
- PendencyType: options.PendencyType,
- To_Account: options.To_Account
- },
- function(resp) {
- var newResp = convertErrorEn2ZhFriend(resp);
- if (newResp.ActionStatus == ACTION_STATUS.FAIL) {
- if (cbErr) cbErr(newResp);
- } else if (cbOk) {
- cbOk(newResp);
- }
- },
- cbErr
- );
- };
- //处理好友申请
- var proto_responseFriend = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.FRIEND,
- 'friend_response',
- {
- From_Account: ctx.identifier,
- ResponseFriendItem: options.ResponseFriendItem
- },
- function(resp) {
- var newResp = convertErrorEn2ZhFriend(resp);
- if (newResp.ActionStatus == ACTION_STATUS.FAIL) {
- if (cbErr) cbErr(newResp);
- } else if (cbOk) {
- cbOk(newResp);
- }
- },
- cbErr
- );
- };
- //我的好友
- var proto_getAllFriend = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.FRIEND,
- 'friend_get_all',
- {
- From_Account: ctx.identifier,
- TimeStamp: options.TimeStamp,
- StartIndex: options.StartIndex,
- GetCount: options.GetCount,
- LastStandardSequence: options.LastStandardSequence,
- TagList: options.TagList
- },
- cbOk,
- cbErr
- );
- };
-
- //资料接口
- //查看个人资料
- var proto_getProfilePortrait = function(options, cbOk, cbErr) {
- if (options.To_Account.length > 100) {
- options.To_Account.length = 100;
- log.error('获取用户资料人数不能超过100人');
- }
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.PROFILE,
- 'portrait_get',
- {
- From_Account: ctx.identifier,
- To_Account: options.To_Account,
- //'LastStandardSequence':options.LastStandardSequence,
- TagList: options.TagList
- },
- function(resp) {
- var errorAccount = [];
- if (resp.Fail_Account && resp.Fail_Account.length) {
- errorAccount = resp.Fail_Account;
- }
- if (resp.Invalid_Account && resp.Invalid_Account.length) {
- for (var k in resp.Invalid_Account) {
- errorAccount.push(resp.Invalid_Account[k]);
- }
- }
- if (errorAccount.length) {
- resp.ActionStatus = ACTION_STATUS.FAIL;
- resp.ErrorCode = ERROR_CODE_CUSTOM;
- resp.ErrorInfo = '';
- for (var i in errorAccount) {
- var failCount = errorAccount[i];
- for (var j in resp.UserProfileItem) {
- if (resp.UserProfileItem[j].To_Account == failCount) {
- var resultCode = resp.UserProfileItem[j].ResultCode;
- resp.UserProfileItem[j].ResultInfo = '[' + resultCode + ']' + resp.UserProfileItem[j].ResultInfo;
- resp.ErrorInfo += '账号:' + failCount + ',' + resp.UserProfileItem[j].ResultInfo + '\n';
- break;
- }
- }
- }
- }
- if (resp.ActionStatus == ACTION_STATUS.FAIL) {
- if (cbErr) cbErr(resp);
- } else if (cbOk) {
- cbOk(resp);
- }
- },
- cbErr
- );
- };
-
- //设置个人资料
- var proto_setProfilePortrait = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.PROFILE,
- 'portrait_set',
- {
- From_Account: ctx.identifier,
- ProfileItem: options.ProfileItem
- },
- function(resp) {
- for (var i in options.ProfileItem) {
- var profile = options.ProfileItem[i];
- if (profile.Tag == 'Tag_Profile_IM_Nick') {
- ctx.identifierNick = profile.Value; //更新昵称
- break;
- }
- }
- if (cbOk) cbOk(resp);
- },
- cbErr
- );
- };
-
- //增加黑名单
- var proto_addBlackList = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.FRIEND,
- 'black_list_add',
- {
- From_Account: ctx.identifier,
- To_Account: options.To_Account
- },
- function(resp) {
- var newResp = convertErrorEn2ZhFriend(resp);
- if (newResp.ActionStatus == ACTION_STATUS.FAIL) {
- if (cbErr) cbErr(newResp);
- } else if (cbOk) {
- cbOk(newResp);
- }
- },
- cbErr
- );
- };
-
- //删除黑名单
- var proto_deleteBlackList = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.FRIEND,
- 'black_list_delete',
- {
- From_Account: ctx.identifier,
- To_Account: options.To_Account
- },
- function(resp) {
- var newResp = convertErrorEn2ZhFriend(resp);
- if (newResp.ActionStatus == ACTION_STATUS.FAIL) {
- if (cbErr) cbErr(newResp);
- } else if (cbOk) {
- cbOk(newResp);
- }
- },
- cbErr
- );
- };
-
- //我的黑名单
- var proto_getBlackList = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.FRIEND,
- 'black_list_get',
- {
- From_Account: ctx.identifier,
- StartIndex: options.StartIndex,
- MaxLimited: options.MaxLimited,
- LastSequence: options.LastSequence
- },
- cbOk,
- cbErr
- );
- };
-
- //获取最近联系人
- var proto_getRecentContactList = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.RECENT_CONTACT,
- 'get',
- {
- From_Account: ctx.identifier,
- Count: options.Count
- },
- cbOk,
- cbErr
- );
- };
-
- //上传图片或文件
- var proto_uploadPic = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- var cmdName;
- if (isAccessFormalEnv()) {
- cmdName = 'pic_up';
- } else {
- cmdName = 'pic_up_test';
- }
- ConnManager.apiCall(
- SRV_NAME.PIC,
- cmdName,
- {
- App_Version: VERSION_INFO.APP_VERSION,
- From_Account: ctx.identifier,
- To_Account: options.To_Account,
- Seq: options.Seq,
- Timestamp: options.Timestamp,
- Random: options.Random,
- File_Str_Md5: options.File_Str_Md5,
- File_Size: options.File_Size,
- File_Type: options.File_Type,
- Server_Ver: VERSION_INFO.SERVER_VERSION,
- Auth_Key: authkey,
- Busi_Id: options.Busi_Id,
- PkgFlag: options.PkgFlag,
- Slice_Offset: options.Slice_Offset,
- Slice_Size: options.Slice_Size,
- Slice_Data: options.Slice_Data,
- content_type: 'application/x-www-form-urlencoded'
- },
- cbOk,
- cbErr
- );
- };
-
- //获取语音和文件下载IP和authkey
- var proto_getIpAndAuthkey = function(cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(SRV_NAME.OPEN_IM, 'authkey', {}, cbOk, cbErr);
- };
-
- //接口质量上报
- var proto_reportApiQuality = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(SRV_NAME.IM_OPEN_STAT, 'web_report', options, cbOk, cbErr);
- };
-
- var proto_getLongPollingId = function(options, cbOk, cbErr) {
- if (!checkLogin(cbErr, true)) return;
- ConnManager.apiCall(
- SRV_NAME.OPEN_IM,
- 'getlongpollingid',
- {},
- function(resp) {
- cbOk && cbOk(resp);
- },
- cbErr
- );
- };
-
- var proto_applyDownload = function(options, cbOk, cbErr) {
- //把下载地址push到map中
- ConnManager.apiCall(SRV_NAME.PIC, 'apply_download', options, cbOk, cbErr);
- };
-
- //end
- initBrowserInfo();
- // singleton object ConnManager
- var ConnManager =
- lowerBR == false
- ? new function() {
- var onConnCallback = null; //回调函数
- this.init = function(onConnNotify, cbOk, cbErr) {
- if (onConnNotify) onConnCallback = onConnNotify;
- };
- this.callBack = function(info) {
- if (onConnCallback) onConnCallback(info);
- };
- this.clear = function() {
- onConnCallback = null;
- };
- //请求后台服务接口
- this.apiCall = function(type, cmd, data, cbOk, cbErr, timeout, isLongPolling) {
- //封装后台服务接口地址
- var url = getApiUrl(type, cmd, cbOk, cbErr);
- if (url == false) return;
- //发起ajax请求
- var content_type = data.content_type ? data.content_type : 'application/x-www-form-urlencoded';
- ajaxRequestJson(
- 'POST',
- url,
- data,
- timeout,
- content_type,
- isLongPolling,
- function(resp) {
- var errorCode = null,
- tempErrorInfo = '';
- if (cmd == 'pic_up') {
- data.Slice_Data = '';
- }
- var info = '\n request url: \n' + url + '\n request body: \n' + JSON.stringify(data) + '\n response: \n' + JSON.stringify(resp);
- //成功
- if (resp.ActionStatus == ACTION_STATUS.OK) {
- log.info('[' + type + '][' + cmd + ']success: ' + info);
- if (cbOk) cbOk(resp); //回调
- errorCode = 0;
- tempErrorInfo = '';
- } else {
- errorCode = resp.ErrorCode;
- tempErrorInfo = resp.ErrorInfo;
- //报错
- if (cbErr) {
- resp.SrcErrorInfo = resp.ErrorInfo;
- resp.ErrorInfo = '[' + type + '][' + cmd + ']failed: ' + info;
- if (cmd != 'longpolling' || resp.ErrorCode != longPollingTimeOutErrorCode) {
- log.error(resp.ErrorInfo);
- }
- cbErr(resp);
- }
- }
- reportApiQuality(cmd, errorCode, tempErrorInfo); //接口质量上报
- },
- function(err) {
- cbErr && cbErr(err);
- reportApiQuality(cmd, err.ErrorCode, err.ErrorInfo); //接口质量上报
- }
- );
- };
- }()
- : new function() {
- var onConnCallback = null; //回调函数
- this.init = function(onConnNotify, cbOk, cbErr) {
- if (onConnNotify) onConnCallback = onConnNotify;
- };
- this.callBack = function(info) {
- if (onConnCallback) onConnCallback(info);
- };
- this.clear = function() {
- onConnCallback = null;
- };
- //请求后台服务接口
- this.apiCall = function(type, cmd, data, cbOk, cbErr, timeout, isLongPolling) {
- //封装后台服务接口地址
- var url = getApiUrl(type, cmd, cbOk, cbErr);
- if (url == false) return;
- //发起jsonp请求
- var reqId = jsonpRequestId++,
- cbkey = 'jsonpcallback', // the 'callback' key
- cbval = 'jsonpRequest' + reqId, // the 'callback' value
- script = document.createElement('script'),
- loaded = 0;
-
- window[cbval] = jsonpCallback;
- script.type = 'text/javascript';
- url = url + '&' + cbkey + '=' + cbval + '&jsonpbody=' + encodeURIComponent(JSON.stringify(data));
- script.src = url;
- script.async = true;
-
- if (typeof script.onreadystatechange !== 'undefined') {
- // need this for IE due to out-of-order onreadystatechange(), binding script
- // execution to an event listener gives us control over when the script
- // is executed. See http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html
- script.event = 'onclick';
- script.htmlFor = script.id = '_jsonpRequest_' + reqId;
- }
-
- script.onload = script.onreadystatechange = function() {
- if ((this.readyState && this.readyState !== 'complete' && this.readyState !== 'loaded') || loaded) {
- return false;
- }
- script.onload = script.onreadystatechange = null;
- script.onclick && script.onclick();
- // Call the user callback with the last value stored and clean up values and scripts.
- var resp = jsonpLastRspData;
- var info = '\n request url: \n' + url + '\n request body: \n' + JSON.stringify(data) + '\n response: \n' + JSON.stringify(resp);
- if (resp.ActionStatus == ACTION_STATUS.OK) {
- log.info('[' + type + '][' + cmd + ']success: ' + info);
- cbOk && cbOk(resp);
- } else {
- resp.ErrorInfo = '[' + type + '][' + cmd + ']failed ' + info;
- if (cmd != 'longpolling' || resp.ErrorCode != longPollingTimeOutErrorCode) {
- log.error(resp.ErrorInfo);
- } else {
- log.warn('[' + type + '][' + cmd + ']success: ' + info);
- }
- cbErr && cbErr(resp);
- }
- jsonpLastRspData = undefined;
- document.body.removeChild(script);
- loaded = 1;
- };
-
- // Add the script to the DOM head
- document.body.appendChild(script);
- };
- }();
- // class Session
- var Session = function(type, id, name, icon, time, seq) {
- this._impl = {
- skey: Session.skey(type, id),
- type: type,
- id: id,
- name: name,
- icon: icon,
- unread: 0, //未读消息数
- isAutoRead: false,
- time: time >= 0 ? time : 0,
- curMaxMsgSeq: seq >= 0 ? seq : 0,
- msgs: [],
- isFinished: 1
- };
- };
- Session.skey = function(type, id) {
- return type + id;
- };
- Session.prototype.type = function() {
- return this._impl.type;
- };
- Session.prototype.id = function() {
- return this._impl.id;
- };
- Session.prototype.name = function() {
- return this._impl.name;
- };
- Session.prototype.icon = function() {
- return this._impl.icon;
- };
- Session.prototype.unread = function(val) {
- if (typeof val !== 'undefined') {
- this._impl.unread = val;
- } else {
- return this._impl.unread;
- }
- };
- Session.prototype.isFinished = function(val) {
- if (typeof val !== 'undefined') {
- this._impl.isFinished = val;
- } else {
- return this._impl.isFinished;
- }
- };
- Session.prototype.time = function() {
- return this._impl.time;
- };
- Session.prototype.curMaxMsgSeq = function(seq) {
- if (typeof seq !== 'undefined') {
- this._impl.curMaxMsgSeq = seq;
- } else {
- return this._impl.curMaxMsgSeq;
- }
- };
- Session.prototype.msgCount = function() {
- return this._impl.msgs.length;
- };
- Session.prototype.msg = function(index) {
- return this._impl.msgs[index];
- };
- Session.prototype.msgs = function() {
- return this._impl.msgs;
- };
- Session.prototype._impl_addMsg = function(msg, unread) {
- this._impl.msgs.push(msg);
- //if (!msg.isSend && msg.time > this._impl.time)
- if (msg.time > this._impl.time) this._impl.time = msg.time;
- //if (!msg.isSend && msg.seq > this._impl.curMaxMsgSeq)
- if (msg.seq > this._impl.curMaxMsgSeq) this._impl.curMaxMsgSeq = msg.seq;
- //自己发送的消息不计入未读数
- if (!msg.isSend && !this._impl.isAutoRead && unread) {
- this._impl.unread++;
- }
- };
- //class C2CMsgReadedItem
- var C2CMsgReadedItem = function(toAccount, lastedMsgTime) {
- this.toAccount = toAccount;
- this.lastedMsgTime = lastedMsgTime;
- };
-
- var calcUniqId = function(num1, num2) {
- var str1 = parseInt(num1).toString(2) + '00000000000000000000000000000000';
- var str2 = parseInt(num2).toString(2);
- var arr1 = str1.split('').reverse();
- var arr2 = str2.split('').reverse();
- var sig = null,
- res = [];
- var length = arr1.length > arr2.length ? arr1.length : arr2.length;
- for (var a = 0; a < length; a++) {
- sig = Number(arr1[a] || 0) || Number(arr2[a] || 0);
- res.push(sig);
- }
- var numstr = res.reverse().join('');
- var long = {
- high: '0x' + parseInt(numstr.substr(0, numstr.length - 32), 2).toString(16),
- low: '0x' + parseInt(numstr.substr(numstr.length - 32 - 1), 2).toString(16)
- };
- var longVal = new Long(long.low, long.high, true);
- return longVal.toString();
- };
- // class Msg
- var Msg = function(sess, isSend, seq, random, time, fromAccount, subType, fromAccountNick, fromAccountHeadurl) {
- this.sess = sess;
- this.subType = subType >= 0 ? subType : 0; //消息类型,c2c消息时,type取值为0;group消息时,type取值0和1,0-普通群消息,1-群提示消息
- this.fromAccount = fromAccount;
- this.fromAccountNick = fromAccountNick ? fromAccountNick : fromAccount;
- this.fromAccountHeadurl = fromAccountHeadurl || null;
- this.isSend = Boolean(isSend);
- this.seq = seq >= 0 ? seq : nextSeq();
- this.random = random >= 0 ? random : createRandom();
- this.time = time >= 0 ? time : unixtime();
- this.elems = [];
- var type = sess.type();
- switch (type) {
- case SESSION_TYPE.GROUP:
- this.uniqueId = calcUniqId(this.seq, this.random);
- break;
- case SESSION_TYPE.C2C:
- default:
- this.uniqueId = calcUniqId(this.time, this.random);
- break;
- }
- };
- Msg.prototype.getSession = function() {
- return this.sess;
- };
- Msg.prototype.getType = function() {
- return this.subType;
- };
- Msg.prototype.getSubType = function() {
- return this.subType;
- };
- Msg.prototype.getFromAccount = function() {
- return this.fromAccount;
- };
- Msg.prototype.getFromAccountNick = function() {
- return this.fromAccountNick;
- };
- Msg.prototype.getIsSend = function() {
- return this.isSend;
- };
- Msg.prototype.getSeq = function() {
- return this.seq;
- };
- Msg.prototype.getTime = function() {
- return this.time;
- };
- Msg.prototype.getRandom = function() {
- return this.random;
- };
- Msg.prototype.getElems = function() {
- return this.elems;
- };
- Msg.prototype.getMsgUniqueId = function() {
- return this.uniqueId;
- };
- //文本
- Msg.prototype.addText = function(text) {
- this.addElem(new webim.Msg.Elem(MSG_ELEMENT_TYPE.TEXT, text));
- };
- //表情
- Msg.prototype.addFace = function(face) {
- this.addElem(new webim.Msg.Elem(MSG_ELEMENT_TYPE.FACE, face));
- };
- //图片
- Msg.prototype.addImage = function(image) {
- this.addElem(new webim.Msg.Elem(MSG_ELEMENT_TYPE.IMAGE, image));
- };
- //地理位置
- Msg.prototype.addLocation = function(location) {
- this.addElem(new webim.Msg.Elem(MSG_ELEMENT_TYPE.LOCATION, location));
- };
- //文件
- Msg.prototype.addFile = function(file) {
- this.addElem(new webim.Msg.Elem(MSG_ELEMENT_TYPE.FILE, file));
- };
- //自定义
- Msg.prototype.addCustom = function(custom) {
- this.addElem(new webim.Msg.Elem(MSG_ELEMENT_TYPE.CUSTOM, custom));
- };
- Msg.prototype.addElem = function(elem) {
- this.elems.push(elem);
- };
- Msg.prototype.toHtml = function() {
- var html = '';
- for (var i in this.elems) {
- var elem = this.elems[i];
- html += elem.toHtml();
- }
- return html;
- };
-
- // 暴力点 直接添加,内部的配置不细写
- Msg.prototype.setOfflinePushInfo = function(offlinePushInfo) {
- this.offlinePushInfo = offlinePushInfo;
- };
-
- // class Msg.Elem
- Msg.Elem = function(type, value) {
- this.type = type;
- this.content = value;
- };
- Msg.Elem.prototype.getType = function() {
- return this.type;
- };
- Msg.Elem.prototype.getContent = function() {
- return this.content;
- };
- Msg.Elem.prototype.toHtml = function() {
- var html;
- html = this.content.toHtml();
- return html;
- };
-
- // class Msg.Elem.Text
- Msg.Elem.Text = function(text) {
- this.text = tool.xssFilter(text);
- };
- Msg.Elem.Text.prototype.getText = function() {
- return this.text;
- };
- Msg.Elem.Text.prototype.toHtml = function() {
- return this.text;
- };
-
- // class Msg.Elem.Face
- Msg.Elem.Face = function(index, data) {
- this.index = index;
- this.data = data;
- };
- Msg.Elem.Face.prototype.getIndex = function() {
- return this.index;
- };
- Msg.Elem.Face.prototype.getData = function() {
- return this.data;
- };
- Msg.Elem.Face.prototype.toHtml = function() {
- var faceUrl = null;
- var index = emotionDataIndexs[this.data];
- var emotion = emotions[index];
- if (emotion && emotion[1]) {
- faceUrl = emotion[1];
- }
- if (faceUrl) {
- return "<img src='" + faceUrl + "'/>";
- } else {
- return this.data;
- }
- };
-
- // 地理位置消息 class Msg.Elem.Location
- Msg.Elem.Location = function(longitude, latitude, desc) {
- this.latitude = latitude; //纬度
- this.longitude = longitude; //经度
- this.desc = desc; //描述
- };
- Msg.Elem.Location.prototype.getLatitude = function() {
- return this.latitude;
- };
- Msg.Elem.Location.prototype.getLongitude = function() {
- return this.longitude;
- };
- Msg.Elem.Location.prototype.getDesc = function() {
- return this.desc;
- };
- Msg.Elem.Location.prototype.toHtml = function() {
- return '经度=' + this.longitude + ',纬度=' + this.latitude + ',描述=' + this.desc;
- };
-
- //图片消息
- // class Msg.Elem.Images
- Msg.Elem.Images = function(imageId, format) {
- this.UUID = imageId;
- if (typeof format !== 'number') {
- format = parseInt(IMAGE_FORMAT[format] || IMAGE_FORMAT['UNKNOWN'], 10);
- }
- this.ImageFormat = format;
- this.ImageInfoArray = [];
- };
- Msg.Elem.Images.prototype.addImage = function(image) {
- this.ImageInfoArray.push(image);
- };
- Msg.Elem.Images.prototype.toHtml = function() {
- var smallImage = this.getImage(IMAGE_TYPE.SMALL);
- var bigImage = this.getImage(IMAGE_TYPE.LARGE);
- var oriImage = this.getImage(IMAGE_TYPE.ORIGIN);
- if (!bigImage) {
- bigImage = smallImage;
- }
- if (!oriImage) {
- oriImage = smallImage;
- }
- return (
- "<img src='" +
- smallImage.getUrl() +
- '#' +
- bigImage.getUrl() +
- '#' +
- oriImage.getUrl() +
- "' style='CURSOR: hand' id='" +
- this.getImageId() +
- "' bigImgUrl='" +
- bigImage.getUrl() +
- "' onclick='imageClick(this)' />"
- );
- };
- Msg.Elem.Images.prototype.getImageId = function() {
- return this.UUID;
- };
- Msg.Elem.Images.prototype.getImageFormat = function() {
- return this.ImageFormat;
- };
- Msg.Elem.Images.prototype.getImage = function(type) {
- for (var i in this.ImageInfoArray) {
- if (this.ImageInfoArray[i].getType() == type) {
- return this.ImageInfoArray[i];
- }
- }
- var img = null;
- this.ImageInfoArray.forEach(function(image) {
- if (image.getType() == type) {
- img = image;
- }
- });
- return img;
- };
- // class Msg.Elem.Images.Image
- Msg.Elem.Images.Image = function(type, size, width, height, url) {
- this.type = type;
- this.size = size;
- this.width = width;
- this.height = height;
- this.url = url;
- };
- Msg.Elem.Images.Image.prototype.getType = function() {
- return this.type;
- };
- Msg.Elem.Images.Image.prototype.getSize = function() {
- return this.size;
- };
- Msg.Elem.Images.Image.prototype.getWidth = function() {
- return this.width;
- };
- Msg.Elem.Images.Image.prototype.getHeight = function() {
- return this.height;
- };
- Msg.Elem.Images.Image.prototype.getUrl = function() {
- return this.url;
- };
-
- // class Msg.Elem.Sound
- Msg.Elem.Sound = function(uuid, second, size, senderId, receiverId, downFlag, chatType) {
- this.uuid = uuid; //文件id
- this.second = second; //时长,单位:秒
- this.size = size; //大小,单位:字节
- this.senderId = senderId; //发送者
- this.receiverId = receiverId; //接收方id
- this.downFlag = downFlag; //下载标志位
- this.busiId = chatType == SESSION_TYPE.C2C ? 2 : 1; //busi_id ( 1:群 2:C2C)
-
- //根据不同情况拉取数据
- //是否需要申请下载地址 0:到架平申请 1:到cos申请 2:不需要申请, 直接拿url下载
- if (this.downFlag !== undefined && this.busiId !== undefined) {
- getFileDownUrlV2(uuid, senderId, second, downFlag, receiverId, this.busiId, UPLOAD_RES_TYPE.SOUND);
- } else {
- this.downUrl = getSoundDownUrl(uuid, senderId, second); //下载地址
- }
- };
- Msg.Elem.Sound.prototype.getUUID = function() {
- return this.uuid;
- };
- Msg.Elem.Sound.prototype.getSecond = function() {
- return this.second;
- };
- Msg.Elem.Sound.prototype.getSize = function() {
- return this.size;
- };
- Msg.Elem.Sound.prototype.getSenderId = function() {
- return this.senderId;
- };
- Msg.Elem.Sound.prototype.getDownUrl = function() {
- return this.downUrl;
- };
- Msg.Elem.Sound.prototype.toHtml = function() {
- if (BROWSER_INFO.type == 'ie' && parseInt(BROWSER_INFO.ver) <= 8) {
- return '[这是一条语音消息]demo暂不支持ie8(含)以下浏览器播放语音,语音URL:' + this.downUrl;
- }
- return '<audio id="uuid_' + this.uuid + '" src="' + this.downUrl + '" controls="controls" onplay="onChangePlayAudio(this)" preload="none"></audio>';
- };
-
- // class Msg.Elem.File
- Msg.Elem.File = function(uuid, name, size, senderId, receiverId, downFlag, chatType) {
- this.uuid = uuid; //文件id
- this.name = name; //文件名
- this.size = size; //大小,单位:字节
- this.senderId = senderId; //发送者
- this.receiverId = receiverId; //接收方id
- this.downFlag = downFlag; //下载标志位
-
- this.busiId = chatType == SESSION_TYPE.C2C ? 2 : 1; //busi_id ( 1:群 2:C2C)
- //根据不同情况拉取数据
- //是否需要申请下载地址 0:到架平申请 1:到cos申请 2:不需要申请, 直接拿url下载
- if (downFlag !== undefined && busiId !== undefined) {
- getFileDownUrlV2(uuid, senderId, name, downFlag, receiverId, this.busiId, UPLOAD_RES_TYPE.FILE);
- } else {
- this.downUrl = getFileDownUrl(uuid, senderId, name); //下载地址
- }
- };
- Msg.Elem.File.prototype.getUUID = function() {
- return this.uuid;
- };
- Msg.Elem.File.prototype.getName = function() {
- return this.name;
- };
- Msg.Elem.File.prototype.getSize = function() {
- return this.size;
- };
- Msg.Elem.File.prototype.getSenderId = function() {
- return this.senderId;
- };
- Msg.Elem.File.prototype.getDownUrl = function() {
- return this.downUrl;
- };
- Msg.Elem.File.prototype.getDownFlag = function() {
- return this.downFlag;
- };
- Msg.Elem.File.prototype.toHtml = function() {
- var fileSize, unitStr;
- fileSize = this.size;
- unitStr = 'Byte';
- if (this.size >= 1024) {
- fileSize = Math.round(this.size / 1024);
- unitStr = 'KB';
- }
- return (
- '<a href="javascript" onclick="webim.onDownFile("' +
- this.uuid +
- '")" title="点击下载文件" ><i class="glyphicon glyphicon-file"> ' +
- this.name +
- '(' +
- fileSize +
- unitStr +
- ')</i></a>'
- );
- };
-
- // class Msg.Elem.GroupTip 群提示消息对象
- Msg.Elem.GroupTip = function(opType, opUserId, groupId, groupName, userIdList, userinfo) {
- this.opType = opType; //操作类型
- this.opUserId = opUserId; //操作者id
- this.groupId = groupId; //群id
- this.groupName = groupName; //群名称
- this.userIdList = userIdList ? userIdList : []; //被操作的用户id列表
- this.groupInfoList = []; //新的群资料信息,群资料变更时才有值
- this.memberInfoList = []; //新的群成员资料信息,群成员资料变更时才有值
- this.groupMemberNum = null; //群成员数,操作类型为加群或者退群时才有值
- this.userinfo = userinfo ? userinfo : []; //被操作的用户信息列表列表
- };
- Msg.Elem.GroupTip.prototype.addGroupInfo = function(groupInfo) {
- this.groupInfoList.push(groupInfo);
- };
- Msg.Elem.GroupTip.prototype.addMemberInfo = function(memberInfo) {
- this.memberInfoList.push(memberInfo);
- };
- Msg.Elem.GroupTip.prototype.getOpType = function() {
- return this.opType;
- };
- Msg.Elem.GroupTip.prototype.getOpUserId = function() {
- return this.opUserId;
- };
- Msg.Elem.GroupTip.prototype.getGroupId = function() {
- return this.groupId;
- };
- Msg.Elem.GroupTip.prototype.getGroupName = function() {
- return this.groupName;
- };
- Msg.Elem.GroupTip.prototype.getUserIdList = function() {
- return this.userIdList;
- };
- Msg.Elem.GroupTip.prototype.getUserInfo = function() {
- return this.userinfo;
- };
- Msg.Elem.GroupTip.prototype.getGroupInfoList = function() {
- return this.groupInfoList;
- };
- Msg.Elem.GroupTip.prototype.getMemberInfoList = function() {
- return this.memberInfoList;
- };
- Msg.Elem.GroupTip.prototype.getGroupMemberNum = function() {
- return this.groupMemberNum;
- };
- Msg.Elem.GroupTip.prototype.setGroupMemberNum = function(groupMemberNum) {
- return (this.groupMemberNum = groupMemberNum);
- };
- Msg.Elem.GroupTip.prototype.toHtml = function() {
- var text = '[群提示消息]';
- var maxIndex = GROUP_TIP_MAX_USER_COUNT - 1;
- switch (this.opType) {
- case GROUP_TIP_TYPE.JOIN: //加入群
- text += this.opUserId + '邀请了';
- for (var m in this.userIdList) {
- text += this.userIdList[m] + ',';
- if (this.userIdList.length > GROUP_TIP_MAX_USER_COUNT && m == maxIndex) {
- text += '等' + this.userIdList.length + '人';
- break;
- }
- }
- text += '加入该群';
- break;
- case GROUP_TIP_TYPE.QUIT: //退出群
- text += this.opUserId + '主动退出该群';
- break;
- case GROUP_TIP_TYPE.KICK: //踢出群
- text += this.opUserId + '将';
- for (var m in this.userIdList) {
- text += this.userIdList[m] + ',';
- if (this.userIdList.length > GROUP_TIP_MAX_USER_COUNT && m == maxIndex) {
- text += '等' + this.userIdList.length + '人';
- break;
- }
- }
- text += '踢出该群';
- break;
- case GROUP_TIP_TYPE.SET_ADMIN: //设置管理员
- text += this.opUserId + '将';
- for (var m in this.userIdList) {
- text += this.userIdList[m] + ',';
- if (this.userIdList.length > GROUP_TIP_MAX_USER_COUNT && m == maxIndex) {
- text += '等' + this.userIdList.length + '人';
- break;
- }
- }
- text += '设为管理员';
- break;
- case GROUP_TIP_TYPE.CANCEL_ADMIN: //取消管理员
- text += this.opUserId + '取消';
- for (var m in this.userIdList) {
- text += this.userIdList[m] + ',';
- if (this.userIdList.length > GROUP_TIP_MAX_USER_COUNT && m == maxIndex) {
- text += '等' + this.userIdList.length + '人';
- break;
- }
- }
- text += '的管理员资格';
- break;
-
- case GROUP_TIP_TYPE.MODIFY_GROUP_INFO: //群资料变更
- text += this.opUserId + '修改了群资料:';
- for (var m in this.groupInfoList) {
- var type = this.groupInfoList[m].getType();
- var value = this.groupInfoList[m].getValue();
- switch (type) {
- case GROUP_TIP_MODIFY_GROUP_INFO_TYPE.FACE_URL:
- text += '群头像为' + value + '; ';
- break;
- case GROUP_TIP_MODIFY_GROUP_INFO_TYPE.NAME:
- text += '群名称为' + value + '; ';
- break;
- case GROUP_TIP_MODIFY_GROUP_INFO_TYPE.OWNER:
- text += '群主为' + value + '; ';
- break;
- case GROUP_TIP_MODIFY_GROUP_INFO_TYPE.NOTIFICATION:
- text += '群公告为' + value + '; ';
- break;
- case GROUP_TIP_MODIFY_GROUP_INFO_TYPE.INTRODUCTION:
- text += '群简介为' + value + '; ';
- break;
- default:
- text += '未知信息为:type=' + type + ',value=' + value + '; ';
- break;
- }
- }
- break;
-
- case GROUP_TIP_TYPE.MODIFY_MEMBER_INFO: //群成员资料变更(禁言时间)
- text += this.opUserId + '修改了群成员资料:';
- for (var m in this.memberInfoList) {
- var userId = this.memberInfoList[m].getUserId();
- var shutupTime = this.memberInfoList[m].getShutupTime();
- text += userId + ': ';
- if (shutupTime != null && shutupTime !== undefined) {
- if (shutupTime == 0) {
- text += '取消禁言; ';
- } else {
- text += '禁言' + shutupTime + '秒; ';
- }
- } else {
- text += ' shutupTime为空';
- }
- if (this.memberInfoList.length > GROUP_TIP_MAX_USER_COUNT && m == maxIndex) {
- text += '等' + this.memberInfoList.length + '人';
- break;
- }
- }
- break;
-
- case GROUP_TIP_TYPE.READED: //消息已读
- /**/
- Log.info('消息已读同步');
- break;
- default:
- text += '未知群提示消息类型:type=' + this.opType;
- break;
- }
- return text;
- };
-
- // class Msg.Elem.GroupTip.GroupInfo,变更的群资料信息对象
- Msg.Elem.GroupTip.GroupInfo = function(type, value) {
- this.type = type; //群资料信息类型
- this.value = value; //对应的值
- };
- Msg.Elem.GroupTip.GroupInfo.prototype.getType = function() {
- return this.type;
- };
- Msg.Elem.GroupTip.GroupInfo.prototype.getValue = function() {
- return this.value;
- };
-
- // class Msg.Elem.GroupTip.MemberInfo,变更的群成员资料信息对象
- Msg.Elem.GroupTip.MemberInfo = function(userId, shutupTime) {
- this.userId = userId; //群成员id
- this.shutupTime = shutupTime; //群成员被禁言时间,0表示取消禁言,大于0表示被禁言时长,单位:秒
- };
- Msg.Elem.GroupTip.MemberInfo.prototype.getUserId = function() {
- return this.userId;
- };
- Msg.Elem.GroupTip.MemberInfo.prototype.getShutupTime = function() {
- return this.shutupTime;
- };
-
- // 自定义消息类型 class Msg.Elem.Custom
- Msg.Elem.Custom = function(data, desc, ext) {
- this.data = data; //数据
- this.desc = desc; //描述
- this.ext = ext; //扩展字段
- };
- Msg.Elem.Custom.prototype.getData = function() {
- return this.data;
- };
- Msg.Elem.Custom.prototype.getDesc = function() {
- return this.desc;
- };
- Msg.Elem.Custom.prototype.getExt = function() {
- return this.ext;
- };
- Msg.Elem.Custom.prototype.toHtml = function() {
- return this.data;
- };
-
- // singleton object MsgStore
- var MsgStore = new function() {
- var sessMap = {}; //跟所有用户或群的聊天记录MAP
- var sessTimeline = []; //按时间降序排列的会话列表
- msgCache = {}; //消息缓存,用于判重
- //C2C
- this.cookie = ''; //上一次拉取新c2c消息的cookie
- this.syncFlag = 0; //上一次拉取新c2c消息的是否继续拉取标记
-
- var visitSess = function(visitor) {
- for (var i in sessMap) {
- visitor(sessMap[i]);
- }
- };
- //消息查重
- var checkDupMsg = function(msg) {
- var dup = false;
- var first_key = msg.sess._impl.skey;
- var second_key = msg.isSend + msg.seq + msg.random;
- var tempMsg = msgCache[first_key] && msgCache[first_key][second_key];
- if (tempMsg) {
- dup = true;
- }
- if (msgCache[first_key]) {
- msgCache[first_key][second_key] = {
- time: msg.time
- };
- } else {
- msgCache[first_key] = {};
- msgCache[first_key][second_key] = {
- time: msg.time
- };
- }
- return dup;
- };
-
- this.sessMap = function() {
- return sessMap;
- };
- this.sessCount = function() {
- return sessTimeline.length;
- };
- this.sessByTypeId = function(type, id) {
- var skey = Session.skey(type, id);
- if (skey === undefined || skey == null) return null;
- return sessMap[skey];
- };
- this.delSessByTypeId = function(type, id) {
- var skey = Session.skey(type, id);
- if (skey === undefined || skey == null) return false;
- if (sessMap[skey]) {
- delete sessMap[skey];
- delete msgCache[skey];
- }
- return true;
- };
- this.resetCookieAndSyncFlag = function() {
- this.cookie = '';
- this.syncFlag = 0;
- };
-
- //切换将当前会话的自动读取消息标志为isOn,重置其他会话的自动读取消息标志为false
- this.setAutoRead = function(selSess, isOn, isResetAll) {
- if (isResetAll)
- visitSess(function(s) {
- s._impl.isAutoRead = false;
- });
- if (selSess) {
- selSess._impl.isAutoRead = isOn; //
- if (isOn) {
- //是否调用已读上报接口
- selSess._impl.unread = 0;
-
- if (selSess._impl.type == SESSION_TYPE.C2C) {
- //私聊消息已读上报
- var tmpC2CMsgReadedItem = [];
- tmpC2CMsgReadedItem.push(new C2CMsgReadedItem(selSess._impl.id, selSess._impl.time));
- //调用C2C消息已读上报接口
- proto_c2CMsgReaded(
- MsgStore.cookie,
- tmpC2CMsgReadedItem,
- function(resp) {
- log.info('[setAutoRead]: c2CMsgReaded success');
- },
- function(err) {
- log.error('[setAutoRead}: c2CMsgReaded failed:' + err.ErrorInfo);
- }
- );
- } else if (selSess._impl.type == SESSION_TYPE.GROUP) {
- //群聊消息已读上报
- var tmpOpt = {
- GroupId: selSess._impl.id,
- MsgReadedSeq: selSess._impl.curMaxMsgSeq
- };
- //调用group消息已读上报接口
- proto_groupMsgReaded(
- tmpOpt,
- function(resp) {
- log.info('groupMsgReaded success');
- },
- function(err) {
- log.error('groupMsgReaded failed:' + err.ErrorInfo);
- }
- );
- }
- }
- }
- };
-
- this.c2CMsgReaded = function(opts, cbOk, cbErr) {
- var tmpC2CMsgReadedItem = [];
- tmpC2CMsgReadedItem.push(new C2CMsgReadedItem(opts.To_Account, opts.LastedMsgTime));
- //调用C2C消息已读上报接口
- proto_c2CMsgReaded(
- MsgStore.cookie,
- tmpC2CMsgReadedItem,
- function(resp) {
- if (cbOk) {
- log.info('c2CMsgReaded success');
- cbOk(resp);
- }
- },
- function(err) {
- if (cbErr) {
- log.error('c2CMsgReaded failed:' + err.ErrorInfo);
- cbErr(err);
- }
- }
- );
- };
-
- this.addSession = function(sess) {
- sessMap[sess._impl.skey] = sess;
- };
- this.delSession = function(sess) {
- delete sessMap[sess._impl.skey];
- };
- this.clear = function() {
- sessMap = {}; //跟所有用户或群的聊天记录MAP
- sessTimeline = []; //按时间降序排列的会话列表
- msgCache = {}; //消息缓存,用于判重
- this.cookie = ''; //上一次拉取新c2c消息的cookie
- this.syncFlag = 0; //上一次拉取新c2c消息的是否继续拉取标记
- };
- this.addMsg = function(msg, unread) {
- if (checkDupMsg(msg)) return false;
- var sess = msg.sess;
- if (!sessMap[sess._impl.skey]) this.addSession(sess);
- sess._impl_addMsg(msg, unread);
- return true;
- };
- this.updateTimeline = function() {
- var arr = new Array();
- visitSess(function(sess) {
- arr.push(sess);
- });
- arr.sort(function(a, b) {
- return b.time - a.time;
- });
- sessTimeline = arr;
- };
- }();
- // singleton object MsgManager
- var MsgManager = new function() {
- var onMsgCallback = null; //新消息(c2c和group)回调
-
- var onGroupInfoChangeCallback = null; //群资料变化回调
- //收到新群系统消息回调列表
- var onGroupSystemNotifyCallbacks = {
- '1': null,
- '2': null,
- '3': null,
- '4': null,
- '5': null,
- '6': null,
- '7': null,
- '8': null,
- '9': null,
- '10': null,
- '11': null,
- '15': null,
- '255': null,
- '12': null
- };
- //监听好友系统通知函数
- var onFriendSystemNotifyCallbacks = {
- '1': null,
- '2': null,
- '3': null,
- '4': null,
- '5': null,
- '6': null,
- '7': null,
- '8': null
- };
-
- var onProfileSystemNotifyCallbacks = {
- '1': null
- };
-
- var onKickedEventCall = null;
-
- var onMsgReadCallback = null;
-
- //普通长轮询
- var longPollingOn = false; //是否开启普通长轮询
- var isLongPollingRequesting = false; //是否在长轮询ing
- var notifySeq = 0; //c2c通知seq
- var noticeSeq = 0; //群消息seq
-
- //大群长轮询
- var onBigGroupMsgCallback = null; //大群消息回调
- var bigGroupLongPollingOn = false; //是否开启长轮询
- var bigGroupLongPollingStartSeq = 0; //请求拉消息的起始seq(大群长轮询)
- var bigGroupLongPollingHoldTime = 90; //客户端长轮询的超时时间,单位是秒(大群长轮询)
- var bigGroupLongPollingKey = null; //客户端加入群组后收到的的Key(大群长轮询)
- var bigGroupLongPollingMsgMap = {}; //记录收到的群消息数
- var onC2cEventCallbacks = {
- '92': null, //消息已读通知,
- '96': null
- };
- var onAppliedDownloadUrl = null;
-
- var getLostGroupMsgCount = 0; //补拉丢失的群消息次数
- //我的群当前最大的seq
- var myGroupMaxSeqs = {}; //用于补拉丢失的群消息
-
- var groupSystemMsgsCache = {}; //群组系统消息缓存,用于判重
-
- //设置长轮询开关
- //isOn=true 开启
- //isOn=false 停止
- this.setLongPollingOn = function(isOn) {
- longPollingOn = isOn;
- };
- this.getLongPollingOn = function() {
- return longPollingOn;
- };
-
- //重置长轮询变量
- this.resetLongPollingInfo = function() {
- longPollingOn = false;
- notifySeq = 0;
- noticeSeq = 0;
- };
-
- //设置大群长轮询开关
- //isOn=true 开启
- //isOn=false 停止
- this.setBigGroupLongPollingOn = function(isOn) {
- bigGroupLongPollingOn = isOn;
- };
- //设置大群长轮询key
- this.setBigGroupLongPollingKey = function(key) {
- bigGroupLongPollingKey = key;
- };
- //重置大群长轮询变量
- this.resetBigGroupLongPollingInfo = function() {
- bigGroupLongPollingOn = false;
- bigGroupLongPollingStartSeq = 0;
- bigGroupLongPollingKey = null;
- bigGroupLongPollingMsgMap = {};
- };
-
- //设置群消息数据条数
- this.setBigGroupLongPollingMsgMap = function(groupId, count) {
- var bigGroupLongPollingMsgCount = bigGroupLongPollingMsgMap[groupId];
- if (bigGroupLongPollingMsgCount) {
- bigGroupLongPollingMsgCount = parseInt(bigGroupLongPollingMsgCount) + count;
- bigGroupLongPollingMsgMap[groupId] = bigGroupLongPollingMsgCount;
- } else {
- bigGroupLongPollingMsgMap[groupId] = count;
- }
- };
-
- //重置
- this.clear = function() {
- onGroupInfoChangeCallback = null;
- onGroupSystemNotifyCallbacks = {
- '1': null, //申请加群请求(只有管理员会收到)
- '2': null, //申请加群被同意(只有申请人能够收到)
- '3': null, //申请加群被拒绝(只有申请人能够收到)
- '4': null, //被管理员踢出群(只有被踢者接收到)
- '5': null, //群被解散(全员接收)
- '6': null, //创建群(创建者接收)
- '7': null, //邀请加群(被邀请者接收)
- '8': null, //主动退群(主动退出者接收)
- '9': null, //设置管理员(被设置者接收)
- '10': null, //取消管理员(被取消者接收)
- '11': null, //群已被回收(全员接收)
- '15': null, //群已被回收(全员接收)
- '255': null, //用户自定义通知(默认全员接收)
- '12': null //邀请加群(被邀请者需要同意)
- };
- onFriendSystemNotifyCallbacks = {
- '1': null, //好友表增加
- '2': null, //好友表删除
- '3': null, //未决增加
- '4': null, //未决删除
- '5': null, //黑名单增加
- '6': null, //黑名单删除
- '7': null, //未决已读上报
- '8': null //好友信息(备注,分组)变更
- };
- onProfileSystemNotifyCallbacks = {
- '1': null //资料修改
- };
- //重置普通长轮询参数
- onMsgCallback = null;
- longPollingOn = false;
- notifySeq = 0; //c2c新消息通知seq
- noticeSeq = 0; //group新消息seq
-
- //重置大群长轮询参数
- onBigGroupMsgCallback = null;
- bigGroupLongPollingOn = false;
- bigGroupLongPollingStartSeq = 0;
- bigGroupLongPollingKey = null;
- bigGroupLongPollingMsgMap = {};
-
- groupSystemMsgsCache = {};
-
- ipList = []; //文件下载地址
- authkey = null; //文件下载票据
- expireTime = null; //票据超时时间
- };
-
- //初始化文件下载ip和票据
- var initIpAndAuthkey = function(cbOk, cbErr) {
- proto_getIpAndAuthkey(
- function(resp) {
- ipList = resp.IpList;
- authkey = resp.AuthKey;
- expireTime = resp.ExpireTime;
- if (cbOk) cbOk(resp);
- },
- function(err) {
- log.error('initIpAndAuthkey failed:' + err.ErrorInfo);
- if (cbErr) cbErr(err);
- }
- );
- };
-
- //初始化我的群当前最大的seq,用于补拉丢失的群消息
- var initMyGroupMaxSeqs = function(cbOk, cbErr) {
- var opts = {
- Member_Account: ctx.identifier,
- Limit: 1000,
- Offset: 0,
- GroupBaseInfoFilter: ['NextMsgSeq']
- };
- proto_getJoinedGroupListHigh(
- opts,
- function(resp) {
- if (!resp.GroupIdList || resp.GroupIdList.length == 0) {
- log.info('initMyGroupMaxSeqs: 目前还没有加入任何群组');
- if (cbOk) cbOk(resp);
- return;
- }
- for (var i = 0; i < resp.GroupIdList.length; i++) {
- var group_id = resp.GroupIdList[i].GroupId;
- var curMaxSeq = resp.GroupIdList[i].NextMsgSeq - 1;
- myGroupMaxSeqs[group_id] = curMaxSeq;
- }
-
- if (cbOk) cbOk(resp);
- },
- function(err) {
- log.error('initMyGroupMaxSeqs failed:' + err.ErrorInfo);
- if (cbErr) cbErr(err);
- }
- );
- };
-
- //补拉群消息
- var getLostGroupMsgs = function(groupId, reqMsgSeq, reqMsgNumber) {
- getLostGroupMsgCount++;
- //发起一个拉群群消息请求
- var tempOpts = {
- GroupId: groupId,
- ReqMsgSeq: reqMsgSeq,
- ReqMsgNumber: reqMsgNumber
- };
- //发起一个拉群群消息请求
- log.warn('第' + getLostGroupMsgCount + '次补齐群消息,参数=' + JSON.stringify(tempOpts));
- MsgManager.syncGroupMsgs(tempOpts);
- };
-
- //更新群当前最大消息seq
- var updateMyGroupCurMaxSeq = function(groupId, msgSeq) {
- //更新myGroupMaxSeqs中的群最大seq
- var curMsgSeq = myGroupMaxSeqs[groupId];
- if (curMsgSeq) {
- //如果存在,比较大小
- if (msgSeq > curMsgSeq) {
- myGroupMaxSeqs[groupId] = msgSeq;
- }
- } else {
- //不存在,新增
- myGroupMaxSeqs[groupId] = msgSeq;
- }
- };
-
- //添加群消息列表
- var addGroupMsgList = function(msgs, new_group_msgs) {
- for (var p in msgs) {
- var newGroupMsg = msgs[p];
- //发群消息时,长轮询接口会返回用户自己发的群消息
- //if(newGroupMsg.From_Account && newGroupMsg.From_Account!=ctx.identifier ){
- if (newGroupMsg.From_Account) {
- //false-不是主动拉取的历史消息
- //true-需要保存到sdk本地session,并且需要判重
- var msg = handlerGroupMsg(newGroupMsg, false, true);
- if (msg) {
- //不为空,加到新消息里
- new_group_msgs.push(msg);
- }
- //更新myGroupMaxSeqs中的群最大seq
- updateMyGroupCurMaxSeq(newGroupMsg.ToGroupId, newGroupMsg.MsgSeq);
- }
- }
- return new_group_msgs;
- };
-
- //处理收到的群普通和提示消息
- var handlerOrdinaryAndTipC2cMsgs = function(eventType, groupMsgArray) {
- var groupMsgMap = {}; //保存收到的C2c消息信息(群号,最小,最大消息seq,消息列表)
- var new_group_msgs = [];
- var minGroupMsgSeq = 99999999;
- var maxGroupMsgSeq = -1;
- for (var j in groupMsgArray) {
- var groupMsgs = groupMsgMap[groupMsgArray[j].ToGroupId];
- if (!groupMsgs) {
- groupMsgs = groupMsgMap[groupMsgArray[j].ToGroupId] = {
- min: minGroupMsgSeq, //收到新消息最小seq
- max: maxGroupMsgSeq, //收到新消息最大seq
- msgs: [] //收到的新消息
- };
- }
- //更新长轮询的群NoticeSeq
- if (groupMsgArray[j].NoticeSeq > noticeSeq) {
- log.warn('noticeSeq=' + noticeSeq + ',msgNoticeSeq=' + groupMsgArray[j].NoticeSeq);
- noticeSeq = groupMsgArray[j].NoticeSeq;
- }
- groupMsgArray[j].Event = eventType;
- groupMsgMap[groupMsgArray[j].ToGroupId].msgs.push(groupMsgArray[j]); //新增一条消息
- if (groupMsgArray[j].MsgSeq < groupMsgs.min) {
- //记录最小的消息seq
- groupMsgMap[groupMsgArray[j].ToGroupId].min = groupMsgArray[j].MsgSeq;
- }
- if (groupMsgArray[j].MsgSeq > groupMsgs.max) {
- //记录最大的消息seq
- groupMsgMap[groupMsgArray[j].ToGroupId].max = groupMsgArray[j].MsgSeq;
- }
- }
-
- for (var groupId in groupMsgMap) {
- var tempCount = groupMsgMap[groupId].max - groupMsgMap[groupId].min + 1; //收到的新的群消息数
- var curMaxMsgSeq = myGroupMaxSeqs[groupId]; //获取本地保存的群最大消息seq
- if (curMaxMsgSeq) {
- //存在这个群的最大消息seq
- //高并发情况下,长轮询可能存在丢消息,这时需要客户端通过拉取群消息接口补齐下
- //1、如果收到的新消息最小seq比当前最大群消息seq大于1,则表示收到的群消息发生跳跃,需要补齐
- //2、收到的新群消息seq存在不连续情况,也需要补齐
- if (groupMsgMap[groupId].min - curMaxMsgSeq > 1 || groupMsgMap[groupId].msgs.length < tempCount) {
- //发起一个拉群群消息请求
- log.warn(
- '发起一次补齐群消息请求,curMaxMsgSeq=' +
- curMaxMsgSeq +
- ', minMsgSeq=' +
- groupMsgMap[groupId].min +
- ', maxMsgSeq=' +
- groupMsgMap[groupId].max +
- ', msgs.length=' +
- groupMsgMap[groupId].msgs.length +
- ', tempCount=' +
- tempCount
- );
- getLostGroupMsgs(groupId, groupMsgMap[groupId].max, groupMsgMap[groupId].max - curMaxMsgSeq);
- //更新myGroupMaxSeqs中的群最大seq
- updateMyGroupCurMaxSeq(groupId, groupMsgMap[groupId].max);
- } else {
- new_group_msgs = addGroupMsgList(groupMsgMap[groupId].msgs, new_group_msgs);
- }
- } else {
- //不存在该群的最大消息seq
- log.warn('不存在该群的最大消息seq,群id=' + groupId);
- //高并发情况下,长轮询可能存在丢消息,这时需要客户端通过拉取群消息接口补齐下
- //1、收到的新群消息seq存在不连续情况,也需要补齐
- if (groupMsgMap[groupId].msgs.length < tempCount) {
- //发起一个拉群群消息请求
- log.warn(
- '发起一次补齐群消息请求,minMsgSeq=' +
- groupMsgMap[groupId].min +
- ', maxMsgSeq=' +
- groupMsgMap[groupId].max +
- ', msgs.length=' +
- groupMsgMap[groupId].msgs.length +
- ', tempCount=' +
- tempCount
- );
- getLostGroupMsgs(groupId, groupMsgMap[groupId].max, tempCount);
- //更新myGroupMaxSeqs中的群最大seq
- updateMyGroupCurMaxSeq(groupId, groupMsgMap[groupId].max);
- } else {
- new_group_msgs = addGroupMsgList(groupMsgMap[groupId].msgs, new_group_msgs);
- }
- }
- }
- if (new_group_msgs.length) {
- MsgStore.updateTimeline();
- }
- if (onMsgCallback && new_group_msgs.length) onMsgCallback(new_group_msgs);
- };
-
- //处理收到的群普通和提示消息
- var handlerOrdinaryAndTipGroupMsgs = function(eventType, groupMsgArray) {
- var groupMsgMap = {}; //保存收到的群消息信息(群号,最小,最大消息seq,消息列表)
- var new_group_msgs = [];
- var minGroupMsgSeq = 99999999;
- var maxGroupMsgSeq = -1;
- for (var j in groupMsgArray) {
- var groupMsgs = groupMsgMap[groupMsgArray[j].ToGroupId];
- if (!groupMsgs) {
- groupMsgs = groupMsgMap[groupMsgArray[j].ToGroupId] = {
- min: minGroupMsgSeq, //收到新消息最小seq
- max: maxGroupMsgSeq, //收到新消息最大seq
- msgs: [] //收到的新消息
- };
- }
- //更新长轮询的群NoticeSeq
- if (groupMsgArray[j].NoticeSeq > noticeSeq) {
- log.warn('noticeSeq=' + noticeSeq + ',msgNoticeSeq=' + groupMsgArray[j].NoticeSeq);
- noticeSeq = groupMsgArray[j].NoticeSeq;
- }
- groupMsgArray[j].Event = eventType;
- groupMsgMap[groupMsgArray[j].ToGroupId].msgs.push(groupMsgArray[j]); //新增一条消息
- if (groupMsgArray[j].MsgSeq < groupMsgs.min) {
- //记录最小的消息seq
- groupMsgMap[groupMsgArray[j].ToGroupId].min = groupMsgArray[j].MsgSeq;
- }
- if (groupMsgArray[j].MsgSeq > groupMsgs.max) {
- //记录最大的消息seq
- groupMsgMap[groupMsgArray[j].ToGroupId].max = groupMsgArray[j].MsgSeq;
- }
- }
-
- for (var groupId in groupMsgMap) {
- var tempCount = groupMsgMap[groupId].max - groupMsgMap[groupId].min + 1; //收到的新的群消息数
- var curMaxMsgSeq = myGroupMaxSeqs[groupId]; //获取本地保存的群最大消息seq
- if (curMaxMsgSeq) {
- //存在这个群的最大消息seq
- //高并发情况下,长轮询可能存在丢消息,这时需要客户端通过拉取群消息接口补齐下
- //1、如果收到的新消息最小seq比当前最大群消息seq大于1,则表示收到的群消息发生跳跃,需要补齐
- //2、收到的新群消息seq存在不连续情况,也需要补齐
- if (groupMsgMap[groupId].min - curMaxMsgSeq > 1 || groupMsgMap[groupId].msgs.length < tempCount) {
- //发起一个拉群群消息请求
- log.warn(
- '发起一次补齐群消息请求,curMaxMsgSeq=' +
- curMaxMsgSeq +
- ', minMsgSeq=' +
- groupMsgMap[groupId].min +
- ', maxMsgSeq=' +
- groupMsgMap[groupId].max +
- ', msgs.length=' +
- groupMsgMap[groupId].msgs.length +
- ', tempCount=' +
- tempCount
- );
- getLostGroupMsgs(groupId, groupMsgMap[groupId].max, groupMsgMap[groupId].max - curMaxMsgSeq);
- //更新myGroupMaxSeqs中的群最大seq
- updateMyGroupCurMaxSeq(groupId, groupMsgMap[groupId].max);
- } else {
- new_group_msgs = addGroupMsgList(groupMsgMap[groupId].msgs, new_group_msgs);
- }
- } else {
- //不存在该群的最大消息seq
- log.warn('不存在该群的最大消息seq,群id=' + groupId);
- //高并发情况下,长轮询可能存在丢消息,这时需要客户端通过拉取群消息接口补齐下
- //1、收到的新群消息seq存在不连续情况,也需要补齐
- if (groupMsgMap[groupId].msgs.length < tempCount) {
- //发起一个拉群群消息请求
- log.warn(
- '发起一次补齐群消息请求,minMsgSeq=' +
- groupMsgMap[groupId].min +
- ', maxMsgSeq=' +
- groupMsgMap[groupId].max +
- ', msgs.length=' +
- groupMsgMap[groupId].msgs.length +
- ', tempCount=' +
- tempCount
- );
- getLostGroupMsgs(groupId, groupMsgMap[groupId].max, tempCount);
- //更新myGroupMaxSeqs中的群最大seq
- updateMyGroupCurMaxSeq(groupId, groupMsgMap[groupId].max);
- } else {
- new_group_msgs = addGroupMsgList(groupMsgMap[groupId].msgs, new_group_msgs);
- }
- }
- }
- if (new_group_msgs.length) {
- MsgStore.updateTimeline();
- }
- if (onMsgCallback && new_group_msgs.length) onMsgCallback(new_group_msgs);
- };
-
- //处理新的群提示消息
- var handlerGroupTips = function(groupTips) {
- var new_group_msgs = [];
- for (var o in groupTips) {
- var groupTip = groupTips[o];
- //添加event字段
- groupTip.Event = LONG_POLLINNG_EVENT_TYPE.GROUP_TIP;
- //更新群消息通知seq
- if (groupTip.NoticeSeq > noticeSeq) {
- noticeSeq = groupTip.NoticeSeq;
- }
- var msg = handlerGroupMsg(groupTip, false, true);
- if (msg) {
- new_group_msgs.push(msg);
- }
- }
- if (new_group_msgs.length) {
- MsgStore.updateTimeline();
- }
- if (onMsgCallback && new_group_msgs.length) onMsgCallback(new_group_msgs);
- };
-
- //处理新的群系统消息
- //isNeedValidRepeatMsg 是否需要判重
- var handlerGroupSystemMsgs = function(groupSystemMsgs, isNeedValidRepeatMsg) {
- for (var k in groupSystemMsgs) {
- var groupTip = groupSystemMsgs[k];
- var groupReportTypeMsg = groupTip.MsgBody;
- var reportType = groupReportTypeMsg.ReportType;
- //当长轮询返回的群系统消息,才需要更新群消息通知seq
- if (isNeedValidRepeatMsg == false && groupTip.NoticeSeq && groupTip.NoticeSeq > noticeSeq) {
- noticeSeq = groupTip.NoticeSeq;
- }
- var toAccount = groupTip.GroupInfo.To_Account;
- //过滤本不应该给自己的系统消息
- /*if (!toAccount || toAccount != ctx.identifier) {
- log.error("收到本不应该给自己的系统消息: To_Account=" + toAccount);
- continue;
- }*/
- if (isNeedValidRepeatMsg) {
- //var key=groupTip.ToGroupId+"_"+reportType+"_"+groupTip.MsgTimeStamp+"_"+groupReportTypeMsg.Operator_Account;
- var key = groupTip.ToGroupId + '_' + reportType + '_' + groupReportTypeMsg.Operator_Account;
- var isExist = groupSystemMsgsCache[key];
- if (isExist) {
- log.warn('收到重复的群系统消息:key=' + key);
- continue;
- }
- groupSystemMsgsCache[key] = true;
- }
-
- var notify = {
- SrcFlag: 0,
- ReportType: reportType,
- GroupId: groupTip.ToGroupId,
- GroupName: groupTip.GroupInfo.GroupName,
- Operator_Account: groupReportTypeMsg.Operator_Account,
- MsgTime: groupTip.MsgTimeStamp,
- groupReportTypeMsg: groupReportTypeMsg
- };
- switch (reportType) {
- case GROUP_SYSTEM_TYPE.JOIN_GROUP_REQUEST: //申请加群(只有管理员会接收到)
- notify['RemarkInfo'] = groupReportTypeMsg.RemarkInfo;
- notify['MsgKey'] = groupReportTypeMsg.MsgKey;
- notify['Authentication'] = groupReportTypeMsg.Authentication;
- notify['UserDefinedField'] = groupTip.UserDefinedField;
- notify['From_Account'] = groupTip.From_Account;
- notify['MsgSeq'] = groupTip.ClientSeq;
- notify['MsgRandom'] = groupTip.MsgRandom;
- break;
- case GROUP_SYSTEM_TYPE.JOIN_GROUP_ACCEPT: //申请加群被同意(只有申请人自己接收到)
- case GROUP_SYSTEM_TYPE.JOIN_GROUP_REFUSE: //申请加群被拒绝(只有申请人自己接收到)
- notify['RemarkInfo'] = groupReportTypeMsg.RemarkInfo;
- break;
- case GROUP_SYSTEM_TYPE.KICK: //被管理员踢出群(只有被踢者接收到)
- case GROUP_SYSTEM_TYPE.DESTORY: //群被解散(全员接收)
- case GROUP_SYSTEM_TYPE.CREATE: //创建群(创建者接收, 不展示)
- case GROUP_SYSTEM_TYPE.INVITED_JOIN_GROUP_REQUEST: //邀请加群(被邀请者接收)
- case GROUP_SYSTEM_TYPE.INVITED_JOIN_GROUP_REQUEST_AGREE: //邀请加群(被邀请者需同意)
- case GROUP_SYSTEM_TYPE.QUIT: //主动退群(主动退出者接收, 不展示)
- case GROUP_SYSTEM_TYPE.SET_ADMIN: //群设置管理员(被设置者接收)
- case GROUP_SYSTEM_TYPE.CANCEL_ADMIN: //取消管理员(被取消者接收)
- case GROUP_SYSTEM_TYPE.REVOKE: //群已被回收(全员接收, 不展示)
- break;
- case GROUP_SYSTEM_TYPE.READED: //群消息已读同步
- break;
- case GROUP_SYSTEM_TYPE.CUSTOM: //用户自定义通知(默认全员接收)
- notify['MsgSeq'] = groupTip.MsgSeq;
- notify['UserDefinedField'] = groupReportTypeMsg.UserDefinedField;
- break;
- default:
- log.error('未知群系统消息类型:reportType=' + reportType);
- break;
- }
-
- if (isNeedValidRepeatMsg) {
- //注释只收取一种通知
- // if (reportType == GROUP_SYSTEM_TYPE.JOIN_GROUP_REQUEST) {
- //回调
- if (onGroupSystemNotifyCallbacks[reportType]) {
- onGroupSystemNotifyCallbacks[reportType](notify);
- } else {
- log.error('未知群系统消息类型:reportType=' + reportType);
- }
- //}
- } else {
- //回调
- if (onGroupSystemNotifyCallbacks[reportType]) {
- if (reportType == GROUP_SYSTEM_TYPE.READED) {
- var arr = notify.groupReportTypeMsg.GroupReadInfoArray;
- for (var i = 0, l = arr.length; i < l; i++) {
- var item = arr[i];
- onGroupSystemNotifyCallbacks[reportType](item);
- }
- } else {
- onGroupSystemNotifyCallbacks[reportType](notify);
- }
- }
- }
- } //loop
- };
-
- //处理新的好友系统通知
- //isNeedValidRepeatMsg 是否需要判重
- var handlerFriendSystemNotices = function(friendSystemNotices, isNeedValidRepeatMsg) {
- var friendNotice, type, notify;
- for (var k in friendSystemNotices) {
- friendNotice = friendSystemNotices[k];
- type = friendNotice.PushType;
- //当长轮询返回的群系统消息,才需要更新通知seq
- if (isNeedValidRepeatMsg == false && friendNotice.NoticeSeq && friendNotice.NoticeSeq > noticeSeq) {
- noticeSeq = friendNotice.NoticeSeq;
- }
- notify = {
- Type: type
- };
- switch (type) {
- case FRIEND_NOTICE_TYPE.FRIEND_ADD: //好友表增加
- notify['Accounts'] = friendNotice.FriendAdd_Account;
- break;
- case FRIEND_NOTICE_TYPE.FRIEND_DELETE: //好友表删除
- notify['Accounts'] = friendNotice.FriendDel_Account;
- break;
- case FRIEND_NOTICE_TYPE.PENDENCY_ADD: //未决增加
- notify['PendencyList'] = friendNotice.PendencyAdd;
- break;
- case FRIEND_NOTICE_TYPE.PENDENCY_DELETE: //未决删除
- notify['Accounts'] = friendNotice.FrienPencydDel_Account;
- break;
- case FRIEND_NOTICE_TYPE.BLACK_LIST_ADD: //黑名单增加
- notify['Accounts'] = friendNotice.BlackListAdd_Account;
- break;
- case FRIEND_NOTICE_TYPE.BLACK_LIST_DELETE: //黑名单删除
- notify['Accounts'] = friendNotice.BlackListDel_Account;
- break;
- /*case FRIEND_NOTICE_TYPE.PENDENCY_REPORT://未决已读上报
-
- break;
- case FRIEND_NOTICE_TYPE.FRIEND_UPDATE://好友数据更新
-
- break;
- */
- default:
- log.error('未知好友系统通知类型:friendNotice=' + JSON.stringify(friendNotice));
- break;
- }
-
- if (isNeedValidRepeatMsg) {
- if (type == FRIEND_NOTICE_TYPE.PENDENCY_ADD) {
- //回调
- if (onFriendSystemNotifyCallbacks[type]) onFriendSystemNotifyCallbacks[type](notify);
- }
- } else {
- //回调
- if (onFriendSystemNotifyCallbacks[type]) onFriendSystemNotifyCallbacks[type](notify);
- }
- } //loop
- };
-
- //处理新的资料系统通知
- //isNeedValidRepeatMsg 是否需要判重
- var handlerProfileSystemNotices = function(profileSystemNotices, isNeedValidRepeatMsg) {
- var profileNotice, type, notify;
- for (var k in profileSystemNotices) {
- profileNotice = profileSystemNotices[k];
- type = profileNotice.PushType;
- //当长轮询返回的群系统消息,才需要更新通知seq
- if (isNeedValidRepeatMsg == false && profileNotice.NoticeSeq && profileNotice.NoticeSeq > noticeSeq) {
- noticeSeq = profileNotice.NoticeSeq;
- }
- notify = {
- Type: type
- };
- switch (type) {
- case PROFILE_NOTICE_TYPE.PROFILE_MODIFY: //资料修改
- notify['Profile_Account'] = profileNotice.Profile_Account;
- notify['ProfileList'] = profileNotice.ProfileList;
- break;
- default:
- log.error('未知资料系统通知类型:profileNotice=' + JSON.stringify(profileNotice));
- break;
- }
-
- if (isNeedValidRepeatMsg) {
- if (type == PROFILE_NOTICE_TYPE.PROFILE_MODIFY) {
- //回调
- if (onProfileSystemNotifyCallbacks[type]) onProfileSystemNotifyCallbacks[type](notify);
- }
- } else {
- //回调
- if (onProfileSystemNotifyCallbacks[type]) onProfileSystemNotifyCallbacks[type](notify);
- }
- } //loop
- };
-
- //处理新的群系统消息(用于直播大群长轮询)
- var handlerGroupSystemMsg = function(groupTip) {
- var groupReportTypeMsg = groupTip.MsgBody;
- var reportType = groupReportTypeMsg.ReportType;
- var toAccount = groupTip.GroupInfo.To_Account;
- //过滤本不应该给自己的系统消息
- //if(!toAccount || toAccount!=ctx.identifier){
- // log.error("收到本不应该给自己的系统消息: To_Account="+toAccount);
- // continue;
- //}
- var notify = {
- SrcFlag: 1,
- ReportType: reportType,
- GroupId: groupTip.ToGroupId,
- GroupName: groupTip.GroupInfo.GroupName,
- Operator_Account: groupReportTypeMsg.Operator_Account,
- MsgTime: groupTip.MsgTimeStamp
- };
- switch (reportType) {
- case GROUP_SYSTEM_TYPE.JOIN_GROUP_REQUEST: //申请加群(只有管理员会接收到)
- notify['RemarkInfo'] = groupReportTypeMsg.RemarkInfo;
- notify['MsgKey'] = groupReportTypeMsg.MsgKey;
- notify['Authentication'] = groupReportTypeMsg.Authentication;
- notify['UserDefinedField'] = groupTip.UserDefinedField;
- notify['From_Account'] = groupTip.From_Account;
- notify['MsgSeq'] = groupTip.ClientSeq;
- notify['MsgRandom'] = groupTip.MsgRandom;
- break;
- case GROUP_SYSTEM_TYPE.JOIN_GROUP_ACCEPT: //申请加群被同意(只有申请人自己接收到)
- case GROUP_SYSTEM_TYPE.JOIN_GROUP_REFUSE: //申请加群被拒绝(只有申请人自己接收到)
- notify['RemarkInfo'] = groupReportTypeMsg.RemarkInfo;
- break;
- case GROUP_SYSTEM_TYPE.KICK: //被管理员踢出群(只有被踢者接收到)
- case GROUP_SYSTEM_TYPE.DESTORY: //群被解散(全员接收)
- case GROUP_SYSTEM_TYPE.CREATE: //创建群(创建者接收, 不展示)
- case GROUP_SYSTEM_TYPE.INVITED_JOIN_GROUP_REQUEST: //邀请加群(被邀请者接收)
- case GROUP_SYSTEM_TYPE.INVITED_JOIN_GROUP_REQUEST_AGREE: //邀请加群(被邀请者需要同意)
- case GROUP_SYSTEM_TYPE.QUIT: //主动退群(主动退出者接收, 不展示)
- case GROUP_SYSTEM_TYPE.SET_ADMIN: //群设置管理员(被设置者接收)
- case GROUP_SYSTEM_TYPE.CANCEL_ADMIN: //取消管理员(被取消者接收)
- case GROUP_SYSTEM_TYPE.REVOKE: //群已被回收(全员接收, 不展示)
- break;
- case GROUP_SYSTEM_TYPE.CUSTOM: //用户自定义通知(默认全员接收)
- notify['MsgSeq'] = groupTip.MsgSeq;
- notify['UserDefinedField'] = groupReportTypeMsg.UserDefinedField;
- break;
- default:
- log.error('未知群系统消息类型:reportType=' + reportType);
- break;
- }
- //回调
- if (onGroupSystemNotifyCallbacks[reportType]) onGroupSystemNotifyCallbacks[reportType](notify);
- };
-
- //处理C2C EVENT 消息通道Array
- var handlerC2cNotifyMsgArray = function(arr) {
- for (var i = 0, l = arr.length; i < l; i++) {
- handlerC2cEventMsg(arr[i]);
- }
- };
-
- //处理C2C EVENT 消息通道Item
- /*
- {
- "ActionStatus": "OK",
- "ErrorInfo": "",
- "ErrorCode": 0,
- "EventArray": [{
- "Event": 10,
- "C2cNotifyMsgArray": [{
- "SubMsgType": 96,
- "NoticeSeq": 2,
- "KickoutMsgNotify": {
- "To_Account": "22",
- "SdkAppid": 1400111560,
- "Instid": 537042377
- }
- }]
- }],
- "NextTimeOut": 5
- }
- */
- var handlerC2cEventMsg = function(notify) {
- console.error(notify);
- var subType = notify.SubMsgType;
- switch (subType) {
- case C2C_EVENT_SUB_TYPE.READED:
- log.warn('C2C已读消息通知');
- if (notify.ReadC2cMsgNotify && notify.ReadC2cMsgNotify.UinPairReadArray && onC2cEventCallbacks[subType]) {
- for (var i = 0, l = notify.ReadC2cMsgNotify.UinPairReadArray.length; i < l; i++) {
- var item = notify.ReadC2cMsgNotify.UinPairReadArray[i];
- onC2cEventCallbacks[subType](item);
- }
- }
- break;
- case C2C_EVENT_SUB_TYPE.KICKEDOUT:
- log.warn('多终端互踢通知');
- proto_logout('instance');
- if (onC2cEventCallbacks[subType]) {
- onC2cEventCallbacks[subType]();
- }
- break;
- default:
- log.error('未知C2c系统消息:subType=' + subType);
- break;
- }
- };
-
- //长轮询
- this.longPolling = function(cbOk, cbErr) {
- var opts = {
- Timeout: longPollingDefaultTimeOut / 1000,
- Cookie: {
- NotifySeq: notifySeq,
- NoticeSeq: noticeSeq
- }
- };
- if (LongPollingId) {
- opts.Cookie.LongPollingId = LongPollingId;
- doPolling();
- } else {
- proto_getLongPollingId({}, function(resp) {
- LongPollingId = opts.Cookie.LongPollingId = resp.LongPollingId;
- //根据回包设置超时时间,超时时长不能>60秒,因为webkit手机端的最长超时时间不能大于60s
- longPollingDefaultTimeOut = resp.Timeout > 60 ? longPollingDefaultTimeOut : resp.Timeout * 1000;
- doPolling();
- });
- }
-
- function doPolling() {
- proto_longPolling(
- opts,
- function(resp) {
- for (var i in resp.EventArray) {
- var e = resp.EventArray[i];
- switch (e.Event) {
- case LONG_POLLINNG_EVENT_TYPE.C2C: //c2c消息通知
- //更新C2C消息通知seq
- notifySeq = e.NotifySeq;
- log.warn('longpolling: received new c2c msg');
- //获取新消息
- MsgManager.syncMsgs();
- break;
- case LONG_POLLINNG_EVENT_TYPE.GROUP_COMMON: //普通群消息通知
- log.warn('longpolling: received new group msgs');
- handlerOrdinaryAndTipGroupMsgs(e.Event, e.GroupMsgArray);
- break;
- case LONG_POLLINNG_EVENT_TYPE.GROUP_TIP: //(全员广播)群提示消息
- log.warn('longpolling: received new group tips');
- handlerOrdinaryAndTipGroupMsgs(e.Event, e.GroupTips);
- break;
- case LONG_POLLINNG_EVENT_TYPE.GROUP_TIP2: //群提示消息
- log.warn('longpolling: received new group tips');
- handlerOrdinaryAndTipGroupMsgs(e.Event, e.GroupTips);
- break;
- case LONG_POLLINNG_EVENT_TYPE.GROUP_SYSTEM: //(多终端同步)群系统消息
- log.warn('longpolling: received new group system msgs');
- //false 表示 通过长轮询收到的群系统消息,可以不判重
- handlerGroupSystemMsgs(e.GroupTips, false);
- break;
- case LONG_POLLINNG_EVENT_TYPE.FRIEND_NOTICE: //好友系统通知
- log.warn('longpolling: received new friend system notice');
- //false 表示 通过长轮询收到的好友系统通知,可以不判重
- handlerFriendSystemNotices(e.FriendListMod, false);
- break;
- case LONG_POLLINNG_EVENT_TYPE.PROFILE_NOTICE: //资料系统通知
- log.warn('longpolling: received new profile system notice');
- //false 表示 通过长轮询收到的资料系统通知,可以不判重
- handlerProfileSystemNotices(e.ProfileDataMod, false);
- break;
- case LONG_POLLINNG_EVENT_TYPE.C2C_COMMON: //c2c消息通知
- noticeSeq = e.C2cMsgArray[0].NoticeSeq;
- //更新C2C消息通知seq
- log.warn('longpolling: received new c2c_common msg', noticeSeq);
- handlerOrdinaryAndTipC2cMsgs(e.Event, e.C2cMsgArray);
- break;
- case LONG_POLLINNG_EVENT_TYPE.C2C_EVENT: //c2c已读消息通知
- noticeSeq = e.C2cNotifyMsgArray[0].NoticeSeq;
- log.warn('longpolling: received new c2c_event msg');
- handlerC2cNotifyMsgArray(e.C2cNotifyMsgArray);
- break;
- default:
- log.error('longpolling收到未知新消息类型: Event=' + e.Event);
- break;
- }
- }
- var successInfo = {
- ActionStatus: ACTION_STATUS.OK,
- ErrorCode: 0
- };
- updatecLongPollingStatus(successInfo);
- },
- function(err) {
- //log.error(err);
- updatecLongPollingStatus(err);
- if (cbErr) cbErr(err);
- }
- );
- }
- };
-
- //大群 长轮询
- this.bigGroupLongPolling = function(cbOk, cbErr) {
- var GroupId = BigGroupId;
- var opts = {
- USP: 1,
- StartSeq: bigGroupLongPollingStartSeq, //请求拉消息的起始seq
- HoldTime: bigGroupLongPollingHoldTime, //客户端长轮询的超时时间,单位是秒
- Key: bigGroupLongPollingKey //客户端加入群组后收到的的Key
- };
-
- proto_bigGroupLongPolling(
- opts,
- function(resp) {
- if (GroupId != BigGroupId) return;
-
- var msgObjList = [];
- bigGroupLongPollingStartSeq = resp.NextSeq;
- bigGroupLongPollingHoldTime = resp.HoldTime;
- bigGroupLongPollingKey = resp.Key;
-
- if (resp.RspMsgList && resp.RspMsgList.length > 0) {
- var msgCount = 0,
- msgInfo,
- event,
- msg;
- for (var i = resp.RspMsgList.length - 1; i >= 0; i--) {
- msgInfo = resp.RspMsgList[i];
- //后台这里做了调整,缩短字段名,以下是兼容代码
- var keyMap = {
- F_Account: 'From_Account',
- T_Account: 'To_Account',
- FAType: 'EnumFrom_AccountType',
- TAType: 'EnumTo_AccountType',
- GCode: 'GroupCode',
- GName: 'GroupName',
- GId: 'GroupId',
- MFlg: 'MsgFlag',
- FAEInfo: 'MsgFrom_AccountExtraInfo',
- Evt: 'Event',
- GInfo: 'GroupInfo',
- BPlc: 'IsPlaceMsg',
- MBody: 'MsgBody',
- Pri: 'MsgPriority',
- Rdm: 'MsgRandom',
- MSeq: 'MsgSeq',
- TStp: 'MsgTimeStamp',
- TGId: 'ToGroupId',
- UEInfo: 'UinExtInfo',
- UId: 'UserId',
- BSys: 'IsSystemMsg',
- FAHUrl: 'From_AccountHeadurl',
- FANick: 'From_AccountNick'
- };
- msgInfo = tool.replaceObject(keyMap, msgInfo);
- //如果是已经删除的消息或者发送者帐号为空或者消息内容为空
- //IsPlaceMsg=1
- if (msgInfo.IsPlaceMsg || !msgInfo.From_Account || !msgInfo.MsgBody || msgInfo.MsgBody.length == 0) {
- continue;
- }
-
- event = msgInfo.Event; //群消息类型
- switch (event) {
- case LONG_POLLINNG_EVENT_TYPE.GROUP_COMMON: //群普通消息
- log.info('bigGroupLongPolling: return new group msg');
- msg = handlerGroupMsg(msgInfo, false, false);
- msg && msgObjList.push(msg);
- msgCount = msgCount + 1;
- break;
- case LONG_POLLINNG_EVENT_TYPE.GROUP_TIP: //群提示消息
- case LONG_POLLINNG_EVENT_TYPE.GROUP_TIP2: //群提示消息
- log.info('bigGroupLongPolling: return new group tip');
- msg = handlerGroupMsg(msgInfo, false, false);
- msg && msgObjList.push(msg);
- //msgCount=msgCount+1;
- break;
- case LONG_POLLINNG_EVENT_TYPE.GROUP_SYSTEM: //群系统消息
- log.info('bigGroupLongPolling: new group system msg');
- handlerGroupSystemMsg(msgInfo);
- break;
- default:
- log.error('bigGroupLongPolling收到未知新消息类型: Event=' + event);
- break;
- }
- } // for loop
- if (msgCount > 0) {
- MsgManager.setBigGroupLongPollingMsgMap(msgInfo.ToGroupId, msgCount); //
- log.warn('current bigGroupLongPollingMsgMap: ' + JSON.stringify(bigGroupLongPollingMsgMap));
- }
- }
- curBigGroupLongPollingRetErrorCount = 0;
- //返回连接状态
- var successInfo = {
- ActionStatus: ACTION_STATUS.OK,
- ErrorCode: CONNECTION_STATUS.ON,
- ErrorInfo: 'connection is ok...'
- };
- ConnManager.callBack(successInfo);
-
- if (cbOk) cbOk(msgObjList);
- else if (onBigGroupMsgCallback) onBigGroupMsgCallback(msgObjList); //返回新消息
-
- //重新启动长轮询
- bigGroupLongPollingOn && MsgManager.bigGroupLongPolling();
- },
- function(err) {
- if (err.ErrorCode == longPollingPackageTooLargeErrorCode) {
- bigGroupLongPollingStartSeq = 0;
- } else if (err.ErrorCode != longPollingTimeOutErrorCode) {
- log.error(err.ErrorInfo);
- //记录长轮询返回错误次数
- curBigGroupLongPollingRetErrorCount++;
- }
- if (err.ErrorCode == longPollingKickedErrorCode) {
- //登出
- log.error('多实例登录,被kick');
- if (onKickedEventCall) {
- onKickedEventCall();
- }
- }
- //累计超过一定次数,不再发起长轮询请求
- if (curBigGroupLongPollingRetErrorCount < LONG_POLLING_MAX_RET_ERROR_COUNT) {
- bigGroupLongPollingOn && MsgManager.bigGroupLongPolling();
- } else {
- var errInfo = {
- ActionStatus: ACTION_STATUS.FAIL,
- ErrorCode: CONNECTION_STATUS.OFF,
- ErrorInfo: 'connection is off'
- };
- ConnManager.callBack(errInfo);
- }
- if (cbErr) cbErr(err);
- },
- bigGroupLongPollingHoldTime * 1000
- );
- };
-
- //更新连接状态
- var updatecLongPollingStatus = function(errObj) {
- if (errObj.ErrorCode == 0 || errObj.ErrorCode == longPollingTimeOutErrorCode) {
- curLongPollingRetErrorCount = 0;
- longPollingOffCallbackFlag = false;
- var errorInfo;
- var isNeedCallback = false;
- switch (curLongPollingStatus) {
- case CONNECTION_STATUS.INIT:
- isNeedCallback = true;
- curLongPollingStatus = CONNECTION_STATUS.ON;
- errorInfo = 'create connection successfully(INIT->ON)';
- break;
- case CONNECTION_STATUS.ON:
- errorInfo = 'connection is on...(ON->ON)';
- break;
- case CONNECTION_STATUS.RECONNECT:
- curLongPollingStatus = CONNECTION_STATUS.ON;
- errorInfo = 'connection is on...(RECONNECT->ON)';
- break;
- case CONNECTION_STATUS.OFF:
- isNeedCallback = true;
- curLongPollingStatus = CONNECTION_STATUS.RECONNECT;
- errorInfo = 'reconnect successfully(OFF->RECONNECT)';
- break;
- }
- var successInfo = {
- ActionStatus: ACTION_STATUS.OK,
- ErrorCode: curLongPollingStatus,
- ErrorInfo: errorInfo
- };
- isNeedCallback && ConnManager.callBack(successInfo);
- longPollingOn && MsgManager.longPolling();
- } else if (errObj.ErrorCode == longPollingKickedErrorCode) {
- //登出
- log.error('多实例登录,被kick');
- if (onKickedEventCall) {
- onKickedEventCall();
- }
- } else {
- //记录长轮询返回解析json错误次数
- curLongPollingRetErrorCount++;
- log.warn('longPolling接口第' + curLongPollingRetErrorCount + '次报错: ' + errObj.ErrorInfo);
- //累计超过一定次数
- if (curLongPollingRetErrorCount <= LONG_POLLING_MAX_RET_ERROR_COUNT) {
- setTimeout(startNextLongPolling, 100); //
- } else {
- curLongPollingStatus = CONNECTION_STATUS.OFF;
- var errInfo = {
- ActionStatus: ACTION_STATUS.FAIL,
- ErrorCode: CONNECTION_STATUS.OFF,
- ErrorInfo: 'connection is off'
- };
- longPollingOffCallbackFlag == false && ConnManager.callBack(errInfo);
- longPollingOffCallbackFlag = true;
- log.warn(longPollingIntervalTime + '毫秒之后,SDK会发起新的longPolling请求...');
- setTimeout(startNextLongPolling, longPollingIntervalTime); //长轮询接口报错次数达到一定值,每间隔5s发起新的长轮询
- }
- }
- };
-
- //处理收到的普通C2C消息
- var handlerOrdinaryAndTipC2cMsgs = function(eventType, C2cMsgArray) {
- //处理c2c消息
- var notifyInfo = [];
- var msgInfos = [];
- msgInfos = C2cMsgArray; //返回的消息列表
- // MsgStore.cookie = resp.Cookie;//cookies,记录当前读到的最新消息位置
-
- for (var i in msgInfos) {
- var msgInfo = msgInfos[i];
- var isSendMsg, id;
- var headUrl = msgInfo.From_AccountHeadurl || '';
- if (msgInfo.From_Account == ctx.identifier) {
- //当前用户发送的消息
- isSendMsg = true;
- id = msgInfo.To_Account; //读取接收者信息
- } else {
- //当前用户收到的消息
- isSendMsg = false;
- id = msgInfo.From_Account; //读取发送者信息
- }
- var sess = MsgStore.sessByTypeId(SESSION_TYPE.C2C, id);
- if (!sess) {
- sess = new Session(SESSION_TYPE.C2C, id, id, headUrl, 0, 0);
- }
- var msg = new Msg(
- sess,
- isSendMsg,
- msgInfo.MsgSeq,
- msgInfo.MsgRandom,
- msgInfo.MsgTimeStamp,
- msgInfo.From_Account,
- C2C_MSG_SUB_TYPE.COMMON,
- msgInfo.From_AccountNick,
- headUrl
- );
- var msgBody = null;
- var msgContent = null;
- var msgType = null;
- for (var mi in msgInfo.MsgBody) {
- msgBody = msgInfo.MsgBody[mi];
- msgType = msgBody.MsgType;
- switch (msgType) {
- case MSG_ELEMENT_TYPE.TEXT:
- msgContent = new Msg.Elem.Text(msgBody.MsgContent.Text);
- break;
- case MSG_ELEMENT_TYPE.FACE:
- msgContent = new Msg.Elem.Face(msgBody.MsgContent.Index, msgBody.MsgContent.Data);
- break;
- case MSG_ELEMENT_TYPE.IMAGE:
- msgContent = new Msg.Elem.Images(msgBody.MsgContent.UUID, msgBody.MsgContent.ImageFormat || '');
- for (var j in msgBody.MsgContent.ImageInfoArray) {
- var tempImg = msgBody.MsgContent.ImageInfoArray[j];
- msgContent.addImage(new Msg.Elem.Images.Image(tempImg.Type, tempImg.Size, tempImg.Width, tempImg.Height, tempImg.URL));
- }
- break;
- case MSG_ELEMENT_TYPE.SOUND:
- if (msgBody.MsgContent) {
- msgContent = new Msg.Elem.Sound(
- msgBody.MsgContent.UUID,
- msgBody.MsgContent.Second,
- msgBody.MsgContent.Size,
- msgInfo.From_Account,
- msgInfo.To_Account,
- msgBody.MsgContent.Download_Flag,
- SESSION_TYPE.C2C
- );
- } else {
- msgType = MSG_ELEMENT_TYPE.TEXT;
- msgContent = new Msg.Elem.Text('[语音消息]下载地址解析出错');
- }
- break;
- case MSG_ELEMENT_TYPE.LOCATION:
- msgContent = new Msg.Elem.Location(msgBody.MsgContent.Longitude, msgBody.MsgContent.Latitude, msgBody.MsgContent.Desc);
- break;
- case MSG_ELEMENT_TYPE.FILE:
- case MSG_ELEMENT_TYPE.FILE + ' ':
- msgType = MSG_ELEMENT_TYPE.FILE;
- if (msgBody.MsgContent) {
- msgContent = new Msg.Elem.File(
- msgBody.MsgContent.UUID,
- msgBody.MsgContent.FileName,
- msgBody.MsgContent.FileSize,
- msgInfo.From_Account,
- msgInfo.To_Account,
- msgBody.MsgContent.Download_Flag,
- SESSION_TYPE.C2C
- );
- } else {
- msgType = MSG_ELEMENT_TYPE.TEXT;
- msgContent = new Msg.Elem.Text('[文件消息下载地址解析出错]');
- }
- break;
- case MSG_ELEMENT_TYPE.CUSTOM:
- try {
- var data = JSON.parse(msgBody.MsgContent.Data);
- if (data && data.userAction && data.userAction == FRIEND_WRITE_MSG_ACTION.ING) {
- //过滤安卓或ios的正在输入自定义消息
- continue;
- }
- } catch (e) {}
-
- msgType = MSG_ELEMENT_TYPE.CUSTOM;
- msgContent = new Msg.Elem.Custom(msgBody.MsgContent.Data, msgBody.MsgContent.Desc, msgBody.MsgContent.Ext);
- break;
- default:
- msgType = MSG_ELEMENT_TYPE.TEXT;
- msgContent = new Msg.Elem.Text('web端暂不支持' + msgBody.MsgType + '消息');
- break;
- }
- msg.elems.push(new Msg.Elem(msgType, msgContent));
- }
-
- if (msg.elems.length > 0 && MsgStore.addMsg(msg, true)) {
- notifyInfo.push(msg);
- }
- } // for loop
- if (notifyInfo.length > 0) MsgStore.updateTimeline();
- if (notifyInfo.length > 0) {
- if (onMsgCallback) onMsgCallback(notifyInfo);
- }
- };
-
- //发起新的长轮询请求
- var startNextLongPolling = function() {
- longPollingOn && MsgManager.longPolling();
- };
-
- //处理未决的加群申请消息列表
- var handlerApplyJoinGroupSystemMsgs = function(eventArray) {
- for (var i in eventArray) {
- var e = eventArray[i];
- handlerGroupSystemMsgs(e.GroupTips, true);
- switch (e.Event) {
- case LONG_POLLINNG_EVENT_TYPE.GROUP_SYSTEM: //(多终端同步)群系统消息
- log.warn('handlerApplyJoinGroupSystemMsgs: handler new group system msg');
- //true 表示 解决加群申请通知存在重复的问题(已处理的通知,下次登录还会拉到),需要判重
- handlerGroupSystemMsgs(e.GroupTips, true);
- break;
- default:
- log.error('syncMsgs收到未知的群系统消息类型: Event=' + e.Event);
- break;
- }
- }
- };
-
- //拉取c2c消息(包含加群未决消息,需要处理)
- this.syncMsgs = function(cbOk, cbErr) {
- var notifyInfo = [];
- var msgInfos = [];
- //读取C2C消息
- proto_getMsgs(
- MsgStore.cookie,
- MsgStore.syncFlag,
- function(resp) {
- //拉取完毕
- if (resp.SyncFlag == 2) {
- MsgStore.syncFlag = 0;
- }
- //处理c2c消息
- msgInfos = resp.MsgList; //返回的消息列表
- MsgStore.cookie = resp.Cookie; //cookies,记录当前读到的最新消息位置
-
- for (var i in msgInfos) {
- var msgInfo = msgInfos[i];
- var isSendMsg, id, headUrl;
- if (msgInfo.From_Account == ctx.identifier) {
- //当前用户发送的消息
- isSendMsg = true;
- id = msgInfo.To_Account; //读取接收者信息
- headUrl = '';
- } else {
- //当前用户收到的消息
- isSendMsg = false;
- id = msgInfo.From_Account; //读取发送者信息
- headUrl = '';
- }
- var sess = MsgStore.sessByTypeId(SESSION_TYPE.C2C, id);
- if (!sess) {
- sess = new Session(SESSION_TYPE.C2C, id, id, headUrl, 0, 0);
- }
- var msg = new Msg(
- sess,
- isSendMsg,
- msgInfo.MsgSeq,
- msgInfo.MsgRandom,
- msgInfo.MsgTimeStamp,
- msgInfo.From_Account,
- C2C_MSG_SUB_TYPE.COMMON,
- msgInfo.From_AccountNick,
- msgInfo.From_AccountHeadurl
- );
- var msgBody = null;
- var msgContent = null;
- var msgType = null;
- for (var mi in msgInfo.MsgBody) {
- msgBody = msgInfo.MsgBody[mi];
- msgType = msgBody.MsgType;
- switch (msgType) {
- case MSG_ELEMENT_TYPE.TEXT:
- msgContent = new Msg.Elem.Text(msgBody.MsgContent.Text);
- break;
- case MSG_ELEMENT_TYPE.FACE:
- msgContent = new Msg.Elem.Face(msgBody.MsgContent.Index, msgBody.MsgContent.Data);
- break;
- case MSG_ELEMENT_TYPE.IMAGE:
- msgContent = new Msg.Elem.Images(msgBody.MsgContent.UUID, msgBody.MsgContent.ImageFormat);
- for (var j in msgBody.MsgContent.ImageInfoArray) {
- var tempImg = msgBody.MsgContent.ImageInfoArray[j];
- msgContent.addImage(new Msg.Elem.Images.Image(tempImg.Type, tempImg.Size, tempImg.Width, tempImg.Height, tempImg.URL));
- }
- break;
- case MSG_ELEMENT_TYPE.SOUND:
- // var soundUrl = getSoundDownUrl(msgBody.MsgContent.UUID, msgInfo.From_Account);
- if (msgBody.MsgContent) {
- msgContent = new Msg.Elem.Sound(
- msgBody.MsgContent.UUID,
- msgBody.MsgContent.Second,
- msgBody.MsgContent.Size,
- msgInfo.From_Account,
- msgInfo.To_Account,
- msgBody.MsgContent.Download_Flag,
- SESSION_TYPE.C2C
- );
- } else {
- msgType = MSG_ELEMENT_TYPE.TEXT;
- msgContent = new Msg.Elem.Text('[语音消息]下载地址解析出错');
- }
- break;
- case MSG_ELEMENT_TYPE.LOCATION:
- msgContent = new Msg.Elem.Location(msgBody.MsgContent.Longitude, msgBody.MsgContent.Latitude, msgBody.MsgContent.Desc);
- break;
- case MSG_ELEMENT_TYPE.FILE:
- case MSG_ELEMENT_TYPE.FILE + ' ':
- msgType = MSG_ELEMENT_TYPE.FILE;
- // var fileUrl = getFileDownUrl(msgBody.MsgContent.UUID, msgInfo.From_Account, msgBody.MsgContent.FileName);
- if (msgBody.MsgContent) {
- msgContent = new Msg.Elem.File(
- msgBody.MsgContent.UUID,
- msgBody.MsgContent.FileName,
- msgBody.MsgContent.FileSize,
- msgInfo.From_Account,
- msgInfo.To_Account,
- msgBody.MsgContent.Download_Flag,
- SESSION_TYPE.C2C
- );
- } else {
- msgType = MSG_ELEMENT_TYPE.TEXT;
- msgContent = new Msg.Elem.Text('[文件消息下载地址解析出错]');
- }
- break;
- case MSG_ELEMENT_TYPE.CUSTOM:
- try {
- var data = JSON.parse(msgBody.MsgContent.Data);
- if (data && data.userAction && data.userAction == FRIEND_WRITE_MSG_ACTION.ING) {
- //过滤安卓或ios的正在输入自定义消息
- continue;
- }
- } catch (e) {}
-
- msgType = MSG_ELEMENT_TYPE.CUSTOM;
- msgContent = new Msg.Elem.Custom(msgBody.MsgContent.Data, msgBody.MsgContent.Desc, msgBody.MsgContent.Ext);
- break;
- default:
- msgType = MSG_ELEMENT_TYPE.TEXT;
- msgContent = new Msg.Elem.Text('web端暂不支持' + msgBody.MsgType + '消息');
- break;
- }
- msg.elems.push(new Msg.Elem(msgType, msgContent));
- }
-
- if (msg.elems.length > 0 && MsgStore.addMsg(msg, true)) {
- notifyInfo.push(msg);
- }
- } // for loop
-
- //处理加群未决申请消息
- handlerApplyJoinGroupSystemMsgs(resp.EventArray);
-
- if (notifyInfo.length > 0) MsgStore.updateTimeline();
- if (cbOk) cbOk(notifyInfo);
- else if (notifyInfo.length > 0) {
- if (onMsgCallback) onMsgCallback(notifyInfo);
- }
- },
- function(err) {
- log.error('getMsgs failed:' + err.ErrorInfo);
- if (cbErr) cbErr(err);
- }
- );
- };
-
- //拉取C2C漫游消息
- this.getC2CHistoryMsgs = function(options, cbOk, cbErr) {
- if (!options.Peer_Account) {
- if (cbErr) {
- cbErr(tool.getReturnError('Peer_Account is empty', -13));
- return;
- }
- }
- if (!options.MaxCnt) {
- options.MaxCnt = 15;
- }
- if (options.MaxCnt <= 0) {
- if (cbErr) {
- cbErr(tool.getReturnError('MaxCnt should be greater than 0', -14));
- return;
- }
- }
- if (options.MaxCnt > 15) {
- if (cbErr) {
- cbErr(tool.getReturnError('MaxCnt can not be greater than 15', -15));
- return;
- }
- return;
- }
- if (options.MsgKey == null || options.MsgKey === undefined) {
- options.MsgKey = '';
- }
- var opts = {
- Peer_Account: options.Peer_Account,
- MaxCnt: options.MaxCnt,
- LastMsgTime: options.LastMsgTime,
- MsgKey: options.MsgKey
- };
- //读取c2c漫游消息
- proto_getC2CHistoryMsgs(
- opts,
- function(resp) {
- var msgObjList = [];
- var msgInfos = [];
- //处理c2c消息
- msgInfos = resp.MsgList; //返回的消息列表
- var sess = MsgStore.sessByTypeId(SESSION_TYPE.C2C, options.Peer_Account);
- if (!sess) {
- sess = new Session(SESSION_TYPE.C2C, options.Peer_Account, options.Peer_Account, '', 0, 0);
- }
- for (var i in msgInfos) {
- var msgInfo = msgInfos[i];
- var isSendMsg, id;
- var headUrl = msgInfo.From_AccountHeadurl || '';
- if (msgInfo.From_Account == ctx.identifier) {
- //当前用户发送的消息
- isSendMsg = true;
- id = msgInfo.To_Account; //读取接收者信息
- } else {
- //当前用户收到的消息
- isSendMsg = false;
- id = msgInfo.From_Account; //读取发送者信息
- }
- var msg = new Msg(
- sess,
- isSendMsg,
- msgInfo.MsgSeq,
- msgInfo.MsgRandom,
- msgInfo.MsgTimeStamp,
- msgInfo.From_Account,
- C2C_MSG_SUB_TYPE.COMMON,
- msgInfo.From_AccountNick,
- headUrl
- );
- var msgBody = null;
- var msgContent = null;
- var msgType = null;
- for (var mi in msgInfo.MsgBody) {
- msgBody = msgInfo.MsgBody[mi];
- msgType = msgBody.MsgType;
- switch (msgType) {
- case MSG_ELEMENT_TYPE.TEXT:
- msgContent = new Msg.Elem.Text(msgBody.MsgContent.Text);
- break;
- case MSG_ELEMENT_TYPE.FACE:
- msgContent = new Msg.Elem.Face(msgBody.MsgContent.Index, msgBody.MsgContent.Data);
- break;
- case MSG_ELEMENT_TYPE.IMAGE:
- msgContent = new Msg.Elem.Images(msgBody.MsgContent.UUID, msgBody.MsgContent.ImageFormat);
- for (var j in msgBody.MsgContent.ImageInfoArray) {
- var tempImg = msgBody.MsgContent.ImageInfoArray[j];
- msgContent.addImage(new Msg.Elem.Images.Image(tempImg.Type, tempImg.Size, tempImg.Width, tempImg.Height, tempImg.URL));
- }
- break;
- case MSG_ELEMENT_TYPE.SOUND:
- // var soundUrl = getSoundDownUrl(msgBody.MsgContent.UUID, msgInfo.From_Account);
-
- if (msgBody.MsgContent) {
- msgContent = new Msg.Elem.Sound(
- msgBody.MsgContent.UUID,
- msgBody.MsgContent.Second,
- msgBody.MsgContent.Size,
- msgInfo.From_Account,
- msgInfo.To_Account,
- msgBody.MsgContent.Download_Flag,
- SESSION_TYPE.C2C
- );
- } else {
- msgType = MSG_ELEMENT_TYPE.TEXT;
- msgContent = new Msg.Elem.Text('[语音消息]下载地址解析出错');
- }
- break;
- case MSG_ELEMENT_TYPE.LOCATION:
- msgContent = new Msg.Elem.Location(msgBody.MsgContent.Longitude, msgBody.MsgContent.Latitude, msgBody.MsgContent.Desc);
- break;
- case MSG_ELEMENT_TYPE.FILE:
- case MSG_ELEMENT_TYPE.FILE + ' ':
- msgType = MSG_ELEMENT_TYPE.FILE;
- // var fileUrl = getFileDownUrl(msgBody.MsgContent.UUID, msgInfo.From_Account, msgBody.MsgContent.FileName);
-
- if (msgBody.MsgContent) {
- msgContent = new Msg.Elem.File(
- msgBody.MsgContent.UUID,
- msgBody.MsgContent.FileName,
- msgBody.MsgContent.FileSize,
- msgInfo.From_Account,
- msgInfo.To_Account,
- msgBody.MsgContent.Download_Flag,
- SESSION_TYPE.C2C
- );
- } else {
- msgType = MSG_ELEMENT_TYPE.TEXT;
- msgContent = new Msg.Elem.Text('[文件消息下载地址解析出错]');
- }
- break;
- case MSG_ELEMENT_TYPE.CUSTOM:
- msgType = MSG_ELEMENT_TYPE.CUSTOM;
- msgContent = new Msg.Elem.Custom(msgBody.MsgContent.Data, msgBody.MsgContent.Desc, msgBody.MsgContent.Ext);
-
- break;
- default:
- msgType = MSG_ELEMENT_TYPE.TEXT;
- msgContent = new Msg.Elem.Text('web端暂不支持' + msgBody.MsgType + '消息');
- break;
- }
- msg.elems.push(new Msg.Elem(msgType, msgContent));
- }
- MsgStore.addMsg(msg);
- msgObjList.push(msg);
- } // for loop
-
- MsgStore.updateTimeline();
- if (cbOk) {
- var newResp = {
- Complete: resp.Complete,
- MsgCount: msgObjList.length,
- LastMsgTime: resp.LastMsgTime,
- MsgKey: resp.MsgKey,
- MsgList: msgObjList
- };
- sess.isFinished(resp.Complete);
- cbOk(newResp);
- }
- },
- function(err) {
- log.error('getC2CHistoryMsgs failed:' + err.ErrorInfo);
- if (cbErr) cbErr(err);
- }
- );
- };
-
- //拉群历史消息
- //不传cbOk 和 cbErr,则会调用新消息回调函数
- this.syncGroupMsgs = function(options, cbOk, cbErr) {
- if (options.ReqMsgSeq <= 0) {
- if (cbErr) {
- var errInfo = 'ReqMsgSeq must be greater than 0';
- var error = tool.getReturnError(errInfo, -16);
- cbErr(error);
- }
- return;
- }
- var opts = {
- GroupId: options.GroupId,
- ReqMsgSeq: options.ReqMsgSeq,
- ReqMsgNumber: options.ReqMsgNumber
- };
- //读群漫游消息
- proto_getGroupMsgs(
- opts,
- function(resp) {
- var notifyInfo = [];
- var group_id = resp.GroupId; //返回的群id
- var msgInfos = resp.RspMsgList; //返回的消息列表
- var isFinished = resp.IsFinished;
-
- if (msgInfos == null || msgInfos === undefined) {
- if (cbOk) {
- cbOk([]);
- }
- return;
- }
- for (var i = msgInfos.length - 1; i >= 0; i--) {
- var msgInfo = msgInfos[i];
- //如果是已经删除的消息或者发送者帐号为空或者消息内容为空
- //IsPlaceMsg=1
- if (msgInfo.IsPlaceMsg || !msgInfo.From_Account || !msgInfo.MsgBody || msgInfo.MsgBody.length == 0) {
- continue;
- }
- var msg = handlerGroupMsg(msgInfo, true, true, isFinished);
- if (msg) {
- notifyInfo.push(msg);
- }
- } // for loop
- if (notifyInfo.length > 0) MsgStore.updateTimeline();
- if (cbOk) cbOk(notifyInfo);
- else if (notifyInfo.length > 0) {
- if (onMsgCallback) onMsgCallback(notifyInfo);
- }
- },
- function(err) {
- log.error('getGroupMsgs failed:' + err.ErrorInfo);
- if (cbErr) cbErr(err);
- }
- );
- };
-
- //处理群消息(普通消息+提示消息)
- //isSyncGroupMsgs 是否主动拉取群消息标志
- //isAddMsgFlag 是否需要保存到MsgStore,如果需要,这里会存在判重逻辑
- var handlerGroupMsg = function(msgInfo, isSyncGroupMsgs, isAddMsgFlag, isFinished) {
- if (msgInfo.IsPlaceMsg || !msgInfo.From_Account || !msgInfo.MsgBody || msgInfo.MsgBody.length == 0) {
- return null;
- }
- var isSendMsg, id, headUrl, fromAccountNick, fromAccountHeadurl;
- var group_id = msgInfo.ToGroupId;
- var group_name = group_id;
- if (msgInfo.GroupInfo) {
- //取出群名称
- if (msgInfo.GroupInfo.GroupName) {
- group_name = msgInfo.GroupInfo.GroupName;
- }
- }
- //取出成员昵称
- fromAccountNick = msgInfo.From_Account;
- //fromAccountHeadurl = msgInfo.GroupInfo.From_AccountHeadurl;
- if (msgInfo.GroupInfo) {
- if (msgInfo.GroupInfo.From_AccountNick) {
- fromAccountNick = msgInfo.GroupInfo.From_AccountNick;
- }
- if (msgInfo.GroupInfo.From_AccountHeadurl) {
- fromAccountHeadurl = msgInfo.GroupInfo.From_AccountHeadurl;
- } else {
- fromAccountHeadurl = null;
- }
- }
- if (msgInfo.From_Account == ctx.identifier) {
- //当前用户发送的消息
- isSendMsg = true;
- id = msgInfo.From_Account; //读取接收者信息
- headUrl = '';
- } else {
- //当前用户收到的消息
- isSendMsg = false;
- id = msgInfo.From_Account; //读取发送者信息
- headUrl = '';
- }
- var sess = MsgStore.sessByTypeId(SESSION_TYPE.GROUP, group_id);
- if (!sess) {
- sess = new Session(SESSION_TYPE.GROUP, group_id, group_name, headUrl, 0, 0);
- }
- if (typeof isFinished !== 'undefined') {
- sess.isFinished(isFinished || 0);
- }
- var subType = GROUP_MSG_SUB_TYPE.COMMON; //消息类型
- //群提示消息,重新封装下
- if (LONG_POLLINNG_EVENT_TYPE.GROUP_TIP == msgInfo.Event || LONG_POLLINNG_EVENT_TYPE.GROUP_TIP2 == msgInfo.Event) {
- subType = GROUP_MSG_SUB_TYPE.TIP;
- var groupTip = msgInfo.MsgBody;
- msgInfo.MsgBody = [];
- msgInfo.MsgBody.push({
- MsgType: MSG_ELEMENT_TYPE.GROUP_TIP,
- MsgContent: groupTip
- });
- } else if (msgInfo.MsgPriority) {
- //群点赞消息
- if (msgInfo.MsgPriority == GROUP_MSG_PRIORITY_TYPE.REDPACKET) {
- subType = GROUP_MSG_SUB_TYPE.REDPACKET;
- } else if (msgInfo.MsgPriority == GROUP_MSG_PRIORITY_TYPE.LOVEMSG) {
- subType = GROUP_MSG_SUB_TYPE.LOVEMSG;
- }
- }
- var msg = new Msg(
- sess,
- isSendMsg,
- msgInfo.MsgSeq,
- msgInfo.MsgRandom,
- msgInfo.MsgTimeStamp,
- msgInfo.From_Account,
- subType,
- fromAccountNick,
- fromAccountHeadurl
- );
- var msgBody = null;
- var msgContent = null;
- var msgType = null;
- for (var mi in msgInfo.MsgBody) {
- msgBody = msgInfo.MsgBody[mi];
- msgType = msgBody.MsgType;
- switch (msgType) {
- case MSG_ELEMENT_TYPE.TEXT:
- msgContent = new Msg.Elem.Text(msgBody.MsgContent.Text);
- break;
- case MSG_ELEMENT_TYPE.FACE:
- msgContent = new Msg.Elem.Face(msgBody.MsgContent.Index, msgBody.MsgContent.Data);
- break;
- case MSG_ELEMENT_TYPE.IMAGE:
- msgContent = new Msg.Elem.Images(msgBody.MsgContent.UUID, msgBody.MsgContent.ImageFormat || '');
- for (var j in msgBody.MsgContent.ImageInfoArray) {
- msgContent.addImage(
- new Msg.Elem.Images.Image(
- msgBody.MsgContent.ImageInfoArray[j].Type,
- msgBody.MsgContent.ImageInfoArray[j].Size,
- msgBody.MsgContent.ImageInfoArray[j].Width,
- msgBody.MsgContent.ImageInfoArray[j].Height,
- msgBody.MsgContent.ImageInfoArray[j].URL
- )
- );
- }
- break;
- case MSG_ELEMENT_TYPE.SOUND:
- if (msgBody.MsgContent) {
- msgContent = new Msg.Elem.Sound(
- msgBody.MsgContent.UUID,
- msgBody.MsgContent.Second,
- msgBody.MsgContent.Size,
- msgInfo.From_Account,
- msgInfo.To_Account,
- msgBody.MsgContent.Download_Flag,
- SESSION_TYPE.GROUP
- );
- } else {
- msgType = MSG_ELEMENT_TYPE.TEXT;
- msgContent = new Msg.Elem.Text('[语音消息]下载地址解析出错');
- }
- break;
- case MSG_ELEMENT_TYPE.LOCATION:
- msgContent = new Msg.Elem.Location(msgBody.MsgContent.Longitude, msgBody.MsgContent.Latitude, msgBody.MsgContent.Desc);
- break;
- case MSG_ELEMENT_TYPE.FILE:
- case MSG_ELEMENT_TYPE.FILE + ' ':
- msgType = MSG_ELEMENT_TYPE.FILE;
- var fileUrl = getFileDownUrl(msgBody.MsgContent.UUID, msgInfo.From_Account, msgBody.MsgContent.FileName);
-
- if (msgBody.MsgContent) {
- msgContent = new Msg.Elem.File(
- msgBody.MsgContent.UUID,
- msgBody.MsgContent.FileName,
- msgBody.MsgContent.FileSize,
- msgInfo.From_Account,
- msgInfo.To_Account,
- msgBody.MsgContent.Download_Flag,
- SESSION_TYPE.GROUP
- );
- } else {
- msgType = MSG_ELEMENT_TYPE.TEXT;
- msgContent = new Msg.Elem.Text('[文件消息]地址解析出错');
- }
- break;
- case MSG_ELEMENT_TYPE.GROUP_TIP:
- var opType = msgBody.MsgContent.OpType;
- msgContent = new Msg.Elem.GroupTip(
- opType,
- msgBody.MsgContent.Operator_Account,
- group_id,
- msgInfo.GroupInfo.GroupName,
- msgBody.MsgContent.List_Account,
- msgBody.MsgContent.MsgMemberExtraInfo
- );
- if (GROUP_TIP_TYPE.JOIN == opType || GROUP_TIP_TYPE.QUIT == opType) {
- //加群或退群时,设置最新群成员数
- msgContent.setGroupMemberNum(msgBody.MsgContent.MemberNum);
- } else if (GROUP_TIP_TYPE.MODIFY_GROUP_INFO == opType) {
- //群资料变更
- var tempIsCallbackFlag = false;
- var tempNewGroupInfo = {
- GroupId: group_id,
- GroupFaceUrl: null,
- GroupName: null,
- OwnerAccount: null,
- GroupNotification: null,
- GroupIntroduction: null
- };
- var msgGroupNewInfo = msgBody.MsgContent.MsgGroupNewInfo;
- if (msgGroupNewInfo.GroupFaceUrl) {
- var tmpNGIFaceUrl = new Msg.Elem.GroupTip.GroupInfo(GROUP_TIP_MODIFY_GROUP_INFO_TYPE.FACE_URL, msgGroupNewInfo.GroupFaceUrl);
- msgContent.addGroupInfo(tmpNGIFaceUrl);
- tempIsCallbackFlag = true;
- tempNewGroupInfo.GroupFaceUrl = msgGroupNewInfo.GroupFaceUrl;
- }
- if (msgGroupNewInfo.GroupName) {
- var tmpNGIName = new Msg.Elem.GroupTip.GroupInfo(GROUP_TIP_MODIFY_GROUP_INFO_TYPE.NAME, msgGroupNewInfo.GroupName);
- msgContent.addGroupInfo(tmpNGIName);
- tempIsCallbackFlag = true;
- tempNewGroupInfo.GroupName = msgGroupNewInfo.GroupName;
- }
- if (msgGroupNewInfo.Owner_Account) {
- var tmpNGIOwner = new Msg.Elem.GroupTip.GroupInfo(GROUP_TIP_MODIFY_GROUP_INFO_TYPE.OWNER, msgGroupNewInfo.Owner_Account);
- msgContent.addGroupInfo(tmpNGIOwner);
- tempIsCallbackFlag = true;
- tempNewGroupInfo.OwnerAccount = msgGroupNewInfo.Owner_Account;
- }
- if (msgGroupNewInfo.GroupNotification) {
- var tmpNGINotification = new Msg.Elem.GroupTip.GroupInfo(
- GROUP_TIP_MODIFY_GROUP_INFO_TYPE.NOTIFICATION,
- msgGroupNewInfo.GroupNotification
- );
- msgContent.addGroupInfo(tmpNGINotification);
- tempIsCallbackFlag = true;
- tempNewGroupInfo.GroupNotification = msgGroupNewInfo.GroupNotification;
- }
- if (msgGroupNewInfo.GroupIntroduction) {
- var tmpNGIIntroduction = new Msg.Elem.GroupTip.GroupInfo(
- GROUP_TIP_MODIFY_GROUP_INFO_TYPE.INTRODUCTION,
- msgGroupNewInfo.GroupIntroduction
- );
- msgContent.addGroupInfo(tmpNGIIntroduction);
- tempIsCallbackFlag = true;
- tempNewGroupInfo.GroupIntroduction = msgGroupNewInfo.GroupIntroduction;
- }
-
- //回调群资料变化通知方法
- if (isSyncGroupMsgs == false && tempIsCallbackFlag && onGroupInfoChangeCallback) {
- onGroupInfoChangeCallback(tempNewGroupInfo);
- }
- } else if (GROUP_TIP_TYPE.MODIFY_MEMBER_INFO == opType) {
- //群成员变更
- var memberInfos = msgBody.MsgContent.MsgMemberInfo;
- for (var n in memberInfos) {
- var memberInfo = memberInfos[n];
- msgContent.addMemberInfo(new Msg.Elem.GroupTip.MemberInfo(memberInfo.User_Account, memberInfo.ShutupTime));
- }
- }
- break;
- case MSG_ELEMENT_TYPE.CUSTOM:
- msgType = MSG_ELEMENT_TYPE.CUSTOM;
- msgContent = new Msg.Elem.Custom(msgBody.MsgContent.Data, msgBody.MsgContent.Desc, msgBody.MsgContent.Ext);
- break;
- default:
- msgType = MSG_ELEMENT_TYPE.TEXT;
- msgContent = new Msg.Elem.Text('web端暂不支持' + msgBody.MsgType + '消息');
- break;
- }
- msg.elems.push(new Msg.Elem(msgType, msgContent));
- }
-
- if (isAddMsgFlag == false) {
- //不需要保存消息
- return msg;
- }
-
- if (MsgStore.addMsg(msg, true)) {
- msg.extraInfo = msgInfo.GroupInfo.MsgFrom_AccountExtraInfo;
- return msg;
- } else {
- return null;
- }
- };
-
- //初始化
- this.init = function(listeners, cbOk, cbErr) {
- if (!listeners.onMsgNotify) {
- log.warn('listeners.onMsgNotify is empty');
- }
- onMsgCallback = listeners.onMsgNotify;
-
- if (listeners.onBigGroupMsgNotify) {
- onBigGroupMsgCallback = listeners.onBigGroupMsgNotify;
- } else {
- log.warn('listeners.onBigGroupMsgNotify is empty');
- }
-
- if (listeners.onC2cEventNotifys) {
- onC2cEventCallbacks = listeners.onC2cEventNotifys;
- } else {
- log.warn('listeners.onC2cEventNotifys is empty');
- }
- if (listeners.onGroupSystemNotifys) {
- onGroupSystemNotifyCallbacks = listeners.onGroupSystemNotifys;
- } else {
- log.warn('listeners.onGroupSystemNotifys is empty');
- }
- if (listeners.onGroupInfoChangeNotify) {
- onGroupInfoChangeCallback = listeners.onGroupInfoChangeNotify;
- } else {
- log.warn('listeners.onGroupInfoChangeNotify is empty');
- }
- if (listeners.onFriendSystemNotifys) {
- onFriendSystemNotifyCallbacks = listeners.onFriendSystemNotifys;
- } else {
- log.warn('listeners.onFriendSystemNotifys is empty');
- }
- if (listeners.onProfileSystemNotifys) {
- onProfileSystemNotifyCallbacks = listeners.onProfileSystemNotifys;
- } else {
- log.warn('listeners.onProfileSystemNotifys is empty');
- }
- if (listeners.onKickedEventCall) {
- onKickedEventCall = listeners.onKickedEventCall;
- } else {
- log.warn('listeners.onKickedEventCall is empty');
- }
- if (listeners.onLongPullingNotify) {
- onLongPullingNotify = listeners.onLongPullingNotify;
- } else {
- log.warn('listeners.onKickedEventCall is empty');
- }
-
- if (listeners.onAppliedDownloadUrl) {
- onAppliedDownloadUrl = listeners.onAppliedDownloadUrl;
- } else {
- log.warn('listeners.onAppliedDownloadUrl is empty');
- }
-
- if (!ctx.identifier || !ctx.userSig) {
- if (cbOk) {
- var success = {
- ActionStatus: ACTION_STATUS.OK,
- ErrorCode: 0,
- ErrorInfo: 'login success(no login state)'
- };
- cbOk(success);
- }
- return;
- }
-
- //初始化
- initMyGroupMaxSeqs(function(resp) {
- log.info('initMyGroupMaxSeqs success');
- //初始化文件
- initIpAndAuthkey(function(initIpAndAuthkeyResp) {
- log.info('initIpAndAuthkey success');
- if (cbOk) {
- log.info('login success(have login state))');
- var success = {
- ActionStatus: ACTION_STATUS.OK,
- ErrorCode: 0,
- ErrorInfo: 'login success'
- };
- cbOk(success);
- }
- MsgManager.setLongPollingOn(true); //开启长轮询
- longPollingOn && MsgManager.longPolling(cbOk);
- }, cbErr);
- }, cbErr);
- };
-
- //发消息(私聊或群聊)
- this.sendMsg = function(msg, cbOk, cbErr) {
- proto_sendMsg(
- msg,
- function(resp) {
- //私聊时,加入自己的发的消息,群聊时,由于seq和服务器的seq不一样,所以不作处理
- if (msg.sess.type() == SESSION_TYPE.C2C) {
- if (!MsgStore.addMsg(msg)) {
- var errInfo = 'sendMsg: addMsg failed!';
- var error = tool.getReturnError(errInfo, -17);
- log.error(errInfo);
- if (cbErr) cbErr(error);
- return;
- }
- //更新信息流时间
- MsgStore.updateTimeline();
- }
- if (cbOk) cbOk(resp);
- },
- function(err) {
- if (cbErr) cbErr(err);
- }
- );
- };
- }();
-
- //上传文件
- var FileUploader = new function() {
- this.fileMd5 = null;
- //获取文件MD5
- var getFileMD5 = function(file, cbOk, cbErr) {
- //FileReader pc浏览器兼容性
- //Feature Firefox (Gecko) Chrome Internet Explorer Opera Safari
- //Basic support 3.6 7 10 12.02 6.0.2
- var fileReader = null;
- try {
- fileReader = new FileReader(); //分块读取文件对象
- } catch (e) {
- if (cbErr) {
- cbErr(tool.getReturnError('当前浏览器不支持FileReader', -18));
- return;
- }
- }
- //file的slice方法,注意它的兼容性,在不同浏览器的写法不同
- var blobSlice = File.prototype.mozSlice || File.prototype.webkitSlice || File.prototype.slice;
- if (!blobSlice) {
- if (cbErr) {
- cbErr(tool.getReturnError('当前浏览器不支持FileAPI', -19));
- return;
- }
- }
-
- var chunkSize = 2 * 1024 * 1024; //分块大小,2M
- var chunks = Math.ceil(file.size / chunkSize); //总块数
- var currentChunk = 0; //当前块数
- var spark = new SparkMD5(); //获取MD5对象
-
- fileReader.onload = function(e) {
- //数据加载完毕事件
-
- var binaryStr = '';
- var bytes = new Uint8Array(e.target.result);
- var length = bytes.byteLength;
- for (var i = 0; i < length; i++) {
- binaryStr += String.fromCharCode(bytes[i]); //二进制转换字符串
- }
- spark.appendBinary(binaryStr);
- currentChunk++;
- if (currentChunk < chunks) {
- loadNext(); //读取下一块数据
- } else {
- this.fileMd5 = spark.end(); //得到文件MD5值
- if (cbOk) {
- cbOk(this.fileMd5);
- }
- }
- };
- //分片读取文件
-
- function loadNext() {
- var start = currentChunk * chunkSize,
- end = start + chunkSize >= file.size ? file.size : start + chunkSize;
- //根据开始和结束位置,切割文件
- var b = blobSlice.call(file, start, end);
- //readAsBinaryString ie浏览器不兼容此方法
- //fileReader.readAsBinaryString(blobSlice.call(file, start, end));
- fileReader.readAsArrayBuffer(b); //ie,chrome,firefox等主流浏览器兼容此方法
- }
-
- loadNext(); //开始读取
- };
- //提交上传图片表单(用于低版本IE9以下)
- this.submitUploadFileForm = function(options, cbOk, cbErr) {
- var errInfo;
- var error;
- var formId = options.formId;
- var fileId = options.fileId;
- var iframeNum = uploadResultIframeId++;
- var iframeName = 'uploadResultIframe_' + iframeNum;
- var toAccount = options.To_Account;
- var businessType = options.businessType;
-
- var form = document.getElementById(formId);
- if (!form) {
- errInfo = '获取表单对象为空: formId=' + formId + '(formId非法)';
- error = tool.getReturnError(errInfo, -20);
- if (cbErr) cbErr(error);
- return;
- }
-
- var fileObj = document.getElementById(fileId);
- if (!fileObj) {
- errInfo = '获取文件对象为空: fileId=' + fileId + '(没有选择文件或者fileId非法)';
- error = tool.getReturnError(errInfo, -21);
- if (cbErr) cbErr(error);
- return;
- }
- //fileObj.type="file";//ie8下不起作用,必须由业务自己设置
- fileObj.name = 'file';
-
- var iframe = document.createElement('iframe');
- iframe.name = iframeName;
- iframe.id = iframeName;
- iframe.style.display = 'none';
- document.body.appendChild(iframe);
-
- var cmdName;
- if (isAccessFormalEnv()) {
- cmdName = 'pic_up';
- } else {
- cmdName = 'pic_up_test';
- }
- var uploadApiUrl =
- 'https://pic.tim.qq.com/v4/openpic/' +
- cmdName +
- '?tinyid=' +
- ctx.tinyid +
- '&a2=' +
- ctx.a2 +
- '&sdkappid=' +
- ctx.sdkAppID +
- '&accounttype=' +
- ctx.accountType +
- '&contenttype=http';
- form.action = uploadApiUrl;
- form.method = 'post';
- //form.enctype='multipart/form-data';//ie8下不起作用,必须由业务自己设置
- form.target = iframeName;
-
- function createFormInput(name, value) {
- var tempInput = document.createElement('input');
- tempInput.type = 'hidden';
- tempInput.name = name;
- tempInput.value = value;
- form.appendChild(tempInput);
- }
-
- createFormInput('App_Version', VERSION_INFO.APP_VERSION);
- createFormInput('From_Account', ctx.identifier);
- createFormInput('To_Account', toAccount);
- createFormInput('Seq', nextSeq().toString());
- createFormInput('Timestamp', unixtime().toString());
- createFormInput('Random', createRandom().toString());
- createFormInput('Busi_Id', businessType);
- createFormInput('PkgFlag', UPLOAD_RES_PKG_FLAG.RAW_DATA.toString());
- createFormInput('Auth_Key', authkey);
- createFormInput('Server_Ver', VERSION_INFO.SERVER_VERSION.toString());
- createFormInput('File_Type', options.fileType);
-
- //检测iframe.contentWindow.name是否有值
-
- function checkFrameName() {
- var resp;
- try {
- resp = JSON.parse(iframe.contentWindow.name) || {};
- } catch (e) {
- resp = {};
- }
- if (resp.ActionStatus) {
- //上传接口返回
- // We've got what we need. Stop the iframe from loading further content.
- iframe.src = 'about:blank';
- iframe.parentNode.removeChild(iframe);
- iframe = null;
-
- if (resp.ActionStatus == ACTION_STATUS.OK) {
- cbOk && cbOk(resp);
- } else {
- cbErr && cbErr(resp);
- }
- } else {
- setTimeout(checkFrameName, 100);
- }
- }
-
- setTimeout(checkFrameName, 500);
-
- form.submit(); //提交上传图片表单
- };
- //上传图片或文件(用于高版本浏览器,支持FileAPI)
- this.uploadFile = function(options, cbOk, cbErr) {
- var file_upload = {
- //初始化
- init: function(options, cbOk, cbErr) {
- var me = this;
- me.file = options.file;
- //分片上传进度回调事件
- me.onProgressCallBack = options.onProgressCallBack;
- //停止上传图片按钮
- if (options.abortButton) {
- options.abortButton.onclick = me.abortHandler;
- }
- me.total = me.file.size; //文件总大小
- me.loaded = 0; //已读取字节数
- me.step = 1080 * 1024; //分块大小,1080K
- me.sliceSize = 0; //分片大小
- me.sliceOffset = 0; //当前分片位置
- me.timestamp = unixtime(); //当前时间戳
- me.seq = nextSeq(); //请求seq
- me.random = createRandom(); //请求随机数
- me.fromAccount = ctx.identifier; //发送者
- me.toAccount = options.To_Account; //接收者
- me.fileMd5 = options.fileMd5; //文件MD5
- me.businessType = options.businessType; //图片或文件的业务类型,群消息:1; c2c消息:2; 个人头像:3; 群头像:4;
- me.fileType = options.fileType; //文件类型,不填为默认认为上传的是图片;1:图片;2:文件;3:短视频;4:PTT
-
- me.cbOk = cbOk; //上传成功回调事件
- me.cbErr = cbErr; //上传失败回调事件
-
- me.reader = new FileReader(); //读取文件对象
- me.blobSlice = File.prototype.mozSlice || File.prototype.webkitSlice || File.prototype.slice; //file的slice方法,不同浏览器不一样
-
- me.reader.onloadstart = me.onLoadStart; //开始读取回调事件
- me.reader.onprogress = me.onProgress; //读取文件进度回调事件
- me.reader.onabort = me.onAbort; //停止读取回调事件
- me.reader.onerror = me.onerror; //读取发生错误回调事件
- me.reader.onload = me.onLoad; //分片加载完毕回调事件
- me.reader.onloadend = me.onLoadEnd; //读取文件完毕回调事件
- },
- //上传方法
- upload: function() {
- var me = file_upload;
- //读取第一块
- me.readBlob(0);
- },
- onLoadStart: function() {
- var me = file_upload;
- },
- onProgress: function(e) {
- var me = file_upload;
- me.loaded += e.loaded;
- if (me.onProgressCallBack) {
- me.onProgressCallBack(me.loaded, me.total);
- }
- },
- onAbort: function() {
- var me = file_upload;
- },
- onError: function() {
- var me = file_upload;
- },
- onLoad: function(e) {
- var me = file_upload;
- if (e.target.readyState == FileReader.DONE) {
- var slice_data_base64 = e.target.result;
- //注意,一定要去除base64编码头部
- var pos = slice_data_base64.indexOf(',');
- if (pos != -1) {
- slice_data_base64 = slice_data_base64.substr(pos + 1);
- }
- //封装上传图片接口的请求参数
- var opt = {
- From_Account: me.fromAccount,
- To_Account: me.toAccount,
- Busi_Id: me.businessType,
- File_Type: me.fileType,
- File_Str_Md5: me.fileMd5,
- PkgFlag: UPLOAD_RES_PKG_FLAG.BASE64_DATA,
- File_Size: me.total,
- Slice_Offset: me.sliceOffset,
- Slice_Size: me.sliceSize,
- Slice_Data: slice_data_base64,
- Seq: me.seq,
- Timestamp: me.timestamp,
- Random: me.random
- };
-
- //上传成功的成功回调
- var succCallback = function(resp) {
- if (resp.IsFinish == 0) {
- me.loaded = resp.Next_Offset;
- if (me.loaded < me.total) {
- me.readBlob(me.loaded);
- } else {
- me.loaded = me.total;
- }
- } else {
- if (me.cbOk) {
- var tempResp = {
- ActionStatus: resp.ActionStatus,
- ErrorCode: resp.ErrorCode,
- ErrorInfo: resp.ErrorInfo,
- File_UUID: resp.File_UUID,
- File_Size: resp.Next_Offset,
- URL_INFO: resp.URL_INFO,
- Download_Flag: resp.Download_Flag
- };
- if (me.fileType == UPLOAD_RES_TYPE.FILE) {
- //如果上传的是文件,下载地址需要sdk内部拼接
- tempResp.URL_INFO = getFileDownUrl(resp.File_UUID, ctx.identifier, me.file.name);
- }
- me.cbOk(tempResp);
- }
- }
- Upload_Retry_Times = 0;
- };
- //上传失败的回调
- var errorCallback = function(resp) {
- if (Upload_Retry_Times < Upload_Retry_Max_Times) {
- Upload_Retry_Times++;
- setTimeout(function() {
- proto_uploadPic(opt, succCallback, errorCallback);
- }, 1000);
- } else {
- me.cbErr(resp);
- }
- //me.cbErr
- };
- //分片上传图片接口
- proto_uploadPic(opt, succCallback, errorCallback);
- }
- },
- onLoadEnd: function() {
- var me = file_upload;
- },
- //分片读取文件方法
- readBlob: function(start) {
- var me = file_upload;
- var blob,
- file = me.file;
- var end = start + me.step;
- if (end > me.total) {
- end = me.total;
- me.sliceSize = end - start;
- } else {
- me.sliceSize = me.step;
- }
- me.sliceOffset = start;
- //根据起始和结束位置,分片读取文件
- blob = me.blobSlice.call(file, start, end);
- //将分片的二进制数据转换为base64编码
- me.reader.readAsDataURL(blob);
- },
- abortHandler: function() {
- var me = file_upload;
- if (me.reader) {
- me.reader.abort();
- }
- }
- };
-
- //读取文件MD5
- getFileMD5(
- options.file,
- function(fileMd5) {
- log.info('fileMd5: ' + fileMd5);
- options.fileMd5 = fileMd5;
- //初始化上传参数
- file_upload.init(options, cbOk, cbErr);
- //开始上传文件
- file_upload.upload();
- },
- cbErr
- );
- };
- }();
-
- //web im 基础对象
-
- //常量对象
-
- //会话类型
- webim.SESSION_TYPE = SESSION_TYPE;
-
- webim.MSG_MAX_LENGTH = MSG_MAX_LENGTH;
-
- //c2c消息子类型
- webim.C2C_MSG_SUB_TYPE = C2C_MSG_SUB_TYPE;
-
- //群消息子类型
- webim.GROUP_MSG_SUB_TYPE = GROUP_MSG_SUB_TYPE;
-
- //消息元素类型
- webim.MSG_ELEMENT_TYPE = MSG_ELEMENT_TYPE;
-
- //群提示消息类型
- webim.GROUP_TIP_TYPE = GROUP_TIP_TYPE;
-
- //图片类型
- webim.IMAGE_TYPE = IMAGE_TYPE;
-
- //群系统消息类型
- webim.GROUP_SYSTEM_TYPE = GROUP_SYSTEM_TYPE;
-
- //好友系统通知子类型
- webim.FRIEND_NOTICE_TYPE = FRIEND_NOTICE_TYPE;
-
- //群提示消息-群资料变更类型
- webim.GROUP_TIP_MODIFY_GROUP_INFO_TYPE = GROUP_TIP_MODIFY_GROUP_INFO_TYPE;
-
- //浏览器信息
- webim.BROWSER_INFO = BROWSER_INFO;
-
- //表情对象
- webim.Emotions = webim.EmotionPicData = emotions;
- //表情标识符和index Map
- webim.EmotionDataIndexs = webim.EmotionPicDataIndex = emotionDataIndexs;
-
- //腾讯登录服务错误码(托管模式)
- webim.TLS_ERROR_CODE = TLS_ERROR_CODE;
-
- //连接状态
- webim.CONNECTION_STATUS = CONNECTION_STATUS;
-
- //上传图片业务类型
- webim.UPLOAD_PIC_BUSSINESS_TYPE = UPLOAD_PIC_BUSSINESS_TYPE;
-
- //最近联系人类型
- webim.RECENT_CONTACT_TYPE = RECENT_CONTACT_TYPE;
-
- //上传资源类型
- webim.UPLOAD_RES_TYPE = UPLOAD_RES_TYPE;
-
- /**************************************/
-
- //类对象
- //
- //工具对象
- webim.Tool = tool;
- //控制台打印日志对象
- webim.Log = log;
-
- //消息对象
- webim.Msg = Msg;
- //会话对象
- webim.Session = Session;
- //会话存储对象
- webim.MsgStore = {
- sessMap: function() {
- return MsgStore.sessMap();
- },
- sessCount: function() {
- return MsgStore.sessCount();
- },
- sessByTypeId: function(type, id) {
- return MsgStore.sessByTypeId(type, id);
- },
- delSessByTypeId: function(type, id) {
- return MsgStore.delSessByTypeId(type, id);
- },
- resetCookieAndSyncFlag: function() {
- return MsgStore.resetCookieAndSyncFlag();
- }
- };
-
- webim.Resources = Resources;
-
- /**************************************/
-
- // webim API impl
- //
- //基本接口
- //登录
- webim.login = webim.init = function(loginInfo, listeners, opts, cbOk, cbErr) {
- //初始化连接状态回调函数
- ConnManager.init(listeners.onConnNotify, cbOk, cbErr);
-
- //设置ie9以下浏览器jsonp回调
- if (listeners.jsonpCallback) jsonpCallback = listeners.jsonpCallback;
- //登录
- _login(loginInfo, listeners, opts, cbOk, cbErr);
- };
- //登出
- //需要传长轮询id
- //这样登出之后其他的登录实例还可以继续收取消息
- webim.logout = webim.offline = function(cbOk, cbErr) {
- return proto_logout('instance', cbOk, cbErr);
- };
-
- //登出
- //这种登出方式,所有的实例都将不会收到消息推送,直到重新登录
- webim.logoutAll = function(cbOk, cbErr) {
- return proto_logout('all', cbOk, cbErr);
- };
-
- //消息管理接口
- //发消息接口(私聊和群聊)
- webim.sendMsg = function(msg, cbOk, cbErr) {
- return MsgManager.sendMsg(msg, cbOk, cbErr);
- };
- //拉取未读c2c消息
- webim.syncMsgs = function(cbOk, cbErr) {
- return MsgManager.syncMsgs(cbOk, cbErr);
- };
- //拉取C2C漫游消息
- webim.getC2CHistoryMsgs = function(options, cbOk, cbErr) {
- return MsgManager.getC2CHistoryMsgs(options, cbOk, cbErr);
- };
- //拉取群漫游消息
- webim.syncGroupMsgs = function(options, cbOk, cbErr) {
- return MsgManager.syncGroupMsgs(options, cbOk, cbErr);
- };
-
- //上报c2c消息已读
- webim.c2CMsgReaded = function(options, cbOk, cbErr) {
- return MsgStore.c2CMsgReaded(options, cbOk, cbErr);
- };
-
- //上报群消息已读
- webim.groupMsgReaded = function(options, cbOk, cbErr) {
- return proto_groupMsgReaded(options, cbOk, cbErr);
- };
-
- //设置聊天会话自动标记已读
- webim.setAutoRead = function(selSess, isOn, isResetAll) {
- return MsgStore.setAutoRead(selSess, isOn, isResetAll);
- };
-
- //群组管理接口
- //
- //创建群
- webim.createGroup = function(options, cbOk, cbErr) {
- return proto_createGroup(options, cbOk, cbErr);
- };
- //创建群-高级接口
- webim.createGroupHigh = function(options, cbOk, cbErr) {
- return proto_createGroupHigh(options, cbOk, cbErr);
- };
- //申请加群
- webim.applyJoinGroup = function(options, cbOk, cbErr) {
- return proto_applyJoinGroup(options, cbOk, cbErr);
- };
- //处理加群申请(同意或拒绝)
- webim.handleApplyJoinGroupPendency = function(options, cbOk, cbErr) {
- return proto_handleApplyJoinGroupPendency(options, cbOk, cbErr);
- };
-
- //获取群组未决列表
- webim.getPendencyGroup = function(options, cbOk, cbErr) {
- return proto_getPendencyGroup(options, cbOk, cbErr);
- };
-
- //群未决已读上报
- webim.getPendencyGroupRead = function(options, cbOk, cbErr) {
- return proto_getPendencyGroupRead(options, cbOk, cbErr);
- };
-
- //处理邀请进群申请(同意或拒绝)
- webim.handleInviteJoinGroupRequest = function(options, cbOk, cbErr) {
- return proto_handleInviteJoinGroupRequest(options, cbOk, cbErr);
- };
-
- //删除加群申请
- webim.deleteApplyJoinGroupPendency = function(options, cbOk, cbErr) {
- return proto_deleteC2CMsg(options, cbOk, cbErr);
- };
-
- //主动退群
- webim.quitGroup = function(options, cbOk, cbErr) {
- return proto_quitGroup(options, cbOk, cbErr);
- };
- //搜索群组(根据名称)
- webim.searchGroupByName = function(options, cbOk, cbErr) {
- return proto_searchGroupByName(options, cbOk, cbErr);
- };
- //获取群组公开资料(根据群id搜索)
- webim.getGroupPublicInfo = function(options, cbOk, cbErr) {
- return proto_getGroupPublicInfo(options, cbOk, cbErr);
- };
- //获取群组详细资料-高级接口
- webim.getGroupInfo = function(options, cbOk, cbErr) {
- return proto_getGroupInfo(options, cbOk, cbErr);
- };
- //修改群基本资料
- webim.modifyGroupBaseInfo = function(options, cbOk, cbErr) {
- return proto_modifyGroupBaseInfo(options, cbOk, cbErr);
- };
- //获取群成员列表
- webim.getGroupMemberInfo = function(options, cbOk, cbErr) {
- return proto_getGroupMemberInfo(options, cbOk, cbErr);
- };
- //邀请好友加群
- webim.addGroupMember = function(options, cbOk, cbErr) {
- return proto_addGroupMember(options, cbOk, cbErr);
- };
- //修改群成员资料
- webim.modifyGroupMember = function(options, cbOk, cbErr) {
- return proto_modifyGroupMember(options, cbOk, cbErr);
- };
- //删除群成员
- webim.deleteGroupMember = function(options, cbOk, cbErr) {
- return proto_deleteGroupMember(options, cbOk, cbErr);
- };
- //解散群
- webim.destroyGroup = function(options, cbOk, cbErr) {
- return proto_destroyGroup(options, cbOk, cbErr);
- };
- //转让群组
- webim.changeGroupOwner = function(options, cbOk, cbErr) {
- return proto_changeGroupOwner(options, cbOk, cbErr);
- };
-
- //获取我的群组列表-高级接口
- webim.getJoinedGroupListHigh = function(options, cbOk, cbErr) {
- return proto_getJoinedGroupListHigh(options, cbOk, cbErr);
- };
- //获取群成员角色
- webim.getRoleInGroup = function(options, cbOk, cbErr) {
- return proto_getRoleInGroup(options, cbOk, cbErr);
- };
- //设置群成员禁言时间
- webim.forbidSendMsg = function(options, cbOk, cbErr) {
- return proto_forbidSendMsg(options, cbOk, cbErr);
- };
- //发送自定义群系统通知
- webim.sendCustomGroupNotify = function(options, cbOk, cbErr) {
- return proto_sendCustomGroupNotify(options, cbOk, cbErr);
- };
-
- //进入大群
- webim.applyJoinBigGroup = function(options, cbOk, cbErr) {
- return proto_applyJoinBigGroup(options, cbOk, cbErr);
- };
- //退出大群
- webim.quitBigGroup = function(options, cbOk, cbErr) {
- return proto_quitBigGroup(options, cbOk, cbErr);
- };
-
- //资料关系链管理接口
- //
- //获取个人资料接口,可用于搜索用户
- webim.getProfilePortrait = function(options, cbOk, cbErr) {
- return proto_getProfilePortrait(options, cbOk, cbErr);
- };
- //设置个人资料
- webim.setProfilePortrait = function(options, cbOk, cbErr) {
- return proto_setProfilePortrait(options, cbOk, cbErr);
- };
- //申请加好友
- webim.applyAddFriend = function(options, cbOk, cbErr) {
- return proto_applyAddFriend(options, cbOk, cbErr);
- };
- //获取好友申请列表
- webim.getPendency = function(options, cbOk, cbErr) {
- return proto_getPendency(options, cbOk, cbErr);
- };
- //好友申请列表已读上报
- webim.getPendencyReport = function(options, cbOk, cbErr) {
- return proto_getPendencyReport(options, cbOk, cbErr);
- };
- //删除好友申请
- webim.deletePendency = function(options, cbOk, cbErr) {
- return proto_deletePendency(options, cbOk, cbErr);
- };
- //处理好友申请
- webim.responseFriend = function(options, cbOk, cbErr) {
- return proto_responseFriend(options, cbOk, cbErr);
- };
- //获取我的好友
- webim.getAllFriend = function(options, cbOk, cbErr) {
- return proto_getAllFriend(options, cbOk, cbErr);
- };
- //删除会话
- webim.deleteChat = function(options, cbOk, cbErr) {
- return proto_deleteChat(options, cbOk, cbErr);
- };
- //删除好友
- webim.deleteFriend = function(options, cbOk, cbErr) {
- return proto_deleteFriend(options, cbOk, cbErr);
- };
- //拉黑
- webim.addBlackList = function(options, cbOk, cbErr) {
- return proto_addBlackList(options, cbOk, cbErr);
- };
- //删除黑名单
- webim.deleteBlackList = function(options, cbOk, cbErr) {
- return proto_deleteBlackList(options, cbOk, cbErr);
- };
- //获取我的黑名单
- webim.getBlackList = function(options, cbOk, cbErr) {
- return proto_getBlackList(options, cbOk, cbErr);
- };
-
- //获取最近会话
- webim.getRecentContactList = function(options, cbOk, cbErr) {
- return proto_getRecentContactList(options, cbOk, cbErr);
- };
-
- //图片或文件服务接口
- //
- //上传文件接口(高版本浏览器)
- webim.uploadFile = webim.uploadPic = function(options, cbOk, cbErr) {
- return FileUploader.uploadFile(options, cbOk, cbErr);
- };
- //提交上传图片表单接口(用于低版本ie)
- webim.submitUploadFileForm = function(options, cbOk, cbErr) {
- return FileUploader.submitUploadFileForm(options, cbOk, cbErr);
- };
- //上传图片或文件(Base64)接口
- webim.uploadFileByBase64 = webim.uploadPicByBase64 = function(options, cbOk, cbErr) {
- //请求参数
- var opt = {
- To_Account: options.toAccount,
- Busi_Id: options.businessType,
- File_Type: options.File_Type,
- File_Str_Md5: options.fileMd5,
- PkgFlag: UPLOAD_RES_PKG_FLAG.BASE64_DATA,
- File_Size: options.totalSize,
- Slice_Offset: 0,
- Slice_Size: options.totalSize,
- Slice_Data: options.base64Str,
- Seq: nextSeq(),
- Timestamp: unixtime(),
- Random: createRandom()
- };
- return proto_uploadPic(opt, cbOk, cbErr);
- };
-
- //设置jsonp返回的值
- webim.setJsonpLastRspData = function(rspData) {
- jsonpLastRspData = typeof rspData == 'string' ? JSON.parse(rspData) : rspData;
- };
-
- //获取长轮询ID
- webim.getLongPollingId = function(options, cbOk, cbErr) {
- return proto_getLongPollingId(options, cbOk, cbErr);
- };
-
- //获取下载地址
- webim.applyDownload = function(options, cbOk, cbErr) {
- return proto_applyDownload(options, cbOk, cbErr);
- };
-
- //获取下载地址
- webim.onDownFile = function(uuid) {
- window.open(Resources.downloadMap['uuid_' + uuid]);
- };
-
- //检查是否登录
- webim.checkLogin = function(cbErr, isNeedCallBack) {
- return checkLogin(cbErr, isNeedCallBack);
- };
- })(webim);
-
- for (const key in webim) {
- if (webim.hasOwnProperty(key)) {
- const element = webim[key];
-
- if (Object.prototype.toString.call(element) === '[object Function]') {
- webim[key + 'Async'] = (...args) => {
- return new Promise((resolve, reject) => {
- webim[key].apply(webim, [...args, resolve, reject]);
- });
- };
- }
- }
- }
-
- exports = module.exports = webim;
|