123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273302743027530276302773027830279302803028130282302833028430285302863028730288302893029030291302923029330294302953029630297302983029930300303013030230303303043030530306303073030830309303103031130312303133031430315303163031730318303193032030321303223032330324303253032630327303283032930330303313033230333303343033530336303373033830339303403034130342303433034430345303463034730348303493035030351303523035330354303553035630357303583035930360303613036230363303643036530366303673036830369303703037130372303733037430375303763037730378303793038030381303823038330384303853038630387303883038930390303913039230393303943039530396303973039830399304003040130402304033040430405304063040730408304093041030411304123041330414304153041630417304183041930420304213042230423304243042530426304273042830429304303043130432304333043430435304363043730438304393044030441304423044330444304453044630447304483044930450304513045230453304543045530456304573045830459304603046130462304633046430465304663046730468304693047030471304723047330474304753047630477304783047930480304813048230483304843048530486304873048830489304903049130492304933049430495304963049730498304993050030501305023050330504305053050630507305083050930510305113051230513305143051530516305173051830519305203052130522305233052430525305263052730528305293053030531305323053330534305353053630537305383053930540305413054230543305443054530546305473054830549305503055130552305533055430555305563055730558305593056030561305623056330564305653056630567305683056930570305713057230573305743057530576305773057830579305803058130582305833058430585305863058730588305893059030591305923059330594305953059630597305983059930600306013060230603306043060530606306073060830609306103061130612306133061430615306163061730618306193062030621306223062330624306253062630627306283062930630306313063230633306343063530636306373063830639306403064130642306433064430645306463064730648306493065030651306523065330654306553065630657306583065930660306613066230663306643066530666306673066830669306703067130672306733067430675306763067730678306793068030681306823068330684306853068630687306883068930690306913069230693306943069530696306973069830699307003070130702307033070430705307063070730708307093071030711307123071330714307153071630717307183071930720307213072230723307243072530726307273072830729307303073130732307333073430735307363073730738307393074030741307423074330744307453074630747307483074930750307513075230753307543075530756307573075830759307603076130762307633076430765307663076730768307693077030771307723077330774307753077630777307783077930780307813078230783307843078530786307873078830789307903079130792307933079430795307963079730798307993080030801308023080330804308053080630807308083080930810308113081230813308143081530816308173081830819308203082130822308233082430825308263082730828308293083030831308323083330834308353083630837308383083930840308413084230843308443084530846308473084830849308503085130852308533085430855308563085730858308593086030861308623086330864308653086630867308683086930870308713087230873308743087530876308773087830879308803088130882308833088430885308863088730888308893089030891308923089330894308953089630897308983089930900309013090230903309043090530906309073090830909309103091130912309133091430915309163091730918309193092030921309223092330924309253092630927309283092930930309313093230933309343093530936309373093830939309403094130942309433094430945309463094730948309493095030951309523095330954309553095630957309583095930960309613096230963309643096530966309673096830969309703097130972309733097430975309763097730978309793098030981309823098330984309853098630987309883098930990309913099230993309943099530996309973099830999310003100131002310033100431005310063100731008310093101031011310123101331014310153101631017310183101931020310213102231023310243102531026310273102831029310303103131032310333103431035310363103731038310393104031041310423104331044310453104631047310483104931050310513105231053310543105531056310573105831059310603106131062310633106431065310663106731068310693107031071310723107331074310753107631077310783107931080310813108231083310843108531086310873108831089310903109131092310933109431095310963109731098310993110031101311023110331104311053110631107311083110931110311113111231113311143111531116311173111831119311203112131122311233112431125311263112731128311293113031131311323113331134311353113631137311383113931140311413114231143311443114531146311473114831149311503115131152311533115431155311563115731158311593116031161311623116331164311653116631167311683116931170311713117231173311743117531176311773117831179311803118131182311833118431185311863118731188311893119031191311923119331194311953119631197311983119931200312013120231203312043120531206312073120831209312103121131212312133121431215312163121731218312193122031221312223122331224312253122631227312283122931230312313123231233312343123531236312373123831239312403124131242312433124431245312463124731248312493125031251312523125331254312553125631257312583125931260312613126231263312643126531266312673126831269312703127131272312733127431275312763127731278312793128031281312823128331284312853128631287312883128931290312913129231293312943129531296312973129831299313003130131302313033130431305313063130731308313093131031311313123131331314313153131631317313183131931320313213132231323313243132531326313273132831329313303133131332313333133431335313363133731338313393134031341313423134331344313453134631347313483134931350313513135231353313543135531356313573135831359313603136131362313633136431365313663136731368313693137031371313723137331374313753137631377313783137931380313813138231383313843138531386313873138831389313903139131392313933139431395313963139731398313993140031401314023140331404314053140631407314083140931410314113141231413314143141531416314173141831419314203142131422314233142431425314263142731428314293143031431314323143331434314353143631437314383143931440314413144231443314443144531446314473144831449314503145131452314533145431455314563145731458314593146031461314623146331464314653146631467314683146931470314713147231473314743147531476314773147831479314803148131482314833148431485314863148731488314893149031491314923149331494314953149631497314983149931500315013150231503315043150531506315073150831509315103151131512315133151431515315163151731518315193152031521315223152331524315253152631527315283152931530315313153231533315343153531536315373153831539315403154131542315433154431545315463154731548315493155031551315523155331554315553155631557315583155931560315613156231563315643156531566315673156831569315703157131572315733157431575315763157731578315793158031581315823158331584315853158631587315883158931590315913159231593315943159531596315973159831599316003160131602316033160431605316063160731608316093161031611316123161331614316153161631617316183161931620316213162231623316243162531626316273162831629316303163131632316333163431635316363163731638316393164031641316423164331644316453164631647316483164931650316513165231653316543165531656316573165831659316603166131662316633166431665316663166731668316693167031671316723167331674316753167631677316783167931680316813168231683316843168531686316873168831689316903169131692316933169431695316963169731698316993170031701317023170331704317053170631707317083170931710317113171231713317143171531716317173171831719317203172131722317233172431725317263172731728317293173031731317323173331734317353173631737317383173931740317413174231743317443174531746317473174831749317503175131752317533175431755317563175731758317593176031761317623176331764317653176631767317683176931770317713177231773317743177531776317773177831779317803178131782317833178431785317863178731788317893179031791317923179331794317953179631797317983179931800318013180231803318043180531806318073180831809318103181131812318133181431815318163181731818318193182031821318223182331824318253182631827318283182931830318313183231833318343183531836318373183831839318403184131842318433184431845318463184731848318493185031851318523185331854318553185631857318583185931860318613186231863318643186531866318673186831869318703187131872318733187431875318763187731878318793188031881318823188331884318853188631887318883188931890318913189231893318943189531896318973189831899319003190131902319033190431905319063190731908319093191031911319123191331914319153191631917319183191931920319213192231923319243192531926319273192831929319303193131932319333193431935319363193731938319393194031941319423194331944319453194631947319483194931950319513195231953319543195531956319573195831959319603196131962319633196431965319663196731968319693197031971319723197331974319753197631977319783197931980319813198231983319843198531986319873198831989319903199131992319933199431995319963199731998319993200032001320023200332004320053200632007320083200932010320113201232013320143201532016320173201832019320203202132022320233202432025320263202732028320293203032031320323203332034320353203632037320383203932040320413204232043320443204532046320473204832049320503205132052320533205432055320563205732058320593206032061320623206332064320653206632067320683206932070320713207232073320743207532076320773207832079320803208132082320833208432085320863208732088320893209032091320923209332094320953209632097320983209932100321013210232103321043210532106321073210832109321103211132112321133211432115321163211732118321193212032121321223212332124321253212632127321283212932130321313213232133321343213532136321373213832139321403214132142321433214432145321463214732148321493215032151321523215332154321553215632157321583215932160321613216232163321643216532166321673216832169321703217132172321733217432175321763217732178321793218032181321823218332184321853218632187321883218932190321913219232193321943219532196321973219832199322003220132202322033220432205322063220732208322093221032211322123221332214322153221632217322183221932220322213222232223322243222532226322273222832229322303223132232322333223432235322363223732238322393224032241322423224332244322453224632247322483224932250322513225232253322543225532256322573225832259322603226132262322633226432265322663226732268322693227032271322723227332274322753227632277322783227932280322813228232283322843228532286322873228832289322903229132292322933229432295322963229732298322993230032301323023230332304323053230632307323083230932310323113231232313323143231532316323173231832319323203232132322323233232432325323263232732328323293233032331323323233332334323353233632337323383233932340323413234232343323443234532346323473234832349323503235132352323533235432355323563235732358323593236032361323623236332364323653236632367323683236932370323713237232373323743237532376323773237832379323803238132382323833238432385323863238732388323893239032391323923239332394323953239632397323983239932400324013240232403324043240532406324073240832409324103241132412324133241432415324163241732418324193242032421324223242332424324253242632427324283242932430324313243232433324343243532436324373243832439324403244132442324433244432445324463244732448324493245032451324523245332454324553245632457324583245932460324613246232463324643246532466324673246832469324703247132472324733247432475324763247732478324793248032481324823248332484324853248632487324883248932490324913249232493324943249532496324973249832499325003250132502325033250432505325063250732508325093251032511325123251332514325153251632517325183251932520325213252232523325243252532526325273252832529325303253132532325333253432535325363253732538325393254032541325423254332544325453254632547325483254932550325513255232553325543255532556325573255832559325603256132562325633256432565325663256732568325693257032571325723257332574325753257632577325783257932580325813258232583325843258532586325873258832589325903259132592325933259432595325963259732598325993260032601326023260332604326053260632607326083260932610326113261232613326143261532616326173261832619326203262132622326233262432625326263262732628326293263032631326323263332634326353263632637326383263932640326413264232643326443264532646326473264832649326503265132652326533265432655326563265732658326593266032661326623266332664326653266632667326683266932670326713267232673326743267532676326773267832679326803268132682326833268432685326863268732688326893269032691326923269332694326953269632697326983269932700327013270232703327043270532706327073270832709327103271132712327133271432715327163271732718327193272032721327223272332724327253272632727327283272932730327313273232733327343273532736327373273832739327403274132742327433274432745327463274732748327493275032751327523275332754327553275632757327583275932760327613276232763327643276532766327673276832769327703277132772327733277432775327763277732778327793278032781327823278332784327853278632787327883278932790327913279232793327943279532796327973279832799328003280132802328033280432805328063280732808328093281032811328123281332814328153281632817328183281932820328213282232823328243282532826328273282832829328303283132832328333283432835328363283732838328393284032841328423284332844328453284632847328483284932850328513285232853328543285532856328573285832859328603286132862328633286432865328663286732868328693287032871328723287332874328753287632877328783287932880328813288232883328843288532886328873288832889328903289132892328933289432895328963289732898328993290032901329023290332904329053290632907329083290932910329113291232913329143291532916329173291832919329203292132922329233292432925329263292732928329293293032931329323293332934329353293632937329383293932940329413294232943329443294532946329473294832949329503295132952329533295432955329563295732958329593296032961329623296332964329653296632967329683296932970329713297232973329743297532976329773297832979329803298132982329833298432985329863298732988329893299032991329923299332994329953299632997329983299933000330013300233003330043300533006330073300833009330103301133012330133301433015330163301733018330193302033021330223302333024330253302633027330283302933030330313303233033330343303533036330373303833039330403304133042330433304433045330463304733048330493305033051330523305333054330553305633057330583305933060330613306233063330643306533066330673306833069330703307133072330733307433075330763307733078330793308033081330823308333084330853308633087330883308933090330913309233093330943309533096330973309833099331003310133102331033310433105331063310733108331093311033111331123311333114331153311633117331183311933120331213312233123331243312533126331273312833129331303313133132331333313433135331363313733138331393314033141331423314333144331453314633147331483314933150331513315233153331543315533156331573315833159331603316133162331633316433165331663316733168331693317033171331723317333174331753317633177331783317933180331813318233183331843318533186331873318833189331903319133192331933319433195331963319733198331993320033201332023320333204332053320633207332083320933210332113321233213332143321533216332173321833219332203322133222332233322433225332263322733228332293323033231332323323333234332353323633237332383323933240332413324233243332443324533246332473324833249332503325133252332533325433255332563325733258332593326033261332623326333264332653326633267332683326933270332713327233273332743327533276332773327833279332803328133282332833328433285332863328733288332893329033291332923329333294332953329633297332983329933300333013330233303333043330533306333073330833309333103331133312333133331433315333163331733318333193332033321333223332333324333253332633327333283332933330333313333233333333343333533336333373333833339333403334133342333433334433345333463334733348333493335033351333523335333354333553335633357333583335933360333613336233363333643336533366333673336833369333703337133372333733337433375333763337733378333793338033381333823338333384333853338633387333883338933390333913339233393333943339533396333973339833399334003340133402334033340433405334063340733408334093341033411334123341333414334153341633417334183341933420334213342233423334243342533426334273342833429334303343133432334333343433435334363343733438334393344033441334423344333444334453344633447334483344933450334513345233453334543345533456334573345833459334603346133462334633346433465334663346733468334693347033471334723347333474334753347633477334783347933480334813348233483334843348533486334873348833489334903349133492334933349433495334963349733498334993350033501335023350333504335053350633507335083350933510335113351233513335143351533516335173351833519335203352133522335233352433525335263352733528335293353033531335323353333534335353353633537335383353933540335413354233543335443354533546335473354833549335503355133552335533355433555335563355733558335593356033561335623356333564335653356633567335683356933570335713357233573335743357533576335773357833579335803358133582335833358433585335863358733588335893359033591335923359333594335953359633597335983359933600336013360233603336043360533606336073360833609336103361133612336133361433615336163361733618336193362033621336223362333624336253362633627336283362933630336313363233633336343363533636336373363833639336403364133642336433364433645336463364733648336493365033651336523365333654336553365633657336583365933660336613366233663336643366533666336673366833669336703367133672336733367433675336763367733678336793368033681336823368333684336853368633687336883368933690336913369233693336943369533696336973369833699337003370133702337033370433705337063370733708337093371033711337123371333714337153371633717337183371933720337213372233723337243372533726337273372833729337303373133732337333373433735337363373733738337393374033741337423374333744337453374633747337483374933750337513375233753337543375533756337573375833759337603376133762337633376433765337663376733768337693377033771337723377333774337753377633777337783377933780337813378233783337843378533786337873378833789337903379133792337933379433795337963379733798337993380033801338023380333804338053380633807338083380933810338113381233813338143381533816338173381833819338203382133822338233382433825338263382733828338293383033831338323383333834338353383633837338383383933840338413384233843338443384533846338473384833849338503385133852338533385433855338563385733858338593386033861338623386333864338653386633867338683386933870338713387233873338743387533876338773387833879338803388133882338833388433885338863388733888338893389033891338923389333894338953389633897338983389933900339013390233903339043390533906339073390833909339103391133912339133391433915339163391733918339193392033921339223392333924339253392633927339283392933930339313393233933339343393533936339373393833939339403394133942339433394433945339463394733948339493395033951339523395333954339553395633957339583395933960339613396233963339643396533966339673396833969339703397133972339733397433975339763397733978339793398033981339823398333984339853398633987339883398933990339913399233993339943399533996339973399833999340003400134002340033400434005340063400734008340093401034011340123401334014340153401634017340183401934020340213402234023340243402534026340273402834029340303403134032340333403434035340363403734038340393404034041340423404334044340453404634047340483404934050340513405234053340543405534056340573405834059340603406134062340633406434065340663406734068340693407034071340723407334074340753407634077340783407934080340813408234083340843408534086340873408834089340903409134092340933409434095340963409734098340993410034101341023410334104341053410634107341083410934110341113411234113341143411534116341173411834119341203412134122341233412434125341263412734128341293413034131341323413334134341353413634137341383413934140341413414234143341443414534146341473414834149341503415134152341533415434155341563415734158341593416034161341623416334164341653416634167341683416934170341713417234173341743417534176341773417834179341803418134182341833418434185341863418734188341893419034191341923419334194341953419634197341983419934200342013420234203342043420534206342073420834209342103421134212342133421434215342163421734218342193422034221342223422334224342253422634227342283422934230342313423234233342343423534236342373423834239342403424134242342433424434245342463424734248342493425034251342523425334254342553425634257342583425934260342613426234263342643426534266342673426834269342703427134272342733427434275342763427734278342793428034281342823428334284342853428634287342883428934290342913429234293342943429534296342973429834299343003430134302343033430434305343063430734308343093431034311343123431334314343153431634317343183431934320343213432234323343243432534326343273432834329343303433134332343333433434335343363433734338343393434034341343423434334344343453434634347343483434934350343513435234353343543435534356343573435834359343603436134362343633436434365343663436734368343693437034371343723437334374343753437634377343783437934380343813438234383343843438534386343873438834389343903439134392343933439434395343963439734398343993440034401344023440334404344053440634407344083440934410344113441234413344143441534416344173441834419344203442134422344233442434425344263442734428344293443034431344323443334434344353443634437344383443934440344413444234443344443444534446344473444834449344503445134452344533445434455344563445734458344593446034461344623446334464344653446634467344683446934470344713447234473344743447534476344773447834479344803448134482344833448434485344863448734488344893449034491344923449334494344953449634497344983449934500345013450234503345043450534506345073450834509345103451134512345133451434515345163451734518345193452034521345223452334524345253452634527345283452934530345313453234533345343453534536345373453834539345403454134542345433454434545345463454734548345493455034551345523455334554345553455634557345583455934560345613456234563345643456534566345673456834569345703457134572345733457434575345763457734578345793458034581345823458334584345853458634587345883458934590345913459234593345943459534596345973459834599346003460134602346033460434605346063460734608346093461034611346123461334614346153461634617346183461934620346213462234623346243462534626346273462834629346303463134632346333463434635346363463734638346393464034641346423464334644346453464634647346483464934650346513465234653346543465534656346573465834659346603466134662346633466434665346663466734668346693467034671346723467334674346753467634677346783467934680346813468234683346843468534686346873468834689346903469134692346933469434695346963469734698346993470034701347023470334704347053470634707347083470934710347113471234713347143471534716347173471834719347203472134722347233472434725347263472734728347293473034731347323473334734347353473634737347383473934740347413474234743347443474534746347473474834749347503475134752347533475434755347563475734758347593476034761347623476334764347653476634767347683476934770347713477234773347743477534776347773477834779347803478134782347833478434785347863478734788347893479034791347923479334794347953479634797347983479934800348013480234803348043480534806348073480834809348103481134812348133481434815348163481734818348193482034821348223482334824348253482634827348283482934830348313483234833348343483534836348373483834839348403484134842348433484434845348463484734848348493485034851348523485334854348553485634857348583485934860348613486234863348643486534866348673486834869348703487134872348733487434875348763487734878348793488034881348823488334884348853488634887348883488934890348913489234893348943489534896348973489834899349003490134902349033490434905349063490734908349093491034911349123491334914349153491634917349183491934920349213492234923349243492534926349273492834929349303493134932349333493434935349363493734938349393494034941349423494334944349453494634947349483494934950349513495234953349543495534956349573495834959349603496134962349633496434965349663496734968349693497034971349723497334974349753497634977349783497934980349813498234983349843498534986349873498834989349903499134992349933499434995349963499734998349993500035001350023500335004350053500635007350083500935010350113501235013350143501535016350173501835019350203502135022350233502435025350263502735028350293503035031350323503335034350353503635037350383503935040350413504235043350443504535046350473504835049350503505135052350533505435055350563505735058350593506035061350623506335064350653506635067350683506935070350713507235073350743507535076350773507835079350803508135082350833508435085350863508735088350893509035091350923509335094350953509635097350983509935100351013510235103351043510535106351073510835109351103511135112351133511435115351163511735118351193512035121351223512335124351253512635127351283512935130351313513235133351343513535136351373513835139351403514135142351433514435145351463514735148351493515035151351523515335154351553515635157351583515935160351613516235163351643516535166351673516835169351703517135172351733517435175351763517735178351793518035181351823518335184351853518635187351883518935190351913519235193351943519535196351973519835199352003520135202352033520435205352063520735208352093521035211352123521335214352153521635217352183521935220352213522235223352243522535226352273522835229352303523135232352333523435235352363523735238352393524035241352423524335244352453524635247352483524935250352513525235253352543525535256352573525835259352603526135262352633526435265352663526735268352693527035271352723527335274352753527635277352783527935280352813528235283352843528535286352873528835289352903529135292352933529435295352963529735298352993530035301353023530335304353053530635307353083530935310353113531235313353143531535316353173531835319353203532135322353233532435325353263532735328353293533035331353323533335334353353533635337353383533935340353413534235343353443534535346353473534835349353503535135352353533535435355353563535735358353593536035361353623536335364353653536635367353683536935370353713537235373353743537535376353773537835379353803538135382353833538435385353863538735388353893539035391353923539335394353953539635397353983539935400354013540235403354043540535406354073540835409354103541135412354133541435415354163541735418354193542035421354223542335424354253542635427354283542935430354313543235433354343543535436354373543835439354403544135442354433544435445354463544735448354493545035451354523545335454354553545635457354583545935460354613546235463354643546535466354673546835469354703547135472354733547435475354763547735478354793548035481354823548335484354853548635487354883548935490354913549235493354943549535496354973549835499355003550135502355033550435505355063550735508355093551035511355123551335514355153551635517355183551935520355213552235523355243552535526355273552835529355303553135532355333553435535355363553735538355393554035541355423554335544355453554635547355483554935550355513555235553355543555535556355573555835559355603556135562355633556435565355663556735568355693557035571355723557335574355753557635577355783557935580355813558235583355843558535586355873558835589355903559135592355933559435595355963559735598355993560035601356023560335604356053560635607356083560935610356113561235613356143561535616356173561835619356203562135622356233562435625356263562735628356293563035631356323563335634356353563635637356383563935640356413564235643356443564535646356473564835649356503565135652356533565435655356563565735658356593566035661356623566335664356653566635667356683566935670356713567235673356743567535676356773567835679356803568135682356833568435685356863568735688356893569035691356923569335694356953569635697356983569935700357013570235703357043570535706357073570835709357103571135712357133571435715357163571735718357193572035721357223572335724357253572635727357283572935730357313573235733357343573535736357373573835739357403574135742357433574435745357463574735748357493575035751357523575335754357553575635757357583575935760357613576235763357643576535766357673576835769357703577135772357733577435775357763577735778357793578035781357823578335784357853578635787357883578935790357913579235793357943579535796357973579835799358003580135802358033580435805358063580735808358093581035811358123581335814358153581635817358183581935820358213582235823358243582535826358273582835829358303583135832358333583435835358363583735838358393584035841358423584335844358453584635847358483584935850358513585235853358543585535856358573585835859358603586135862358633586435865358663586735868358693587035871358723587335874358753587635877358783587935880358813588235883358843588535886358873588835889358903589135892358933589435895358963589735898358993590035901359023590335904359053590635907359083590935910359113591235913359143591535916359173591835919359203592135922359233592435925359263592735928359293593035931359323593335934359353593635937359383593935940359413594235943359443594535946359473594835949359503595135952359533595435955359563595735958359593596035961359623596335964359653596635967359683596935970359713597235973359743597535976359773597835979359803598135982359833598435985359863598735988359893599035991359923599335994359953599635997359983599936000360013600236003360043600536006360073600836009360103601136012360133601436015360163601736018360193602036021360223602336024360253602636027360283602936030360313603236033360343603536036360373603836039360403604136042360433604436045360463604736048360493605036051360523605336054360553605636057360583605936060360613606236063360643606536066360673606836069360703607136072360733607436075360763607736078360793608036081360823608336084360853608636087360883608936090360913609236093360943609536096360973609836099361003610136102361033610436105361063610736108361093611036111361123611336114361153611636117361183611936120361213612236123361243612536126361273612836129361303613136132361333613436135361363613736138361393614036141361423614336144361453614636147361483614936150361513615236153361543615536156361573615836159361603616136162361633616436165361663616736168361693617036171361723617336174361753617636177361783617936180361813618236183361843618536186361873618836189361903619136192361933619436195361963619736198361993620036201362023620336204362053620636207362083620936210362113621236213362143621536216362173621836219362203622136222362233622436225362263622736228362293623036231362323623336234362353623636237362383623936240362413624236243362443624536246362473624836249362503625136252362533625436255362563625736258362593626036261362623626336264362653626636267362683626936270362713627236273362743627536276362773627836279362803628136282362833628436285362863628736288362893629036291362923629336294362953629636297362983629936300363013630236303363043630536306363073630836309363103631136312363133631436315363163631736318363193632036321363223632336324363253632636327363283632936330363313633236333363343633536336363373633836339363403634136342363433634436345363463634736348363493635036351363523635336354363553635636357363583635936360363613636236363363643636536366363673636836369363703637136372363733637436375363763637736378363793638036381363823638336384363853638636387363883638936390363913639236393363943639536396363973639836399364003640136402364033640436405364063640736408364093641036411364123641336414364153641636417364183641936420364213642236423364243642536426364273642836429364303643136432364333643436435364363643736438364393644036441364423644336444364453644636447364483644936450364513645236453364543645536456364573645836459364603646136462364633646436465364663646736468364693647036471364723647336474364753647636477364783647936480364813648236483364843648536486364873648836489364903649136492364933649436495364963649736498364993650036501365023650336504365053650636507365083650936510365113651236513365143651536516365173651836519365203652136522365233652436525365263652736528365293653036531365323653336534365353653636537365383653936540365413654236543365443654536546365473654836549365503655136552365533655436555365563655736558365593656036561365623656336564365653656636567365683656936570365713657236573365743657536576365773657836579365803658136582365833658436585365863658736588365893659036591365923659336594365953659636597365983659936600366013660236603366043660536606366073660836609366103661136612366133661436615366163661736618366193662036621366223662336624366253662636627366283662936630366313663236633366343663536636366373663836639366403664136642366433664436645366463664736648366493665036651366523665336654366553665636657366583665936660366613666236663366643666536666366673666836669366703667136672366733667436675366763667736678366793668036681366823668336684366853668636687366883668936690366913669236693366943669536696366973669836699367003670136702367033670436705367063670736708367093671036711367123671336714367153671636717367183671936720367213672236723367243672536726367273672836729367303673136732367333673436735367363673736738367393674036741367423674336744367453674636747367483674936750367513675236753367543675536756367573675836759367603676136762367633676436765367663676736768367693677036771367723677336774367753677636777367783677936780367813678236783367843678536786367873678836789367903679136792367933679436795367963679736798367993680036801368023680336804368053680636807368083680936810368113681236813368143681536816368173681836819368203682136822368233682436825368263682736828368293683036831368323683336834368353683636837368383683936840368413684236843368443684536846368473684836849368503685136852368533685436855368563685736858368593686036861368623686336864368653686636867368683686936870368713687236873368743687536876368773687836879368803688136882368833688436885368863688736888368893689036891368923689336894368953689636897368983689936900369013690236903369043690536906369073690836909369103691136912369133691436915369163691736918369193692036921369223692336924369253692636927369283692936930369313693236933369343693536936369373693836939369403694136942369433694436945369463694736948369493695036951369523695336954369553695636957369583695936960369613696236963369643696536966369673696836969369703697136972369733697436975369763697736978369793698036981369823698336984369853698636987369883698936990369913699236993369943699536996369973699836999370003700137002370033700437005370063700737008370093701037011370123701337014370153701637017370183701937020370213702237023370243702537026370273702837029370303703137032370333703437035370363703737038370393704037041370423704337044370453704637047370483704937050370513705237053370543705537056370573705837059370603706137062370633706437065370663706737068370693707037071370723707337074370753707637077370783707937080370813708237083370843708537086370873708837089370903709137092370933709437095370963709737098370993710037101371023710337104371053710637107371083710937110371113711237113371143711537116371173711837119371203712137122371233712437125371263712737128371293713037131371323713337134371353713637137371383713937140371413714237143371443714537146371473714837149371503715137152371533715437155371563715737158371593716037161371623716337164371653716637167371683716937170371713717237173371743717537176371773717837179371803718137182371833718437185371863718737188371893719037191371923719337194371953719637197371983719937200372013720237203372043720537206372073720837209372103721137212372133721437215372163721737218372193722037221372223722337224372253722637227372283722937230372313723237233372343723537236372373723837239372403724137242372433724437245372463724737248372493725037251372523725337254372553725637257372583725937260372613726237263372643726537266372673726837269372703727137272372733727437275372763727737278372793728037281372823728337284372853728637287372883728937290372913729237293372943729537296372973729837299373003730137302373033730437305373063730737308373093731037311373123731337314373153731637317373183731937320373213732237323373243732537326373273732837329373303733137332373333733437335373363733737338373393734037341373423734337344373453734637347373483734937350373513735237353373543735537356373573735837359373603736137362373633736437365373663736737368373693737037371373723737337374373753737637377373783737937380373813738237383373843738537386373873738837389373903739137392373933739437395373963739737398373993740037401374023740337404374053740637407374083740937410374113741237413374143741537416374173741837419374203742137422374233742437425374263742737428374293743037431374323743337434374353743637437374383743937440374413744237443374443744537446374473744837449374503745137452374533745437455374563745737458374593746037461374623746337464374653746637467374683746937470374713747237473374743747537476374773747837479374803748137482374833748437485374863748737488374893749037491374923749337494374953749637497374983749937500375013750237503375043750537506375073750837509375103751137512375133751437515375163751737518375193752037521375223752337524375253752637527375283752937530375313753237533375343753537536375373753837539375403754137542375433754437545375463754737548375493755037551375523755337554375553755637557375583755937560375613756237563375643756537566375673756837569375703757137572375733757437575375763757737578375793758037581375823758337584375853758637587375883758937590375913759237593375943759537596375973759837599376003760137602376033760437605376063760737608376093761037611376123761337614376153761637617376183761937620376213762237623376243762537626376273762837629376303763137632376333763437635376363763737638376393764037641376423764337644376453764637647376483764937650376513765237653376543765537656376573765837659376603766137662376633766437665376663766737668376693767037671376723767337674376753767637677376783767937680376813768237683376843768537686376873768837689376903769137692376933769437695376963769737698376993770037701377023770337704377053770637707377083770937710377113771237713377143771537716377173771837719377203772137722377233772437725377263772737728377293773037731377323773337734377353773637737377383773937740377413774237743377443774537746377473774837749377503775137752377533775437755377563775737758377593776037761377623776337764377653776637767377683776937770377713777237773377743777537776377773777837779377803778137782377833778437785377863778737788377893779037791377923779337794377953779637797377983779937800378013780237803378043780537806378073780837809378103781137812378133781437815378163781737818378193782037821378223782337824378253782637827378283782937830378313783237833378343783537836378373783837839378403784137842378433784437845378463784737848378493785037851378523785337854378553785637857378583785937860378613786237863378643786537866378673786837869378703787137872378733787437875378763787737878378793788037881378823788337884378853788637887378883788937890378913789237893378943789537896378973789837899379003790137902379033790437905379063790737908379093791037911379123791337914379153791637917379183791937920379213792237923379243792537926379273792837929379303793137932379333793437935379363793737938379393794037941379423794337944379453794637947379483794937950379513795237953379543795537956379573795837959379603796137962379633796437965379663796737968379693797037971379723797337974379753797637977379783797937980379813798237983379843798537986379873798837989379903799137992379933799437995379963799737998379993800038001380023800338004380053800638007380083800938010380113801238013380143801538016380173801838019380203802138022380233802438025380263802738028380293803038031380323803338034380353803638037380383803938040380413804238043380443804538046380473804838049380503805138052380533805438055380563805738058380593806038061380623806338064380653806638067380683806938070380713807238073380743807538076380773807838079380803808138082380833808438085380863808738088380893809038091380923809338094380953809638097380983809938100381013810238103381043810538106381073810838109381103811138112381133811438115381163811738118381193812038121381223812338124381253812638127381283812938130381313813238133381343813538136381373813838139381403814138142381433814438145381463814738148381493815038151381523815338154381553815638157381583815938160381613816238163381643816538166381673816838169381703817138172381733817438175381763817738178381793818038181381823818338184381853818638187381883818938190381913819238193381943819538196381973819838199382003820138202382033820438205382063820738208382093821038211382123821338214382153821638217382183821938220382213822238223382243822538226382273822838229382303823138232382333823438235382363823738238382393824038241382423824338244382453824638247382483824938250382513825238253382543825538256382573825838259382603826138262382633826438265382663826738268382693827038271382723827338274382753827638277382783827938280382813828238283382843828538286382873828838289382903829138292382933829438295382963829738298382993830038301383023830338304383053830638307383083830938310383113831238313383143831538316383173831838319383203832138322383233832438325383263832738328383293833038331383323833338334383353833638337383383833938340383413834238343383443834538346383473834838349383503835138352383533835438355383563835738358383593836038361383623836338364383653836638367383683836938370383713837238373383743837538376383773837838379383803838138382383833838438385383863838738388383893839038391383923839338394383953839638397383983839938400384013840238403384043840538406384073840838409384103841138412384133841438415384163841738418384193842038421384223842338424384253842638427384283842938430384313843238433384343843538436384373843838439384403844138442384433844438445384463844738448384493845038451384523845338454384553845638457384583845938460384613846238463384643846538466384673846838469384703847138472384733847438475384763847738478384793848038481384823848338484384853848638487384883848938490384913849238493384943849538496384973849838499385003850138502385033850438505385063850738508385093851038511385123851338514385153851638517385183851938520385213852238523385243852538526385273852838529385303853138532385333853438535385363853738538385393854038541385423854338544385453854638547385483854938550385513855238553385543855538556385573855838559385603856138562385633856438565385663856738568385693857038571385723857338574385753857638577385783857938580385813858238583385843858538586385873858838589385903859138592385933859438595385963859738598385993860038601386023860338604386053860638607386083860938610386113861238613386143861538616386173861838619386203862138622386233862438625386263862738628386293863038631386323863338634386353863638637386383863938640386413864238643386443864538646386473864838649386503865138652386533865438655386563865738658386593866038661386623866338664386653866638667386683866938670386713867238673386743867538676386773867838679386803868138682386833868438685386863868738688386893869038691386923869338694386953869638697386983869938700387013870238703387043870538706387073870838709387103871138712387133871438715387163871738718387193872038721387223872338724387253872638727387283872938730387313873238733387343873538736387373873838739387403874138742387433874438745387463874738748387493875038751387523875338754387553875638757387583875938760387613876238763387643876538766387673876838769387703877138772387733877438775387763877738778387793878038781387823878338784387853878638787387883878938790387913879238793387943879538796387973879838799388003880138802388033880438805388063880738808388093881038811388123881338814388153881638817388183881938820388213882238823388243882538826388273882838829388303883138832388333883438835388363883738838388393884038841388423884338844388453884638847388483884938850388513885238853388543885538856388573885838859388603886138862388633886438865388663886738868388693887038871388723887338874388753887638877388783887938880388813888238883388843888538886388873888838889388903889138892388933889438895388963889738898388993890038901389023890338904389053890638907389083890938910389113891238913389143891538916389173891838919389203892138922389233892438925389263892738928389293893038931389323893338934389353893638937389383893938940389413894238943389443894538946389473894838949389503895138952389533895438955389563895738958389593896038961389623896338964389653896638967389683896938970389713897238973389743897538976389773897838979389803898138982389833898438985389863898738988389893899038991389923899338994389953899638997389983899939000390013900239003390043900539006390073900839009390103901139012390133901439015390163901739018390193902039021390223902339024390253902639027390283902939030390313903239033390343903539036390373903839039390403904139042390433904439045390463904739048390493905039051390523905339054390553905639057390583905939060390613906239063390643906539066390673906839069390703907139072390733907439075390763907739078390793908039081390823908339084390853908639087390883908939090390913909239093390943909539096390973909839099391003910139102391033910439105391063910739108391093911039111391123911339114391153911639117391183911939120391213912239123391243912539126391273912839129391303913139132391333913439135391363913739138391393914039141391423914339144391453914639147391483914939150391513915239153391543915539156391573915839159391603916139162391633916439165391663916739168391693917039171391723917339174391753917639177391783917939180391813918239183391843918539186391873918839189391903919139192391933919439195391963919739198391993920039201392023920339204392053920639207392083920939210392113921239213392143921539216392173921839219392203922139222392233922439225392263922739228392293923039231392323923339234392353923639237392383923939240392413924239243392443924539246392473924839249392503925139252392533925439255392563925739258392593926039261392623926339264392653926639267392683926939270392713927239273392743927539276392773927839279392803928139282392833928439285392863928739288392893929039291392923929339294392953929639297392983929939300393013930239303393043930539306393073930839309393103931139312393133931439315393163931739318393193932039321393223932339324393253932639327393283932939330393313933239333393343933539336393373933839339393403934139342393433934439345393463934739348393493935039351393523935339354393553935639357393583935939360393613936239363393643936539366393673936839369393703937139372393733937439375393763937739378393793938039381393823938339384393853938639387393883938939390393913939239393393943939539396393973939839399394003940139402394033940439405394063940739408394093941039411394123941339414394153941639417394183941939420394213942239423394243942539426394273942839429394303943139432394333943439435394363943739438394393944039441394423944339444394453944639447394483944939450394513945239453394543945539456394573945839459394603946139462394633946439465394663946739468394693947039471394723947339474394753947639477394783947939480394813948239483394843948539486394873948839489394903949139492394933949439495394963949739498394993950039501395023950339504395053950639507395083950939510395113951239513395143951539516395173951839519395203952139522395233952439525395263952739528395293953039531395323953339534395353953639537395383953939540395413954239543395443954539546395473954839549395503955139552395533955439555395563955739558395593956039561395623956339564395653956639567395683956939570395713957239573395743957539576395773957839579395803958139582395833958439585395863958739588395893959039591395923959339594395953959639597395983959939600396013960239603396043960539606396073960839609396103961139612396133961439615396163961739618396193962039621396223962339624396253962639627396283962939630396313963239633396343963539636396373963839639396403964139642396433964439645396463964739648396493965039651396523965339654396553965639657396583965939660396613966239663396643966539666396673966839669396703967139672396733967439675396763967739678396793968039681396823968339684396853968639687396883968939690396913969239693396943969539696396973969839699397003970139702397033970439705397063970739708397093971039711397123971339714397153971639717397183971939720397213972239723397243972539726397273972839729397303973139732397333973439735397363973739738397393974039741397423974339744397453974639747397483974939750397513975239753397543975539756397573975839759397603976139762397633976439765397663976739768397693977039771397723977339774397753977639777397783977939780397813978239783397843978539786397873978839789397903979139792397933979439795397963979739798397993980039801398023980339804398053980639807398083980939810398113981239813398143981539816398173981839819398203982139822398233982439825398263982739828398293983039831398323983339834398353983639837398383983939840398413984239843398443984539846398473984839849398503985139852398533985439855398563985739858398593986039861398623986339864398653986639867398683986939870398713987239873398743987539876398773987839879398803988139882398833988439885398863988739888398893989039891398923989339894398953989639897398983989939900399013990239903399043990539906399073990839909399103991139912399133991439915399163991739918399193992039921399223992339924399253992639927399283992939930399313993239933399343993539936399373993839939399403994139942399433994439945399463994739948399493995039951399523995339954399553995639957399583995939960399613996239963399643996539966399673996839969399703997139972399733997439975399763997739978399793998039981399823998339984399853998639987399883998939990399913999239993399943999539996399973999839999400004000140002400034000440005400064000740008400094001040011400124001340014400154001640017400184001940020400214002240023400244002540026400274002840029400304003140032400334003440035400364003740038400394004040041400424004340044400454004640047400484004940050400514005240053400544005540056400574005840059400604006140062400634006440065400664006740068400694007040071400724007340074400754007640077400784007940080400814008240083400844008540086400874008840089400904009140092400934009440095400964009740098400994010040101401024010340104401054010640107401084010940110401114011240113401144011540116401174011840119401204012140122401234012440125401264012740128401294013040131401324013340134401354013640137401384013940140401414014240143401444014540146401474014840149401504015140152401534015440155401564015740158401594016040161401624016340164401654016640167401684016940170401714017240173401744017540176401774017840179401804018140182401834018440185401864018740188401894019040191401924019340194401954019640197401984019940200402014020240203402044020540206402074020840209402104021140212402134021440215402164021740218402194022040221402224022340224402254022640227402284022940230402314023240233402344023540236402374023840239402404024140242402434024440245402464024740248402494025040251402524025340254402554025640257402584025940260402614026240263402644026540266402674026840269402704027140272402734027440275402764027740278402794028040281402824028340284402854028640287402884028940290402914029240293402944029540296402974029840299403004030140302403034030440305403064030740308403094031040311403124031340314403154031640317403184031940320403214032240323403244032540326403274032840329403304033140332403334033440335403364033740338403394034040341403424034340344403454034640347403484034940350403514035240353403544035540356403574035840359403604036140362403634036440365403664036740368403694037040371403724037340374403754037640377403784037940380403814038240383403844038540386403874038840389403904039140392403934039440395403964039740398403994040040401404024040340404404054040640407404084040940410404114041240413404144041540416404174041840419404204042140422404234042440425404264042740428404294043040431404324043340434404354043640437404384043940440404414044240443404444044540446404474044840449404504045140452404534045440455404564045740458404594046040461404624046340464404654046640467404684046940470404714047240473404744047540476404774047840479404804048140482404834048440485404864048740488404894049040491404924049340494404954049640497404984049940500405014050240503405044050540506405074050840509405104051140512405134051440515405164051740518405194052040521405224052340524405254052640527405284052940530405314053240533405344053540536405374053840539405404054140542405434054440545405464054740548405494055040551405524055340554405554055640557405584055940560405614056240563405644056540566405674056840569405704057140572405734057440575405764057740578405794058040581405824058340584405854058640587405884058940590405914059240593405944059540596405974059840599406004060140602406034060440605406064060740608406094061040611406124061340614406154061640617406184061940620406214062240623406244062540626406274062840629406304063140632406334063440635406364063740638406394064040641406424064340644406454064640647406484064940650406514065240653406544065540656406574065840659406604066140662406634066440665406664066740668406694067040671406724067340674406754067640677406784067940680406814068240683406844068540686406874068840689406904069140692406934069440695406964069740698406994070040701407024070340704407054070640707407084070940710407114071240713407144071540716407174071840719407204072140722407234072440725407264072740728407294073040731407324073340734407354073640737407384073940740407414074240743407444074540746407474074840749407504075140752407534075440755407564075740758407594076040761407624076340764407654076640767407684076940770407714077240773407744077540776407774077840779407804078140782407834078440785407864078740788407894079040791407924079340794407954079640797407984079940800408014080240803408044080540806408074080840809408104081140812408134081440815408164081740818408194082040821408224082340824408254082640827408284082940830408314083240833408344083540836408374083840839408404084140842408434084440845408464084740848408494085040851408524085340854408554085640857408584085940860408614086240863408644086540866408674086840869408704087140872408734087440875408764087740878408794088040881408824088340884408854088640887408884088940890408914089240893408944089540896408974089840899409004090140902409034090440905409064090740908409094091040911409124091340914409154091640917409184091940920409214092240923409244092540926409274092840929409304093140932409334093440935409364093740938409394094040941409424094340944409454094640947409484094940950409514095240953409544095540956409574095840959409604096140962409634096440965409664096740968409694097040971409724097340974409754097640977409784097940980409814098240983409844098540986409874098840989409904099140992409934099440995409964099740998409994100041001410024100341004410054100641007410084100941010410114101241013410144101541016410174101841019410204102141022410234102441025410264102741028410294103041031410324103341034410354103641037410384103941040410414104241043410444104541046410474104841049410504105141052410534105441055410564105741058410594106041061410624106341064410654106641067410684106941070410714107241073410744107541076410774107841079410804108141082410834108441085410864108741088410894109041091410924109341094410954109641097410984109941100411014110241103411044110541106411074110841109411104111141112411134111441115411164111741118411194112041121411224112341124411254112641127411284112941130411314113241133411344113541136411374113841139411404114141142411434114441145411464114741148411494115041151411524115341154411554115641157411584115941160411614116241163411644116541166411674116841169411704117141172411734117441175411764117741178411794118041181411824118341184411854118641187411884118941190411914119241193411944119541196411974119841199412004120141202412034120441205412064120741208412094121041211412124121341214412154121641217412184121941220412214122241223412244122541226412274122841229412304123141232412334123441235412364123741238412394124041241412424124341244412454124641247412484124941250412514125241253412544125541256412574125841259412604126141262412634126441265412664126741268412694127041271412724127341274412754127641277412784127941280412814128241283412844128541286412874128841289412904129141292412934129441295412964129741298412994130041301413024130341304413054130641307413084130941310413114131241313413144131541316413174131841319413204132141322413234132441325413264132741328413294133041331413324133341334413354133641337413384133941340413414134241343413444134541346413474134841349413504135141352413534135441355413564135741358413594136041361413624136341364413654136641367413684136941370413714137241373413744137541376413774137841379413804138141382413834138441385413864138741388413894139041391413924139341394413954139641397413984139941400414014140241403414044140541406414074140841409414104141141412414134141441415414164141741418414194142041421414224142341424414254142641427414284142941430414314143241433414344143541436414374143841439414404144141442414434144441445414464144741448414494145041451414524145341454414554145641457414584145941460414614146241463414644146541466414674146841469414704147141472414734147441475414764147741478414794148041481414824148341484414854148641487414884148941490414914149241493414944149541496414974149841499415004150141502415034150441505415064150741508415094151041511415124151341514415154151641517415184151941520415214152241523415244152541526415274152841529415304153141532415334153441535415364153741538415394154041541415424154341544415454154641547415484154941550415514155241553415544155541556415574155841559415604156141562415634156441565415664156741568415694157041571415724157341574415754157641577415784157941580415814158241583415844158541586415874158841589415904159141592415934159441595415964159741598415994160041601416024160341604416054160641607416084160941610416114161241613416144161541616416174161841619416204162141622416234162441625416264162741628416294163041631416324163341634416354163641637416384163941640416414164241643416444164541646416474164841649416504165141652416534165441655416564165741658416594166041661416624166341664416654166641667416684166941670416714167241673416744167541676416774167841679416804168141682416834168441685416864168741688416894169041691416924169341694416954169641697416984169941700417014170241703417044170541706417074170841709417104171141712417134171441715417164171741718417194172041721417224172341724417254172641727417284172941730417314173241733417344173541736417374173841739417404174141742417434174441745417464174741748417494175041751417524175341754417554175641757417584175941760417614176241763417644176541766417674176841769417704177141772417734177441775417764177741778417794178041781417824178341784417854178641787417884178941790417914179241793417944179541796417974179841799418004180141802418034180441805418064180741808418094181041811418124181341814418154181641817418184181941820418214182241823418244182541826418274182841829418304183141832418334183441835418364183741838418394184041841418424184341844418454184641847418484184941850418514185241853418544185541856418574185841859418604186141862418634186441865418664186741868418694187041871418724187341874418754187641877418784187941880418814188241883418844188541886418874188841889418904189141892418934189441895418964189741898418994190041901419024190341904419054190641907419084190941910419114191241913419144191541916419174191841919419204192141922419234192441925419264192741928419294193041931419324193341934419354193641937419384193941940419414194241943419444194541946419474194841949419504195141952419534195441955419564195741958419594196041961419624196341964419654196641967419684196941970419714197241973419744197541976419774197841979419804198141982419834198441985419864198741988419894199041991419924199341994419954199641997419984199942000420014200242003420044200542006420074200842009420104201142012420134201442015420164201742018420194202042021420224202342024420254202642027420284202942030420314203242033420344203542036420374203842039420404204142042420434204442045420464204742048420494205042051420524205342054420554205642057420584205942060420614206242063420644206542066420674206842069420704207142072420734207442075420764207742078420794208042081420824208342084420854208642087420884208942090420914209242093420944209542096420974209842099421004210142102421034210442105421064210742108421094211042111421124211342114421154211642117421184211942120421214212242123421244212542126421274212842129421304213142132421334213442135421364213742138421394214042141421424214342144421454214642147421484214942150421514215242153421544215542156421574215842159421604216142162421634216442165421664216742168421694217042171421724217342174421754217642177421784217942180421814218242183421844218542186421874218842189421904219142192421934219442195421964219742198421994220042201422024220342204422054220642207422084220942210422114221242213422144221542216422174221842219422204222142222422234222442225422264222742228422294223042231422324223342234422354223642237422384223942240422414224242243422444224542246422474224842249422504225142252422534225442255422564225742258422594226042261422624226342264422654226642267422684226942270422714227242273422744227542276422774227842279422804228142282422834228442285422864228742288422894229042291422924229342294422954229642297422984229942300423014230242303423044230542306423074230842309423104231142312423134231442315423164231742318423194232042321423224232342324423254232642327423284232942330423314233242333423344233542336423374233842339423404234142342423434234442345423464234742348423494235042351423524235342354423554235642357423584235942360423614236242363423644236542366423674236842369423704237142372423734237442375423764237742378423794238042381423824238342384423854238642387423884238942390423914239242393423944239542396423974239842399424004240142402424034240442405424064240742408424094241042411424124241342414424154241642417424184241942420424214242242423424244242542426424274242842429424304243142432424334243442435424364243742438424394244042441424424244342444424454244642447424484244942450424514245242453424544245542456424574245842459424604246142462424634246442465424664246742468424694247042471424724247342474424754247642477424784247942480424814248242483424844248542486424874248842489424904249142492424934249442495424964249742498424994250042501425024250342504425054250642507425084250942510425114251242513425144251542516425174251842519425204252142522425234252442525425264252742528425294253042531425324253342534425354253642537425384253942540425414254242543425444254542546425474254842549425504255142552425534255442555425564255742558425594256042561425624256342564425654256642567425684256942570425714257242573425744257542576425774257842579425804258142582425834258442585425864258742588425894259042591425924259342594425954259642597425984259942600426014260242603426044260542606426074260842609426104261142612426134261442615426164261742618426194262042621426224262342624426254262642627426284262942630426314263242633426344263542636426374263842639426404264142642426434264442645426464264742648426494265042651426524265342654426554265642657426584265942660426614266242663426644266542666426674266842669426704267142672426734267442675426764267742678426794268042681426824268342684426854268642687426884268942690426914269242693426944269542696426974269842699427004270142702427034270442705427064270742708427094271042711427124271342714427154271642717427184271942720427214272242723427244272542726427274272842729427304273142732427334273442735427364273742738427394274042741427424274342744427454274642747427484274942750427514275242753427544275542756427574275842759427604276142762427634276442765427664276742768427694277042771427724277342774427754277642777427784277942780427814278242783427844278542786427874278842789427904279142792427934279442795427964279742798427994280042801428024280342804428054280642807428084280942810428114281242813428144281542816428174281842819428204282142822428234282442825428264282742828428294283042831428324283342834428354283642837428384283942840428414284242843428444284542846428474284842849428504285142852428534285442855428564285742858428594286042861428624286342864428654286642867428684286942870428714287242873428744287542876428774287842879428804288142882428834288442885428864288742888428894289042891428924289342894428954289642897428984289942900429014290242903429044290542906429074290842909429104291142912429134291442915429164291742918429194292042921429224292342924429254292642927429284292942930429314293242933429344293542936429374293842939429404294142942429434294442945429464294742948429494295042951429524295342954429554295642957429584295942960429614296242963429644296542966429674296842969429704297142972429734297442975429764297742978429794298042981429824298342984429854298642987429884298942990429914299242993429944299542996429974299842999430004300143002430034300443005430064300743008430094301043011430124301343014430154301643017430184301943020430214302243023430244302543026430274302843029430304303143032430334303443035430364303743038430394304043041430424304343044430454304643047430484304943050430514305243053430544305543056430574305843059430604306143062430634306443065430664306743068430694307043071430724307343074430754307643077430784307943080430814308243083430844308543086430874308843089430904309143092430934309443095430964309743098430994310043101431024310343104431054310643107431084310943110431114311243113431144311543116431174311843119431204312143122431234312443125431264312743128431294313043131431324313343134431354313643137431384313943140431414314243143431444314543146431474314843149431504315143152431534315443155431564315743158431594316043161431624316343164431654316643167431684316943170431714317243173431744317543176431774317843179431804318143182431834318443185431864318743188431894319043191431924319343194431954319643197431984319943200432014320243203432044320543206432074320843209432104321143212432134321443215432164321743218432194322043221432224322343224432254322643227432284322943230432314323243233432344323543236432374323843239432404324143242432434324443245432464324743248432494325043251432524325343254432554325643257432584325943260432614326243263432644326543266432674326843269432704327143272432734327443275432764327743278432794328043281432824328343284432854328643287432884328943290432914329243293432944329543296432974329843299433004330143302433034330443305433064330743308433094331043311433124331343314433154331643317433184331943320433214332243323433244332543326433274332843329433304333143332433334333443335433364333743338433394334043341433424334343344433454334643347433484334943350433514335243353433544335543356433574335843359433604336143362433634336443365433664336743368433694337043371433724337343374433754337643377433784337943380433814338243383433844338543386433874338843389433904339143392433934339443395433964339743398433994340043401434024340343404434054340643407434084340943410434114341243413434144341543416434174341843419434204342143422434234342443425434264342743428434294343043431434324343343434434354343643437434384343943440434414344243443434444344543446434474344843449434504345143452434534345443455434564345743458434594346043461434624346343464434654346643467434684346943470434714347243473434744347543476434774347843479434804348143482434834348443485434864348743488434894349043491434924349343494434954349643497434984349943500435014350243503435044350543506435074350843509435104351143512435134351443515435164351743518435194352043521435224352343524435254352643527435284352943530435314353243533435344353543536435374353843539435404354143542435434354443545435464354743548435494355043551435524355343554435554355643557435584355943560435614356243563435644356543566435674356843569435704357143572435734357443575435764357743578435794358043581435824358343584435854358643587435884358943590435914359243593435944359543596435974359843599436004360143602436034360443605436064360743608436094361043611436124361343614436154361643617436184361943620436214362243623436244362543626436274362843629436304363143632436334363443635436364363743638436394364043641436424364343644436454364643647436484364943650436514365243653436544365543656436574365843659436604366143662436634366443665436664366743668436694367043671436724367343674436754367643677436784367943680436814368243683436844368543686436874368843689436904369143692436934369443695436964369743698436994370043701437024370343704437054370643707437084370943710437114371243713437144371543716437174371843719437204372143722437234372443725437264372743728437294373043731437324373343734437354373643737437384373943740437414374243743437444374543746437474374843749437504375143752437534375443755437564375743758437594376043761437624376343764437654376643767437684376943770437714377243773437744377543776437774377843779437804378143782437834378443785437864378743788437894379043791437924379343794437954379643797437984379943800438014380243803438044380543806438074380843809438104381143812438134381443815438164381743818438194382043821438224382343824438254382643827438284382943830438314383243833438344383543836438374383843839438404384143842438434384443845438464384743848438494385043851438524385343854438554385643857438584385943860438614386243863438644386543866438674386843869438704387143872438734387443875438764387743878438794388043881438824388343884438854388643887438884388943890438914389243893438944389543896438974389843899439004390143902439034390443905439064390743908439094391043911439124391343914439154391643917439184391943920439214392243923439244392543926439274392843929439304393143932439334393443935439364393743938439394394043941439424394343944439454394643947439484394943950439514395243953439544395543956439574395843959439604396143962439634396443965439664396743968439694397043971439724397343974439754397643977439784397943980439814398243983439844398543986439874398843989439904399143992439934399443995439964399743998439994400044001440024400344004440054400644007440084400944010440114401244013440144401544016440174401844019440204402144022440234402444025440264402744028440294403044031440324403344034440354403644037440384403944040440414404244043440444404544046440474404844049440504405144052440534405444055440564405744058440594406044061440624406344064440654406644067440684406944070440714407244073440744407544076440774407844079440804408144082440834408444085440864408744088440894409044091440924409344094440954409644097440984409944100441014410244103441044410544106441074410844109441104411144112441134411444115441164411744118441194412044121441224412344124441254412644127441284412944130441314413244133441344413544136441374413844139441404414144142441434414444145441464414744148441494415044151441524415344154441554415644157441584415944160441614416244163441644416544166441674416844169441704417144172441734417444175441764417744178441794418044181441824418344184441854418644187441884418944190441914419244193441944419544196441974419844199442004420144202442034420444205442064420744208442094421044211442124421344214442154421644217442184421944220442214422244223442244422544226442274422844229442304423144232442334423444235442364423744238442394424044241442424424344244442454424644247442484424944250442514425244253442544425544256442574425844259442604426144262442634426444265442664426744268442694427044271442724427344274442754427644277442784427944280442814428244283442844428544286442874428844289442904429144292442934429444295442964429744298442994430044301443024430344304443054430644307443084430944310443114431244313443144431544316443174431844319443204432144322443234432444325443264432744328443294433044331443324433344334443354433644337443384433944340443414434244343443444434544346443474434844349443504435144352443534435444355443564435744358443594436044361443624436344364443654436644367443684436944370443714437244373443744437544376443774437844379443804438144382443834438444385443864438744388443894439044391443924439344394443954439644397443984439944400444014440244403444044440544406444074440844409444104441144412444134441444415444164441744418444194442044421444224442344424444254442644427444284442944430444314443244433444344443544436444374443844439444404444144442444434444444445444464444744448444494445044451444524445344454444554445644457444584445944460444614446244463444644446544466444674446844469444704447144472444734447444475444764447744478444794448044481444824448344484444854448644487444884448944490444914449244493444944449544496444974449844499445004450144502445034450444505445064450744508445094451044511445124451344514445154451644517445184451944520445214452244523445244452544526445274452844529445304453144532445334453444535445364453744538445394454044541445424454344544445454454644547445484454944550445514455244553445544455544556445574455844559445604456144562445634456444565445664456744568445694457044571445724457344574445754457644577445784457944580445814458244583445844458544586445874458844589445904459144592445934459444595445964459744598445994460044601446024460344604446054460644607446084460944610446114461244613446144461544616446174461844619446204462144622446234462444625446264462744628446294463044631446324463344634446354463644637446384463944640446414464244643446444464544646446474464844649446504465144652446534465444655446564465744658446594466044661446624466344664446654466644667446684466944670446714467244673446744467544676446774467844679446804468144682446834468444685446864468744688446894469044691446924469344694446954469644697446984469944700447014470244703447044470544706447074470844709447104471144712447134471444715447164471744718447194472044721447224472344724447254472644727447284472944730447314473244733447344473544736447374473844739447404474144742447434474444745447464474744748447494475044751447524475344754447554475644757447584475944760447614476244763447644476544766447674476844769447704477144772447734477444775447764477744778447794478044781447824478344784447854478644787447884478944790447914479244793447944479544796447974479844799448004480144802448034480444805448064480744808448094481044811448124481344814448154481644817448184481944820448214482244823448244482544826448274482844829448304483144832448334483444835448364483744838448394484044841448424484344844448454484644847448484484944850448514485244853448544485544856448574485844859448604486144862448634486444865448664486744868448694487044871448724487344874448754487644877448784487944880448814488244883448844488544886448874488844889448904489144892448934489444895448964489744898448994490044901449024490344904449054490644907449084490944910449114491244913449144491544916449174491844919449204492144922449234492444925449264492744928449294493044931449324493344934449354493644937449384493944940449414494244943449444494544946449474494844949449504495144952449534495444955449564495744958449594496044961449624496344964449654496644967449684496944970449714497244973449744497544976449774497844979449804498144982449834498444985449864498744988449894499044991449924499344994449954499644997449984499945000450014500245003450044500545006450074500845009450104501145012450134501445015450164501745018450194502045021450224502345024450254502645027450284502945030450314503245033450344503545036450374503845039450404504145042450434504445045450464504745048450494505045051450524505345054450554505645057450584505945060450614506245063450644506545066450674506845069450704507145072450734507445075450764507745078450794508045081450824508345084450854508645087450884508945090450914509245093450944509545096450974509845099451004510145102451034510445105451064510745108451094511045111451124511345114451154511645117451184511945120451214512245123451244512545126451274512845129451304513145132451334513445135451364513745138451394514045141451424514345144451454514645147451484514945150451514515245153451544515545156451574515845159451604516145162451634516445165451664516745168451694517045171451724517345174451754517645177451784517945180451814518245183451844518545186451874518845189451904519145192451934519445195451964519745198451994520045201452024520345204452054520645207452084520945210452114521245213452144521545216452174521845219452204522145222452234522445225452264522745228452294523045231452324523345234452354523645237452384523945240452414524245243452444524545246452474524845249452504525145252452534525445255452564525745258452594526045261452624526345264452654526645267452684526945270452714527245273452744527545276452774527845279452804528145282452834528445285452864528745288452894529045291452924529345294452954529645297452984529945300453014530245303453044530545306453074530845309453104531145312453134531445315453164531745318453194532045321453224532345324453254532645327453284532945330453314533245333453344533545336453374533845339453404534145342453434534445345453464534745348453494535045351453524535345354453554535645357453584535945360453614536245363453644536545366453674536845369453704537145372453734537445375453764537745378453794538045381453824538345384453854538645387453884538945390453914539245393453944539545396453974539845399454004540145402454034540445405454064540745408454094541045411454124541345414454154541645417454184541945420454214542245423454244542545426454274542845429454304543145432454334543445435454364543745438454394544045441454424544345444454454544645447454484544945450454514545245453454544545545456454574545845459454604546145462454634546445465454664546745468454694547045471454724547345474454754547645477454784547945480454814548245483454844548545486454874548845489454904549145492454934549445495454964549745498454994550045501455024550345504455054550645507455084550945510455114551245513455144551545516455174551845519455204552145522455234552445525455264552745528455294553045531455324553345534455354553645537455384553945540455414554245543455444554545546455474554845549455504555145552455534555445555455564555745558455594556045561455624556345564455654556645567455684556945570455714557245573455744557545576455774557845579455804558145582455834558445585455864558745588455894559045591455924559345594455954559645597455984559945600456014560245603456044560545606456074560845609456104561145612456134561445615456164561745618456194562045621456224562345624456254562645627456284562945630456314563245633456344563545636456374563845639456404564145642456434564445645456464564745648456494565045651456524565345654456554565645657456584565945660456614566245663456644566545666456674566845669456704567145672456734567445675456764567745678456794568045681456824568345684456854568645687456884568945690456914569245693456944569545696456974569845699457004570145702457034570445705457064570745708457094571045711457124571345714457154571645717457184571945720457214572245723457244572545726457274572845729457304573145732457334573445735457364573745738457394574045741457424574345744457454574645747457484574945750457514575245753457544575545756457574575845759457604576145762457634576445765457664576745768457694577045771457724577345774457754577645777457784577945780457814578245783457844578545786457874578845789457904579145792457934579445795457964579745798457994580045801458024580345804458054580645807458084580945810458114581245813458144581545816458174581845819458204582145822458234582445825458264582745828458294583045831458324583345834458354583645837458384583945840458414584245843458444584545846458474584845849458504585145852458534585445855458564585745858458594586045861458624586345864458654586645867458684586945870458714587245873458744587545876458774587845879458804588145882458834588445885458864588745888458894589045891458924589345894458954589645897458984589945900459014590245903459044590545906459074590845909459104591145912459134591445915459164591745918459194592045921459224592345924459254592645927459284592945930459314593245933459344593545936459374593845939459404594145942459434594445945459464594745948459494595045951459524595345954459554595645957459584595945960459614596245963459644596545966459674596845969459704597145972459734597445975459764597745978459794598045981459824598345984459854598645987459884598945990459914599245993459944599545996459974599845999460004600146002460034600446005460064600746008460094601046011460124601346014460154601646017460184601946020460214602246023460244602546026460274602846029460304603146032460334603446035460364603746038460394604046041460424604346044460454604646047460484604946050460514605246053460544605546056460574605846059460604606146062460634606446065460664606746068460694607046071460724607346074460754607646077460784607946080460814608246083460844608546086460874608846089460904609146092460934609446095460964609746098460994610046101461024610346104461054610646107461084610946110461114611246113461144611546116461174611846119461204612146122461234612446125461264612746128461294613046131461324613346134461354613646137461384613946140461414614246143461444614546146461474614846149461504615146152461534615446155461564615746158461594616046161461624616346164461654616646167461684616946170461714617246173461744617546176461774617846179461804618146182461834618446185461864618746188461894619046191461924619346194461954619646197461984619946200462014620246203462044620546206462074620846209462104621146212462134621446215462164621746218462194622046221462224622346224462254622646227462284622946230462314623246233462344623546236462374623846239462404624146242462434624446245462464624746248462494625046251462524625346254462554625646257462584625946260462614626246263462644626546266462674626846269462704627146272462734627446275462764627746278462794628046281462824628346284462854628646287462884628946290462914629246293462944629546296462974629846299463004630146302463034630446305463064630746308463094631046311463124631346314463154631646317463184631946320463214632246323463244632546326463274632846329463304633146332463334633446335463364633746338463394634046341463424634346344463454634646347463484634946350463514635246353463544635546356463574635846359463604636146362463634636446365463664636746368463694637046371463724637346374463754637646377463784637946380463814638246383463844638546386463874638846389463904639146392463934639446395463964639746398463994640046401464024640346404464054640646407464084640946410464114641246413464144641546416464174641846419464204642146422464234642446425464264642746428464294643046431464324643346434464354643646437464384643946440464414644246443464444644546446464474644846449464504645146452464534645446455464564645746458464594646046461464624646346464464654646646467464684646946470464714647246473464744647546476464774647846479464804648146482464834648446485464864648746488464894649046491464924649346494464954649646497464984649946500465014650246503465044650546506465074650846509465104651146512465134651446515465164651746518465194652046521465224652346524465254652646527465284652946530465314653246533465344653546536465374653846539465404654146542465434654446545465464654746548465494655046551465524655346554465554655646557465584655946560465614656246563465644656546566465674656846569465704657146572465734657446575465764657746578465794658046581465824658346584465854658646587465884658946590465914659246593465944659546596465974659846599466004660146602466034660446605466064660746608466094661046611466124661346614466154661646617466184661946620466214662246623466244662546626466274662846629466304663146632466334663446635466364663746638466394664046641466424664346644466454664646647466484664946650466514665246653466544665546656466574665846659466604666146662466634666446665466664666746668466694667046671466724667346674466754667646677466784667946680466814668246683466844668546686466874668846689466904669146692466934669446695466964669746698466994670046701467024670346704467054670646707467084670946710467114671246713467144671546716467174671846719467204672146722467234672446725467264672746728467294673046731467324673346734467354673646737467384673946740467414674246743467444674546746467474674846749467504675146752467534675446755467564675746758467594676046761467624676346764467654676646767467684676946770467714677246773467744677546776467774677846779467804678146782467834678446785467864678746788467894679046791467924679346794467954679646797467984679946800468014680246803468044680546806468074680846809468104681146812468134681446815468164681746818468194682046821468224682346824468254682646827468284682946830468314683246833468344683546836468374683846839468404684146842468434684446845468464684746848468494685046851468524685346854468554685646857468584685946860468614686246863468644686546866468674686846869468704687146872468734687446875468764687746878468794688046881468824688346884468854688646887468884688946890468914689246893468944689546896468974689846899469004690146902469034690446905469064690746908469094691046911469124691346914469154691646917469184691946920469214692246923469244692546926469274692846929469304693146932469334693446935469364693746938469394694046941469424694346944469454694646947469484694946950469514695246953469544695546956469574695846959469604696146962469634696446965469664696746968469694697046971469724697346974469754697646977469784697946980469814698246983469844698546986469874698846989469904699146992469934699446995469964699746998469994700047001470024700347004470054700647007470084700947010470114701247013470144701547016470174701847019470204702147022470234702447025470264702747028470294703047031470324703347034470354703647037470384703947040470414704247043470444704547046470474704847049470504705147052470534705447055470564705747058470594706047061470624706347064470654706647067470684706947070470714707247073470744707547076470774707847079470804708147082470834708447085470864708747088470894709047091470924709347094470954709647097470984709947100471014710247103471044710547106471074710847109471104711147112471134711447115471164711747118471194712047121471224712347124471254712647127471284712947130471314713247133471344713547136471374713847139471404714147142471434714447145471464714747148471494715047151471524715347154471554715647157471584715947160471614716247163471644716547166471674716847169471704717147172471734717447175471764717747178471794718047181471824718347184471854718647187471884718947190471914719247193471944719547196471974719847199472004720147202472034720447205472064720747208472094721047211472124721347214472154721647217472184721947220472214722247223472244722547226472274722847229472304723147232472334723447235472364723747238472394724047241472424724347244472454724647247472484724947250472514725247253472544725547256472574725847259472604726147262472634726447265472664726747268472694727047271472724727347274472754727647277472784727947280472814728247283472844728547286472874728847289472904729147292472934729447295472964729747298472994730047301473024730347304473054730647307473084730947310473114731247313473144731547316473174731847319473204732147322473234732447325473264732747328473294733047331473324733347334473354733647337473384733947340473414734247343473444734547346473474734847349473504735147352473534735447355473564735747358473594736047361473624736347364473654736647367473684736947370473714737247373473744737547376473774737847379473804738147382473834738447385473864738747388473894739047391473924739347394473954739647397473984739947400474014740247403474044740547406474074740847409474104741147412474134741447415474164741747418474194742047421474224742347424474254742647427474284742947430474314743247433474344743547436474374743847439474404744147442474434744447445474464744747448474494745047451474524745347454474554745647457474584745947460474614746247463474644746547466474674746847469474704747147472474734747447475474764747747478474794748047481474824748347484474854748647487474884748947490474914749247493474944749547496474974749847499475004750147502475034750447505475064750747508475094751047511475124751347514475154751647517475184751947520475214752247523475244752547526475274752847529475304753147532475334753447535475364753747538475394754047541 |
- (function webpackUniversalModuleDefinition(root, factory) {
- if(typeof exports === 'object' && typeof module === 'object')
- module.exports = factory();
- else if(typeof define === 'function' && define.amd)
- define([], factory);
- else if(typeof exports === 'object')
- exports["PhoneJs"] = factory();
- else
- root["PhoneJs"] = factory();
- })(typeof self !== 'undefined' ? self : this, function() {
- return (function(modules) { // webpackBootstrap
- // The module cache
- var installedModules = {};
- // The require function
- function __webpack_require__(moduleId) {
- // Check if module is in cache
- if(installedModules[moduleId]) {
- return installedModules[moduleId].exports;
- }
- // Create a new module (and put it into the cache)
- var module = installedModules[moduleId] = {
- i: moduleId,
- l: false,
- exports: {}
- };
- // Execute the module function
- modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
- // Flag the module as loaded
- module.l = true;
- // Return the exports of the module
- return module.exports;
- }
- // expose the modules object (__webpack_modules__)
- __webpack_require__.m = modules;
- // expose the module cache
- __webpack_require__.c = installedModules;
- // define getter function for harmony exports
- __webpack_require__.d = function(exports, name, getter) {
- if(!__webpack_require__.o(exports, name)) {
- Object.defineProperty(exports, name, {
- configurable: false,
- enumerable: true,
- get: getter
- });
- }
- };
- // getDefaultExport function for compatibility with non-harmony modules
- __webpack_require__.n = function(module) {
- var getter = module && module.__esModule ?
- function getDefault() { return module['default']; } :
- function getModuleExports() { return module; };
- __webpack_require__.d(getter, 'a', getter);
- return getter;
- };
- // Object.prototype.hasOwnProperty.call
- __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
- // __webpack_public_path__
- __webpack_require__.p = "";
- // Load entry module and return exports
- return __webpack_require__(__webpack_require__.s = 23);
- })
- /************************************************************************/
- ([
- /* 0 */
- (function(module, exports, __webpack_require__) {
- /* WEBPACK VAR INJECTION */(function(process) {/* eslint-env browser */
- /**
- * This is the web browser implementation of `debug()`.
- */
- exports.log = log;
- exports.formatArgs = formatArgs;
- exports.save = save;
- exports.load = load;
- exports.useColors = useColors;
- exports.storage = localstorage();
- /**
- * Colors.
- */
- exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33'];
- /**
- * Currently only WebKit-based Web Inspectors, Firefox >= v31,
- * and the Firebug extension (any Firefox version) are known
- * to support "%c" CSS customizations.
- *
- * TODO: add a `localStorage` variable to explicitly enable/disable colors
- */
- // eslint-disable-next-line complexity
- function useColors() {
- // NB: In an Electron preload script, document will be defined but not fully
- // initialized. Since we know we're in Chrome, we'll just detect this case
- // explicitly
- if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
- return true;
- } // Internet Explorer and Edge do not support colors.
- if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
- return false;
- } // Is webkit? http://stackoverflow.com/a/16459606/376773
- // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
- return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773
- typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?
- // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
- typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker
- typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
- }
- /**
- * Colorize log arguments if enabled.
- *
- * @api public
- */
- function formatArgs(args) {
- args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff);
- if (!this.useColors) {
- return;
- }
- const c = 'color: ' + this.color;
- args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other
- // arguments passed either before or after the %c, so we need to
- // figure out the correct index to insert the CSS into
- let index = 0;
- let lastC = 0;
- args[0].replace(/%[a-zA-Z%]/g, match => {
- if (match === '%%') {
- return;
- }
- index++;
- if (match === '%c') {
- // We only are interested in the *last* %c
- // (the user may have provided their own)
- lastC = index;
- }
- });
- args.splice(lastC, 0, c);
- }
- /**
- * Invokes `console.log()` when available.
- * No-op when `console.log` is not a "function".
- *
- * @api public
- */
- function log(...args) {
- // This hackery is required for IE8/9, where
- // the `console.log` function doesn't have 'apply'
- return typeof console === 'object' && console.log && console.log(...args);
- }
- /**
- * Save `namespaces`.
- *
- * @param {String} namespaces
- * @api private
- */
- function save(namespaces) {
- try {
- if (namespaces) {
- exports.storage.setItem('debug', namespaces);
- } else {
- exports.storage.removeItem('debug');
- }
- } catch (error) {// Swallow
- // XXX (@Qix-) should we be logging these?
- }
- }
- /**
- * Load `namespaces`.
- *
- * @return {String} returns the previously persisted debug modes
- * @api private
- */
- function load() {
- let r;
- try {
- r = exports.storage.getItem('debug');
- } catch (error) {} // Swallow
- // XXX (@Qix-) should we be logging these?
- // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
- if (!r && typeof process !== 'undefined' && 'env' in process) {
- r = process.env.DEBUG;
- }
- return r;
- }
- /**
- * Localstorage attempts to return the localstorage.
- *
- * This is necessary because safari throws
- * when a user disables cookies/localstorage
- * and you attempt to access it.
- *
- * @return {LocalStorage}
- * @api private
- */
- function localstorage() {
- try {
- // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
- // The Browser also has localStorage in the global context.
- return localStorage;
- } catch (error) {// Swallow
- // XXX (@Qix-) should we be logging these?
- }
- }
- module.exports = __webpack_require__(29)(exports);
- const {
- formatters
- } = module.exports;
- /**
- * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
- */
- formatters.j = function (v) {
- try {
- return JSON.stringify(v);
- } catch (error) {
- return '[UnexpectedJSONParseError]: ' + error.message;
- }
- };
- /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(15)))
- }),
- /* 1 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- var pkg = __webpack_require__(12);
- module.exports = {
- USER_AGENT: "".concat(pkg.title, " ").concat(pkg.version),
- // SIP scheme.
- SIP: 'sip',
- SIPS: 'sips',
- // End and Failure causes.
- causes: {
- // Generic error causes.
- CONNECTION_ERROR: 'Connection Error',
- REQUEST_TIMEOUT: 'Request Timeout',
- SIP_FAILURE_CODE: 'SIP Failure Code',
- INTERNAL_ERROR: 'Internal Error',
- // SIP error causes.
- BUSY: 'Busy',
- REJECTED: 'Rejected',
- REDIRECTED: 'Redirected',
- UNAVAILABLE: 'Unavailable',
- NOT_FOUND: 'Not Found',
- ADDRESS_INCOMPLETE: 'Address Incomplete',
- INCOMPATIBLE_SDP: 'Incompatible SDP',
- MISSING_SDP: 'Missing SDP',
- AUTHENTICATION_ERROR: 'Authentication Error',
- // Session error causes.
- BYE: 'Terminated',
- WEBRTC_ERROR: 'WebRTC Error',
- CANCELED: 'Canceled',
- NO_ANSWER: 'No Answer',
- EXPIRES: 'Expires',
- NO_ACK: 'No ACK',
- DIALOG_ERROR: 'Dialog Error',
- USER_DENIED_MEDIA_ACCESS: 'User Denied Media Access',
- BAD_MEDIA_DESCRIPTION: 'Bad Media Description',
- RTP_TIMEOUT: 'RTP Timeout'
- },
- SIP_ERROR_CAUSES: {
- REDIRECTED: [300, 301, 302, 305, 380],
- BUSY: [486, 600],
- REJECTED: [403, 603],
- NOT_FOUND: [404, 604],
- UNAVAILABLE: [480, 410, 408, 430],
- ADDRESS_INCOMPLETE: [484, 424],
- INCOMPATIBLE_SDP: [488, 606],
- AUTHENTICATION_ERROR: [401, 407]
- },
- // SIP Methods.
- ACK: 'ACK',
- BYE: 'BYE',
- CANCEL: 'CANCEL',
- INFO: 'INFO',
- INVITE: 'INVITE',
- MESSAGE: 'MESSAGE',
- NOTIFY: 'NOTIFY',
- OPTIONS: 'OPTIONS',
- REGISTER: 'REGISTER',
- REFER: 'REFER',
- UPDATE: 'UPDATE',
- SUBSCRIBE: 'SUBSCRIBE',
- /* SIP Response Reasons
- * DOC: https://www.iana.org/assignments/sip-parameters
- * Copied from https://github.com/versatica/OverSIP/blob/master/lib/oversip/sip/constants.rb#L7
- */
- REASON_PHRASE: {
- 100: 'Trying',
- 180: 'Ringing',
- 181: 'Call Is Being Forwarded',
- 182: 'Queued',
- 183: 'Session Progress',
- 199: 'Early Dialog Terminated',
- // draft-ietf-sipcore-199
- 200: 'OK',
- 202: 'Accepted',
- // RFC 3265
- 204: 'No Notification',
- // RFC 5839
- 300: 'Multiple Choices',
- 301: 'Moved Permanently',
- 302: 'Moved Temporarily',
- 305: 'Use Proxy',
- 380: 'Alternative Service',
- 400: 'Bad Request',
- 401: 'Unauthorized',
- 402: 'Payment Required',
- 403: 'Forbidden',
- 404: 'Not Found',
- 405: 'Method Not Allowed',
- 406: 'Not Acceptable',
- 407: 'Proxy Authentication Required',
- 408: 'Request Timeout',
- 410: 'Gone',
- 412: 'Conditional Request Failed',
- // RFC 3903
- 413: 'Request Entity Too Large',
- 414: 'Request-URI Too Long',
- 415: 'Unsupported Media Type',
- 416: 'Unsupported URI Scheme',
- 417: 'Unknown Resource-Priority',
- // RFC 4412
- 420: 'Bad Extension',
- 421: 'Extension Required',
- 422: 'Session Interval Too Small',
- // RFC 4028
- 423: 'Interval Too Brief',
- 424: 'Bad Location Information',
- // RFC 6442
- 428: 'Use Identity Header',
- // RFC 4474
- 429: 'Provide Referrer Identity',
- // RFC 3892
- 430: 'Flow Failed',
- // RFC 5626
- 433: 'Anonymity Disallowed',
- // RFC 5079
- 436: 'Bad Identity-Info',
- // RFC 4474
- 437: 'Unsupported Certificate',
- // RFC 4744
- 438: 'Invalid Identity Header',
- // RFC 4744
- 439: 'First Hop Lacks Outbound Support',
- // RFC 5626
- 440: 'Max-Breadth Exceeded',
- // RFC 5393
- 469: 'Bad Info Package',
- // draft-ietf-sipcore-info-events
- 470: 'Consent Needed',
- // RFC 5360
- 478: 'Unresolvable Destination',
- // Custom code copied from Kamailio.
- 480: 'Temporarily Unavailable',
- 481: 'Call/Transaction Does Not Exist',
- 482: 'Loop Detected',
- 483: 'Too Many Hops',
- 484: 'Address Incomplete',
- 485: 'Ambiguous',
- 486: 'Busy Here',
- 487: 'Request Terminated',
- 488: 'Not Acceptable Here',
- 489: 'Bad Event',
- // RFC 3265
- 491: 'Request Pending',
- 493: 'Undecipherable',
- 494: 'Security Agreement Required',
- // RFC 3329
- 500: 'JsSIP Internal Error',
- 501: 'Not Implemented',
- 502: 'Bad Gateway',
- 503: 'Service Unavailable',
- 504: 'Server Time-out',
- 505: 'Version Not Supported',
- 513: 'Message Too Large',
- 580: 'Precondition Failure',
- // RFC 3312
- 600: 'Busy Everywhere',
- 603: 'Decline',
- 604: 'Does Not Exist Anywhere',
- 606: 'Not Acceptable'
- },
- ALLOWED_METHODS: 'INVITE,ACK,CANCEL,BYE,UPDATE,MESSAGE,OPTIONS,REFER,INFO',
- ACCEPTED_BODY_TYPES: 'application/sdp, application/dtmf-relay',
- MAX_FORWARDS: 69,
- SESSION_EXPIRES: 90,
- MIN_SESSION_EXPIRES: 60
- };
- }),
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _typeof(obj) {
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
- _typeof = function _typeof(obj) {
- return typeof obj;
- };
- } else {
- _typeof = function _typeof(obj) {
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
- };
- }
- return _typeof(obj);
- }
- var JsSIP_C = __webpack_require__(1);
- var URI = __webpack_require__(8);
- var Grammar = __webpack_require__(3);
- exports.str_utf8_length = function (string) {
- return unescape(encodeURIComponent(string)).length;
- }; // Used by 'hasMethods'.
- var isFunction = exports.isFunction = function (fn) {
- if (fn !== undefined) {
- return Object.prototype.toString.call(fn) === '[object Function]' ? true : false;
- } else {
- return false;
- }
- };
- exports.isString = function (str) {
- if (str !== undefined) {
- return Object.prototype.toString.call(str) === '[object String]' ? true : false;
- } else {
- return false;
- }
- };
- exports.isDecimal = function (num) {
- return !isNaN(num) && parseFloat(num) === parseInt(num, 10);
- };
- exports.isEmpty = function (value) {
- return value === null || value === '' || value === undefined || Array.isArray(value) && value.length === 0 || typeof value === 'number' && isNaN(value);
- };
- exports.hasMethods = function (obj) {
- for (var _len = arguments.length, methodNames = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
- methodNames[_key - 1] = arguments[_key];
- }
- for (var _i = 0; _i < methodNames.length; _i++) {
- var methodName = methodNames[_i];
- if (isFunction(obj[methodName])) {
- return false;
- }
- }
- return true;
- }; // Used by 'newTag'.
- var createRandomToken = exports.createRandomToken = function (size) {
- var base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 32;
- var i,
- r,
- token = '';
- for (i = 0; i < size; i++) {
- r = Math.random() * base | 0;
- token += r.toString(base);
- }
- return token;
- };
- exports.newTag = function () {
- return createRandomToken(10);
- }; // https://stackoverflow.com/users/109538/broofa.
- exports.newUUID = function () {
- var UUID = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
- var r = Math.random() * 16 | 0,
- v = c === 'x' ? r : r & 0x3 | 0x8;
- return v.toString(16);
- });
- return UUID;
- };
- exports.hostType = function (host) {
- if (!host) {
- return;
- } else {
- host = Grammar.parse(host, 'host');
- if (host !== -1) {
- return host.host_type;
- }
- }
- };
- /**
- * Hex-escape a SIP URI user.
- * Don't hex-escape ':' (%3A), '+' (%2B), '?' (%3F"), '/' (%2F).
- *
- * Used by 'normalizeTarget'.
- */
- var escapeUser = exports.escapeUser = function (user) {
- return encodeURIComponent(decodeURIComponent(user)).replace(/%3A/ig, ':').replace(/%2B/ig, '+').replace(/%3F/ig, '?').replace(/%2F/ig, '/');
- };
- /**
- * Normalize SIP URI.
- * NOTE: It does not allow a SIP URI without username.
- * Accepts 'sip', 'sips' and 'tel' URIs and convert them into 'sip'.
- * Detects the domain part (if given) and properly hex-escapes the user portion.
- * If the user portion has only 'tel' number symbols the user portion is clean of 'tel' visual separators.
- */
- exports.normalizeTarget = function (target, domain) {
- // If no target is given then raise an error.
- if (!target) {
- return; // If a URI instance is given then return it.
- } else if (target instanceof URI) {
- return target; // If a string is given split it by '@':
- // - Last fragment is the desired domain.
- // - Otherwise append the given domain argument.
- } else if (typeof target === 'string') {
- var target_array = target.split('@');
- var target_user;
- var target_domain;
- switch (target_array.length) {
- case 1:
- if (!domain) {
- return;
- }
- target_user = target;
- target_domain = domain;
- break;
- case 2:
- target_user = target_array[0];
- target_domain = target_array[1];
- break;
- default:
- target_user = target_array.slice(0, target_array.length - 1).join('@');
- target_domain = target_array[target_array.length - 1];
- } // Remove the URI scheme (if present).
- target_user = target_user.replace(/^(sips?|tel):/i, ''); // Remove 'tel' visual separators if the user portion just contains 'tel' number symbols.
- if (/^[-.()]*\+?[0-9\-.()]+$/.test(target_user)) {
- target_user = target_user.replace(/[-.()]/g, '');
- } // Build the complete SIP URI.
- target = "".concat(JsSIP_C.SIP, ":").concat(escapeUser(target_user), "@").concat(target_domain); // Finally parse the resulting URI.
- var uri;
- if (uri = URI.parse(target)) {
- return uri;
- } else {
- return;
- }
- } else {
- return;
- }
- };
- exports.headerize = function (string) {
- var exceptions = {
- 'Call-Id': 'Call-ID',
- 'Cseq': 'CSeq',
- 'Www-Authenticate': 'WWW-Authenticate'
- };
- var name = string.toLowerCase().replace(/_/g, '-').split('-');
- var hname = '';
- var parts = name.length;
- var part;
- for (part = 0; part < parts; part++) {
- if (part !== 0) {
- hname += '-';
- }
- hname += name[part].charAt(0).toUpperCase() + name[part].substring(1);
- }
- if (exceptions[hname]) {
- hname = exceptions[hname];
- }
- return hname;
- };
- exports.sipErrorCause = function (status_code) {
- for (var cause in JsSIP_C.SIP_ERROR_CAUSES) {
- if (JsSIP_C.SIP_ERROR_CAUSES[cause].indexOf(status_code) !== -1) {
- return JsSIP_C.causes[cause];
- }
- }
- return JsSIP_C.causes.SIP_FAILURE_CODE;
- };
- /**
- * Generate a random Test-Net IP (https://tools.ietf.org/html/rfc5735)
- */
- exports.getRandomTestNetIP = function () {
- function getOctet(from, to) {
- return Math.floor(Math.random() * (to - from + 1) + from);
- }
- return "192.0.2.".concat(getOctet(1, 254));
- }; // MD5 (Message-Digest Algorithm) https://www.webtoolkit.info.
- exports.calculateMD5 = function (string) {
- function rotateLeft(lValue, iShiftBits) {
- return lValue << iShiftBits | lValue >>> 32 - iShiftBits;
- }
- function addUnsigned(lX, lY) {
- var lX8 = lX & 0x80000000;
- var lY8 = lY & 0x80000000;
- var lX4 = lX & 0x40000000;
- var lY4 = lY & 0x40000000;
- var lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
- if (lX4 & lY4) {
- return lResult ^ 0x80000000 ^ lX8 ^ lY8;
- }
- if (lX4 | lY4) {
- if (lResult & 0x40000000) {
- return lResult ^ 0xC0000000 ^ lX8 ^ lY8;
- } else {
- return lResult ^ 0x40000000 ^ lX8 ^ lY8;
- }
- } else {
- return lResult ^ lX8 ^ lY8;
- }
- }
- function doF(x, y, z) {
- return x & y | ~x & z;
- }
- function doG(x, y, z) {
- return x & z | y & ~z;
- }
- function doH(x, y, z) {
- return x ^ y ^ z;
- }
- function doI(x, y, z) {
- return y ^ (x | ~z);
- }
- function doFF(a, b, c, d, x, s, ac) {
- a = addUnsigned(a, addUnsigned(addUnsigned(doF(b, c, d), x), ac));
- return addUnsigned(rotateLeft(a, s), b);
- }
- function doGG(a, b, c, d, x, s, ac) {
- a = addUnsigned(a, addUnsigned(addUnsigned(doG(b, c, d), x), ac));
- return addUnsigned(rotateLeft(a, s), b);
- }
- function doHH(a, b, c, d, x, s, ac) {
- a = addUnsigned(a, addUnsigned(addUnsigned(doH(b, c, d), x), ac));
- return addUnsigned(rotateLeft(a, s), b);
- }
- function doII(a, b, c, d, x, s, ac) {
- a = addUnsigned(a, addUnsigned(addUnsigned(doI(b, c, d), x), ac));
- return addUnsigned(rotateLeft(a, s), b);
- }
- function convertToWordArray(str) {
- var lWordCount;
- var lMessageLength = str.length;
- var lNumberOfWords_temp1 = lMessageLength + 8;
- var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - lNumberOfWords_temp1 % 64) / 64;
- var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
- var lWordArray = new Array(lNumberOfWords - 1);
- var lBytePosition = 0;
- var lByteCount = 0;
- while (lByteCount < lMessageLength) {
- lWordCount = (lByteCount - lByteCount % 4) / 4;
- lBytePosition = lByteCount % 4 * 8;
- lWordArray[lWordCount] = lWordArray[lWordCount] | str.charCodeAt(lByteCount) << lBytePosition;
- lByteCount++;
- }
- lWordCount = (lByteCount - lByteCount % 4) / 4;
- lBytePosition = lByteCount % 4 * 8;
- lWordArray[lWordCount] = lWordArray[lWordCount] | 0x80 << lBytePosition;
- lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
- lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
- return lWordArray;
- }
- function wordToHex(lValue) {
- var wordToHexValue = '',
- wordToHexValue_temp = '',
- lByte,
- lCount;
- for (lCount = 0; lCount <= 3; lCount++) {
- lByte = lValue >>> lCount * 8 & 255;
- wordToHexValue_temp = "0".concat(lByte.toString(16));
- wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length - 2, 2);
- }
- return wordToHexValue;
- }
- function utf8Encode(str) {
- str = str.replace(/\r\n/g, '\n');
- var utftext = '';
- for (var n = 0; n < str.length; n++) {
- var _c = str.charCodeAt(n);
- if (_c < 128) {
- utftext += String.fromCharCode(_c);
- } else if (_c > 127 && _c < 2048) {
- utftext += String.fromCharCode(_c >> 6 | 192);
- utftext += String.fromCharCode(_c & 63 | 128);
- } else {
- utftext += String.fromCharCode(_c >> 12 | 224);
- utftext += String.fromCharCode(_c >> 6 & 63 | 128);
- utftext += String.fromCharCode(_c & 63 | 128);
- }
- }
- return utftext;
- }
- var x = [];
- var k, AA, BB, CC, DD, a, b, c, d;
- var S11 = 7,
- S12 = 12,
- S13 = 17,
- S14 = 22;
- var S21 = 5,
- S22 = 9,
- S23 = 14,
- S24 = 20;
- var S31 = 4,
- S32 = 11,
- S33 = 16,
- S34 = 23;
- var S41 = 6,
- S42 = 10,
- S43 = 15,
- S44 = 21;
- string = utf8Encode(string);
- x = convertToWordArray(string);
- a = 0x67452301;
- b = 0xEFCDAB89;
- c = 0x98BADCFE;
- d = 0x10325476;
- for (k = 0; k < x.length; k += 16) {
- AA = a;
- BB = b;
- CC = c;
- DD = d;
- a = doFF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
- d = doFF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
- c = doFF(c, d, a, b, x[k + 2], S13, 0x242070DB);
- b = doFF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
- a = doFF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
- d = doFF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
- c = doFF(c, d, a, b, x[k + 6], S13, 0xA8304613);
- b = doFF(b, c, d, a, x[k + 7], S14, 0xFD469501);
- a = doFF(a, b, c, d, x[k + 8], S11, 0x698098D8);
- d = doFF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
- c = doFF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
- b = doFF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
- a = doFF(a, b, c, d, x[k + 12], S11, 0x6B901122);
- d = doFF(d, a, b, c, x[k + 13], S12, 0xFD987193);
- c = doFF(c, d, a, b, x[k + 14], S13, 0xA679438E);
- b = doFF(b, c, d, a, x[k + 15], S14, 0x49B40821);
- a = doGG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
- d = doGG(d, a, b, c, x[k + 6], S22, 0xC040B340);
- c = doGG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
- b = doGG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
- a = doGG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
- d = doGG(d, a, b, c, x[k + 10], S22, 0x2441453);
- c = doGG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
- b = doGG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
- a = doGG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
- d = doGG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
- c = doGG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
- b = doGG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
- a = doGG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
- d = doGG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
- c = doGG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
- b = doGG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
- a = doHH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
- d = doHH(d, a, b, c, x[k + 8], S32, 0x8771F681);
- c = doHH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
- b = doHH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
- a = doHH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
- d = doHH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
- c = doHH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
- b = doHH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
- a = doHH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
- d = doHH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
- c = doHH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
- b = doHH(b, c, d, a, x[k + 6], S34, 0x4881D05);
- a = doHH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
- d = doHH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
- c = doHH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
- b = doHH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
- a = doII(a, b, c, d, x[k + 0], S41, 0xF4292244);
- d = doII(d, a, b, c, x[k + 7], S42, 0x432AFF97);
- c = doII(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
- b = doII(b, c, d, a, x[k + 5], S44, 0xFC93A039);
- a = doII(a, b, c, d, x[k + 12], S41, 0x655B59C3);
- d = doII(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
- c = doII(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
- b = doII(b, c, d, a, x[k + 1], S44, 0x85845DD1);
- a = doII(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
- d = doII(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
- c = doII(c, d, a, b, x[k + 6], S43, 0xA3014314);
- b = doII(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
- a = doII(a, b, c, d, x[k + 4], S41, 0xF7537E82);
- d = doII(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
- c = doII(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
- b = doII(b, c, d, a, x[k + 9], S44, 0xEB86D391);
- a = addUnsigned(a, AA);
- b = addUnsigned(b, BB);
- c = addUnsigned(c, CC);
- d = addUnsigned(d, DD);
- }
- var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
- return temp.toLowerCase();
- };
- exports.closeMediaStream = function (stream) {
- if (!stream) {
- return;
- } // Latest spec states that MediaStream has no stop() method and instead must
- // call stop() on every MediaStreamTrack.
- try {
- var tracks;
- if (stream.getTracks) {
- tracks = stream.getTracks();
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
- try {
- for (var _iterator = tracks[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var track = _step.value;
- track.stop();
- }
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator.return != null) {
- _iterator.return();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
- }
- } else {
- tracks = stream.getAudioTracks();
- var _iteratorNormalCompletion2 = true;
- var _didIteratorError2 = false;
- var _iteratorError2 = undefined;
- try {
- for (var _iterator2 = tracks[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
- var _track = _step2.value;
- _track.stop();
- }
- } catch (err) {
- _didIteratorError2 = true;
- _iteratorError2 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
- _iterator2.return();
- }
- } finally {
- if (_didIteratorError2) {
- throw _iteratorError2;
- }
- }
- }
- tracks = stream.getVideoTracks();
- var _iteratorNormalCompletion3 = true;
- var _didIteratorError3 = false;
- var _iteratorError3 = undefined;
- try {
- for (var _iterator3 = tracks[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
- var _track2 = _step3.value;
- _track2.stop();
- }
- } catch (err) {
- _didIteratorError3 = true;
- _iteratorError3 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
- _iterator3.return();
- }
- } finally {
- if (_didIteratorError3) {
- throw _iteratorError3;
- }
- }
- }
- }
- } catch (error) {
- // Deprecated by the spec, but still in use.
- // NOTE: In Temasys IE plugin stream.stop is a callable 'object'.
- if (typeof stream.stop === 'function' || _typeof(stream.stop) === 'object') {
- stream.stop();
- }
- }
- };
- exports.cloneArray = function (array) {
- return array && array.slice() || [];
- };
- }),
- /* 3 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- module.exports = function () {
- /*
- * Generated by PEG.js 0.7.0.
- *
- * http://pegjs.majda.cz/
- */
- function quote(s) {
- /*
- * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a
- * string literal except for the closing quote character, backslash,
- * carriage return, line separator, paragraph separator, and line feed.
- * Any character may appear in the form of an escape sequence.
- *
- * For portability, we also escape escape all control and non-ASCII
- * characters. Note that "\0" and "\v" escape sequences are not used
- * because JSHint does not like the first and IE the second.
- */
- return '"' + s.replace(/\\/g, '\\\\') // backslash
- .replace(/"/g, '\\"') // closing quote character
- .replace(/\x08/g, '\\b') // backspace
- .replace(/\t/g, '\\t') // horizontal tab
- .replace(/\n/g, '\\n') // line feed
- .replace(/\f/g, '\\f') // form feed
- .replace(/\r/g, '\\r') // carriage return
- .replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape) + '"';
- }
- var result = {
- /*
- * Parses the input with a generated parser. If the parsing is successfull,
- * returns a value explicitly or implicitly specified by the grammar from
- * which the parser was generated (see |PEG.buildParser|). If the parsing is
- * unsuccessful, throws |PEG.parser.SyntaxError| describing the error.
- */
- parse: function parse(input, startRule) {
- var parseFunctions = {
- "CRLF": parse_CRLF,
- "DIGIT": parse_DIGIT,
- "ALPHA": parse_ALPHA,
- "HEXDIG": parse_HEXDIG,
- "WSP": parse_WSP,
- "OCTET": parse_OCTET,
- "DQUOTE": parse_DQUOTE,
- "SP": parse_SP,
- "HTAB": parse_HTAB,
- "alphanum": parse_alphanum,
- "reserved": parse_reserved,
- "unreserved": parse_unreserved,
- "mark": parse_mark,
- "escaped": parse_escaped,
- "LWS": parse_LWS,
- "SWS": parse_SWS,
- "HCOLON": parse_HCOLON,
- "TEXT_UTF8_TRIM": parse_TEXT_UTF8_TRIM,
- "TEXT_UTF8char": parse_TEXT_UTF8char,
- "UTF8_NONASCII": parse_UTF8_NONASCII,
- "UTF8_CONT": parse_UTF8_CONT,
- "LHEX": parse_LHEX,
- "token": parse_token,
- "token_nodot": parse_token_nodot,
- "separators": parse_separators,
- "word": parse_word,
- "STAR": parse_STAR,
- "SLASH": parse_SLASH,
- "EQUAL": parse_EQUAL,
- "LPAREN": parse_LPAREN,
- "RPAREN": parse_RPAREN,
- "RAQUOT": parse_RAQUOT,
- "LAQUOT": parse_LAQUOT,
- "COMMA": parse_COMMA,
- "SEMI": parse_SEMI,
- "COLON": parse_COLON,
- "LDQUOT": parse_LDQUOT,
- "RDQUOT": parse_RDQUOT,
- "comment": parse_comment,
- "ctext": parse_ctext,
- "quoted_string": parse_quoted_string,
- "quoted_string_clean": parse_quoted_string_clean,
- "qdtext": parse_qdtext,
- "quoted_pair": parse_quoted_pair,
- "SIP_URI_noparams": parse_SIP_URI_noparams,
- "SIP_URI": parse_SIP_URI,
- "uri_scheme": parse_uri_scheme,
- "uri_scheme_sips": parse_uri_scheme_sips,
- "uri_scheme_sip": parse_uri_scheme_sip,
- "userinfo": parse_userinfo,
- "user": parse_user,
- "user_unreserved": parse_user_unreserved,
- "password": parse_password,
- "hostport": parse_hostport,
- "host": parse_host,
- "hostname": parse_hostname,
- "domainlabel": parse_domainlabel,
- "toplabel": parse_toplabel,
- "IPv6reference": parse_IPv6reference,
- "IPv6address": parse_IPv6address,
- "h16": parse_h16,
- "ls32": parse_ls32,
- "IPv4address": parse_IPv4address,
- "dec_octet": parse_dec_octet,
- "port": parse_port,
- "uri_parameters": parse_uri_parameters,
- "uri_parameter": parse_uri_parameter,
- "transport_param": parse_transport_param,
- "user_param": parse_user_param,
- "method_param": parse_method_param,
- "ttl_param": parse_ttl_param,
- "maddr_param": parse_maddr_param,
- "lr_param": parse_lr_param,
- "other_param": parse_other_param,
- "pname": parse_pname,
- "pvalue": parse_pvalue,
- "paramchar": parse_paramchar,
- "param_unreserved": parse_param_unreserved,
- "headers": parse_headers,
- "header": parse_header,
- "hname": parse_hname,
- "hvalue": parse_hvalue,
- "hnv_unreserved": parse_hnv_unreserved,
- "Request_Response": parse_Request_Response,
- "Request_Line": parse_Request_Line,
- "Request_URI": parse_Request_URI,
- "absoluteURI": parse_absoluteURI,
- "hier_part": parse_hier_part,
- "net_path": parse_net_path,
- "abs_path": parse_abs_path,
- "opaque_part": parse_opaque_part,
- "uric": parse_uric,
- "uric_no_slash": parse_uric_no_slash,
- "path_segments": parse_path_segments,
- "segment": parse_segment,
- "param": parse_param,
- "pchar": parse_pchar,
- "scheme": parse_scheme,
- "authority": parse_authority,
- "srvr": parse_srvr,
- "reg_name": parse_reg_name,
- "query": parse_query,
- "SIP_Version": parse_SIP_Version,
- "INVITEm": parse_INVITEm,
- "ACKm": parse_ACKm,
- "OPTIONSm": parse_OPTIONSm,
- "BYEm": parse_BYEm,
- "CANCELm": parse_CANCELm,
- "REGISTERm": parse_REGISTERm,
- "SUBSCRIBEm": parse_SUBSCRIBEm,
- "NOTIFYm": parse_NOTIFYm,
- "REFERm": parse_REFERm,
- "Method": parse_Method,
- "Status_Line": parse_Status_Line,
- "Status_Code": parse_Status_Code,
- "extension_code": parse_extension_code,
- "Reason_Phrase": parse_Reason_Phrase,
- "Allow_Events": parse_Allow_Events,
- "Call_ID": parse_Call_ID,
- "Contact": parse_Contact,
- "contact_param": parse_contact_param,
- "name_addr": parse_name_addr,
- "display_name": parse_display_name,
- "contact_params": parse_contact_params,
- "c_p_q": parse_c_p_q,
- "c_p_expires": parse_c_p_expires,
- "delta_seconds": parse_delta_seconds,
- "qvalue": parse_qvalue,
- "generic_param": parse_generic_param,
- "gen_value": parse_gen_value,
- "Content_Disposition": parse_Content_Disposition,
- "disp_type": parse_disp_type,
- "disp_param": parse_disp_param,
- "handling_param": parse_handling_param,
- "Content_Encoding": parse_Content_Encoding,
- "Content_Length": parse_Content_Length,
- "Content_Type": parse_Content_Type,
- "media_type": parse_media_type,
- "m_type": parse_m_type,
- "discrete_type": parse_discrete_type,
- "composite_type": parse_composite_type,
- "extension_token": parse_extension_token,
- "x_token": parse_x_token,
- "m_subtype": parse_m_subtype,
- "m_parameter": parse_m_parameter,
- "m_value": parse_m_value,
- "CSeq": parse_CSeq,
- "CSeq_value": parse_CSeq_value,
- "Expires": parse_Expires,
- "Event": parse_Event,
- "event_type": parse_event_type,
- "From": parse_From,
- "from_param": parse_from_param,
- "tag_param": parse_tag_param,
- "Max_Forwards": parse_Max_Forwards,
- "Min_Expires": parse_Min_Expires,
- "Name_Addr_Header": parse_Name_Addr_Header,
- "Proxy_Authenticate": parse_Proxy_Authenticate,
- "challenge": parse_challenge,
- "other_challenge": parse_other_challenge,
- "auth_param": parse_auth_param,
- "digest_cln": parse_digest_cln,
- "realm": parse_realm,
- "realm_value": parse_realm_value,
- "domain": parse_domain,
- "URI": parse_URI,
- "nonce": parse_nonce,
- "nonce_value": parse_nonce_value,
- "opaque": parse_opaque,
- "stale": parse_stale,
- "algorithm": parse_algorithm,
- "qop_options": parse_qop_options,
- "qop_value": parse_qop_value,
- "Proxy_Require": parse_Proxy_Require,
- "Record_Route": parse_Record_Route,
- "rec_route": parse_rec_route,
- "Reason": parse_Reason,
- "reason_param": parse_reason_param,
- "reason_cause": parse_reason_cause,
- "Require": parse_Require,
- "Route": parse_Route,
- "route_param": parse_route_param,
- "Subscription_State": parse_Subscription_State,
- "substate_value": parse_substate_value,
- "subexp_params": parse_subexp_params,
- "event_reason_value": parse_event_reason_value,
- "Subject": parse_Subject,
- "Supported": parse_Supported,
- "To": parse_To,
- "to_param": parse_to_param,
- "Via": parse_Via,
- "via_param": parse_via_param,
- "via_params": parse_via_params,
- "via_ttl": parse_via_ttl,
- "via_maddr": parse_via_maddr,
- "via_received": parse_via_received,
- "via_branch": parse_via_branch,
- "response_port": parse_response_port,
- "sent_protocol": parse_sent_protocol,
- "protocol_name": parse_protocol_name,
- "transport": parse_transport,
- "sent_by": parse_sent_by,
- "via_host": parse_via_host,
- "via_port": parse_via_port,
- "ttl": parse_ttl,
- "WWW_Authenticate": parse_WWW_Authenticate,
- "Session_Expires": parse_Session_Expires,
- "s_e_expires": parse_s_e_expires,
- "s_e_params": parse_s_e_params,
- "s_e_refresher": parse_s_e_refresher,
- "extension_header": parse_extension_header,
- "header_value": parse_header_value,
- "message_body": parse_message_body,
- "uuid_URI": parse_uuid_URI,
- "uuid": parse_uuid,
- "hex4": parse_hex4,
- "hex8": parse_hex8,
- "hex12": parse_hex12,
- "Refer_To": parse_Refer_To,
- "Replaces": parse_Replaces,
- "call_id": parse_call_id,
- "replaces_param": parse_replaces_param,
- "to_tag": parse_to_tag,
- "from_tag": parse_from_tag,
- "early_flag": parse_early_flag
- };
- if (startRule !== undefined) {
- if (parseFunctions[startRule] === undefined) {
- throw new Error("Invalid rule name: " + quote(startRule) + ".");
- }
- } else {
- startRule = "CRLF";
- }
- var pos = 0;
- var reportFailures = 0;
- var rightmostFailuresPos = 0;
- var rightmostFailuresExpected = [];
- function padLeft(input, padding, length) {
- var result = input;
- var padLength = length - input.length;
- for (var i = 0; i < padLength; i++) {
- result = padding + result;
- }
- return result;
- }
- function escape(ch) {
- var charCode = ch.charCodeAt(0);
- var escapeChar;
- var length;
- if (charCode <= 0xFF) {
- escapeChar = 'x';
- length = 2;
- } else {
- escapeChar = 'u';
- length = 4;
- }
- return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);
- }
- function matchFailed(failure) {
- if (pos < rightmostFailuresPos) {
- return;
- }
- if (pos > rightmostFailuresPos) {
- rightmostFailuresPos = pos;
- rightmostFailuresExpected = [];
- }
- rightmostFailuresExpected.push(failure);
- }
- function parse_CRLF() {
- var result0;
- if (input.substr(pos, 2) === "\r\n") {
- result0 = "\r\n";
- pos += 2;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"\\r\\n\"");
- }
- }
- return result0;
- }
- function parse_DIGIT() {
- var result0;
- if (/^[0-9]/.test(input.charAt(pos))) {
- result0 = input.charAt(pos);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("[0-9]");
- }
- }
- return result0;
- }
- function parse_ALPHA() {
- var result0;
- if (/^[a-zA-Z]/.test(input.charAt(pos))) {
- result0 = input.charAt(pos);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("[a-zA-Z]");
- }
- }
- return result0;
- }
- function parse_HEXDIG() {
- var result0;
- if (/^[0-9a-fA-F]/.test(input.charAt(pos))) {
- result0 = input.charAt(pos);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("[0-9a-fA-F]");
- }
- }
- return result0;
- }
- function parse_WSP() {
- var result0;
- result0 = parse_SP();
- if (result0 === null) {
- result0 = parse_HTAB();
- }
- return result0;
- }
- function parse_OCTET() {
- var result0;
- if (/^[\0-\xFF]/.test(input.charAt(pos))) {
- result0 = input.charAt(pos);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("[\\0-\\xFF]");
- }
- }
- return result0;
- }
- function parse_DQUOTE() {
- var result0;
- if (/^["]/.test(input.charAt(pos))) {
- result0 = input.charAt(pos);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("[\"]");
- }
- }
- return result0;
- }
- function parse_SP() {
- var result0;
- if (input.charCodeAt(pos) === 32) {
- result0 = " ";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\" \"");
- }
- }
- return result0;
- }
- function parse_HTAB() {
- var result0;
- if (input.charCodeAt(pos) === 9) {
- result0 = "\t";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"\\t\"");
- }
- }
- return result0;
- }
- function parse_alphanum() {
- var result0;
- if (/^[a-zA-Z0-9]/.test(input.charAt(pos))) {
- result0 = input.charAt(pos);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("[a-zA-Z0-9]");
- }
- }
- return result0;
- }
- function parse_reserved() {
- var result0;
- if (input.charCodeAt(pos) === 59) {
- result0 = ";";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\";\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 47) {
- result0 = "/";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"/\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 63) {
- result0 = "?";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"?\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 58) {
- result0 = ":";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 64) {
- result0 = "@";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"@\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 38) {
- result0 = "&";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"&\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 61) {
- result0 = "=";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"=\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 43) {
- result0 = "+";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 36) {
- result0 = "$";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"$\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 44) {
- result0 = ",";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\",\"");
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- return result0;
- }
- function parse_unreserved() {
- var result0;
- result0 = parse_alphanum();
- if (result0 === null) {
- result0 = parse_mark();
- }
- return result0;
- }
- function parse_mark() {
- var result0;
- if (input.charCodeAt(pos) === 45) {
- result0 = "-";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 95) {
- result0 = "_";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"_\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 46) {
- result0 = ".";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 33) {
- result0 = "!";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"!\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 126) {
- result0 = "~";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"~\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 42) {
- result0 = "*";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"*\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 39) {
- result0 = "'";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"'\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 40) {
- result0 = "(";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"(\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 41) {
- result0 = ")";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\")\"");
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- return result0;
- }
- function parse_escaped() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.charCodeAt(pos) === 37) {
- result0 = "%";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"%\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_HEXDIG();
- if (result1 !== null) {
- result2 = parse_HEXDIG();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, escaped) {
- return escaped.join('');
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_LWS() {
- var result0, result1, result2;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- pos2 = pos;
- result0 = [];
- result1 = parse_WSP();
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_WSP();
- }
- if (result0 !== null) {
- result1 = parse_CRLF();
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos2;
- }
- } else {
- result0 = null;
- pos = pos2;
- }
- result0 = result0 !== null ? result0 : "";
- if (result0 !== null) {
- result2 = parse_WSP();
- if (result2 !== null) {
- result1 = [];
- while (result2 !== null) {
- result1.push(result2);
- result2 = parse_WSP();
- }
- } else {
- result1 = null;
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return " ";
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_SWS() {
- var result0;
- result0 = parse_LWS();
- result0 = result0 !== null ? result0 : "";
- return result0;
- }
- function parse_HCOLON() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = [];
- result1 = parse_SP();
- if (result1 === null) {
- result1 = parse_HTAB();
- }
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_SP();
- if (result1 === null) {
- result1 = parse_HTAB();
- }
- }
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_SWS();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return ':';
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_TEXT_UTF8_TRIM() {
- var result0, result1, result2, result3;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result1 = parse_TEXT_UTF8char();
- if (result1 !== null) {
- result0 = [];
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_TEXT_UTF8char();
- }
- } else {
- result0 = null;
- }
- if (result0 !== null) {
- result1 = [];
- pos2 = pos;
- result2 = [];
- result3 = parse_LWS();
- while (result3 !== null) {
- result2.push(result3);
- result3 = parse_LWS();
- }
- if (result2 !== null) {
- result3 = parse_TEXT_UTF8char();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos2 = pos;
- result2 = [];
- result3 = parse_LWS();
- while (result3 !== null) {
- result2.push(result3);
- result3 = parse_LWS();
- }
- if (result2 !== null) {
- result3 = parse_TEXT_UTF8char();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_TEXT_UTF8char() {
- var result0;
- if (/^[!-~]/.test(input.charAt(pos))) {
- result0 = input.charAt(pos);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("[!-~]");
- }
- }
- if (result0 === null) {
- result0 = parse_UTF8_NONASCII();
- }
- return result0;
- }
- function parse_UTF8_NONASCII() {
- var result0;
- if (/^[\x80-\uFFFF]/.test(input.charAt(pos))) {
- result0 = input.charAt(pos);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("[\\x80-\\uFFFF]");
- }
- }
- return result0;
- }
- function parse_UTF8_CONT() {
- var result0;
- if (/^[\x80-\xBF]/.test(input.charAt(pos))) {
- result0 = input.charAt(pos);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("[\\x80-\\xBF]");
- }
- }
- return result0;
- }
- function parse_LHEX() {
- var result0;
- result0 = parse_DIGIT();
- if (result0 === null) {
- if (/^[a-f]/.test(input.charAt(pos))) {
- result0 = input.charAt(pos);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("[a-f]");
- }
- }
- }
- return result0;
- }
- function parse_token() {
- var result0, result1;
- var pos0;
- pos0 = pos;
- result1 = parse_alphanum();
- if (result1 === null) {
- if (input.charCodeAt(pos) === 45) {
- result1 = "-";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 46) {
- result1 = ".";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 33) {
- result1 = "!";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"!\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 37) {
- result1 = "%";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"%\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 42) {
- result1 = "*";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"*\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 95) {
- result1 = "_";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"_\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 43) {
- result1 = "+";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 96) {
- result1 = "`";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"`\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 39) {
- result1 = "'";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"'\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 126) {
- result1 = "~";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"~\"");
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- if (result1 !== null) {
- result0 = [];
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_alphanum();
- if (result1 === null) {
- if (input.charCodeAt(pos) === 45) {
- result1 = "-";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 46) {
- result1 = ".";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 33) {
- result1 = "!";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"!\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 37) {
- result1 = "%";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"%\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 42) {
- result1 = "*";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"*\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 95) {
- result1 = "_";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"_\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 43) {
- result1 = "+";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 96) {
- result1 = "`";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"`\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 39) {
- result1 = "'";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"'\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 126) {
- result1 = "~";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"~\"");
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- } else {
- result0 = null;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_token_nodot() {
- var result0, result1;
- var pos0;
- pos0 = pos;
- result1 = parse_alphanum();
- if (result1 === null) {
- if (input.charCodeAt(pos) === 45) {
- result1 = "-";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 33) {
- result1 = "!";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"!\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 37) {
- result1 = "%";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"%\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 42) {
- result1 = "*";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"*\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 95) {
- result1 = "_";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"_\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 43) {
- result1 = "+";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 96) {
- result1 = "`";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"`\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 39) {
- result1 = "'";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"'\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 126) {
- result1 = "~";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"~\"");
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- if (result1 !== null) {
- result0 = [];
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_alphanum();
- if (result1 === null) {
- if (input.charCodeAt(pos) === 45) {
- result1 = "-";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 33) {
- result1 = "!";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"!\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 37) {
- result1 = "%";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"%\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 42) {
- result1 = "*";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"*\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 95) {
- result1 = "_";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"_\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 43) {
- result1 = "+";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 96) {
- result1 = "`";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"`\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 39) {
- result1 = "'";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"'\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 126) {
- result1 = "~";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"~\"");
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- } else {
- result0 = null;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_separators() {
- var result0;
- if (input.charCodeAt(pos) === 40) {
- result0 = "(";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"(\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 41) {
- result0 = ")";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\")\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 60) {
- result0 = "<";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"<\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 62) {
- result0 = ">";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\">\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 64) {
- result0 = "@";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"@\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 44) {
- result0 = ",";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\",\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 59) {
- result0 = ";";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\";\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 58) {
- result0 = ":";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 92) {
- result0 = "\\";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"\\\\\"");
- }
- }
- if (result0 === null) {
- result0 = parse_DQUOTE();
- if (result0 === null) {
- if (input.charCodeAt(pos) === 47) {
- result0 = "/";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"/\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 91) {
- result0 = "[";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"[\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 93) {
- result0 = "]";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"]\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 63) {
- result0 = "?";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"?\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 61) {
- result0 = "=";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"=\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 123) {
- result0 = "{";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"{\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 125) {
- result0 = "}";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"}\"");
- }
- }
- if (result0 === null) {
- result0 = parse_SP();
- if (result0 === null) {
- result0 = parse_HTAB();
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- return result0;
- }
- function parse_word() {
- var result0, result1;
- var pos0;
- pos0 = pos;
- result1 = parse_alphanum();
- if (result1 === null) {
- if (input.charCodeAt(pos) === 45) {
- result1 = "-";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 46) {
- result1 = ".";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 33) {
- result1 = "!";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"!\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 37) {
- result1 = "%";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"%\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 42) {
- result1 = "*";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"*\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 95) {
- result1 = "_";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"_\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 43) {
- result1 = "+";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 96) {
- result1 = "`";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"`\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 39) {
- result1 = "'";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"'\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 126) {
- result1 = "~";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"~\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 40) {
- result1 = "(";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"(\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 41) {
- result1 = ")";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\")\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 60) {
- result1 = "<";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"<\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 62) {
- result1 = ">";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\">\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 92) {
- result1 = "\\";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"\\\\\"");
- }
- }
- if (result1 === null) {
- result1 = parse_DQUOTE();
- if (result1 === null) {
- if (input.charCodeAt(pos) === 47) {
- result1 = "/";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"/\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 91) {
- result1 = "[";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"[\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 93) {
- result1 = "]";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"]\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 63) {
- result1 = "?";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"?\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 123) {
- result1 = "{";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"{\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 125) {
- result1 = "}";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"}\"");
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- if (result1 !== null) {
- result0 = [];
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_alphanum();
- if (result1 === null) {
- if (input.charCodeAt(pos) === 45) {
- result1 = "-";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 46) {
- result1 = ".";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 33) {
- result1 = "!";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"!\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 37) {
- result1 = "%";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"%\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 42) {
- result1 = "*";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"*\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 95) {
- result1 = "_";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"_\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 43) {
- result1 = "+";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 96) {
- result1 = "`";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"`\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 39) {
- result1 = "'";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"'\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 126) {
- result1 = "~";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"~\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 40) {
- result1 = "(";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"(\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 41) {
- result1 = ")";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\")\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 60) {
- result1 = "<";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"<\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 62) {
- result1 = ">";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\">\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 92) {
- result1 = "\\";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"\\\\\"");
- }
- }
- if (result1 === null) {
- result1 = parse_DQUOTE();
- if (result1 === null) {
- if (input.charCodeAt(pos) === 47) {
- result1 = "/";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"/\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 91) {
- result1 = "[";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"[\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 93) {
- result1 = "]";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"]\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 63) {
- result1 = "?";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"?\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 123) {
- result1 = "{";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"{\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 125) {
- result1 = "}";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"}\"");
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- } else {
- result0 = null;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_STAR() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_SWS();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 42) {
- result1 = "*";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"*\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_SWS();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return "*";
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_SLASH() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_SWS();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 47) {
- result1 = "/";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"/\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_SWS();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return "/";
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_EQUAL() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_SWS();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 61) {
- result1 = "=";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"=\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_SWS();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return "=";
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_LPAREN() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_SWS();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 40) {
- result1 = "(";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"(\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_SWS();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return "(";
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_RPAREN() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_SWS();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 41) {
- result1 = ")";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\")\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_SWS();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return ")";
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_RAQUOT() {
- var result0, result1;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.charCodeAt(pos) === 62) {
- result0 = ">";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\">\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_SWS();
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return ">";
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_LAQUOT() {
- var result0, result1;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_SWS();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 60) {
- result1 = "<";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"<\"");
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return "<";
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_COMMA() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_SWS();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 44) {
- result1 = ",";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\",\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_SWS();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return ",";
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_SEMI() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_SWS();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 59) {
- result1 = ";";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\";\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_SWS();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return ";";
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_COLON() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_SWS();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_SWS();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return ":";
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_LDQUOT() {
- var result0, result1;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_SWS();
- if (result0 !== null) {
- result1 = parse_DQUOTE();
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return "\"";
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_RDQUOT() {
- var result0, result1;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_DQUOTE();
- if (result0 !== null) {
- result1 = parse_SWS();
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return "\"";
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_comment() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- result0 = parse_LPAREN();
- if (result0 !== null) {
- result1 = [];
- result2 = parse_ctext();
- if (result2 === null) {
- result2 = parse_quoted_pair();
- if (result2 === null) {
- result2 = parse_comment();
- }
- }
- while (result2 !== null) {
- result1.push(result2);
- result2 = parse_ctext();
- if (result2 === null) {
- result2 = parse_quoted_pair();
- if (result2 === null) {
- result2 = parse_comment();
- }
- }
- }
- if (result1 !== null) {
- result2 = parse_RPAREN();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_ctext() {
- var result0;
- if (/^[!-']/.test(input.charAt(pos))) {
- result0 = input.charAt(pos);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("[!-']");
- }
- }
- if (result0 === null) {
- if (/^[*-[]/.test(input.charAt(pos))) {
- result0 = input.charAt(pos);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("[*-[]");
- }
- }
- if (result0 === null) {
- if (/^[\]-~]/.test(input.charAt(pos))) {
- result0 = input.charAt(pos);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("[\\]-~]");
- }
- }
- if (result0 === null) {
- result0 = parse_UTF8_NONASCII();
- if (result0 === null) {
- result0 = parse_LWS();
- }
- }
- }
- }
- return result0;
- }
- function parse_quoted_string() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_SWS();
- if (result0 !== null) {
- result1 = parse_DQUOTE();
- if (result1 !== null) {
- result2 = [];
- result3 = parse_qdtext();
- if (result3 === null) {
- result3 = parse_quoted_pair();
- }
- while (result3 !== null) {
- result2.push(result3);
- result3 = parse_qdtext();
- if (result3 === null) {
- result3 = parse_quoted_pair();
- }
- }
- if (result2 !== null) {
- result3 = parse_DQUOTE();
- if (result3 !== null) {
- result0 = [result0, result1, result2, result3];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_quoted_string_clean() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_SWS();
- if (result0 !== null) {
- result1 = parse_DQUOTE();
- if (result1 !== null) {
- result2 = [];
- result3 = parse_qdtext();
- if (result3 === null) {
- result3 = parse_quoted_pair();
- }
- while (result3 !== null) {
- result2.push(result3);
- result3 = parse_qdtext();
- if (result3 === null) {
- result3 = parse_quoted_pair();
- }
- }
- if (result2 !== null) {
- result3 = parse_DQUOTE();
- if (result3 !== null) {
- result0 = [result0, result1, result2, result3];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return input.substring(pos - 1, offset + 1);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_qdtext() {
- var result0;
- result0 = parse_LWS();
- if (result0 === null) {
- if (input.charCodeAt(pos) === 33) {
- result0 = "!";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"!\"");
- }
- }
- if (result0 === null) {
- if (/^[#-[]/.test(input.charAt(pos))) {
- result0 = input.charAt(pos);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("[#-[]");
- }
- }
- if (result0 === null) {
- if (/^[\]-~]/.test(input.charAt(pos))) {
- result0 = input.charAt(pos);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("[\\]-~]");
- }
- }
- if (result0 === null) {
- result0 = parse_UTF8_NONASCII();
- }
- }
- }
- }
- return result0;
- }
- function parse_quoted_pair() {
- var result0, result1;
- var pos0;
- pos0 = pos;
- if (input.charCodeAt(pos) === 92) {
- result0 = "\\";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"\\\\\"");
- }
- }
- if (result0 !== null) {
- if (/^[\0-\t]/.test(input.charAt(pos))) {
- result1 = input.charAt(pos);
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("[\\0-\\t]");
- }
- }
- if (result1 === null) {
- if (/^[\x0B-\f]/.test(input.charAt(pos))) {
- result1 = input.charAt(pos);
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("[\\x0B-\\f]");
- }
- }
- if (result1 === null) {
- if (/^[\x0E-]/.test(input.charAt(pos))) {
- result1 = input.charAt(pos);
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("[\\x0E-]");
- }
- }
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_SIP_URI_noparams() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_uri_scheme();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_userinfo();
- result2 = result2 !== null ? result2 : "";
- if (result2 !== null) {
- result3 = parse_hostport();
- if (result3 !== null) {
- result0 = [result0, result1, result2, result3];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- try {
- data.uri = new URI(data.scheme, data.user, data.host, data.port);
- delete data.scheme;
- delete data.user;
- delete data.host;
- delete data.host_type;
- delete data.port;
- } catch (e) {
- data = -1;
- }
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_SIP_URI() {
- var result0, result1, result2, result3, result4, result5;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_uri_scheme();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_userinfo();
- result2 = result2 !== null ? result2 : "";
- if (result2 !== null) {
- result3 = parse_hostport();
- if (result3 !== null) {
- result4 = parse_uri_parameters();
- if (result4 !== null) {
- result5 = parse_headers();
- result5 = result5 !== null ? result5 : "";
- if (result5 !== null) {
- result0 = [result0, result1, result2, result3, result4, result5];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- var header;
- try {
- data.uri = new URI(data.scheme, data.user, data.host, data.port, data.uri_params, data.uri_headers);
- delete data.scheme;
- delete data.user;
- delete data.host;
- delete data.host_type;
- delete data.port;
- delete data.uri_params;
- if (startRule === 'SIP_URI') {
- data = data.uri;
- }
- } catch (e) {
- data = -1;
- }
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_uri_scheme() {
- var result0;
- result0 = parse_uri_scheme_sips();
- if (result0 === null) {
- result0 = parse_uri_scheme_sip();
- }
- return result0;
- }
- function parse_uri_scheme_sips() {
- var result0;
- var pos0;
- pos0 = pos;
- if (input.substr(pos, 4).toLowerCase() === "sips") {
- result0 = input.substr(pos, 4);
- pos += 4;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"sips\"");
- }
- }
- if (result0 !== null) {
- result0 = function (offset, scheme) {
- data.scheme = scheme.toLowerCase();
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_uri_scheme_sip() {
- var result0;
- var pos0;
- pos0 = pos;
- if (input.substr(pos, 3).toLowerCase() === "sip") {
- result0 = input.substr(pos, 3);
- pos += 3;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"sip\"");
- }
- }
- if (result0 !== null) {
- result0 = function (offset, scheme) {
- data.scheme = scheme.toLowerCase();
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_userinfo() {
- var result0, result1, result2;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_user();
- if (result0 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_password();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- if (input.charCodeAt(pos) === 64) {
- result2 = "@";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"@\"");
- }
- }
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- data.user = decodeURIComponent(input.substring(pos - 1, offset));
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_user() {
- var result0, result1;
- result1 = parse_unreserved();
- if (result1 === null) {
- result1 = parse_escaped();
- if (result1 === null) {
- result1 = parse_user_unreserved();
- }
- }
- if (result1 !== null) {
- result0 = [];
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_unreserved();
- if (result1 === null) {
- result1 = parse_escaped();
- if (result1 === null) {
- result1 = parse_user_unreserved();
- }
- }
- }
- } else {
- result0 = null;
- }
- return result0;
- }
- function parse_user_unreserved() {
- var result0;
- if (input.charCodeAt(pos) === 38) {
- result0 = "&";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"&\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 61) {
- result0 = "=";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"=\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 43) {
- result0 = "+";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 36) {
- result0 = "$";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"$\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 44) {
- result0 = ",";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\",\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 59) {
- result0 = ";";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\";\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 63) {
- result0 = "?";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"?\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 47) {
- result0 = "/";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"/\"");
- }
- }
- }
- }
- }
- }
- }
- }
- }
- return result0;
- }
- function parse_password() {
- var result0, result1;
- var pos0;
- pos0 = pos;
- result0 = [];
- result1 = parse_unreserved();
- if (result1 === null) {
- result1 = parse_escaped();
- if (result1 === null) {
- if (input.charCodeAt(pos) === 38) {
- result1 = "&";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"&\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 61) {
- result1 = "=";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"=\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 43) {
- result1 = "+";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 36) {
- result1 = "$";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"$\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 44) {
- result1 = ",";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\",\"");
- }
- }
- }
- }
- }
- }
- }
- }
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_unreserved();
- if (result1 === null) {
- result1 = parse_escaped();
- if (result1 === null) {
- if (input.charCodeAt(pos) === 38) {
- result1 = "&";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"&\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 61) {
- result1 = "=";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"=\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 43) {
- result1 = "+";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 36) {
- result1 = "$";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"$\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 44) {
- result1 = ",";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\",\"");
- }
- }
- }
- }
- }
- }
- }
- }
- }
- if (result0 !== null) {
- result0 = function (offset) {
- data.password = input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_hostport() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_host();
- if (result0 !== null) {
- pos1 = pos;
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_port();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos1;
- }
- } else {
- result1 = null;
- pos = pos1;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_host() {
- var result0;
- var pos0;
- pos0 = pos;
- result0 = parse_hostname();
- if (result0 === null) {
- result0 = parse_IPv4address();
- if (result0 === null) {
- result0 = parse_IPv6reference();
- }
- }
- if (result0 !== null) {
- result0 = function (offset) {
- data.host = input.substring(pos, offset).toLowerCase();
- return data.host;
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_hostname() {
- var result0, result1, result2;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result0 = [];
- pos2 = pos;
- result1 = parse_domainlabel();
- if (result1 !== null) {
- if (input.charCodeAt(pos) === 46) {
- result2 = ".";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- while (result1 !== null) {
- result0.push(result1);
- pos2 = pos;
- result1 = parse_domainlabel();
- if (result1 !== null) {
- if (input.charCodeAt(pos) === 46) {
- result2 = ".";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- }
- if (result0 !== null) {
- result1 = parse_toplabel();
- if (result1 !== null) {
- if (input.charCodeAt(pos) === 46) {
- result2 = ".";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- result2 = result2 !== null ? result2 : "";
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- data.host_type = 'domain';
- return input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_domainlabel() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- result0 = parse_alphanum();
- if (result0 !== null) {
- result1 = [];
- result2 = parse_alphanum();
- if (result2 === null) {
- if (input.charCodeAt(pos) === 45) {
- result2 = "-";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result2 === null) {
- if (input.charCodeAt(pos) === 95) {
- result2 = "_";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"_\"");
- }
- }
- }
- }
- while (result2 !== null) {
- result1.push(result2);
- result2 = parse_alphanum();
- if (result2 === null) {
- if (input.charCodeAt(pos) === 45) {
- result2 = "-";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result2 === null) {
- if (input.charCodeAt(pos) === 95) {
- result2 = "_";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"_\"");
- }
- }
- }
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_toplabel() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- result0 = parse_ALPHA();
- if (result0 !== null) {
- result1 = [];
- result2 = parse_alphanum();
- if (result2 === null) {
- if (input.charCodeAt(pos) === 45) {
- result2 = "-";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result2 === null) {
- if (input.charCodeAt(pos) === 95) {
- result2 = "_";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"_\"");
- }
- }
- }
- }
- while (result2 !== null) {
- result1.push(result2);
- result2 = parse_alphanum();
- if (result2 === null) {
- if (input.charCodeAt(pos) === 45) {
- result2 = "-";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result2 === null) {
- if (input.charCodeAt(pos) === 95) {
- result2 = "_";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"_\"");
- }
- }
- }
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_IPv6reference() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.charCodeAt(pos) === 91) {
- result0 = "[";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"[\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_IPv6address();
- if (result1 !== null) {
- if (input.charCodeAt(pos) === 93) {
- result2 = "]";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"]\"");
- }
- }
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- data.host_type = 'IPv6';
- return input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_IPv6address() {
- var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_h16();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_h16();
- if (result2 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result3 = ":";
- pos++;
- } else {
- result3 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result3 !== null) {
- result4 = parse_h16();
- if (result4 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result5 = ":";
- pos++;
- } else {
- result5 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result5 !== null) {
- result6 = parse_h16();
- if (result6 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result7 = ":";
- pos++;
- } else {
- result7 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result7 !== null) {
- result8 = parse_h16();
- if (result8 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result9 = ":";
- pos++;
- } else {
- result9 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result9 !== null) {
- result10 = parse_h16();
- if (result10 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result11 = ":";
- pos++;
- } else {
- result11 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result11 !== null) {
- result12 = parse_ls32();
- if (result12 !== null) {
- result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 === null) {
- pos1 = pos;
- if (input.substr(pos, 2) === "::") {
- result0 = "::";
- pos += 2;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"::\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_h16();
- if (result1 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result2 = ":";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_h16();
- if (result3 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result4 = ":";
- pos++;
- } else {
- result4 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result4 !== null) {
- result5 = parse_h16();
- if (result5 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result6 = ":";
- pos++;
- } else {
- result6 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result6 !== null) {
- result7 = parse_h16();
- if (result7 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result8 = ":";
- pos++;
- } else {
- result8 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result8 !== null) {
- result9 = parse_h16();
- if (result9 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result10 = ":";
- pos++;
- } else {
- result10 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result10 !== null) {
- result11 = parse_ls32();
- if (result11 !== null) {
- result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 === null) {
- pos1 = pos;
- if (input.substr(pos, 2) === "::") {
- result0 = "::";
- pos += 2;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"::\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_h16();
- if (result1 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result2 = ":";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_h16();
- if (result3 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result4 = ":";
- pos++;
- } else {
- result4 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result4 !== null) {
- result5 = parse_h16();
- if (result5 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result6 = ":";
- pos++;
- } else {
- result6 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result6 !== null) {
- result7 = parse_h16();
- if (result7 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result8 = ":";
- pos++;
- } else {
- result8 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result8 !== null) {
- result9 = parse_ls32();
- if (result9 !== null) {
- result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 === null) {
- pos1 = pos;
- if (input.substr(pos, 2) === "::") {
- result0 = "::";
- pos += 2;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"::\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_h16();
- if (result1 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result2 = ":";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_h16();
- if (result3 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result4 = ":";
- pos++;
- } else {
- result4 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result4 !== null) {
- result5 = parse_h16();
- if (result5 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result6 = ":";
- pos++;
- } else {
- result6 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result6 !== null) {
- result7 = parse_ls32();
- if (result7 !== null) {
- result0 = [result0, result1, result2, result3, result4, result5, result6, result7];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 === null) {
- pos1 = pos;
- if (input.substr(pos, 2) === "::") {
- result0 = "::";
- pos += 2;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"::\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_h16();
- if (result1 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result2 = ":";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_h16();
- if (result3 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result4 = ":";
- pos++;
- } else {
- result4 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result4 !== null) {
- result5 = parse_ls32();
- if (result5 !== null) {
- result0 = [result0, result1, result2, result3, result4, result5];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 === null) {
- pos1 = pos;
- if (input.substr(pos, 2) === "::") {
- result0 = "::";
- pos += 2;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"::\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_h16();
- if (result1 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result2 = ":";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_ls32();
- if (result3 !== null) {
- result0 = [result0, result1, result2, result3];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 === null) {
- pos1 = pos;
- if (input.substr(pos, 2) === "::") {
- result0 = "::";
- pos += 2;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"::\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_ls32();
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 === null) {
- pos1 = pos;
- if (input.substr(pos, 2) === "::") {
- result0 = "::";
- pos += 2;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"::\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_h16();
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 === null) {
- pos1 = pos;
- result0 = parse_h16();
- if (result0 !== null) {
- if (input.substr(pos, 2) === "::") {
- result1 = "::";
- pos += 2;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"::\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_h16();
- if (result2 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result3 = ":";
- pos++;
- } else {
- result3 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result3 !== null) {
- result4 = parse_h16();
- if (result4 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result5 = ":";
- pos++;
- } else {
- result5 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result5 !== null) {
- result6 = parse_h16();
- if (result6 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result7 = ":";
- pos++;
- } else {
- result7 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result7 !== null) {
- result8 = parse_h16();
- if (result8 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result9 = ":";
- pos++;
- } else {
- result9 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result9 !== null) {
- result10 = parse_ls32();
- if (result10 !== null) {
- result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 === null) {
- pos1 = pos;
- result0 = parse_h16();
- if (result0 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_h16();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- if (input.substr(pos, 2) === "::") {
- result2 = "::";
- pos += 2;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"::\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_h16();
- if (result3 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result4 = ":";
- pos++;
- } else {
- result4 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result4 !== null) {
- result5 = parse_h16();
- if (result5 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result6 = ":";
- pos++;
- } else {
- result6 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result6 !== null) {
- result7 = parse_h16();
- if (result7 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result8 = ":";
- pos++;
- } else {
- result8 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result8 !== null) {
- result9 = parse_ls32();
- if (result9 !== null) {
- result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 === null) {
- pos1 = pos;
- result0 = parse_h16();
- if (result0 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_h16();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result2 = ":";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_h16();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- result2 = result2 !== null ? result2 : "";
- if (result2 !== null) {
- if (input.substr(pos, 2) === "::") {
- result3 = "::";
- pos += 2;
- } else {
- result3 = null;
- if (reportFailures === 0) {
- matchFailed("\"::\"");
- }
- }
- if (result3 !== null) {
- result4 = parse_h16();
- if (result4 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result5 = ":";
- pos++;
- } else {
- result5 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result5 !== null) {
- result6 = parse_h16();
- if (result6 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result7 = ":";
- pos++;
- } else {
- result7 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result7 !== null) {
- result8 = parse_ls32();
- if (result8 !== null) {
- result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 === null) {
- pos1 = pos;
- result0 = parse_h16();
- if (result0 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_h16();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result2 = ":";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_h16();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- result2 = result2 !== null ? result2 : "";
- if (result2 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result3 = ":";
- pos++;
- } else {
- result3 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result3 !== null) {
- result4 = parse_h16();
- if (result4 !== null) {
- result3 = [result3, result4];
- } else {
- result3 = null;
- pos = pos2;
- }
- } else {
- result3 = null;
- pos = pos2;
- }
- result3 = result3 !== null ? result3 : "";
- if (result3 !== null) {
- if (input.substr(pos, 2) === "::") {
- result4 = "::";
- pos += 2;
- } else {
- result4 = null;
- if (reportFailures === 0) {
- matchFailed("\"::\"");
- }
- }
- if (result4 !== null) {
- result5 = parse_h16();
- if (result5 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result6 = ":";
- pos++;
- } else {
- result6 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result6 !== null) {
- result7 = parse_ls32();
- if (result7 !== null) {
- result0 = [result0, result1, result2, result3, result4, result5, result6, result7];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 === null) {
- pos1 = pos;
- result0 = parse_h16();
- if (result0 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_h16();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result2 = ":";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_h16();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- result2 = result2 !== null ? result2 : "";
- if (result2 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result3 = ":";
- pos++;
- } else {
- result3 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result3 !== null) {
- result4 = parse_h16();
- if (result4 !== null) {
- result3 = [result3, result4];
- } else {
- result3 = null;
- pos = pos2;
- }
- } else {
- result3 = null;
- pos = pos2;
- }
- result3 = result3 !== null ? result3 : "";
- if (result3 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result4 = ":";
- pos++;
- } else {
- result4 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result4 !== null) {
- result5 = parse_h16();
- if (result5 !== null) {
- result4 = [result4, result5];
- } else {
- result4 = null;
- pos = pos2;
- }
- } else {
- result4 = null;
- pos = pos2;
- }
- result4 = result4 !== null ? result4 : "";
- if (result4 !== null) {
- if (input.substr(pos, 2) === "::") {
- result5 = "::";
- pos += 2;
- } else {
- result5 = null;
- if (reportFailures === 0) {
- matchFailed("\"::\"");
- }
- }
- if (result5 !== null) {
- result6 = parse_ls32();
- if (result6 !== null) {
- result0 = [result0, result1, result2, result3, result4, result5, result6];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 === null) {
- pos1 = pos;
- result0 = parse_h16();
- if (result0 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_h16();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result2 = ":";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_h16();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- result2 = result2 !== null ? result2 : "";
- if (result2 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result3 = ":";
- pos++;
- } else {
- result3 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result3 !== null) {
- result4 = parse_h16();
- if (result4 !== null) {
- result3 = [result3, result4];
- } else {
- result3 = null;
- pos = pos2;
- }
- } else {
- result3 = null;
- pos = pos2;
- }
- result3 = result3 !== null ? result3 : "";
- if (result3 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result4 = ":";
- pos++;
- } else {
- result4 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result4 !== null) {
- result5 = parse_h16();
- if (result5 !== null) {
- result4 = [result4, result5];
- } else {
- result4 = null;
- pos = pos2;
- }
- } else {
- result4 = null;
- pos = pos2;
- }
- result4 = result4 !== null ? result4 : "";
- if (result4 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result5 = ":";
- pos++;
- } else {
- result5 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result5 !== null) {
- result6 = parse_h16();
- if (result6 !== null) {
- result5 = [result5, result6];
- } else {
- result5 = null;
- pos = pos2;
- }
- } else {
- result5 = null;
- pos = pos2;
- }
- result5 = result5 !== null ? result5 : "";
- if (result5 !== null) {
- if (input.substr(pos, 2) === "::") {
- result6 = "::";
- pos += 2;
- } else {
- result6 = null;
- if (reportFailures === 0) {
- matchFailed("\"::\"");
- }
- }
- if (result6 !== null) {
- result7 = parse_h16();
- if (result7 !== null) {
- result0 = [result0, result1, result2, result3, result4, result5, result6, result7];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 === null) {
- pos1 = pos;
- result0 = parse_h16();
- if (result0 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_h16();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result2 = ":";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_h16();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- result2 = result2 !== null ? result2 : "";
- if (result2 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result3 = ":";
- pos++;
- } else {
- result3 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result3 !== null) {
- result4 = parse_h16();
- if (result4 !== null) {
- result3 = [result3, result4];
- } else {
- result3 = null;
- pos = pos2;
- }
- } else {
- result3 = null;
- pos = pos2;
- }
- result3 = result3 !== null ? result3 : "";
- if (result3 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result4 = ":";
- pos++;
- } else {
- result4 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result4 !== null) {
- result5 = parse_h16();
- if (result5 !== null) {
- result4 = [result4, result5];
- } else {
- result4 = null;
- pos = pos2;
- }
- } else {
- result4 = null;
- pos = pos2;
- }
- result4 = result4 !== null ? result4 : "";
- if (result4 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result5 = ":";
- pos++;
- } else {
- result5 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result5 !== null) {
- result6 = parse_h16();
- if (result6 !== null) {
- result5 = [result5, result6];
- } else {
- result5 = null;
- pos = pos2;
- }
- } else {
- result5 = null;
- pos = pos2;
- }
- result5 = result5 !== null ? result5 : "";
- if (result5 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 58) {
- result6 = ":";
- pos++;
- } else {
- result6 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result6 !== null) {
- result7 = parse_h16();
- if (result7 !== null) {
- result6 = [result6, result7];
- } else {
- result6 = null;
- pos = pos2;
- }
- } else {
- result6 = null;
- pos = pos2;
- }
- result6 = result6 !== null ? result6 : "";
- if (result6 !== null) {
- if (input.substr(pos, 2) === "::") {
- result7 = "::";
- pos += 2;
- } else {
- result7 = null;
- if (reportFailures === 0) {
- matchFailed("\"::\"");
- }
- }
- if (result7 !== null) {
- result0 = [result0, result1, result2, result3, result4, result5, result6, result7];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- if (result0 !== null) {
- result0 = function (offset) {
- data.host_type = 'IPv6';
- return input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_h16() {
- var result0, result1, result2, result3;
- var pos0;
- pos0 = pos;
- result0 = parse_HEXDIG();
- if (result0 !== null) {
- result1 = parse_HEXDIG();
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- result2 = parse_HEXDIG();
- result2 = result2 !== null ? result2 : "";
- if (result2 !== null) {
- result3 = parse_HEXDIG();
- result3 = result3 !== null ? result3 : "";
- if (result3 !== null) {
- result0 = [result0, result1, result2, result3];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_ls32() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- result0 = parse_h16();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_h16();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- if (result0 === null) {
- result0 = parse_IPv4address();
- }
- return result0;
- }
- function parse_IPv4address() {
- var result0, result1, result2, result3, result4, result5, result6;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_dec_octet();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 46) {
- result1 = ".";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_dec_octet();
- if (result2 !== null) {
- if (input.charCodeAt(pos) === 46) {
- result3 = ".";
- pos++;
- } else {
- result3 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- if (result3 !== null) {
- result4 = parse_dec_octet();
- if (result4 !== null) {
- if (input.charCodeAt(pos) === 46) {
- result5 = ".";
- pos++;
- } else {
- result5 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- if (result5 !== null) {
- result6 = parse_dec_octet();
- if (result6 !== null) {
- result0 = [result0, result1, result2, result3, result4, result5, result6];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- data.host_type = 'IPv4';
- return input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_dec_octet() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- if (input.substr(pos, 2) === "25") {
- result0 = "25";
- pos += 2;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"25\"");
- }
- }
- if (result0 !== null) {
- if (/^[0-5]/.test(input.charAt(pos))) {
- result1 = input.charAt(pos);
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("[0-5]");
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- if (result0 === null) {
- pos0 = pos;
- if (input.charCodeAt(pos) === 50) {
- result0 = "2";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"2\"");
- }
- }
- if (result0 !== null) {
- if (/^[0-4]/.test(input.charAt(pos))) {
- result1 = input.charAt(pos);
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("[0-4]");
- }
- }
- if (result1 !== null) {
- result2 = parse_DIGIT();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- if (result0 === null) {
- pos0 = pos;
- if (input.charCodeAt(pos) === 49) {
- result0 = "1";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"1\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_DIGIT();
- if (result1 !== null) {
- result2 = parse_DIGIT();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- if (result0 === null) {
- pos0 = pos;
- if (/^[1-9]/.test(input.charAt(pos))) {
- result0 = input.charAt(pos);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("[1-9]");
- }
- }
- if (result0 !== null) {
- result1 = parse_DIGIT();
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- if (result0 === null) {
- result0 = parse_DIGIT();
- }
- }
- }
- }
- return result0;
- }
- function parse_port() {
- var result0, result1, result2, result3, result4;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_DIGIT();
- result0 = result0 !== null ? result0 : "";
- if (result0 !== null) {
- result1 = parse_DIGIT();
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- result2 = parse_DIGIT();
- result2 = result2 !== null ? result2 : "";
- if (result2 !== null) {
- result3 = parse_DIGIT();
- result3 = result3 !== null ? result3 : "";
- if (result3 !== null) {
- result4 = parse_DIGIT();
- result4 = result4 !== null ? result4 : "";
- if (result4 !== null) {
- result0 = [result0, result1, result2, result3, result4];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, port) {
- port = parseInt(port.join(''));
- data.port = port;
- return port;
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_uri_parameters() {
- var result0, result1, result2;
- var pos0;
- result0 = [];
- pos0 = pos;
- if (input.charCodeAt(pos) === 59) {
- result1 = ";";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\";\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_uri_parameter();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos0;
- }
- } else {
- result1 = null;
- pos = pos0;
- }
- while (result1 !== null) {
- result0.push(result1);
- pos0 = pos;
- if (input.charCodeAt(pos) === 59) {
- result1 = ";";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\";\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_uri_parameter();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos0;
- }
- } else {
- result1 = null;
- pos = pos0;
- }
- }
- return result0;
- }
- function parse_uri_parameter() {
- var result0;
- result0 = parse_transport_param();
- if (result0 === null) {
- result0 = parse_user_param();
- if (result0 === null) {
- result0 = parse_method_param();
- if (result0 === null) {
- result0 = parse_ttl_param();
- if (result0 === null) {
- result0 = parse_maddr_param();
- if (result0 === null) {
- result0 = parse_lr_param();
- if (result0 === null) {
- result0 = parse_other_param();
- }
- }
- }
- }
- }
- }
- return result0;
- }
- function parse_transport_param() {
- var result0, result1;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 10).toLowerCase() === "transport=") {
- result0 = input.substr(pos, 10);
- pos += 10;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"transport=\"");
- }
- }
- if (result0 !== null) {
- if (input.substr(pos, 3).toLowerCase() === "udp") {
- result1 = input.substr(pos, 3);
- pos += 3;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"udp\"");
- }
- }
- if (result1 === null) {
- if (input.substr(pos, 3).toLowerCase() === "tcp") {
- result1 = input.substr(pos, 3);
- pos += 3;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"tcp\"");
- }
- }
- if (result1 === null) {
- if (input.substr(pos, 4).toLowerCase() === "sctp") {
- result1 = input.substr(pos, 4);
- pos += 4;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"sctp\"");
- }
- }
- if (result1 === null) {
- if (input.substr(pos, 3).toLowerCase() === "tls") {
- result1 = input.substr(pos, 3);
- pos += 3;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"tls\"");
- }
- }
- if (result1 === null) {
- result1 = parse_token();
- }
- }
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, transport) {
- if (!data.uri_params) data.uri_params = {};
- data.uri_params['transport'] = transport.toLowerCase();
- }(pos0, result0[1]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_user_param() {
- var result0, result1;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 5).toLowerCase() === "user=") {
- result0 = input.substr(pos, 5);
- pos += 5;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"user=\"");
- }
- }
- if (result0 !== null) {
- if (input.substr(pos, 5).toLowerCase() === "phone") {
- result1 = input.substr(pos, 5);
- pos += 5;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"phone\"");
- }
- }
- if (result1 === null) {
- if (input.substr(pos, 2).toLowerCase() === "ip") {
- result1 = input.substr(pos, 2);
- pos += 2;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"ip\"");
- }
- }
- if (result1 === null) {
- result1 = parse_token();
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, user) {
- if (!data.uri_params) data.uri_params = {};
- data.uri_params['user'] = user.toLowerCase();
- }(pos0, result0[1]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_method_param() {
- var result0, result1;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 7).toLowerCase() === "method=") {
- result0 = input.substr(pos, 7);
- pos += 7;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"method=\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_Method();
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, method) {
- if (!data.uri_params) data.uri_params = {};
- data.uri_params['method'] = method;
- }(pos0, result0[1]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_ttl_param() {
- var result0, result1;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 4).toLowerCase() === "ttl=") {
- result0 = input.substr(pos, 4);
- pos += 4;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"ttl=\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_ttl();
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, ttl) {
- if (!data.params) data.params = {};
- data.params['ttl'] = ttl;
- }(pos0, result0[1]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_maddr_param() {
- var result0, result1;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 6).toLowerCase() === "maddr=") {
- result0 = input.substr(pos, 6);
- pos += 6;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"maddr=\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_host();
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, maddr) {
- if (!data.uri_params) data.uri_params = {};
- data.uri_params['maddr'] = maddr;
- }(pos0, result0[1]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_lr_param() {
- var result0, result1, result2;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 2).toLowerCase() === "lr") {
- result0 = input.substr(pos, 2);
- pos += 2;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"lr\"");
- }
- }
- if (result0 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 61) {
- result1 = "=";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"=\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_token();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- if (!data.uri_params) data.uri_params = {};
- data.uri_params['lr'] = undefined;
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_other_param() {
- var result0, result1, result2;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_pname();
- if (result0 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 61) {
- result1 = "=";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"=\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_pvalue();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, param, value) {
- if (!data.uri_params) data.uri_params = {};
- if (typeof value === 'undefined') {
- value = undefined;
- } else {
- value = value[1];
- }
- data.uri_params[param.toLowerCase()] = value;
- }(pos0, result0[0], result0[1]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_pname() {
- var result0, result1;
- var pos0;
- pos0 = pos;
- result1 = parse_paramchar();
- if (result1 !== null) {
- result0 = [];
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_paramchar();
- }
- } else {
- result0 = null;
- }
- if (result0 !== null) {
- result0 = function (offset, pname) {
- return pname.join('');
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_pvalue() {
- var result0, result1;
- var pos0;
- pos0 = pos;
- result1 = parse_paramchar();
- if (result1 !== null) {
- result0 = [];
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_paramchar();
- }
- } else {
- result0 = null;
- }
- if (result0 !== null) {
- result0 = function (offset, pvalue) {
- return pvalue.join('');
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_paramchar() {
- var result0;
- result0 = parse_param_unreserved();
- if (result0 === null) {
- result0 = parse_unreserved();
- if (result0 === null) {
- result0 = parse_escaped();
- }
- }
- return result0;
- }
- function parse_param_unreserved() {
- var result0;
- if (input.charCodeAt(pos) === 91) {
- result0 = "[";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"[\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 93) {
- result0 = "]";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"]\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 47) {
- result0 = "/";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"/\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 58) {
- result0 = ":";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 38) {
- result0 = "&";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"&\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 43) {
- result0 = "+";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 36) {
- result0 = "$";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"$\"");
- }
- }
- }
- }
- }
- }
- }
- }
- return result0;
- }
- function parse_headers() {
- var result0, result1, result2, result3, result4;
- var pos0, pos1;
- pos0 = pos;
- if (input.charCodeAt(pos) === 63) {
- result0 = "?";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"?\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_header();
- if (result1 !== null) {
- result2 = [];
- pos1 = pos;
- if (input.charCodeAt(pos) === 38) {
- result3 = "&";
- pos++;
- } else {
- result3 = null;
- if (reportFailures === 0) {
- matchFailed("\"&\"");
- }
- }
- if (result3 !== null) {
- result4 = parse_header();
- if (result4 !== null) {
- result3 = [result3, result4];
- } else {
- result3 = null;
- pos = pos1;
- }
- } else {
- result3 = null;
- pos = pos1;
- }
- while (result3 !== null) {
- result2.push(result3);
- pos1 = pos;
- if (input.charCodeAt(pos) === 38) {
- result3 = "&";
- pos++;
- } else {
- result3 = null;
- if (reportFailures === 0) {
- matchFailed("\"&\"");
- }
- }
- if (result3 !== null) {
- result4 = parse_header();
- if (result4 !== null) {
- result3 = [result3, result4];
- } else {
- result3 = null;
- pos = pos1;
- }
- } else {
- result3 = null;
- pos = pos1;
- }
- }
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_header() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_hname();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 61) {
- result1 = "=";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"=\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_hvalue();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, hname, hvalue) {
- hname = hname.join('').toLowerCase();
- hvalue = hvalue.join('');
- if (!data.uri_headers) data.uri_headers = {};
- if (!data.uri_headers[hname]) {
- data.uri_headers[hname] = [hvalue];
- } else {
- data.uri_headers[hname].push(hvalue);
- }
- }(pos0, result0[0], result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_hname() {
- var result0, result1;
- result1 = parse_hnv_unreserved();
- if (result1 === null) {
- result1 = parse_unreserved();
- if (result1 === null) {
- result1 = parse_escaped();
- }
- }
- if (result1 !== null) {
- result0 = [];
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_hnv_unreserved();
- if (result1 === null) {
- result1 = parse_unreserved();
- if (result1 === null) {
- result1 = parse_escaped();
- }
- }
- }
- } else {
- result0 = null;
- }
- return result0;
- }
- function parse_hvalue() {
- var result0, result1;
- result0 = [];
- result1 = parse_hnv_unreserved();
- if (result1 === null) {
- result1 = parse_unreserved();
- if (result1 === null) {
- result1 = parse_escaped();
- }
- }
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_hnv_unreserved();
- if (result1 === null) {
- result1 = parse_unreserved();
- if (result1 === null) {
- result1 = parse_escaped();
- }
- }
- }
- return result0;
- }
- function parse_hnv_unreserved() {
- var result0;
- if (input.charCodeAt(pos) === 91) {
- result0 = "[";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"[\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 93) {
- result0 = "]";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"]\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 47) {
- result0 = "/";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"/\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 63) {
- result0 = "?";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"?\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 58) {
- result0 = ":";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 43) {
- result0 = "+";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 36) {
- result0 = "$";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"$\"");
- }
- }
- }
- }
- }
- }
- }
- }
- return result0;
- }
- function parse_Request_Response() {
- var result0;
- result0 = parse_Status_Line();
- if (result0 === null) {
- result0 = parse_Request_Line();
- }
- return result0;
- }
- function parse_Request_Line() {
- var result0, result1, result2, result3, result4;
- var pos0;
- pos0 = pos;
- result0 = parse_Method();
- if (result0 !== null) {
- result1 = parse_SP();
- if (result1 !== null) {
- result2 = parse_Request_URI();
- if (result2 !== null) {
- result3 = parse_SP();
- if (result3 !== null) {
- result4 = parse_SIP_Version();
- if (result4 !== null) {
- result0 = [result0, result1, result2, result3, result4];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_Request_URI() {
- var result0;
- result0 = parse_SIP_URI();
- if (result0 === null) {
- result0 = parse_absoluteURI();
- }
- return result0;
- }
- function parse_absoluteURI() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- result0 = parse_scheme();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_hier_part();
- if (result2 === null) {
- result2 = parse_opaque_part();
- }
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_hier_part() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_net_path();
- if (result0 === null) {
- result0 = parse_abs_path();
- }
- if (result0 !== null) {
- pos1 = pos;
- if (input.charCodeAt(pos) === 63) {
- result1 = "?";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"?\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_query();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos1;
- }
- } else {
- result1 = null;
- pos = pos1;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_net_path() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- if (input.substr(pos, 2) === "//") {
- result0 = "//";
- pos += 2;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"//\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_authority();
- if (result1 !== null) {
- result2 = parse_abs_path();
- result2 = result2 !== null ? result2 : "";
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_abs_path() {
- var result0, result1;
- var pos0;
- pos0 = pos;
- if (input.charCodeAt(pos) === 47) {
- result0 = "/";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"/\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_path_segments();
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_opaque_part() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- result0 = parse_uric_no_slash();
- if (result0 !== null) {
- result1 = [];
- result2 = parse_uric();
- while (result2 !== null) {
- result1.push(result2);
- result2 = parse_uric();
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_uric() {
- var result0;
- result0 = parse_reserved();
- if (result0 === null) {
- result0 = parse_unreserved();
- if (result0 === null) {
- result0 = parse_escaped();
- }
- }
- return result0;
- }
- function parse_uric_no_slash() {
- var result0;
- result0 = parse_unreserved();
- if (result0 === null) {
- result0 = parse_escaped();
- if (result0 === null) {
- if (input.charCodeAt(pos) === 59) {
- result0 = ";";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\";\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 63) {
- result0 = "?";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"?\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 58) {
- result0 = ":";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 64) {
- result0 = "@";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"@\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 38) {
- result0 = "&";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"&\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 61) {
- result0 = "=";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"=\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 43) {
- result0 = "+";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 36) {
- result0 = "$";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"$\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 44) {
- result0 = ",";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\",\"");
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- return result0;
- }
- function parse_path_segments() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_segment();
- if (result0 !== null) {
- result1 = [];
- pos1 = pos;
- if (input.charCodeAt(pos) === 47) {
- result2 = "/";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"/\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_segment();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos1 = pos;
- if (input.charCodeAt(pos) === 47) {
- result2 = "/";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"/\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_segment();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_segment() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- result0 = [];
- result1 = parse_pchar();
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_pchar();
- }
- if (result0 !== null) {
- result1 = [];
- pos1 = pos;
- if (input.charCodeAt(pos) === 59) {
- result2 = ";";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\";\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos1 = pos;
- if (input.charCodeAt(pos) === 59) {
- result2 = ";";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\";\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_param() {
- var result0, result1;
- result0 = [];
- result1 = parse_pchar();
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_pchar();
- }
- return result0;
- }
- function parse_pchar() {
- var result0;
- result0 = parse_unreserved();
- if (result0 === null) {
- result0 = parse_escaped();
- if (result0 === null) {
- if (input.charCodeAt(pos) === 58) {
- result0 = ":";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 64) {
- result0 = "@";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"@\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 38) {
- result0 = "&";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"&\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 61) {
- result0 = "=";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"=\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 43) {
- result0 = "+";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 36) {
- result0 = "$";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"$\"");
- }
- }
- if (result0 === null) {
- if (input.charCodeAt(pos) === 44) {
- result0 = ",";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\",\"");
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- return result0;
- }
- function parse_scheme() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_ALPHA();
- if (result0 !== null) {
- result1 = [];
- result2 = parse_ALPHA();
- if (result2 === null) {
- result2 = parse_DIGIT();
- if (result2 === null) {
- if (input.charCodeAt(pos) === 43) {
- result2 = "+";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- if (result2 === null) {
- if (input.charCodeAt(pos) === 45) {
- result2 = "-";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result2 === null) {
- if (input.charCodeAt(pos) === 46) {
- result2 = ".";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- }
- }
- }
- }
- while (result2 !== null) {
- result1.push(result2);
- result2 = parse_ALPHA();
- if (result2 === null) {
- result2 = parse_DIGIT();
- if (result2 === null) {
- if (input.charCodeAt(pos) === 43) {
- result2 = "+";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- if (result2 === null) {
- if (input.charCodeAt(pos) === 45) {
- result2 = "-";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result2 === null) {
- if (input.charCodeAt(pos) === 46) {
- result2 = ".";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- }
- }
- }
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- data.scheme = input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_authority() {
- var result0;
- result0 = parse_srvr();
- if (result0 === null) {
- result0 = parse_reg_name();
- }
- return result0;
- }
- function parse_srvr() {
- var result0, result1;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_userinfo();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 64) {
- result1 = "@";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"@\"");
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- result0 = result0 !== null ? result0 : "";
- if (result0 !== null) {
- result1 = parse_hostport();
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- result0 = result0 !== null ? result0 : "";
- return result0;
- }
- function parse_reg_name() {
- var result0, result1;
- result1 = parse_unreserved();
- if (result1 === null) {
- result1 = parse_escaped();
- if (result1 === null) {
- if (input.charCodeAt(pos) === 36) {
- result1 = "$";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"$\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 44) {
- result1 = ",";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\",\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 59) {
- result1 = ";";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\";\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 64) {
- result1 = "@";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"@\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 38) {
- result1 = "&";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"&\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 61) {
- result1 = "=";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"=\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 43) {
- result1 = "+";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- if (result1 !== null) {
- result0 = [];
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_unreserved();
- if (result1 === null) {
- result1 = parse_escaped();
- if (result1 === null) {
- if (input.charCodeAt(pos) === 36) {
- result1 = "$";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"$\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 44) {
- result1 = ",";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\",\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 59) {
- result1 = ";";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\";\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 58) {
- result1 = ":";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\":\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 64) {
- result1 = "@";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"@\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 38) {
- result1 = "&";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"&\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 61) {
- result1 = "=";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"=\"");
- }
- }
- if (result1 === null) {
- if (input.charCodeAt(pos) === 43) {
- result1 = "+";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"+\"");
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- } else {
- result0 = null;
- }
- return result0;
- }
- function parse_query() {
- var result0, result1;
- result0 = [];
- result1 = parse_uric();
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_uric();
- }
- return result0;
- }
- function parse_SIP_Version() {
- var result0, result1, result2, result3, result4, result5;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 3).toLowerCase() === "sip") {
- result0 = input.substr(pos, 3);
- pos += 3;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"SIP\"");
- }
- }
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 47) {
- result1 = "/";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"/\"");
- }
- }
- if (result1 !== null) {
- result3 = parse_DIGIT();
- if (result3 !== null) {
- result2 = [];
- while (result3 !== null) {
- result2.push(result3);
- result3 = parse_DIGIT();
- }
- } else {
- result2 = null;
- }
- if (result2 !== null) {
- if (input.charCodeAt(pos) === 46) {
- result3 = ".";
- pos++;
- } else {
- result3 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- if (result3 !== null) {
- result5 = parse_DIGIT();
- if (result5 !== null) {
- result4 = [];
- while (result5 !== null) {
- result4.push(result5);
- result5 = parse_DIGIT();
- }
- } else {
- result4 = null;
- }
- if (result4 !== null) {
- result0 = [result0, result1, result2, result3, result4];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- data.sip_version = input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_INVITEm() {
- var result0;
- if (input.substr(pos, 6) === "INVITE") {
- result0 = "INVITE";
- pos += 6;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"INVITE\"");
- }
- }
- return result0;
- }
- function parse_ACKm() {
- var result0;
- if (input.substr(pos, 3) === "ACK") {
- result0 = "ACK";
- pos += 3;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"ACK\"");
- }
- }
- return result0;
- }
- function parse_OPTIONSm() {
- var result0;
- if (input.substr(pos, 7) === "OPTIONS") {
- result0 = "OPTIONS";
- pos += 7;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"OPTIONS\"");
- }
- }
- return result0;
- }
- function parse_BYEm() {
- var result0;
- if (input.substr(pos, 3) === "BYE") {
- result0 = "BYE";
- pos += 3;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"BYE\"");
- }
- }
- return result0;
- }
- function parse_CANCELm() {
- var result0;
- if (input.substr(pos, 6) === "CANCEL") {
- result0 = "CANCEL";
- pos += 6;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"CANCEL\"");
- }
- }
- return result0;
- }
- function parse_REGISTERm() {
- var result0;
- if (input.substr(pos, 8) === "REGISTER") {
- result0 = "REGISTER";
- pos += 8;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"REGISTER\"");
- }
- }
- return result0;
- }
- function parse_SUBSCRIBEm() {
- var result0;
- if (input.substr(pos, 9) === "SUBSCRIBE") {
- result0 = "SUBSCRIBE";
- pos += 9;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"SUBSCRIBE\"");
- }
- }
- return result0;
- }
- function parse_NOTIFYm() {
- var result0;
- if (input.substr(pos, 6) === "NOTIFY") {
- result0 = "NOTIFY";
- pos += 6;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"NOTIFY\"");
- }
- }
- return result0;
- }
- function parse_REFERm() {
- var result0;
- if (input.substr(pos, 5) === "REFER") {
- result0 = "REFER";
- pos += 5;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"REFER\"");
- }
- }
- return result0;
- }
- function parse_Method() {
- var result0;
- var pos0;
- pos0 = pos;
- result0 = parse_INVITEm();
- if (result0 === null) {
- result0 = parse_ACKm();
- if (result0 === null) {
- result0 = parse_OPTIONSm();
- if (result0 === null) {
- result0 = parse_BYEm();
- if (result0 === null) {
- result0 = parse_CANCELm();
- if (result0 === null) {
- result0 = parse_REGISTERm();
- if (result0 === null) {
- result0 = parse_SUBSCRIBEm();
- if (result0 === null) {
- result0 = parse_NOTIFYm();
- if (result0 === null) {
- result0 = parse_REFERm();
- if (result0 === null) {
- result0 = parse_token();
- }
- }
- }
- }
- }
- }
- }
- }
- }
- if (result0 !== null) {
- result0 = function (offset) {
- data.method = input.substring(pos, offset);
- return data.method;
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_Status_Line() {
- var result0, result1, result2, result3, result4;
- var pos0;
- pos0 = pos;
- result0 = parse_SIP_Version();
- if (result0 !== null) {
- result1 = parse_SP();
- if (result1 !== null) {
- result2 = parse_Status_Code();
- if (result2 !== null) {
- result3 = parse_SP();
- if (result3 !== null) {
- result4 = parse_Reason_Phrase();
- if (result4 !== null) {
- result0 = [result0, result1, result2, result3, result4];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_Status_Code() {
- var result0;
- var pos0;
- pos0 = pos;
- result0 = parse_extension_code();
- if (result0 !== null) {
- result0 = function (offset, status_code) {
- data.status_code = parseInt(status_code.join(''));
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_extension_code() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- result0 = parse_DIGIT();
- if (result0 !== null) {
- result1 = parse_DIGIT();
- if (result1 !== null) {
- result2 = parse_DIGIT();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_Reason_Phrase() {
- var result0, result1;
- var pos0;
- pos0 = pos;
- result0 = [];
- result1 = parse_reserved();
- if (result1 === null) {
- result1 = parse_unreserved();
- if (result1 === null) {
- result1 = parse_escaped();
- if (result1 === null) {
- result1 = parse_UTF8_NONASCII();
- if (result1 === null) {
- result1 = parse_UTF8_CONT();
- if (result1 === null) {
- result1 = parse_SP();
- if (result1 === null) {
- result1 = parse_HTAB();
- }
- }
- }
- }
- }
- }
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_reserved();
- if (result1 === null) {
- result1 = parse_unreserved();
- if (result1 === null) {
- result1 = parse_escaped();
- if (result1 === null) {
- result1 = parse_UTF8_NONASCII();
- if (result1 === null) {
- result1 = parse_UTF8_CONT();
- if (result1 === null) {
- result1 = parse_SP();
- if (result1 === null) {
- result1 = parse_HTAB();
- }
- }
- }
- }
- }
- }
- }
- if (result0 !== null) {
- result0 = function (offset) {
- data.reason_phrase = input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_Allow_Events() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_event_type();
- if (result0 !== null) {
- result1 = [];
- pos1 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_event_type();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos1 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_event_type();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_Call_ID() {
- var result0, result1, result2;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_word();
- if (result0 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 64) {
- result1 = "@";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"@\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_word();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- data = input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_Contact() {
- var result0, result1, result2, result3;
- var pos0, pos1, pos2;
- pos0 = pos;
- result0 = parse_STAR();
- if (result0 === null) {
- pos1 = pos;
- result0 = parse_contact_param();
- if (result0 !== null) {
- result1 = [];
- pos2 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_contact_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos2 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_contact_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- }
- if (result0 !== null) {
- result0 = function (offset) {
- var idx, length;
- length = data.multi_header.length;
- for (idx = 0; idx < length; idx++) {
- if (data.multi_header[idx].parsed === null) {
- data = null;
- break;
- }
- }
- if (data !== null) {
- data = data.multi_header;
- } else {
- data = -1;
- }
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_contact_param() {
- var result0, result1, result2, result3;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_SIP_URI_noparams();
- if (result0 === null) {
- result0 = parse_name_addr();
- }
- if (result0 !== null) {
- result1 = [];
- pos2 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_contact_params();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos2 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_contact_params();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- var header;
- if (!data.multi_header) data.multi_header = [];
- try {
- header = new NameAddrHeader(data.uri, data.display_name, data.params);
- delete data.uri;
- delete data.display_name;
- delete data.params;
- } catch (e) {
- header = null;
- }
- data.multi_header.push({
- 'possition': pos,
- 'offset': offset,
- 'parsed': header
- });
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_name_addr() {
- var result0, result1, result2, result3;
- var pos0;
- pos0 = pos;
- result0 = parse_display_name();
- result0 = result0 !== null ? result0 : "";
- if (result0 !== null) {
- result1 = parse_LAQUOT();
- if (result1 !== null) {
- result2 = parse_SIP_URI();
- if (result2 !== null) {
- result3 = parse_RAQUOT();
- if (result3 !== null) {
- result0 = [result0, result1, result2, result3];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_display_name() {
- var result0, result1, result2, result3;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_token();
- if (result0 !== null) {
- result1 = [];
- pos2 = pos;
- result2 = parse_LWS();
- if (result2 !== null) {
- result3 = parse_token();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos2 = pos;
- result2 = parse_LWS();
- if (result2 !== null) {
- result3 = parse_token();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 === null) {
- result0 = parse_quoted_string();
- }
- if (result0 !== null) {
- result0 = function (offset, display_name) {
- display_name = input.substring(pos, offset).trim();
- if (display_name[0] === '\"') {
- display_name = display_name.substring(1, display_name.length - 1);
- }
- data.display_name = display_name;
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_contact_params() {
- var result0;
- result0 = parse_c_p_q();
- if (result0 === null) {
- result0 = parse_c_p_expires();
- if (result0 === null) {
- result0 = parse_generic_param();
- }
- }
- return result0;
- }
- function parse_c_p_q() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 1).toLowerCase() === "q") {
- result0 = input.substr(pos, 1);
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"q\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_qvalue();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, q) {
- if (!data.params) data.params = {};
- data.params['q'] = q;
- }(pos0, result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_c_p_expires() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 7).toLowerCase() === "expires") {
- result0 = input.substr(pos, 7);
- pos += 7;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"expires\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_delta_seconds();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, expires) {
- if (!data.params) data.params = {};
- data.params['expires'] = expires;
- }(pos0, result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_delta_seconds() {
- var result0, result1;
- var pos0;
- pos0 = pos;
- result1 = parse_DIGIT();
- if (result1 !== null) {
- result0 = [];
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_DIGIT();
- }
- } else {
- result0 = null;
- }
- if (result0 !== null) {
- result0 = function (offset, delta_seconds) {
- return parseInt(delta_seconds.join(''));
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_qvalue() {
- var result0, result1, result2, result3, result4;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- if (input.charCodeAt(pos) === 48) {
- result0 = "0";
- pos++;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"0\"");
- }
- }
- if (result0 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 46) {
- result1 = ".";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_DIGIT();
- result2 = result2 !== null ? result2 : "";
- if (result2 !== null) {
- result3 = parse_DIGIT();
- result3 = result3 !== null ? result3 : "";
- if (result3 !== null) {
- result4 = parse_DIGIT();
- result4 = result4 !== null ? result4 : "";
- if (result4 !== null) {
- result1 = [result1, result2, result3, result4];
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- return parseFloat(input.substring(pos, offset));
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_generic_param() {
- var result0, result1, result2;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_token();
- if (result0 !== null) {
- pos2 = pos;
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_gen_value();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, param, value) {
- if (!data.params) data.params = {};
- if (typeof value === 'undefined') {
- value = undefined;
- } else {
- value = value[1];
- }
- data.params[param.toLowerCase()] = value;
- }(pos0, result0[0], result0[1]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_gen_value() {
- var result0;
- result0 = parse_token();
- if (result0 === null) {
- result0 = parse_host();
- if (result0 === null) {
- result0 = parse_quoted_string();
- }
- }
- return result0;
- }
- function parse_Content_Disposition() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_disp_type();
- if (result0 !== null) {
- result1 = [];
- pos1 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_disp_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos1 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_disp_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_disp_type() {
- var result0;
- if (input.substr(pos, 6).toLowerCase() === "render") {
- result0 = input.substr(pos, 6);
- pos += 6;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"render\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 7).toLowerCase() === "session") {
- result0 = input.substr(pos, 7);
- pos += 7;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"session\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 4).toLowerCase() === "icon") {
- result0 = input.substr(pos, 4);
- pos += 4;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"icon\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 5).toLowerCase() === "alert") {
- result0 = input.substr(pos, 5);
- pos += 5;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"alert\"");
- }
- }
- if (result0 === null) {
- result0 = parse_token();
- }
- }
- }
- }
- return result0;
- }
- function parse_disp_param() {
- var result0;
- result0 = parse_handling_param();
- if (result0 === null) {
- result0 = parse_generic_param();
- }
- return result0;
- }
- function parse_handling_param() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- if (input.substr(pos, 8).toLowerCase() === "handling") {
- result0 = input.substr(pos, 8);
- pos += 8;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"handling\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- if (input.substr(pos, 8).toLowerCase() === "optional") {
- result2 = input.substr(pos, 8);
- pos += 8;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"optional\"");
- }
- }
- if (result2 === null) {
- if (input.substr(pos, 8).toLowerCase() === "required") {
- result2 = input.substr(pos, 8);
- pos += 8;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"required\"");
- }
- }
- if (result2 === null) {
- result2 = parse_token();
- }
- }
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_Content_Encoding() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_token();
- if (result0 !== null) {
- result1 = [];
- pos1 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_token();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos1 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_token();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_Content_Length() {
- var result0, result1;
- var pos0;
- pos0 = pos;
- result1 = parse_DIGIT();
- if (result1 !== null) {
- result0 = [];
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_DIGIT();
- }
- } else {
- result0 = null;
- }
- if (result0 !== null) {
- result0 = function (offset, length) {
- data = parseInt(length.join(''));
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_Content_Type() {
- var result0;
- var pos0;
- pos0 = pos;
- result0 = parse_media_type();
- if (result0 !== null) {
- result0 = function (offset) {
- data = input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_media_type() {
- var result0, result1, result2, result3, result4, result5;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_m_type();
- if (result0 !== null) {
- result1 = parse_SLASH();
- if (result1 !== null) {
- result2 = parse_m_subtype();
- if (result2 !== null) {
- result3 = [];
- pos1 = pos;
- result4 = parse_SEMI();
- if (result4 !== null) {
- result5 = parse_m_parameter();
- if (result5 !== null) {
- result4 = [result4, result5];
- } else {
- result4 = null;
- pos = pos1;
- }
- } else {
- result4 = null;
- pos = pos1;
- }
- while (result4 !== null) {
- result3.push(result4);
- pos1 = pos;
- result4 = parse_SEMI();
- if (result4 !== null) {
- result5 = parse_m_parameter();
- if (result5 !== null) {
- result4 = [result4, result5];
- } else {
- result4 = null;
- pos = pos1;
- }
- } else {
- result4 = null;
- pos = pos1;
- }
- }
- if (result3 !== null) {
- result0 = [result0, result1, result2, result3];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_m_type() {
- var result0;
- result0 = parse_discrete_type();
- if (result0 === null) {
- result0 = parse_composite_type();
- }
- return result0;
- }
- function parse_discrete_type() {
- var result0;
- if (input.substr(pos, 4).toLowerCase() === "text") {
- result0 = input.substr(pos, 4);
- pos += 4;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"text\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 5).toLowerCase() === "image") {
- result0 = input.substr(pos, 5);
- pos += 5;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"image\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 5).toLowerCase() === "audio") {
- result0 = input.substr(pos, 5);
- pos += 5;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"audio\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 5).toLowerCase() === "video") {
- result0 = input.substr(pos, 5);
- pos += 5;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"video\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 11).toLowerCase() === "application") {
- result0 = input.substr(pos, 11);
- pos += 11;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"application\"");
- }
- }
- if (result0 === null) {
- result0 = parse_extension_token();
- }
- }
- }
- }
- }
- return result0;
- }
- function parse_composite_type() {
- var result0;
- if (input.substr(pos, 7).toLowerCase() === "message") {
- result0 = input.substr(pos, 7);
- pos += 7;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"message\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 9).toLowerCase() === "multipart") {
- result0 = input.substr(pos, 9);
- pos += 9;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"multipart\"");
- }
- }
- if (result0 === null) {
- result0 = parse_extension_token();
- }
- }
- return result0;
- }
- function parse_extension_token() {
- var result0;
- result0 = parse_token();
- if (result0 === null) {
- result0 = parse_x_token();
- }
- return result0;
- }
- function parse_x_token() {
- var result0, result1;
- var pos0;
- pos0 = pos;
- if (input.substr(pos, 2).toLowerCase() === "x-") {
- result0 = input.substr(pos, 2);
- pos += 2;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"x-\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_token();
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_m_subtype() {
- var result0;
- result0 = parse_extension_token();
- if (result0 === null) {
- result0 = parse_token();
- }
- return result0;
- }
- function parse_m_parameter() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- result0 = parse_token();
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_m_value();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_m_value() {
- var result0;
- result0 = parse_token();
- if (result0 === null) {
- result0 = parse_quoted_string();
- }
- return result0;
- }
- function parse_CSeq() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- result0 = parse_CSeq_value();
- if (result0 !== null) {
- result1 = parse_LWS();
- if (result1 !== null) {
- result2 = parse_Method();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_CSeq_value() {
- var result0, result1;
- var pos0;
- pos0 = pos;
- result1 = parse_DIGIT();
- if (result1 !== null) {
- result0 = [];
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_DIGIT();
- }
- } else {
- result0 = null;
- }
- if (result0 !== null) {
- result0 = function (offset, cseq_value) {
- data.value = parseInt(cseq_value.join(''));
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_Expires() {
- var result0;
- var pos0;
- pos0 = pos;
- result0 = parse_delta_seconds();
- if (result0 !== null) {
- result0 = function (offset, expires) {
- data = expires;
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_Event() {
- var result0, result1, result2, result3;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_event_type();
- if (result0 !== null) {
- result1 = [];
- pos2 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_generic_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos2 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_generic_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, event_type) {
- data.event = event_type.join('').toLowerCase();
- }(pos0, result0[0]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_event_type() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_token_nodot();
- if (result0 !== null) {
- result1 = [];
- pos1 = pos;
- if (input.charCodeAt(pos) === 46) {
- result2 = ".";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_token_nodot();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos1 = pos;
- if (input.charCodeAt(pos) === 46) {
- result2 = ".";
- pos++;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\".\"");
- }
- }
- if (result2 !== null) {
- result3 = parse_token_nodot();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_From() {
- var result0, result1, result2, result3;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_SIP_URI_noparams();
- if (result0 === null) {
- result0 = parse_name_addr();
- }
- if (result0 !== null) {
- result1 = [];
- pos2 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_from_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos2 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_from_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- var tag = data.tag;
- try {
- data = new NameAddrHeader(data.uri, data.display_name, data.params);
- if (tag) {
- data.setParam('tag', tag);
- }
- } catch (e) {
- data = -1;
- }
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_from_param() {
- var result0;
- result0 = parse_tag_param();
- if (result0 === null) {
- result0 = parse_generic_param();
- }
- return result0;
- }
- function parse_tag_param() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 3).toLowerCase() === "tag") {
- result0 = input.substr(pos, 3);
- pos += 3;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"tag\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_token();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, tag) {
- data.tag = tag;
- }(pos0, result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_Max_Forwards() {
- var result0, result1;
- var pos0;
- pos0 = pos;
- result1 = parse_DIGIT();
- if (result1 !== null) {
- result0 = [];
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_DIGIT();
- }
- } else {
- result0 = null;
- }
- if (result0 !== null) {
- result0 = function (offset, forwards) {
- data = parseInt(forwards.join(''));
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_Min_Expires() {
- var result0;
- var pos0;
- pos0 = pos;
- result0 = parse_delta_seconds();
- if (result0 !== null) {
- result0 = function (offset, min_expires) {
- data = min_expires;
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_Name_Addr_Header() {
- var result0, result1, result2, result3, result4, result5, result6;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result0 = [];
- result1 = parse_display_name();
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_display_name();
- }
- if (result0 !== null) {
- result1 = parse_LAQUOT();
- if (result1 !== null) {
- result2 = parse_SIP_URI();
- if (result2 !== null) {
- result3 = parse_RAQUOT();
- if (result3 !== null) {
- result4 = [];
- pos2 = pos;
- result5 = parse_SEMI();
- if (result5 !== null) {
- result6 = parse_generic_param();
- if (result6 !== null) {
- result5 = [result5, result6];
- } else {
- result5 = null;
- pos = pos2;
- }
- } else {
- result5 = null;
- pos = pos2;
- }
- while (result5 !== null) {
- result4.push(result5);
- pos2 = pos;
- result5 = parse_SEMI();
- if (result5 !== null) {
- result6 = parse_generic_param();
- if (result6 !== null) {
- result5 = [result5, result6];
- } else {
- result5 = null;
- pos = pos2;
- }
- } else {
- result5 = null;
- pos = pos2;
- }
- }
- if (result4 !== null) {
- result0 = [result0, result1, result2, result3, result4];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- try {
- data = new NameAddrHeader(data.uri, data.display_name, data.params);
- } catch (e) {
- data = -1;
- }
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_Proxy_Authenticate() {
- var result0;
- result0 = parse_challenge();
- return result0;
- }
- function parse_challenge() {
- var result0, result1, result2, result3, result4, result5;
- var pos0, pos1;
- pos0 = pos;
- if (input.substr(pos, 6).toLowerCase() === "digest") {
- result0 = input.substr(pos, 6);
- pos += 6;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"Digest\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_LWS();
- if (result1 !== null) {
- result2 = parse_digest_cln();
- if (result2 !== null) {
- result3 = [];
- pos1 = pos;
- result4 = parse_COMMA();
- if (result4 !== null) {
- result5 = parse_digest_cln();
- if (result5 !== null) {
- result4 = [result4, result5];
- } else {
- result4 = null;
- pos = pos1;
- }
- } else {
- result4 = null;
- pos = pos1;
- }
- while (result4 !== null) {
- result3.push(result4);
- pos1 = pos;
- result4 = parse_COMMA();
- if (result4 !== null) {
- result5 = parse_digest_cln();
- if (result5 !== null) {
- result4 = [result4, result5];
- } else {
- result4 = null;
- pos = pos1;
- }
- } else {
- result4 = null;
- pos = pos1;
- }
- }
- if (result3 !== null) {
- result0 = [result0, result1, result2, result3];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- if (result0 === null) {
- result0 = parse_other_challenge();
- }
- return result0;
- }
- function parse_other_challenge() {
- var result0, result1, result2, result3, result4, result5;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_token();
- if (result0 !== null) {
- result1 = parse_LWS();
- if (result1 !== null) {
- result2 = parse_auth_param();
- if (result2 !== null) {
- result3 = [];
- pos1 = pos;
- result4 = parse_COMMA();
- if (result4 !== null) {
- result5 = parse_auth_param();
- if (result5 !== null) {
- result4 = [result4, result5];
- } else {
- result4 = null;
- pos = pos1;
- }
- } else {
- result4 = null;
- pos = pos1;
- }
- while (result4 !== null) {
- result3.push(result4);
- pos1 = pos;
- result4 = parse_COMMA();
- if (result4 !== null) {
- result5 = parse_auth_param();
- if (result5 !== null) {
- result4 = [result4, result5];
- } else {
- result4 = null;
- pos = pos1;
- }
- } else {
- result4 = null;
- pos = pos1;
- }
- }
- if (result3 !== null) {
- result0 = [result0, result1, result2, result3];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_auth_param() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- result0 = parse_token();
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_token();
- if (result2 === null) {
- result2 = parse_quoted_string();
- }
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_digest_cln() {
- var result0;
- result0 = parse_realm();
- if (result0 === null) {
- result0 = parse_domain();
- if (result0 === null) {
- result0 = parse_nonce();
- if (result0 === null) {
- result0 = parse_opaque();
- if (result0 === null) {
- result0 = parse_stale();
- if (result0 === null) {
- result0 = parse_algorithm();
- if (result0 === null) {
- result0 = parse_qop_options();
- if (result0 === null) {
- result0 = parse_auth_param();
- }
- }
- }
- }
- }
- }
- }
- return result0;
- }
- function parse_realm() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- if (input.substr(pos, 5).toLowerCase() === "realm") {
- result0 = input.substr(pos, 5);
- pos += 5;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"realm\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_realm_value();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_realm_value() {
- var result0;
- var pos0;
- pos0 = pos;
- result0 = parse_quoted_string_clean();
- if (result0 !== null) {
- result0 = function (offset, realm) {
- data.realm = realm;
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_domain() {
- var result0, result1, result2, result3, result4, result5, result6;
- var pos0, pos1;
- pos0 = pos;
- if (input.substr(pos, 6).toLowerCase() === "domain") {
- result0 = input.substr(pos, 6);
- pos += 6;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"domain\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_LDQUOT();
- if (result2 !== null) {
- result3 = parse_URI();
- if (result3 !== null) {
- result4 = [];
- pos1 = pos;
- result6 = parse_SP();
- if (result6 !== null) {
- result5 = [];
- while (result6 !== null) {
- result5.push(result6);
- result6 = parse_SP();
- }
- } else {
- result5 = null;
- }
- if (result5 !== null) {
- result6 = parse_URI();
- if (result6 !== null) {
- result5 = [result5, result6];
- } else {
- result5 = null;
- pos = pos1;
- }
- } else {
- result5 = null;
- pos = pos1;
- }
- while (result5 !== null) {
- result4.push(result5);
- pos1 = pos;
- result6 = parse_SP();
- if (result6 !== null) {
- result5 = [];
- while (result6 !== null) {
- result5.push(result6);
- result6 = parse_SP();
- }
- } else {
- result5 = null;
- }
- if (result5 !== null) {
- result6 = parse_URI();
- if (result6 !== null) {
- result5 = [result5, result6];
- } else {
- result5 = null;
- pos = pos1;
- }
- } else {
- result5 = null;
- pos = pos1;
- }
- }
- if (result4 !== null) {
- result5 = parse_RDQUOT();
- if (result5 !== null) {
- result0 = [result0, result1, result2, result3, result4, result5];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_URI() {
- var result0;
- result0 = parse_absoluteURI();
- if (result0 === null) {
- result0 = parse_abs_path();
- }
- return result0;
- }
- function parse_nonce() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- if (input.substr(pos, 5).toLowerCase() === "nonce") {
- result0 = input.substr(pos, 5);
- pos += 5;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"nonce\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_nonce_value();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_nonce_value() {
- var result0;
- var pos0;
- pos0 = pos;
- result0 = parse_quoted_string_clean();
- if (result0 !== null) {
- result0 = function (offset, nonce) {
- data.nonce = nonce;
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_opaque() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 6).toLowerCase() === "opaque") {
- result0 = input.substr(pos, 6);
- pos += 6;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"opaque\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_quoted_string_clean();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, opaque) {
- data.opaque = opaque;
- }(pos0, result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_stale() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- if (input.substr(pos, 5).toLowerCase() === "stale") {
- result0 = input.substr(pos, 5);
- pos += 5;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"stale\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- pos1 = pos;
- if (input.substr(pos, 4).toLowerCase() === "true") {
- result2 = input.substr(pos, 4);
- pos += 4;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"true\"");
- }
- }
- if (result2 !== null) {
- result2 = function (offset) {
- data.stale = true;
- }(pos1);
- }
- if (result2 === null) {
- pos = pos1;
- }
- if (result2 === null) {
- pos1 = pos;
- if (input.substr(pos, 5).toLowerCase() === "false") {
- result2 = input.substr(pos, 5);
- pos += 5;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"false\"");
- }
- }
- if (result2 !== null) {
- result2 = function (offset) {
- data.stale = false;
- }(pos1);
- }
- if (result2 === null) {
- pos = pos1;
- }
- }
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_algorithm() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 9).toLowerCase() === "algorithm") {
- result0 = input.substr(pos, 9);
- pos += 9;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"algorithm\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- if (input.substr(pos, 3).toLowerCase() === "md5") {
- result2 = input.substr(pos, 3);
- pos += 3;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"MD5\"");
- }
- }
- if (result2 === null) {
- if (input.substr(pos, 8).toLowerCase() === "md5-sess") {
- result2 = input.substr(pos, 8);
- pos += 8;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"MD5-sess\"");
- }
- }
- if (result2 === null) {
- result2 = parse_token();
- }
- }
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, algorithm) {
- data.algorithm = algorithm.toUpperCase();
- }(pos0, result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_qop_options() {
- var result0, result1, result2, result3, result4, result5, result6;
- var pos0, pos1, pos2;
- pos0 = pos;
- if (input.substr(pos, 3).toLowerCase() === "qop") {
- result0 = input.substr(pos, 3);
- pos += 3;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"qop\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_LDQUOT();
- if (result2 !== null) {
- pos1 = pos;
- result3 = parse_qop_value();
- if (result3 !== null) {
- result4 = [];
- pos2 = pos;
- if (input.charCodeAt(pos) === 44) {
- result5 = ",";
- pos++;
- } else {
- result5 = null;
- if (reportFailures === 0) {
- matchFailed("\",\"");
- }
- }
- if (result5 !== null) {
- result6 = parse_qop_value();
- if (result6 !== null) {
- result5 = [result5, result6];
- } else {
- result5 = null;
- pos = pos2;
- }
- } else {
- result5 = null;
- pos = pos2;
- }
- while (result5 !== null) {
- result4.push(result5);
- pos2 = pos;
- if (input.charCodeAt(pos) === 44) {
- result5 = ",";
- pos++;
- } else {
- result5 = null;
- if (reportFailures === 0) {
- matchFailed("\",\"");
- }
- }
- if (result5 !== null) {
- result6 = parse_qop_value();
- if (result6 !== null) {
- result5 = [result5, result6];
- } else {
- result5 = null;
- pos = pos2;
- }
- } else {
- result5 = null;
- pos = pos2;
- }
- }
- if (result4 !== null) {
- result3 = [result3, result4];
- } else {
- result3 = null;
- pos = pos1;
- }
- } else {
- result3 = null;
- pos = pos1;
- }
- if (result3 !== null) {
- result4 = parse_RDQUOT();
- if (result4 !== null) {
- result0 = [result0, result1, result2, result3, result4];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_qop_value() {
- var result0;
- var pos0;
- pos0 = pos;
- if (input.substr(pos, 8).toLowerCase() === "auth-int") {
- result0 = input.substr(pos, 8);
- pos += 8;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"auth-int\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 4).toLowerCase() === "auth") {
- result0 = input.substr(pos, 4);
- pos += 4;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"auth\"");
- }
- }
- if (result0 === null) {
- result0 = parse_token();
- }
- }
- if (result0 !== null) {
- result0 = function (offset, qop_value) {
- data.qop || (data.qop = []);
- data.qop.push(qop_value.toLowerCase());
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_Proxy_Require() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_token();
- if (result0 !== null) {
- result1 = [];
- pos1 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_token();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos1 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_token();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_Record_Route() {
- var result0, result1, result2, result3;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_rec_route();
- if (result0 !== null) {
- result1 = [];
- pos2 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_rec_route();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos2 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_rec_route();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- var idx, length;
- length = data.multi_header.length;
- for (idx = 0; idx < length; idx++) {
- if (data.multi_header[idx].parsed === null) {
- data = null;
- break;
- }
- }
- if (data !== null) {
- data = data.multi_header;
- } else {
- data = -1;
- }
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_rec_route() {
- var result0, result1, result2, result3;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_name_addr();
- if (result0 !== null) {
- result1 = [];
- pos2 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_generic_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos2 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_generic_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- var header;
- if (!data.multi_header) data.multi_header = [];
- try {
- header = new NameAddrHeader(data.uri, data.display_name, data.params);
- delete data.uri;
- delete data.display_name;
- delete data.params;
- } catch (e) {
- header = null;
- }
- data.multi_header.push({
- 'possition': pos,
- 'offset': offset,
- 'parsed': header
- });
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_Reason() {
- var result0, result1, result2, result3;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 3).toLowerCase() === "sip") {
- result0 = input.substr(pos, 3);
- pos += 3;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"SIP\"");
- }
- }
- if (result0 === null) {
- result0 = parse_token();
- }
- if (result0 !== null) {
- result1 = [];
- pos2 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_reason_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos2 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_reason_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, protocol) {
- data.protocol = protocol.toLowerCase();
- if (!data.params) data.params = {};
- if (data.params.text && data.params.text[0] === '"') {
- var text = data.params.text;
- data.text = text.substring(1, text.length - 1);
- delete data.params.text;
- }
- }(pos0, result0[0]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_reason_param() {
- var result0;
- result0 = parse_reason_cause();
- if (result0 === null) {
- result0 = parse_generic_param();
- }
- return result0;
- }
- function parse_reason_cause() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 5).toLowerCase() === "cause") {
- result0 = input.substr(pos, 5);
- pos += 5;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"cause\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result3 = parse_DIGIT();
- if (result3 !== null) {
- result2 = [];
- while (result3 !== null) {
- result2.push(result3);
- result3 = parse_DIGIT();
- }
- } else {
- result2 = null;
- }
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, cause) {
- data.cause = parseInt(cause.join(''));
- }(pos0, result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_Require() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_token();
- if (result0 !== null) {
- result1 = [];
- pos1 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_token();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos1 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_token();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_Route() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_route_param();
- if (result0 !== null) {
- result1 = [];
- pos1 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_route_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos1 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_route_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_route_param() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_name_addr();
- if (result0 !== null) {
- result1 = [];
- pos1 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_generic_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos1 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_generic_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_Subscription_State() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_substate_value();
- if (result0 !== null) {
- result1 = [];
- pos1 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_subexp_params();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos1 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_subexp_params();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_substate_value() {
- var result0;
- var pos0;
- pos0 = pos;
- if (input.substr(pos, 6).toLowerCase() === "active") {
- result0 = input.substr(pos, 6);
- pos += 6;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"active\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 7).toLowerCase() === "pending") {
- result0 = input.substr(pos, 7);
- pos += 7;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"pending\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 10).toLowerCase() === "terminated") {
- result0 = input.substr(pos, 10);
- pos += 10;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"terminated\"");
- }
- }
- if (result0 === null) {
- result0 = parse_token();
- }
- }
- }
- if (result0 !== null) {
- result0 = function (offset) {
- data.state = input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_subexp_params() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 6).toLowerCase() === "reason") {
- result0 = input.substr(pos, 6);
- pos += 6;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"reason\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_event_reason_value();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, reason) {
- if (typeof reason !== 'undefined') data.reason = reason;
- }(pos0, result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- if (result0 === null) {
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 7).toLowerCase() === "expires") {
- result0 = input.substr(pos, 7);
- pos += 7;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"expires\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_delta_seconds();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, expires) {
- if (typeof expires !== 'undefined') data.expires = expires;
- }(pos0, result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- if (result0 === null) {
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 11).toLowerCase() === "retry_after") {
- result0 = input.substr(pos, 11);
- pos += 11;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"retry_after\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_delta_seconds();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, retry_after) {
- if (typeof retry_after !== 'undefined') data.retry_after = retry_after;
- }(pos0, result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- if (result0 === null) {
- result0 = parse_generic_param();
- }
- }
- }
- return result0;
- }
- function parse_event_reason_value() {
- var result0;
- if (input.substr(pos, 11).toLowerCase() === "deactivated") {
- result0 = input.substr(pos, 11);
- pos += 11;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"deactivated\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 9).toLowerCase() === "probation") {
- result0 = input.substr(pos, 9);
- pos += 9;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"probation\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 8).toLowerCase() === "rejected") {
- result0 = input.substr(pos, 8);
- pos += 8;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"rejected\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 7).toLowerCase() === "timeout") {
- result0 = input.substr(pos, 7);
- pos += 7;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"timeout\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 6).toLowerCase() === "giveup") {
- result0 = input.substr(pos, 6);
- pos += 6;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"giveup\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 10).toLowerCase() === "noresource") {
- result0 = input.substr(pos, 10);
- pos += 10;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"noresource\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 9).toLowerCase() === "invariant") {
- result0 = input.substr(pos, 9);
- pos += 9;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"invariant\"");
- }
- }
- if (result0 === null) {
- result0 = parse_token();
- }
- }
- }
- }
- }
- }
- }
- return result0;
- }
- function parse_Subject() {
- var result0;
- result0 = parse_TEXT_UTF8_TRIM();
- result0 = result0 !== null ? result0 : "";
- return result0;
- }
- function parse_Supported() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_token();
- if (result0 !== null) {
- result1 = [];
- pos1 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_token();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos1 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_token();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- result0 = result0 !== null ? result0 : "";
- return result0;
- }
- function parse_To() {
- var result0, result1, result2, result3;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_SIP_URI_noparams();
- if (result0 === null) {
- result0 = parse_name_addr();
- }
- if (result0 !== null) {
- result1 = [];
- pos2 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_to_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos2 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_to_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- var tag = data.tag;
- try {
- data = new NameAddrHeader(data.uri, data.display_name, data.params);
- if (tag) {
- data.setParam('tag', tag);
- }
- } catch (e) {
- data = -1;
- }
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_to_param() {
- var result0;
- result0 = parse_tag_param();
- if (result0 === null) {
- result0 = parse_generic_param();
- }
- return result0;
- }
- function parse_Via() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_via_param();
- if (result0 !== null) {
- result1 = [];
- pos1 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_via_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos1 = pos;
- result2 = parse_COMMA();
- if (result2 !== null) {
- result3 = parse_via_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_via_param() {
- var result0, result1, result2, result3, result4, result5;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_sent_protocol();
- if (result0 !== null) {
- result1 = parse_LWS();
- if (result1 !== null) {
- result2 = parse_sent_by();
- if (result2 !== null) {
- result3 = [];
- pos1 = pos;
- result4 = parse_SEMI();
- if (result4 !== null) {
- result5 = parse_via_params();
- if (result5 !== null) {
- result4 = [result4, result5];
- } else {
- result4 = null;
- pos = pos1;
- }
- } else {
- result4 = null;
- pos = pos1;
- }
- while (result4 !== null) {
- result3.push(result4);
- pos1 = pos;
- result4 = parse_SEMI();
- if (result4 !== null) {
- result5 = parse_via_params();
- if (result5 !== null) {
- result4 = [result4, result5];
- } else {
- result4 = null;
- pos = pos1;
- }
- } else {
- result4 = null;
- pos = pos1;
- }
- }
- if (result3 !== null) {
- result0 = [result0, result1, result2, result3];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_via_params() {
- var result0;
- result0 = parse_via_ttl();
- if (result0 === null) {
- result0 = parse_via_maddr();
- if (result0 === null) {
- result0 = parse_via_received();
- if (result0 === null) {
- result0 = parse_via_branch();
- if (result0 === null) {
- result0 = parse_response_port();
- if (result0 === null) {
- result0 = parse_generic_param();
- }
- }
- }
- }
- }
- return result0;
- }
- function parse_via_ttl() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 3).toLowerCase() === "ttl") {
- result0 = input.substr(pos, 3);
- pos += 3;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"ttl\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_ttl();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, via_ttl_value) {
- data.ttl = via_ttl_value;
- }(pos0, result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_via_maddr() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 5).toLowerCase() === "maddr") {
- result0 = input.substr(pos, 5);
- pos += 5;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"maddr\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_host();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, via_maddr) {
- data.maddr = via_maddr;
- }(pos0, result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_via_received() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 8).toLowerCase() === "received") {
- result0 = input.substr(pos, 8);
- pos += 8;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"received\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_IPv4address();
- if (result2 === null) {
- result2 = parse_IPv6address();
- }
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, via_received) {
- data.received = via_received;
- }(pos0, result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_via_branch() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 6).toLowerCase() === "branch") {
- result0 = input.substr(pos, 6);
- pos += 6;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"branch\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_token();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, via_branch) {
- data.branch = via_branch;
- }(pos0, result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_response_port() {
- var result0, result1, result2, result3;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 5).toLowerCase() === "rport") {
- result0 = input.substr(pos, 5);
- pos += 5;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"rport\"");
- }
- }
- if (result0 !== null) {
- pos2 = pos;
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = [];
- result3 = parse_DIGIT();
- while (result3 !== null) {
- result2.push(result3);
- result3 = parse_DIGIT();
- }
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- if (typeof response_port !== 'undefined') data.rport = response_port.join('');
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_sent_protocol() {
- var result0, result1, result2, result3, result4;
- var pos0;
- pos0 = pos;
- result0 = parse_protocol_name();
- if (result0 !== null) {
- result1 = parse_SLASH();
- if (result1 !== null) {
- result2 = parse_token();
- if (result2 !== null) {
- result3 = parse_SLASH();
- if (result3 !== null) {
- result4 = parse_transport();
- if (result4 !== null) {
- result0 = [result0, result1, result2, result3, result4];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_protocol_name() {
- var result0;
- var pos0;
- pos0 = pos;
- if (input.substr(pos, 3).toLowerCase() === "sip") {
- result0 = input.substr(pos, 3);
- pos += 3;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"SIP\"");
- }
- }
- if (result0 === null) {
- result0 = parse_token();
- }
- if (result0 !== null) {
- result0 = function (offset, via_protocol) {
- data.protocol = via_protocol;
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_transport() {
- var result0;
- var pos0;
- pos0 = pos;
- if (input.substr(pos, 3).toLowerCase() === "udp") {
- result0 = input.substr(pos, 3);
- pos += 3;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"UDP\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 3).toLowerCase() === "tcp") {
- result0 = input.substr(pos, 3);
- pos += 3;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"TCP\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 3).toLowerCase() === "tls") {
- result0 = input.substr(pos, 3);
- pos += 3;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"TLS\"");
- }
- }
- if (result0 === null) {
- if (input.substr(pos, 4).toLowerCase() === "sctp") {
- result0 = input.substr(pos, 4);
- pos += 4;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"SCTP\"");
- }
- }
- if (result0 === null) {
- result0 = parse_token();
- }
- }
- }
- }
- if (result0 !== null) {
- result0 = function (offset, via_transport) {
- data.transport = via_transport;
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_sent_by() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_via_host();
- if (result0 !== null) {
- pos1 = pos;
- result1 = parse_COLON();
- if (result1 !== null) {
- result2 = parse_via_port();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos1;
- }
- } else {
- result1 = null;
- pos = pos1;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_via_host() {
- var result0;
- var pos0;
- pos0 = pos;
- result0 = parse_IPv4address();
- if (result0 === null) {
- result0 = parse_IPv6reference();
- if (result0 === null) {
- result0 = parse_hostname();
- }
- }
- if (result0 !== null) {
- result0 = function (offset) {
- data.host = input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_via_port() {
- var result0, result1, result2, result3, result4;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_DIGIT();
- result0 = result0 !== null ? result0 : "";
- if (result0 !== null) {
- result1 = parse_DIGIT();
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- result2 = parse_DIGIT();
- result2 = result2 !== null ? result2 : "";
- if (result2 !== null) {
- result3 = parse_DIGIT();
- result3 = result3 !== null ? result3 : "";
- if (result3 !== null) {
- result4 = parse_DIGIT();
- result4 = result4 !== null ? result4 : "";
- if (result4 !== null) {
- result0 = [result0, result1, result2, result3, result4];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, via_sent_by_port) {
- data.port = parseInt(via_sent_by_port.join(''));
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_ttl() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_DIGIT();
- if (result0 !== null) {
- result1 = parse_DIGIT();
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- result2 = parse_DIGIT();
- result2 = result2 !== null ? result2 : "";
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, ttl) {
- return parseInt(ttl.join(''));
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_WWW_Authenticate() {
- var result0;
- result0 = parse_challenge();
- return result0;
- }
- function parse_Session_Expires() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_s_e_expires();
- if (result0 !== null) {
- result1 = [];
- pos1 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_s_e_params();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos1 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_s_e_params();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_s_e_expires() {
- var result0;
- var pos0;
- pos0 = pos;
- result0 = parse_delta_seconds();
- if (result0 !== null) {
- result0 = function (offset, expires) {
- data.expires = expires;
- }(pos0, result0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_s_e_params() {
- var result0;
- result0 = parse_s_e_refresher();
- if (result0 === null) {
- result0 = parse_generic_param();
- }
- return result0;
- }
- function parse_s_e_refresher() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 9).toLowerCase() === "refresher") {
- result0 = input.substr(pos, 9);
- pos += 9;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"refresher\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- if (input.substr(pos, 3).toLowerCase() === "uac") {
- result2 = input.substr(pos, 3);
- pos += 3;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"uac\"");
- }
- }
- if (result2 === null) {
- if (input.substr(pos, 3).toLowerCase() === "uas") {
- result2 = input.substr(pos, 3);
- pos += 3;
- } else {
- result2 = null;
- if (reportFailures === 0) {
- matchFailed("\"uas\"");
- }
- }
- }
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, s_e_refresher_value) {
- data.refresher = s_e_refresher_value.toLowerCase();
- }(pos0, result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_extension_header() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- result0 = parse_token();
- if (result0 !== null) {
- result1 = parse_HCOLON();
- if (result1 !== null) {
- result2 = parse_header_value();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_header_value() {
- var result0, result1;
- result0 = [];
- result1 = parse_TEXT_UTF8char();
- if (result1 === null) {
- result1 = parse_UTF8_CONT();
- if (result1 === null) {
- result1 = parse_LWS();
- }
- }
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_TEXT_UTF8char();
- if (result1 === null) {
- result1 = parse_UTF8_CONT();
- if (result1 === null) {
- result1 = parse_LWS();
- }
- }
- }
- return result0;
- }
- function parse_message_body() {
- var result0, result1;
- result0 = [];
- result1 = parse_OCTET();
- while (result1 !== null) {
- result0.push(result1);
- result1 = parse_OCTET();
- }
- return result0;
- }
- function parse_uuid_URI() {
- var result0, result1;
- var pos0;
- pos0 = pos;
- if (input.substr(pos, 5) === "uuid:") {
- result0 = "uuid:";
- pos += 5;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"uuid:\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_uuid();
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_uuid() {
- var result0, result1, result2, result3, result4, result5, result6, result7, result8;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_hex8();
- if (result0 !== null) {
- if (input.charCodeAt(pos) === 45) {
- result1 = "-";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_hex4();
- if (result2 !== null) {
- if (input.charCodeAt(pos) === 45) {
- result3 = "-";
- pos++;
- } else {
- result3 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result3 !== null) {
- result4 = parse_hex4();
- if (result4 !== null) {
- if (input.charCodeAt(pos) === 45) {
- result5 = "-";
- pos++;
- } else {
- result5 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result5 !== null) {
- result6 = parse_hex4();
- if (result6 !== null) {
- if (input.charCodeAt(pos) === 45) {
- result7 = "-";
- pos++;
- } else {
- result7 = null;
- if (reportFailures === 0) {
- matchFailed("\"-\"");
- }
- }
- if (result7 !== null) {
- result8 = parse_hex12();
- if (result8 !== null) {
- result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, uuid) {
- data = input.substring(pos + 5, offset);
- }(pos0, result0[0]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_hex4() {
- var result0, result1, result2, result3;
- var pos0;
- pos0 = pos;
- result0 = parse_HEXDIG();
- if (result0 !== null) {
- result1 = parse_HEXDIG();
- if (result1 !== null) {
- result2 = parse_HEXDIG();
- if (result2 !== null) {
- result3 = parse_HEXDIG();
- if (result3 !== null) {
- result0 = [result0, result1, result2, result3];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_hex8() {
- var result0, result1;
- var pos0;
- pos0 = pos;
- result0 = parse_hex4();
- if (result0 !== null) {
- result1 = parse_hex4();
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_hex12() {
- var result0, result1, result2;
- var pos0;
- pos0 = pos;
- result0 = parse_hex4();
- if (result0 !== null) {
- result1 = parse_hex4();
- if (result1 !== null) {
- result2 = parse_hex4();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_Refer_To() {
- var result0, result1, result2, result3;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_SIP_URI_noparams();
- if (result0 === null) {
- result0 = parse_name_addr();
- }
- if (result0 !== null) {
- result1 = [];
- pos2 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_generic_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos2 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_generic_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos2;
- }
- } else {
- result2 = null;
- pos = pos2;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- try {
- data = new NameAddrHeader(data.uri, data.display_name, data.params);
- } catch (e) {
- data = -1;
- }
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_Replaces() {
- var result0, result1, result2, result3;
- var pos0, pos1;
- pos0 = pos;
- result0 = parse_call_id();
- if (result0 !== null) {
- result1 = [];
- pos1 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_replaces_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- while (result2 !== null) {
- result1.push(result2);
- pos1 = pos;
- result2 = parse_SEMI();
- if (result2 !== null) {
- result3 = parse_replaces_param();
- if (result3 !== null) {
- result2 = [result2, result3];
- } else {
- result2 = null;
- pos = pos1;
- }
- } else {
- result2 = null;
- pos = pos1;
- }
- }
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos0;
- }
- } else {
- result0 = null;
- pos = pos0;
- }
- return result0;
- }
- function parse_call_id() {
- var result0, result1, result2;
- var pos0, pos1, pos2;
- pos0 = pos;
- pos1 = pos;
- result0 = parse_word();
- if (result0 !== null) {
- pos2 = pos;
- if (input.charCodeAt(pos) === 64) {
- result1 = "@";
- pos++;
- } else {
- result1 = null;
- if (reportFailures === 0) {
- matchFailed("\"@\"");
- }
- }
- if (result1 !== null) {
- result2 = parse_word();
- if (result2 !== null) {
- result1 = [result1, result2];
- } else {
- result1 = null;
- pos = pos2;
- }
- } else {
- result1 = null;
- pos = pos2;
- }
- result1 = result1 !== null ? result1 : "";
- if (result1 !== null) {
- result0 = [result0, result1];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset) {
- data.call_id = input.substring(pos, offset);
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_replaces_param() {
- var result0;
- result0 = parse_to_tag();
- if (result0 === null) {
- result0 = parse_from_tag();
- if (result0 === null) {
- result0 = parse_early_flag();
- if (result0 === null) {
- result0 = parse_generic_param();
- }
- }
- }
- return result0;
- }
- function parse_to_tag() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 6) === "to-tag") {
- result0 = "to-tag";
- pos += 6;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"to-tag\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_token();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, to_tag) {
- data.to_tag = to_tag;
- }(pos0, result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_from_tag() {
- var result0, result1, result2;
- var pos0, pos1;
- pos0 = pos;
- pos1 = pos;
- if (input.substr(pos, 8) === "from-tag") {
- result0 = "from-tag";
- pos += 8;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"from-tag\"");
- }
- }
- if (result0 !== null) {
- result1 = parse_EQUAL();
- if (result1 !== null) {
- result2 = parse_token();
- if (result2 !== null) {
- result0 = [result0, result1, result2];
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- } else {
- result0 = null;
- pos = pos1;
- }
- if (result0 !== null) {
- result0 = function (offset, from_tag) {
- data.from_tag = from_tag;
- }(pos0, result0[2]);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function parse_early_flag() {
- var result0;
- var pos0;
- pos0 = pos;
- if (input.substr(pos, 10) === "early-only") {
- result0 = "early-only";
- pos += 10;
- } else {
- result0 = null;
- if (reportFailures === 0) {
- matchFailed("\"early-only\"");
- }
- }
- if (result0 !== null) {
- result0 = function (offset) {
- data.early_only = true;
- }(pos0);
- }
- if (result0 === null) {
- pos = pos0;
- }
- return result0;
- }
- function cleanupExpected(expected) {
- expected.sort();
- var lastExpected = null;
- var cleanExpected = [];
- for (var i = 0; i < expected.length; i++) {
- if (expected[i] !== lastExpected) {
- cleanExpected.push(expected[i]);
- lastExpected = expected[i];
- }
- }
- return cleanExpected;
- }
- function computeErrorPosition() {
- /*
- * The first idea was to use |String.split| to break the input up to the
- * error position along newlines and derive the line and column from
- * there. However IE's |split| implementation is so broken that it was
- * enough to prevent it.
- */
- var line = 1;
- var column = 1;
- var seenCR = false;
- for (var i = 0; i < Math.max(pos, rightmostFailuresPos); i++) {
- var ch = input.charAt(i);
- if (ch === "\n") {
- if (!seenCR) {
- line++;
- }
- column = 1;
- seenCR = false;
- } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") {
- line++;
- column = 1;
- seenCR = true;
- } else {
- column++;
- seenCR = false;
- }
- }
- return {
- line: line,
- column: column
- };
- }
- var URI = __webpack_require__(8);
- var NameAddrHeader = __webpack_require__(11);
- var data = {};
- var result = parseFunctions[startRule]();
- /*
- * The parser is now in one of the following three states:
- *
- * 1. The parser successfully parsed the whole input.
- *
- * - |result !== null|
- * - |pos === input.length|
- * - |rightmostFailuresExpected| may or may not contain something
- *
- * 2. The parser successfully parsed only a part of the input.
- *
- * - |result !== null|
- * - |pos < input.length|
- * - |rightmostFailuresExpected| may or may not contain something
- *
- * 3. The parser did not successfully parse any part of the input.
- *
- * - |result === null|
- * - |pos === 0|
- * - |rightmostFailuresExpected| contains at least one failure
- *
- * All code following this comment (including called functions) must
- * handle these states.
- */
- if (result === null || pos !== input.length) {
- var offset = Math.max(pos, rightmostFailuresPos);
- var found = offset < input.length ? input.charAt(offset) : null;
- var errorPosition = computeErrorPosition();
- new this.SyntaxError(cleanupExpected(rightmostFailuresExpected), found, offset, errorPosition.line, errorPosition.column);
- return -1;
- }
- return data;
- },
- /* Returns the parser source code. */
- toSource: function toSource() {
- return this._source;
- }
- };
- /* Thrown when a parser encounters a syntax error. */
- result.SyntaxError = function (expected, found, offset, line, column) {
- function buildMessage(expected, found) {
- var expectedHumanized, foundHumanized;
- switch (expected.length) {
- case 0:
- expectedHumanized = "end of input";
- break;
- case 1:
- expectedHumanized = expected[0];
- break;
- default:
- expectedHumanized = expected.slice(0, expected.length - 1).join(", ") + " or " + expected[expected.length - 1];
- }
- foundHumanized = found ? quote(found) : "end of input";
- return "Expected " + expectedHumanized + " but " + foundHumanized + " found.";
- }
- this.name = "SyntaxError";
- this.expected = expected;
- this.found = found;
- this.message = buildMessage(expected, found);
- this.offset = offset;
- this.line = line;
- this.column = column;
- };
- result.SyntaxError.prototype = Error.prototype;
- return result;
- }();
- }),
- /* 4 */
- (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- /* harmony export (immutable) */ __webpack_exports__["e"] = extractVersion;
- /* harmony export (immutable) */ __webpack_exports__["g"] = wrapPeerConnectionEvent;
- /* harmony export (immutable) */ __webpack_exports__["c"] = disableLog;
- /* harmony export (immutable) */ __webpack_exports__["d"] = disableWarnings;
- /* harmony export (immutable) */ __webpack_exports__["f"] = log;
- /* harmony export (immutable) */ __webpack_exports__["a"] = deprecated;
- /* harmony export (immutable) */ __webpack_exports__["b"] = detectBrowser;
- /*
- * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- /* eslint-env node */
- let logDisabled_ = true;
- let deprecationWarnings_ = true;
- /**
- * Extract browser version out of the provided user agent string.
- *
- * @param {!string} uastring userAgent string.
- * @param {!string} expr Regular expression used as match criteria.
- * @param {!number} pos position in the version string to be returned.
- * @return {!number} browser version.
- */
- function extractVersion(uastring, expr, pos) {
- const match = uastring.match(expr);
- return match && match.length >= pos && parseInt(match[pos], 10);
- } // Wraps the peerconnection event eventNameToWrap in a function
- // which returns the modified event object (or false to prevent
- // the event).
- function wrapPeerConnectionEvent(window, eventNameToWrap, wrapper) {
- if (!window.RTCPeerConnection) {
- return;
- }
- const proto = window.RTCPeerConnection.prototype;
- const nativeAddEventListener = proto.addEventListener;
- proto.addEventListener = function (nativeEventName, cb) {
- if (nativeEventName !== eventNameToWrap) {
- return nativeAddEventListener.apply(this, arguments);
- }
- const wrappedCallback = e => {
- const modifiedEvent = wrapper(e);
- if (modifiedEvent) {
- cb(modifiedEvent);
- }
- };
- this._eventMap = this._eventMap || {};
- this._eventMap[cb] = wrappedCallback;
- return nativeAddEventListener.apply(this, [nativeEventName, wrappedCallback]);
- };
- const nativeRemoveEventListener = proto.removeEventListener;
- proto.removeEventListener = function (nativeEventName, cb) {
- if (nativeEventName !== eventNameToWrap || !this._eventMap || !this._eventMap[cb]) {
- return nativeRemoveEventListener.apply(this, arguments);
- }
- const unwrappedCb = this._eventMap[cb];
- delete this._eventMap[cb];
- return nativeRemoveEventListener.apply(this, [nativeEventName, unwrappedCb]);
- };
- Object.defineProperty(proto, 'on' + eventNameToWrap, {
- get() {
- return this['_on' + eventNameToWrap];
- },
- set(cb) {
- if (this['_on' + eventNameToWrap]) {
- this.removeEventListener(eventNameToWrap, this['_on' + eventNameToWrap]);
- delete this['_on' + eventNameToWrap];
- }
- if (cb) {
- this.addEventListener(eventNameToWrap, this['_on' + eventNameToWrap] = cb);
- }
- },
- enumerable: true,
- configurable: true
- });
- }
- function disableLog(bool) {
- if (typeof bool !== 'boolean') {
- return new Error('Argument type: ' + typeof bool + '. Please use a boolean.');
- }
- logDisabled_ = bool;
- return bool ? 'adapter.js logging disabled' : 'adapter.js logging enabled';
- }
- /**
- * Disable or enable deprecation warnings
- * @param {!boolean} bool set to true to disable warnings.
- */
- function disableWarnings(bool) {
- if (typeof bool !== 'boolean') {
- return new Error('Argument type: ' + typeof bool + '. Please use a boolean.');
- }
- deprecationWarnings_ = !bool;
- return 'adapter.js deprecation warnings ' + (bool ? 'disabled' : 'enabled');
- }
- function log() {
- if (typeof window === 'object') {
- if (logDisabled_) {
- return;
- }
- if (typeof console !== 'undefined' && typeof console.log === 'function') {
- console.log.apply(console, arguments);
- }
- }
- }
- /**
- * Shows a deprecation warning suggesting the modern and spec-compatible API.
- */
- function deprecated(oldMethod, newMethod) {
- if (!deprecationWarnings_) {
- return;
- }
- console.warn(oldMethod + ' is deprecated, please use ' + newMethod + ' instead.');
- }
- /**
- * Browser detector.
- *
- * @return {object} result containing browser and version
- * properties.
- */
- function detectBrowser(window) {
- const {
- navigator
- } = window; // Returned result object.
- const result = {
- browser: null,
- version: null
- }; // Fail early if it's not a browser
- if (typeof window === 'undefined' || !window.navigator) {
- result.browser = 'Not a browser.';
- return result;
- }
- if (navigator.mozGetUserMedia) {
- // Firefox.
- result.browser = 'firefox';
- result.version = extractVersion(navigator.userAgent, /Firefox\/(\d+)\./, 1);
- } else if (navigator.webkitGetUserMedia) {
- // Chrome, Chromium, Webview, Opera.
- // Version matches Chrome/WebRTC version.
- result.browser = 'chrome';
- result.version = extractVersion(navigator.userAgent, /Chrom(e|ium)\/(\d+)\./, 2);
- } else if (navigator.mediaDevices && navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)) {
- // Edge.
- result.browser = 'edge';
- result.version = extractVersion(navigator.userAgent, /Edge\/(\d+).(\d+)$/, 2);
- } else if (window.RTCPeerConnection && navigator.userAgent.match(/AppleWebKit\/(\d+)\./)) {
- // Safari.
- result.browser = 'safari';
- result.version = extractVersion(navigator.userAgent, /AppleWebKit\/(\d+)\./, 1);
- } else {
- // Default fallthrough: not supported.
- result.browser = 'Not a supported browser.';
- return result;
- }
- return result;
- }
- }),
- /* 5 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _typeof(obj) {
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
- _typeof = function _typeof(obj) {
- return typeof obj;
- };
- } else {
- _typeof = function _typeof(obj) {
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
- };
- }
- return _typeof(obj);
- }
- function _possibleConstructorReturn(self, call) {
- if (call && (_typeof(call) === "object" || typeof call === "function")) {
- return call;
- }
- return _assertThisInitialized(self);
- }
- function _assertThisInitialized(self) {
- if (self === void 0) {
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- }
- return self;
- }
- function _getPrototypeOf(o) {
- _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
- return o.__proto__ || Object.getPrototypeOf(o);
- };
- return _getPrototypeOf(o);
- }
- function _inherits(subClass, superClass) {
- if (typeof superClass !== "function" && superClass !== null) {
- throw new TypeError("Super expression must either be null or a function");
- }
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- writable: true,
- configurable: true
- }
- });
- if (superClass) _setPrototypeOf(subClass, superClass);
- }
- function _setPrototypeOf(o, p) {
- _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
- o.__proto__ = p;
- return o;
- };
- return _setPrototypeOf(o, p);
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- var sdp_transform = __webpack_require__(13);
- var JsSIP_C = __webpack_require__(1);
- var Utils = __webpack_require__(2);
- var NameAddrHeader = __webpack_require__(11);
- var Grammar = __webpack_require__(3);
- var debug = __webpack_require__(0)('JsSIP:SIPMessage');
- /**
- * -param {String} method request method
- * -param {String} ruri request uri
- * -param {UA} ua
- * -param {Object} params parameters that will have priority over ua.configuration parameters:
- * <br>
- * - cseq, call_id, from_tag, from_uri, from_display_name, to_uri, to_tag, route_set
- * -param {Object} [headers] extra headers
- * -param {String} [body]
- */
- var OutgoingRequest =
- /*#__PURE__*/
- function () {
- function OutgoingRequest(method, ruri, ua, params, extraHeaders, body) {
- _classCallCheck(this, OutgoingRequest); // Mandatory parameters check.
- if (!method || !ruri || !ua) {
- return null;
- }
- params = params || {};
- this.ua = ua;
- this.headers = {};
- this.method = method;
- this.ruri = ruri;
- this.body = body;
- this.extraHeaders = Utils.cloneArray(extraHeaders); // Fill the Common SIP Request Headers.
- // Route.
- if (params.route_set) {
- this.setHeader('route', params.route_set);
- } else if (ua.configuration.use_preloaded_route) {
- this.setHeader('route', "<".concat(ua.transport.sip_uri, ";lr>"));
- } // Via.
- // Empty Via header. Will be filled by the client transaction.
- this.setHeader('via', ''); // Max-Forwards.
- this.setHeader('max-forwards', JsSIP_C.MAX_FORWARDS); // To
- var to = params.to_display_name || params.to_display_name === 0 ? "\"".concat(params.to_display_name, "\" ") : '';
- to += "<".concat(params.to_uri || ruri, ">");
- to += params.to_tag ? ";tag=".concat(params.to_tag) : '';
- this.to = NameAddrHeader.parse(to);
- this.setHeader('to', to); // From.
- var from;
- if (params.from_display_name || params.from_display_name === 0) {
- from = "\"".concat(params.from_display_name, "\" ");
- } else if (ua.configuration.display_name) {
- from = "\"".concat(ua.configuration.display_name, "\" ");
- } else {
- from = '';
- }
- from += "<".concat(params.from_uri || ua.configuration.uri, ">;tag=");
- from += params.from_tag || Utils.newTag();
- this.from = NameAddrHeader.parse(from);
- this.setHeader('from', from); // Call-ID.
- var call_id = params.call_id || ua.configuration.jssip_id + Utils.createRandomToken(15);
- this.call_id = call_id;
- this.setHeader('call-id', call_id); // CSeq.
- var cseq = params.cseq || Math.floor(Math.random() * 10000);
- this.cseq = cseq;
- this.setHeader('cseq', "".concat(cseq, " ").concat(method));
- }
- /**
- * Replace the the given header by the given value.
- * -param {String} name header name
- * -param {String | Array} value header value
- */
- _createClass(OutgoingRequest, [{
- key: "setHeader",
- value: function setHeader(name, value) {
- // Remove the header from extraHeaders if present.
- var regexp = new RegExp("^\\s*".concat(name, "\\s*:"), 'i');
- for (var idx = 0; idx < this.extraHeaders.length; idx++) {
- if (regexp.test(this.extraHeaders[idx])) {
- this.extraHeaders.splice(idx, 1);
- }
- }
- this.headers[Utils.headerize(name)] = Array.isArray(value) ? value : [value];
- }
- /**
- * Get the value of the given header name at the given position.
- * -param {String} name header name
- * -returns {String|undefined} Returns the specified header, null if header doesn't exist.
- */
- }, {
- key: "getHeader",
- value: function getHeader(name) {
- var headers = this.headers[Utils.headerize(name)];
- if (headers) {
- if (headers[0]) {
- return headers[0];
- }
- } else {
- var regexp = new RegExp("^\\s*".concat(name, "\\s*:"), 'i');
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
- try {
- for (var _iterator = this.extraHeaders[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var header = _step.value;
- if (regexp.test(header)) {
- return header.substring(header.indexOf(':') + 1).trim();
- }
- }
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator.return != null) {
- _iterator.return();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
- }
- }
- return;
- }
- /**
- * Get the header/s of the given name.
- * -param {String} name header name
- * -returns {Array} Array with all the headers of the specified name.
- */
- }, {
- key: "getHeaders",
- value: function getHeaders(name) {
- var headers = this.headers[Utils.headerize(name)];
- var result = [];
- if (headers) {
- var _iteratorNormalCompletion2 = true;
- var _didIteratorError2 = false;
- var _iteratorError2 = undefined;
- try {
- for (var _iterator2 = headers[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
- var header = _step2.value;
- result.push(header);
- }
- } catch (err) {
- _didIteratorError2 = true;
- _iteratorError2 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
- _iterator2.return();
- }
- } finally {
- if (_didIteratorError2) {
- throw _iteratorError2;
- }
- }
- }
- return result;
- } else {
- var regexp = new RegExp("^\\s*".concat(name, "\\s*:"), 'i');
- var _iteratorNormalCompletion3 = true;
- var _didIteratorError3 = false;
- var _iteratorError3 = undefined;
- try {
- for (var _iterator3 = this.extraHeaders[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
- var _header = _step3.value;
- if (regexp.test(_header)) {
- result.push(_header.substring(_header.indexOf(':') + 1).trim());
- }
- }
- } catch (err) {
- _didIteratorError3 = true;
- _iteratorError3 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
- _iterator3.return();
- }
- } finally {
- if (_didIteratorError3) {
- throw _iteratorError3;
- }
- }
- }
- return result;
- }
- }
- /**
- * Verify the existence of the given header.
- * -param {String} name header name
- * -returns {boolean} true if header with given name exists, false otherwise
- */
- }, {
- key: "hasHeader",
- value: function hasHeader(name) {
- if (this.headers[Utils.headerize(name)]) {
- return true;
- } else {
- var regexp = new RegExp("^\\s*".concat(name, "\\s*:"), 'i');
- var _iteratorNormalCompletion4 = true;
- var _didIteratorError4 = false;
- var _iteratorError4 = undefined;
- try {
- for (var _iterator4 = this.extraHeaders[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
- var header = _step4.value;
- if (regexp.test(header)) {
- return true;
- }
- }
- } catch (err) {
- _didIteratorError4 = true;
- _iteratorError4 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
- _iterator4.return();
- }
- } finally {
- if (_didIteratorError4) {
- throw _iteratorError4;
- }
- }
- }
- }
- return false;
- }
- /**
- * Parse the current body as a SDP and store the resulting object
- * into this.sdp.
- * -param {Boolean} force: Parse even if this.sdp already exists.
- *
- * Returns this.sdp.
- */
- }, {
- key: "parseSDP",
- value: function parseSDP(force) {
- if (!force && this.sdp) {
- return this.sdp;
- } else {
- this.sdp = sdp_transform.parse(this.body || '');
- return this.sdp;
- }
- }
- }, {
- key: "toString",
- value: function toString() {
- var msg = "".concat(this.method, " ").concat(this.ruri, " SIP/2.0\r\n");
- for (var headerName in this.headers) {
- if (Object.prototype.hasOwnProperty.call(this.headers, headerName)) {
- var _iteratorNormalCompletion5 = true;
- var _didIteratorError5 = false;
- var _iteratorError5 = undefined;
- try {
- for (var _iterator5 = this.headers[headerName][Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
- var headerValue = _step5.value;
- msg += "".concat(headerName, ": ").concat(headerValue, "\r\n");
- }
- } catch (err) {
- _didIteratorError5 = true;
- _iteratorError5 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion5 && _iterator5.return != null) {
- _iterator5.return();
- }
- } finally {
- if (_didIteratorError5) {
- throw _iteratorError5;
- }
- }
- }
- }
- }
- var _iteratorNormalCompletion6 = true;
- var _didIteratorError6 = false;
- var _iteratorError6 = undefined;
- try {
- for (var _iterator6 = this.extraHeaders[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
- var header = _step6.value;
- msg += "".concat(header.trim(), "\r\n");
- } // Supported.
- } catch (err) {
- _didIteratorError6 = true;
- _iteratorError6 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion6 && _iterator6.return != null) {
- _iterator6.return();
- }
- } finally {
- if (_didIteratorError6) {
- throw _iteratorError6;
- }
- }
- }
- var supported = [];
- switch (this.method) {
- case JsSIP_C.REGISTER:
- supported.push('path', 'gruu');
- break;
- case JsSIP_C.INVITE:
- if (this.ua.configuration.session_timers) {
- supported.push('timer');
- }
- if (this.ua.contact.pub_gruu || this.ua.contact.temp_gruu) {
- supported.push('gruu');
- }
- supported.push('ice', 'replaces');
- break;
- case JsSIP_C.UPDATE:
- if (this.ua.configuration.session_timers) {
- supported.push('timer');
- }
- supported.push('ice');
- break;
- }
- supported.push('outbound');
- var userAgent = this.ua.configuration.user_agent || JsSIP_C.USER_AGENT; // Allow.
- msg += "Allow: ".concat(JsSIP_C.ALLOWED_METHODS, "\r\n");
- msg += "Supported: ".concat(supported, "\r\n");
- msg += "User-Agent: ".concat(userAgent, "\r\n");
- if (this.body) {
- var length = Utils.str_utf8_length(this.body);
- msg += "Content-Length: ".concat(length, "\r\n\r\n");
- msg += this.body;
- } else {
- msg += 'Content-Length: 0\r\n\r\n';
- }
- return msg;
- }
- }, {
- key: "clone",
- value: function clone() {
- var request = new OutgoingRequest(this.method, this.ruri, this.ua);
- Object.keys(this.headers).forEach(function (name) {
- request.headers[name] = this.headers[name].slice();
- }, this);
- request.body = this.body;
- request.extraHeaders = Utils.cloneArray(this.extraHeaders);
- request.to = this.to;
- request.from = this.from;
- request.call_id = this.call_id;
- request.cseq = this.cseq;
- return request;
- }
- }]);
- return OutgoingRequest;
- }();
- var InitialOutgoingInviteRequest =
- /*#__PURE__*/
- function (_OutgoingRequest) {
- _inherits(InitialOutgoingInviteRequest, _OutgoingRequest);
- function InitialOutgoingInviteRequest(ruri, ua, params, extraHeaders, body) {
- var _this;
- _classCallCheck(this, InitialOutgoingInviteRequest);
- _this = _possibleConstructorReturn(this, _getPrototypeOf(InitialOutgoingInviteRequest).call(this, JsSIP_C.INVITE, ruri, ua, params, extraHeaders, body));
- _this.transaction = null;
- return _this;
- }
- _createClass(InitialOutgoingInviteRequest, [{
- key: "cancel",
- value: function cancel(reason) {
- this.transaction.cancel(reason);
- }
- }, {
- key: "clone",
- value: function clone() {
- var request = new InitialOutgoingInviteRequest(this.ruri, this.ua);
- Object.keys(this.headers).forEach(function (name) {
- request.headers[name] = this.headers[name].slice();
- }, this);
- request.body = this.body;
- request.extraHeaders = Utils.cloneArray(this.extraHeaders);
- request.to = this.to;
- request.from = this.from;
- request.call_id = this.call_id;
- request.cseq = this.cseq;
- request.transaction = this.transaction;
- return request;
- }
- }]);
- return InitialOutgoingInviteRequest;
- }(OutgoingRequest);
- var IncomingMessage =
- /*#__PURE__*/
- function () {
- function IncomingMessage() {
- _classCallCheck(this, IncomingMessage);
- this.data = null;
- this.headers = null;
- this.method = null;
- this.via = null;
- this.via_branch = null;
- this.call_id = null;
- this.cseq = null;
- this.from = null;
- this.from_tag = null;
- this.to = null;
- this.to_tag = null;
- this.body = null;
- this.sdp = null;
- }
- /**
- * Insert a header of the given name and value into the last position of the
- * header array.
- */
- _createClass(IncomingMessage, [{
- key: "addHeader",
- value: function addHeader(name, value) {
- var header = {
- raw: value
- };
- name = Utils.headerize(name);
- if (this.headers[name]) {
- this.headers[name].push(header);
- } else {
- this.headers[name] = [header];
- }
- }
- /**
- * Get the value of the given header name at the given position.
- */
- }, {
- key: "getHeader",
- value: function getHeader(name) {
- var header = this.headers[Utils.headerize(name)];
- if (header) {
- if (header[0]) {
- return header[0].raw;
- }
- } else {
- return;
- }
- }
- /**
- * Get the header/s of the given name.
- */
- }, {
- key: "getHeaders",
- value: function getHeaders(name) {
- var headers = this.headers[Utils.headerize(name)];
- var result = [];
- if (!headers) {
- return [];
- }
- var _iteratorNormalCompletion7 = true;
- var _didIteratorError7 = false;
- var _iteratorError7 = undefined;
- try {
- for (var _iterator7 = headers[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
- var header = _step7.value;
- result.push(header.raw);
- }
- } catch (err) {
- _didIteratorError7 = true;
- _iteratorError7 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion7 && _iterator7.return != null) {
- _iterator7.return();
- }
- } finally {
- if (_didIteratorError7) {
- throw _iteratorError7;
- }
- }
- }
- return result;
- }
- /**
- * Verify the existence of the given header.
- */
- }, {
- key: "hasHeader",
- value: function hasHeader(name) {
- return this.headers[Utils.headerize(name)] ? true : false;
- }
- /**
- * Parse the given header on the given index.
- * -param {String} name header name
- * -param {Number} [idx=0] header index
- * -returns {Object|undefined} Parsed header object, undefined if the header
- * is not present or in case of a parsing error.
- */
- }, {
- key: "parseHeader",
- value: function parseHeader(name) {
- var idx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
- name = Utils.headerize(name);
- if (!this.headers[name]) {
- debug("header \"".concat(name, "\" not present"));
- return;
- } else if (idx >= this.headers[name].length) {
- debug("not so many \"".concat(name, "\" headers present"));
- return;
- }
- var header = this.headers[name][idx];
- var value = header.raw;
- if (header.parsed) {
- return header.parsed;
- } // Substitute '-' by '_' for grammar rule matching.
- var parsed = Grammar.parse(value, name.replace(/-/g, '_'));
- if (parsed === -1) {
- this.headers[name].splice(idx, 1); // delete from headers
- debug("error parsing \"".concat(name, "\" header field with value \"").concat(value, "\""));
- return;
- } else {
- header.parsed = parsed;
- return parsed;
- }
- }
- /**
- * Message Header attribute selector. Alias of parseHeader.
- * -param {String} name header name
- * -param {Number} [idx=0] header index
- * -returns {Object|undefined} Parsed header object, undefined if the header
- * is not present or in case of a parsing error.
- *
- * -example
- * message.s('via',3).port
- */
- }, {
- key: "s",
- value: function s(name, idx) {
- return this.parseHeader(name, idx);
- }
- /**
- * Replace the value of the given header by the value.
- * -param {String} name header name
- * -param {String} value header value
- */
- }, {
- key: "setHeader",
- value: function setHeader(name, value) {
- var header = {
- raw: value
- };
- this.headers[Utils.headerize(name)] = [header];
- }
- /**
- * Parse the current body as a SDP and store the resulting object
- * into this.sdp.
- * -param {Boolean} force: Parse even if this.sdp already exists.
- *
- * Returns this.sdp.
- */
- }, {
- key: "parseSDP",
- value: function parseSDP(force) {
- if (!force && this.sdp) {
- return this.sdp;
- } else {
- this.sdp = sdp_transform.parse(this.body || '');
- return this.sdp;
- }
- }
- }, {
- key: "toString",
- value: function toString() {
- return this.data;
- }
- }]);
- return IncomingMessage;
- }();
- var IncomingRequest =
- /*#__PURE__*/
- function (_IncomingMessage) {
- _inherits(IncomingRequest, _IncomingMessage);
- function IncomingRequest(ua) {
- var _this2;
- _classCallCheck(this, IncomingRequest);
- _this2 = _possibleConstructorReturn(this, _getPrototypeOf(IncomingRequest).call(this));
- _this2.ua = ua;
- _this2.headers = {};
- _this2.ruri = null;
- _this2.transport = null;
- _this2.server_transaction = null;
- return _this2;
- }
- /**
- * Stateful reply.
- * -param {Number} code status code
- * -param {String} reason reason phrase
- * -param {Object} headers extra headers
- * -param {String} body body
- * -param {Function} [onSuccess] onSuccess callback
- * -param {Function} [onFailure] onFailure callback
- */
- _createClass(IncomingRequest, [{
- key: "reply",
- value: function reply(code, reason, extraHeaders, body, onSuccess, onFailure) {
- var supported = [];
- var to = this.getHeader('To');
- code = code || null;
- reason = reason || null; // Validate code and reason values.
- if (!code || code < 100 || code > 699) {
- throw new TypeError("Invalid status_code: ".concat(code));
- } else if (reason && typeof reason !== 'string' && !(reason instanceof String)) {
- throw new TypeError("Invalid reason_phrase: ".concat(reason));
- }
- reason = reason || JsSIP_C.REASON_PHRASE[code] || '';
- extraHeaders = Utils.cloneArray(extraHeaders);
- var response = "SIP/2.0 ".concat(code, " ").concat(reason, "\r\n");
- if (this.method === JsSIP_C.INVITE && code > 100 && code <= 200) {
- var headers = this.getHeaders('record-route');
- var _iteratorNormalCompletion8 = true;
- var _didIteratorError8 = false;
- var _iteratorError8 = undefined;
- try {
- for (var _iterator8 = headers[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
- var header = _step8.value;
- response += "Record-Route: ".concat(header, "\r\n");
- }
- } catch (err) {
- _didIteratorError8 = true;
- _iteratorError8 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion8 && _iterator8.return != null) {
- _iterator8.return();
- }
- } finally {
- if (_didIteratorError8) {
- throw _iteratorError8;
- }
- }
- }
- }
- var vias = this.getHeaders('via');
- var _iteratorNormalCompletion9 = true;
- var _didIteratorError9 = false;
- var _iteratorError9 = undefined;
- try {
- for (var _iterator9 = vias[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
- var via = _step9.value;
- response += "Via: ".concat(via, "\r\n");
- }
- } catch (err) {
- _didIteratorError9 = true;
- _iteratorError9 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion9 && _iterator9.return != null) {
- _iterator9.return();
- }
- } finally {
- if (_didIteratorError9) {
- throw _iteratorError9;
- }
- }
- }
- if (!this.to_tag && code > 100) {
- to += ";tag=".concat(Utils.newTag());
- } else if (this.to_tag && !this.s('to').hasParam('tag')) {
- to += ";tag=".concat(this.to_tag);
- }
- response += "To: ".concat(to, "\r\n");
- response += "From: ".concat(this.getHeader('From'), "\r\n");
- response += "Call-ID: ".concat(this.call_id, "\r\n");
- response += "CSeq: ".concat(this.cseq, " ").concat(this.method, "\r\n");
- var _iteratorNormalCompletion10 = true;
- var _didIteratorError10 = false;
- var _iteratorError10 = undefined;
- try {
- for (var _iterator10 = extraHeaders[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {
- var _header2 = _step10.value;
- response += "".concat(_header2.trim(), "\r\n");
- } // Supported.
- } catch (err) {
- _didIteratorError10 = true;
- _iteratorError10 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion10 && _iterator10.return != null) {
- _iterator10.return();
- }
- } finally {
- if (_didIteratorError10) {
- throw _iteratorError10;
- }
- }
- }
- switch (this.method) {
- case JsSIP_C.INVITE:
- if (this.ua.configuration.session_timers) {
- supported.push('timer');
- }
- if (this.ua.contact.pub_gruu || this.ua.contact.temp_gruu) {
- supported.push('gruu');
- }
- supported.push('ice', 'replaces');
- break;
- case JsSIP_C.UPDATE:
- if (this.ua.configuration.session_timers) {
- supported.push('timer');
- }
- if (body) {
- supported.push('ice');
- }
- supported.push('replaces');
- }
- supported.push('outbound'); // Allow and Accept.
- if (this.method === JsSIP_C.OPTIONS) {
- response += "Allow: ".concat(JsSIP_C.ALLOWED_METHODS, "\r\n");
- response += "Accept: ".concat(JsSIP_C.ACCEPTED_BODY_TYPES, "\r\n");
- } else if (code === 405) {
- response += "Allow: ".concat(JsSIP_C.ALLOWED_METHODS, "\r\n");
- } else if (code === 415) {
- response += "Accept: ".concat(JsSIP_C.ACCEPTED_BODY_TYPES, "\r\n");
- }
- response += "Supported: ".concat(supported, "\r\n");
- if (body) {
- var length = Utils.str_utf8_length(body);
- response += 'Content-Type: application/sdp\r\n';
- response += "Content-Length: ".concat(length, "\r\n\r\n");
- response += body;
- } else {
- response += "Content-Length: ".concat(0, "\r\n\r\n");
- }
- this.server_transaction.receiveResponse(code, response, onSuccess, onFailure);
- }
- /**
- * Stateless reply.
- * -param {Number} code status code
- * -param {String} reason reason phrase
- */
- }, {
- key: "reply_sl",
- value: function reply_sl() {
- var code = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
- var reason = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
- var vias = this.getHeaders('via'); // Validate code and reason values.
- if (!code || code < 100 || code > 699) {
- throw new TypeError("Invalid status_code: ".concat(code));
- } else if (reason && typeof reason !== 'string' && !(reason instanceof String)) {
- throw new TypeError("Invalid reason_phrase: ".concat(reason));
- }
- reason = reason || JsSIP_C.REASON_PHRASE[code] || '';
- var response = "SIP/2.0 ".concat(code, " ").concat(reason, "\r\n");
- var _iteratorNormalCompletion11 = true;
- var _didIteratorError11 = false;
- var _iteratorError11 = undefined;
- try {
- for (var _iterator11 = vias[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {
- var via = _step11.value;
- response += "Via: ".concat(via, "\r\n");
- }
- } catch (err) {
- _didIteratorError11 = true;
- _iteratorError11 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion11 && _iterator11.return != null) {
- _iterator11.return();
- }
- } finally {
- if (_didIteratorError11) {
- throw _iteratorError11;
- }
- }
- }
- var to = this.getHeader('To');
- if (!this.to_tag && code > 100) {
- to += ";tag=".concat(Utils.newTag());
- } else if (this.to_tag && !this.s('to').hasParam('tag')) {
- to += ";tag=".concat(this.to_tag);
- }
- response += "To: ".concat(to, "\r\n");
- response += "From: ".concat(this.getHeader('From'), "\r\n");
- response += "Call-ID: ".concat(this.call_id, "\r\n");
- response += "CSeq: ".concat(this.cseq, " ").concat(this.method, "\r\n");
- response += "Content-Length: ".concat(0, "\r\n\r\n");
- this.transport.send(response);
- }
- }]);
- return IncomingRequest;
- }(IncomingMessage);
- var IncomingResponse =
- /*#__PURE__*/
- function (_IncomingMessage2) {
- _inherits(IncomingResponse, _IncomingMessage2);
- function IncomingResponse() {
- var _this3;
- _classCallCheck(this, IncomingResponse);
- _this3 = _possibleConstructorReturn(this, _getPrototypeOf(IncomingResponse).call(this));
- _this3.headers = {};
- _this3.status_code = null;
- _this3.reason_phrase = null;
- return _this3;
- }
- return IncomingResponse;
- }(IncomingMessage);
- module.exports = {
- OutgoingRequest: OutgoingRequest,
- InitialOutgoingInviteRequest: InitialOutgoingInviteRequest,
- IncomingRequest: IncomingRequest,
- IncomingResponse: IncomingResponse
- };
- }),
- /* 6 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _typeof(obj) {
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
- _typeof = function _typeof(obj) {
- return typeof obj;
- };
- } else {
- _typeof = function _typeof(obj) {
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
- };
- }
- return _typeof(obj);
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _possibleConstructorReturn(self, call) {
- if (call && (_typeof(call) === "object" || typeof call === "function")) {
- return call;
- }
- return _assertThisInitialized(self);
- }
- function _assertThisInitialized(self) {
- if (self === void 0) {
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- }
- return self;
- }
- function _inherits(subClass, superClass) {
- if (typeof superClass !== "function" && superClass !== null) {
- throw new TypeError("Super expression must either be null or a function");
- }
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- writable: true,
- configurable: true
- }
- });
- if (superClass) _setPrototypeOf(subClass, superClass);
- }
- function _wrapNativeSuper(Class) {
- var _cache = typeof Map === "function" ? new Map() : undefined;
- _wrapNativeSuper = function _wrapNativeSuper(Class) {
- if (Class === null || !_isNativeFunction(Class)) return Class;
- if (typeof Class !== "function") {
- throw new TypeError("Super expression must either be null or a function");
- }
- if (typeof _cache !== "undefined") {
- if (_cache.has(Class)) return _cache.get(Class);
- _cache.set(Class, Wrapper);
- }
- function Wrapper() {
- return _construct(Class, arguments, _getPrototypeOf(this).constructor);
- }
- Wrapper.prototype = Object.create(Class.prototype, {
- constructor: {
- value: Wrapper,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
- return _setPrototypeOf(Wrapper, Class);
- };
- return _wrapNativeSuper(Class);
- }
- function isNativeReflectConstruct() {
- if (typeof Reflect === "undefined" || !Reflect.construct) return false;
- if (Reflect.construct.sham) return false;
- if (typeof Proxy === "function") return true;
- try {
- Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
- return true;
- } catch (e) {
- return false;
- }
- }
- function _construct(Parent, args, Class) {
- if (isNativeReflectConstruct()) {
- _construct = Reflect.construct;
- } else {
- _construct = function _construct(Parent, args, Class) {
- var a = [null];
- a.push.apply(a, args);
- var Constructor = Function.bind.apply(Parent, a);
- var instance = new Constructor();
- if (Class) _setPrototypeOf(instance, Class.prototype);
- return instance;
- };
- }
- return _construct.apply(null, arguments);
- }
- function _isNativeFunction(fn) {
- return Function.toString.call(fn).indexOf("[native code]") !== -1;
- }
- function _setPrototypeOf(o, p) {
- _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
- o.__proto__ = p;
- return o;
- };
- return _setPrototypeOf(o, p);
- }
- function _getPrototypeOf(o) {
- _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
- return o.__proto__ || Object.getPrototypeOf(o);
- };
- return _getPrototypeOf(o);
- }
- var ConfigurationError =
- /*#__PURE__*/
- function (_Error) {
- _inherits(ConfigurationError, _Error);
- function ConfigurationError(parameter, value) {
- var _this;
- _classCallCheck(this, ConfigurationError);
- _this = _possibleConstructorReturn(this, _getPrototypeOf(ConfigurationError).call(this));
- _this.code = 1;
- _this.name = 'CONFIGURATION_ERROR';
- _this.parameter = parameter;
- _this.value = value;
- _this.message = !_this.value ? "Missing parameter: ".concat(_this.parameter) : "Invalid value ".concat(JSON.stringify(_this.value), " for parameter \"").concat(_this.parameter, "\"");
- return _this;
- }
- return ConfigurationError;
- }(_wrapNativeSuper(Error));
- var InvalidStateError =
- /*#__PURE__*/
- function (_Error2) {
- _inherits(InvalidStateError, _Error2);
- function InvalidStateError(status) {
- var _this2;
- _classCallCheck(this, InvalidStateError);
- _this2 = _possibleConstructorReturn(this, _getPrototypeOf(InvalidStateError).call(this));
- _this2.code = 2;
- _this2.name = 'INVALID_STATE_ERROR';
- _this2.status = status;
- _this2.message = "Invalid status: ".concat(status);
- return _this2;
- }
- return InvalidStateError;
- }(_wrapNativeSuper(Error));
- var NotSupportedError =
- /*#__PURE__*/
- function (_Error3) {
- _inherits(NotSupportedError, _Error3);
- function NotSupportedError(message) {
- var _this3;
- _classCallCheck(this, NotSupportedError);
- _this3 = _possibleConstructorReturn(this, _getPrototypeOf(NotSupportedError).call(this));
- _this3.code = 3;
- _this3.name = 'NOT_SUPPORTED_ERROR';
- _this3.message = message;
- return _this3;
- }
- return NotSupportedError;
- }(_wrapNativeSuper(Error));
- var NotReadyError =
- /*#__PURE__*/
- function (_Error4) {
- _inherits(NotReadyError, _Error4);
- function NotReadyError(message) {
- var _this4;
- _classCallCheck(this, NotReadyError);
- _this4 = _possibleConstructorReturn(this, _getPrototypeOf(NotReadyError).call(this));
- _this4.code = 4;
- _this4.name = 'NOT_READY_ERROR';
- _this4.message = message;
- return _this4;
- }
- return NotReadyError;
- }(_wrapNativeSuper(Error));
- module.exports = {
- ConfigurationError: ConfigurationError,
- InvalidStateError: InvalidStateError,
- NotSupportedError: NotSupportedError,
- NotReadyError: NotReadyError
- };
- }),
- /* 7 */
- (function(module, exports) {
- // Copyright Joyent, Inc. and other Node contributors.
- //
- // Permission is hereby granted, free of charge, to any person obtaining a
- // copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to permit
- // persons to whom the Software is furnished to do so, subject to the
- // following conditions:
- //
- // The above copyright notice and this permission notice shall be included
- // in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
- // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- // USE OR OTHER DEALINGS IN THE SOFTWARE.
- function EventEmitter() {
- this._events = this._events || {};
- this._maxListeners = this._maxListeners || undefined;
- }
- module.exports = EventEmitter; // Backwards-compat with node 0.10.x
- EventEmitter.EventEmitter = EventEmitter;
- EventEmitter.prototype._events = undefined;
- EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are
- // added to it. This is a useful default which helps finding memory leaks.
- EventEmitter.defaultMaxListeners = 10; // Obviously not all Emitters should be limited to 10. This function allows
- // that to be increased. Set to zero for unlimited.
- EventEmitter.prototype.setMaxListeners = function (n) {
- if (!isNumber(n) || n < 0 || isNaN(n)) throw TypeError('n must be a positive number');
- this._maxListeners = n;
- return this;
- };
- EventEmitter.prototype.emit = function (type) {
- var er, handler, len, args, i, listeners;
- if (!this._events) this._events = {}; // If there is no 'error' event listener then throw.
- if (type === 'error') {
- if (!this._events.error || isObject(this._events.error) && !this._events.error.length) {
- er = arguments[1];
- if (er instanceof Error) {
- throw er; // Unhandled 'error' event
- } else {
- // At least give some kind of context to the user
- var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
- err.context = er;
- throw err;
- }
- }
- }
- handler = this._events[type];
- if (isUndefined(handler)) return false;
- if (isFunction(handler)) {
- switch (arguments.length) {
- // fast cases
- case 1:
- handler.call(this);
- break;
- case 2:
- handler.call(this, arguments[1]);
- break;
- case 3:
- handler.call(this, arguments[1], arguments[2]);
- break;
- // slower
- default:
- args = Array.prototype.slice.call(arguments, 1);
- handler.apply(this, args);
- }
- } else if (isObject(handler)) {
- args = Array.prototype.slice.call(arguments, 1);
- listeners = handler.slice();
- len = listeners.length;
- for (i = 0; i < len; i++) listeners[i].apply(this, args);
- }
- return true;
- };
- EventEmitter.prototype.addListener = function (type, listener) {
- var m;
- if (!isFunction(listener)) throw TypeError('listener must be a function');
- if (!this._events) this._events = {}; // To avoid recursion in the case that type === "newListener"! Before
- // adding it to the listeners, first emit "newListener".
- if (this._events.newListener) this.emit('newListener', type, isFunction(listener.listener) ? listener.listener : listener);
- if (!this._events[type]) // Optimize the case of one listener. Don't need the extra array object.
- this._events[type] = listener;else if (isObject(this._events[type])) // If we've already got an array, just append.
- this._events[type].push(listener);else // Adding the second element, need to change to array.
- this._events[type] = [this._events[type], listener]; // Check for listener leak
- if (isObject(this._events[type]) && !this._events[type].warned) {
- if (!isUndefined(this._maxListeners)) {
- m = this._maxListeners;
- } else {
- m = EventEmitter.defaultMaxListeners;
- }
- if (m && m > 0 && this._events[type].length > m) {
- this._events[type].warned = true;
- console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length);
- if (typeof console.trace === 'function') {
- // not supported in IE 10
- console.trace();
- }
- }
- }
- return this;
- };
- EventEmitter.prototype.on = EventEmitter.prototype.addListener;
- EventEmitter.prototype.once = function (type, listener) {
- if (!isFunction(listener)) throw TypeError('listener must be a function');
- var fired = false;
- function g() {
- this.removeListener(type, g);
- if (!fired) {
- fired = true;
- listener.apply(this, arguments);
- }
- }
- g.listener = listener;
- this.on(type, g);
- return this;
- }; // emits a 'removeListener' event iff the listener was removed
- EventEmitter.prototype.removeListener = function (type, listener) {
- var list, position, length, i;
- if (!isFunction(listener)) throw TypeError('listener must be a function');
- if (!this._events || !this._events[type]) return this;
- list = this._events[type];
- length = list.length;
- position = -1;
- if (list === listener || isFunction(list.listener) && list.listener === listener) {
- delete this._events[type];
- if (this._events.removeListener) this.emit('removeListener', type, listener);
- } else if (isObject(list)) {
- for (i = length; i-- > 0;) {
- if (list[i] === listener || list[i].listener && list[i].listener === listener) {
- position = i;
- break;
- }
- }
- if (position < 0) return this;
- if (list.length === 1) {
- list.length = 0;
- delete this._events[type];
- } else {
- list.splice(position, 1);
- }
- if (this._events.removeListener) this.emit('removeListener', type, listener);
- }
- return this;
- };
- EventEmitter.prototype.removeAllListeners = function (type) {
- var key, listeners;
- if (!this._events) return this; // not listening for removeListener, no need to emit
- if (!this._events.removeListener) {
- if (arguments.length === 0) this._events = {};else if (this._events[type]) delete this._events[type];
- return this;
- } // emit removeListener for all listeners on all events
- if (arguments.length === 0) {
- for (key in this._events) {
- if (key === 'removeListener') continue;
- this.removeAllListeners(key);
- }
- this.removeAllListeners('removeListener');
- this._events = {};
- return this;
- }
- listeners = this._events[type];
- if (isFunction(listeners)) {
- this.removeListener(type, listeners);
- } else if (listeners) {
- // LIFO order
- while (listeners.length) this.removeListener(type, listeners[listeners.length - 1]);
- }
- delete this._events[type];
- return this;
- };
- EventEmitter.prototype.listeners = function (type) {
- var ret;
- if (!this._events || !this._events[type]) ret = [];else if (isFunction(this._events[type])) ret = [this._events[type]];else ret = this._events[type].slice();
- return ret;
- };
- EventEmitter.prototype.listenerCount = function (type) {
- if (this._events) {
- var evlistener = this._events[type];
- if (isFunction(evlistener)) return 1;else if (evlistener) return evlistener.length;
- }
- return 0;
- };
- EventEmitter.listenerCount = function (emitter, type) {
- return emitter.listenerCount(type);
- };
- function isFunction(arg) {
- return typeof arg === 'function';
- }
- function isNumber(arg) {
- return typeof arg === 'number';
- }
- function isObject(arg) {
- return typeof arg === 'object' && arg !== null;
- }
- function isUndefined(arg) {
- return arg === void 0;
- }
- }),
- /* 8 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- var JsSIP_C = __webpack_require__(1);
- var Utils = __webpack_require__(2);
- var Grammar = __webpack_require__(3);
- /**
- * -param {String} [scheme]
- * -param {String} [user]
- * -param {String} host
- * -param {String} [port]
- * -param {Object} [parameters]
- * -param {Object} [headers]
- *
- */
- module.exports =
- /*#__PURE__*/
- function () {
- _createClass(URI, null, [{
- key: "parse",
- /**
- * Parse the given string and returns a JsSIP.URI instance or undefined if
- * it is an invalid URI.
- */
- value: function parse(uri) {
- uri = Grammar.parse(uri, 'SIP_URI');
- if (uri !== -1) {
- return uri;
- } else {
- return undefined;
- }
- }
- }]);
- function URI(scheme, user, host, port) {
- var parameters = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
- var headers = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
- _classCallCheck(this, URI); // Checks.
- if (!host) {
- throw new TypeError('missing or invalid "host" parameter');
- } // Initialize parameters.
- this._parameters = {};
- this._headers = {};
- this._scheme = scheme || JsSIP_C.SIP;
- this._user = user;
- this._host = host;
- this._port = port;
- for (var param in parameters) {
- if (Object.prototype.hasOwnProperty.call(parameters, param)) {
- this.setParam(param, parameters[param]);
- }
- }
- for (var header in headers) {
- if (Object.prototype.hasOwnProperty.call(headers, header)) {
- this.setHeader(header, headers[header]);
- }
- }
- }
- _createClass(URI, [{
- key: "setParam",
- value: function setParam(key, value) {
- if (key) {
- this._parameters[key.toLowerCase()] = typeof value === 'undefined' || value === null ? null : value.toString();
- }
- }
- }, {
- key: "getParam",
- value: function getParam(key) {
- if (key) {
- return this._parameters[key.toLowerCase()];
- }
- }
- }, {
- key: "hasParam",
- value: function hasParam(key) {
- if (key) {
- return this._parameters.hasOwnProperty(key.toLowerCase()) && true || false;
- }
- }
- }, {
- key: "deleteParam",
- value: function deleteParam(parameter) {
- parameter = parameter.toLowerCase();
- if (this._parameters.hasOwnProperty(parameter)) {
- var value = this._parameters[parameter];
- delete this._parameters[parameter];
- return value;
- }
- }
- }, {
- key: "clearParams",
- value: function clearParams() {
- this._parameters = {};
- }
- }, {
- key: "setHeader",
- value: function setHeader(name, value) {
- this._headers[Utils.headerize(name)] = Array.isArray(value) ? value : [value];
- }
- }, {
- key: "getHeader",
- value: function getHeader(name) {
- if (name) {
- return this._headers[Utils.headerize(name)];
- }
- }
- }, {
- key: "hasHeader",
- value: function hasHeader(name) {
- if (name) {
- return this._headers.hasOwnProperty(Utils.headerize(name)) && true || false;
- }
- }
- }, {
- key: "deleteHeader",
- value: function deleteHeader(header) {
- header = Utils.headerize(header);
- if (this._headers.hasOwnProperty(header)) {
- var value = this._headers[header];
- delete this._headers[header];
- return value;
- }
- }
- }, {
- key: "clearHeaders",
- value: function clearHeaders() {
- this._headers = {};
- }
- }, {
- key: "clone",
- value: function clone() {
- return new URI(this._scheme, this._user, this._host, this._port, JSON.parse(JSON.stringify(this._parameters)), JSON.parse(JSON.stringify(this._headers)));
- }
- }, {
- key: "toString",
- value: function toString() {
- var headers = [];
- var uri = "".concat(this._scheme, ":");
- if (this._user) {
- uri += "".concat(Utils.escapeUser(this._user), "@");
- }
- uri += this._host;
- if (this._port || this._port === 0) {
- uri += ":".concat(this._port);
- }
- for (var parameter in this._parameters) {
- if (Object.prototype.hasOwnProperty.call(this._parameters, parameter)) {
- uri += ";".concat(parameter);
- if (this._parameters[parameter] !== null) {
- uri += "=".concat(this._parameters[parameter]);
- }
- }
- }
- for (var header in this._headers) {
- if (Object.prototype.hasOwnProperty.call(this._headers, header)) {
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
- try {
- for (var _iterator = this._headers[header][Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var item = _step.value;
- headers.push("".concat(header, "=").concat(item));
- }
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator.return != null) {
- _iterator.return();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
- }
- }
- }
- if (headers.length > 0) {
- uri += "?".concat(headers.join('&'));
- }
- return uri;
- }
- }, {
- key: "toAor",
- value: function toAor(show_port) {
- var aor = "".concat(this._scheme, ":");
- if (this._user) {
- aor += "".concat(Utils.escapeUser(this._user), "@");
- }
- aor += this._host;
- if (show_port && (this._port || this._port === 0)) {
- aor += ":".concat(this._port);
- }
- return aor;
- }
- }, {
- key: "scheme",
- get: function get() {
- return this._scheme;
- },
- set: function set(value) {
- this._scheme = value.toLowerCase();
- }
- }, {
- key: "user",
- get: function get() {
- return this._user;
- },
- set: function set(value) {
- this._user = value;
- }
- }, {
- key: "host",
- get: function get() {
- return this._host;
- },
- set: function set(value) {
- this._host = value.toLowerCase();
- }
- }, {
- key: "port",
- get: function get() {
- return this._port;
- },
- set: function set(value) {
- this._port = value === 0 ? value : parseInt(value, 10) || null;
- }
- }]);
- return URI;
- }();
- }),
- /* 9 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _typeof(obj) {
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
- _typeof = function _typeof(obj) {
- return typeof obj;
- };
- } else {
- _typeof = function _typeof(obj) {
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
- };
- }
- return _typeof(obj);
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- function _possibleConstructorReturn(self, call) {
- if (call && (_typeof(call) === "object" || typeof call === "function")) {
- return call;
- }
- return _assertThisInitialized(self);
- }
- function _getPrototypeOf(o) {
- _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
- return o.__proto__ || Object.getPrototypeOf(o);
- };
- return _getPrototypeOf(o);
- }
- function _inherits(subClass, superClass) {
- if (typeof superClass !== "function" && superClass !== null) {
- throw new TypeError("Super expression must either be null or a function");
- }
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- writable: true,
- configurable: true
- }
- });
- if (superClass) _setPrototypeOf(subClass, superClass);
- }
- function _setPrototypeOf(o, p) {
- _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
- o.__proto__ = p;
- return o;
- };
- return _setPrototypeOf(o, p);
- }
- function _assertThisInitialized(self) {
- if (self === void 0) {
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- }
- return self;
- }
- var EventEmitter = __webpack_require__(7).EventEmitter;
- var JsSIP_C = __webpack_require__(1);
- var SIPMessage = __webpack_require__(5);
- var Timers = __webpack_require__(16);
- var debugnict = __webpack_require__(0)('JsSIP:NonInviteClientTransaction');
- var debugict = __webpack_require__(0)('JsSIP:InviteClientTransaction');
- var debugact = __webpack_require__(0)('JsSIP:AckClientTransaction');
- var debugnist = __webpack_require__(0)('JsSIP:NonInviteServerTransaction');
- var debugist = __webpack_require__(0)('JsSIP:InviteServerTransaction');
- var C = {
- // Transaction states.
- STATUS_TRYING: 1,
- STATUS_PROCEEDING: 2,
- STATUS_CALLING: 3,
- STATUS_ACCEPTED: 4,
- STATUS_COMPLETED: 5,
- STATUS_TERMINATED: 6,
- STATUS_CONFIRMED: 7,
- // Transaction types.
- NON_INVITE_CLIENT: 'nict',
- NON_INVITE_SERVER: 'nist',
- INVITE_CLIENT: 'ict',
- INVITE_SERVER: 'ist'
- };
- var NonInviteClientTransaction =
- /*#__PURE__*/
- function (_EventEmitter) {
- _inherits(NonInviteClientTransaction, _EventEmitter);
- function NonInviteClientTransaction(ua, transport, request, eventHandlers) {
- var _this;
- _classCallCheck(this, NonInviteClientTransaction);
- _this = _possibleConstructorReturn(this, _getPrototypeOf(NonInviteClientTransaction).call(this));
- _this.type = C.NON_INVITE_CLIENT;
- _this.id = "z9hG4bK".concat(Math.floor(Math.random() * 10000000));
- _this.ua = ua;
- _this.transport = transport;
- _this.request = request;
- _this.eventHandlers = eventHandlers;
- var via = "SIP/2.0/".concat(transport.via_transport);
- via += " ".concat(ua.configuration.via_host, ";branch=").concat(_this.id);
- _this.request.setHeader('via', via);
- _this.ua.newTransaction(_assertThisInitialized(_assertThisInitialized(_this)));
- return _this;
- }
- _createClass(NonInviteClientTransaction, [{
- key: "stateChanged",
- value: function stateChanged(state) {
- this.state = state;
- this.emit('stateChanged');
- }
- }, {
- key: "send",
- value: function send() {
- var _this2 = this;
- this.stateChanged(C.STATUS_TRYING);
- this.F = setTimeout(function () {
- _this2.timer_F();
- }, Timers.TIMER_F);
- if (!this.transport.send(this.request)) {
- this.onTransportError();
- }
- }
- }, {
- key: "onTransportError",
- value: function onTransportError() {
- debugnict("transport error occurred, deleting transaction ".concat(this.id));
- clearTimeout(this.F);
- clearTimeout(this.K);
- this.stateChanged(C.STATUS_TERMINATED);
- this.ua.destroyTransaction(this);
- this.eventHandlers.onTransportError();
- }
- }, {
- key: "timer_F",
- value: function timer_F() {
- debugnict("Timer F expired for transaction ".concat(this.id));
- this.stateChanged(C.STATUS_TERMINATED);
- this.ua.destroyTransaction(this);
- this.eventHandlers.onRequestTimeout();
- }
- }, {
- key: "timer_K",
- value: function timer_K() {
- this.stateChanged(C.STATUS_TERMINATED);
- this.ua.destroyTransaction(this);
- }
- }, {
- key: "receiveResponse",
- value: function receiveResponse(response) {
- var _this3 = this;
- var status_code = response.status_code;
- if (status_code < 200) {
- switch (this.state) {
- case C.STATUS_TRYING:
- case C.STATUS_PROCEEDING:
- this.stateChanged(C.STATUS_PROCEEDING);
- this.eventHandlers.onReceiveResponse(response);
- break;
- }
- } else {
- switch (this.state) {
- case C.STATUS_TRYING:
- case C.STATUS_PROCEEDING:
- this.stateChanged(C.STATUS_COMPLETED);
- clearTimeout(this.F);
- if (status_code === 408) {
- this.eventHandlers.onRequestTimeout();
- } else {
- this.eventHandlers.onReceiveResponse(response);
- }
- this.K = setTimeout(function () {
- _this3.timer_K();
- }, Timers.TIMER_K);
- break;
- case C.STATUS_COMPLETED:
- break;
- }
- }
- }
- }, {
- key: "C",
- get: function get() {
- return C;
- }
- }]);
- return NonInviteClientTransaction;
- }(EventEmitter);
- var InviteClientTransaction =
- /*#__PURE__*/
- function (_EventEmitter2) {
- _inherits(InviteClientTransaction, _EventEmitter2);
- function InviteClientTransaction(ua, transport, request, eventHandlers) {
- var _this4;
- _classCallCheck(this, InviteClientTransaction);
- _this4 = _possibleConstructorReturn(this, _getPrototypeOf(InviteClientTransaction).call(this));
- _this4.type = C.INVITE_CLIENT;
- _this4.id = "z9hG4bK".concat(Math.floor(Math.random() * 10000000));
- _this4.ua = ua;
- _this4.transport = transport;
- _this4.request = request;
- _this4.eventHandlers = eventHandlers;
- request.transaction = _assertThisInitialized(_assertThisInitialized(_this4));
- var via = "SIP/2.0/".concat(transport.via_transport);
- via += " ".concat(ua.configuration.via_host, ";branch=").concat(_this4.id);
- _this4.request.setHeader('via', via);
- _this4.ua.newTransaction(_assertThisInitialized(_assertThisInitialized(_this4)));
- return _this4;
- }
- _createClass(InviteClientTransaction, [{
- key: "stateChanged",
- value: function stateChanged(state) {
- this.state = state;
- this.emit('stateChanged');
- }
- }, {
- key: "send",
- value: function send() {
- var _this5 = this;
- this.stateChanged(C.STATUS_CALLING);
- this.B = setTimeout(function () {
- _this5.timer_B();
- }, Timers.TIMER_B);
- if (!this.transport.send(this.request)) {
- this.onTransportError();
- }
- }
- }, {
- key: "onTransportError",
- value: function onTransportError() {
- clearTimeout(this.B);
- clearTimeout(this.D);
- clearTimeout(this.M);
- if (this.state !== C.STATUS_ACCEPTED) {
- debugict("transport error occurred, deleting transaction ".concat(this.id));
- this.eventHandlers.onTransportError();
- }
- this.stateChanged(C.STATUS_TERMINATED);
- this.ua.destroyTransaction(this);
- } // RFC 6026 7.2.
- }, {
- key: "timer_M",
- value: function timer_M() {
- debugict("Timer M expired for transaction ".concat(this.id));
- if (this.state === C.STATUS_ACCEPTED) {
- clearTimeout(this.B);
- this.stateChanged(C.STATUS_TERMINATED);
- this.ua.destroyTransaction(this);
- }
- } // RFC 3261 17.1.1.
- }, {
- key: "timer_B",
- value: function timer_B() {
- debugict("Timer B expired for transaction ".concat(this.id));
- if (this.state === C.STATUS_CALLING) {
- this.stateChanged(C.STATUS_TERMINATED);
- this.ua.destroyTransaction(this);
- this.eventHandlers.onRequestTimeout();
- }
- }
- }, {
- key: "timer_D",
- value: function timer_D() {
- debugict("Timer D expired for transaction ".concat(this.id));
- clearTimeout(this.B);
- this.stateChanged(C.STATUS_TERMINATED);
- this.ua.destroyTransaction(this);
- }
- }, {
- key: "sendACK",
- value: function sendACK(response) {
- var _this6 = this;
- var ack = new SIPMessage.OutgoingRequest(JsSIP_C.ACK, this.request.ruri, this.ua, {
- 'route_set': this.request.getHeaders('route'),
- 'call_id': this.request.getHeader('call-id'),
- 'cseq': this.request.cseq
- });
- ack.setHeader('from', this.request.getHeader('from'));
- ack.setHeader('via', this.request.getHeader('via'));
- ack.setHeader('to', response.getHeader('to'));
- this.D = setTimeout(function () {
- _this6.timer_D();
- }, Timers.TIMER_D);
- this.transport.send(ack);
- }
- }, {
- key: "cancel",
- value: function cancel(reason) {
- // Send only if a provisional response (>100) has been received.
- if (this.state !== C.STATUS_PROCEEDING) {
- return;
- }
- var cancel = new SIPMessage.OutgoingRequest(JsSIP_C.CANCEL, this.request.ruri, this.ua, {
- 'route_set': this.request.getHeaders('route'),
- 'call_id': this.request.getHeader('call-id'),
- 'cseq': this.request.cseq
- });
- cancel.setHeader('from', this.request.getHeader('from'));
- cancel.setHeader('via', this.request.getHeader('via'));
- cancel.setHeader('to', this.request.getHeader('to'));
- if (reason) {
- cancel.setHeader('reason', reason);
- }
- this.transport.send(cancel);
- }
- }, {
- key: "receiveResponse",
- value: function receiveResponse(response) {
- var _this7 = this;
- var status_code = response.status_code;
- if (status_code >= 100 && status_code <= 199) {
- switch (this.state) {
- case C.STATUS_CALLING:
- this.stateChanged(C.STATUS_PROCEEDING);
- this.eventHandlers.onReceiveResponse(response);
- break;
- case C.STATUS_PROCEEDING:
- this.eventHandlers.onReceiveResponse(response);
- break;
- }
- } else if (status_code >= 200 && status_code <= 299) {
- switch (this.state) {
- case C.STATUS_CALLING:
- case C.STATUS_PROCEEDING:
- this.stateChanged(C.STATUS_ACCEPTED);
- this.M = setTimeout(function () {
- _this7.timer_M();
- }, Timers.TIMER_M);
- this.eventHandlers.onReceiveResponse(response);
- break;
- case C.STATUS_ACCEPTED:
- this.eventHandlers.onReceiveResponse(response);
- break;
- }
- } else if (status_code >= 300 && status_code <= 699) {
- switch (this.state) {
- case C.STATUS_CALLING:
- case C.STATUS_PROCEEDING:
- this.stateChanged(C.STATUS_COMPLETED);
- this.sendACK(response);
- this.eventHandlers.onReceiveResponse(response);
- break;
- case C.STATUS_COMPLETED:
- this.sendACK(response);
- break;
- }
- }
- }
- }, {
- key: "C",
- get: function get() {
- return C;
- }
- }]);
- return InviteClientTransaction;
- }(EventEmitter);
- var AckClientTransaction =
- /*#__PURE__*/
- function (_EventEmitter3) {
- _inherits(AckClientTransaction, _EventEmitter3);
- function AckClientTransaction(ua, transport, request, eventHandlers) {
- var _this8;
- _classCallCheck(this, AckClientTransaction);
- _this8 = _possibleConstructorReturn(this, _getPrototypeOf(AckClientTransaction).call(this));
- _this8.id = "z9hG4bK".concat(Math.floor(Math.random() * 10000000));
- _this8.transport = transport;
- _this8.request = request;
- _this8.eventHandlers = eventHandlers;
- var via = "SIP/2.0/".concat(transport.via_transport);
- via += " ".concat(ua.configuration.via_host, ";branch=").concat(_this8.id);
- _this8.request.setHeader('via', via);
- return _this8;
- }
- _createClass(AckClientTransaction, [{
- key: "send",
- value: function send() {
- if (!this.transport.send(this.request)) {
- this.onTransportError();
- }
- }
- }, {
- key: "onTransportError",
- value: function onTransportError() {
- debugact("transport error occurred for transaction ".concat(this.id));
- this.eventHandlers.onTransportError();
- }
- }, {
- key: "C",
- get: function get() {
- return C;
- }
- }]);
- return AckClientTransaction;
- }(EventEmitter);
- var NonInviteServerTransaction =
- /*#__PURE__*/
- function (_EventEmitter4) {
- _inherits(NonInviteServerTransaction, _EventEmitter4);
- function NonInviteServerTransaction(ua, transport, request) {
- var _this9;
- _classCallCheck(this, NonInviteServerTransaction);
- _this9 = _possibleConstructorReturn(this, _getPrototypeOf(NonInviteServerTransaction).call(this));
- _this9.type = C.NON_INVITE_SERVER;
- _this9.id = request.via_branch;
- _this9.ua = ua;
- _this9.transport = transport;
- _this9.request = request;
- _this9.last_response = '';
- request.server_transaction = _assertThisInitialized(_assertThisInitialized(_this9));
- _this9.state = C.STATUS_TRYING;
- ua.newTransaction(_assertThisInitialized(_assertThisInitialized(_this9)));
- return _this9;
- }
- _createClass(NonInviteServerTransaction, [{
- key: "stateChanged",
- value: function stateChanged(state) {
- this.state = state;
- this.emit('stateChanged');
- }
- }, {
- key: "timer_J",
- value: function timer_J() {
- debugnist("Timer J expired for transaction ".concat(this.id));
- this.stateChanged(C.STATUS_TERMINATED);
- this.ua.destroyTransaction(this);
- }
- }, {
- key: "onTransportError",
- value: function onTransportError() {
- if (!this.transportError) {
- this.transportError = true;
- debugnist("transport error occurred, deleting transaction ".concat(this.id));
- clearTimeout(this.J);
- this.stateChanged(C.STATUS_TERMINATED);
- this.ua.destroyTransaction(this);
- }
- }
- }, {
- key: "receiveResponse",
- value: function receiveResponse(status_code, response, onSuccess, onFailure) {
- var _this10 = this;
- if (status_code === 100) {
- /* RFC 4320 4.1
- * 'A SIP element MUST NOT
- * send any provisional response with a
- * Status-Code other than 100 to a non-INVITE request.'
- */
- switch (this.state) {
- case C.STATUS_TRYING:
- this.stateChanged(C.STATUS_PROCEEDING);
- if (!this.transport.send(response)) {
- this.onTransportError();
- }
- break;
- case C.STATUS_PROCEEDING:
- this.last_response = response;
- if (!this.transport.send(response)) {
- this.onTransportError();
- if (onFailure) {
- onFailure();
- }
- } else if (onSuccess) {
- onSuccess();
- }
- break;
- }
- } else if (status_code >= 200 && status_code <= 699) {
- switch (this.state) {
- case C.STATUS_TRYING:
- case C.STATUS_PROCEEDING:
- this.stateChanged(C.STATUS_COMPLETED);
- this.last_response = response;
- this.J = setTimeout(function () {
- _this10.timer_J();
- }, Timers.TIMER_J);
- if (!this.transport.send(response)) {
- this.onTransportError();
- if (onFailure) {
- onFailure();
- }
- } else if (onSuccess) {
- onSuccess();
- }
- break;
- case C.STATUS_COMPLETED:
- break;
- }
- }
- }
- }, {
- key: "C",
- get: function get() {
- return C;
- }
- }]);
- return NonInviteServerTransaction;
- }(EventEmitter);
- var InviteServerTransaction =
- /*#__PURE__*/
- function (_EventEmitter5) {
- _inherits(InviteServerTransaction, _EventEmitter5);
- function InviteServerTransaction(ua, transport, request) {
- var _this11;
- _classCallCheck(this, InviteServerTransaction);
- _this11 = _possibleConstructorReturn(this, _getPrototypeOf(InviteServerTransaction).call(this));
- _this11.type = C.INVITE_SERVER;
- _this11.id = request.via_branch;
- _this11.ua = ua;
- _this11.transport = transport;
- _this11.request = request;
- _this11.last_response = '';
- request.server_transaction = _assertThisInitialized(_assertThisInitialized(_this11));
- _this11.state = C.STATUS_PROCEEDING;
- ua.newTransaction(_assertThisInitialized(_assertThisInitialized(_this11)));
- _this11.resendProvisionalTimer = null;
- request.reply(100);
- return _this11;
- }
- _createClass(InviteServerTransaction, [{
- key: "stateChanged",
- value: function stateChanged(state) {
- this.state = state;
- this.emit('stateChanged');
- }
- }, {
- key: "timer_H",
- value: function timer_H() {
- debugist("Timer H expired for transaction ".concat(this.id));
- if (this.state === C.STATUS_COMPLETED) {
- debugist('ACK not received, dialog will be terminated');
- }
- this.stateChanged(C.STATUS_TERMINATED);
- this.ua.destroyTransaction(this);
- }
- }, {
- key: "timer_I",
- value: function timer_I() {
- this.stateChanged(C.STATUS_TERMINATED);
- } // RFC 6026 7.1.
- }, {
- key: "timer_L",
- value: function timer_L() {
- debugist("Timer L expired for transaction ".concat(this.id));
- if (this.state === C.STATUS_ACCEPTED) {
- this.stateChanged(C.STATUS_TERMINATED);
- this.ua.destroyTransaction(this);
- }
- }
- }, {
- key: "onTransportError",
- value: function onTransportError() {
- if (!this.transportError) {
- this.transportError = true;
- debugist("transport error occurred, deleting transaction ".concat(this.id));
- if (this.resendProvisionalTimer !== null) {
- clearInterval(this.resendProvisionalTimer);
- this.resendProvisionalTimer = null;
- }
- clearTimeout(this.L);
- clearTimeout(this.H);
- clearTimeout(this.I);
- this.stateChanged(C.STATUS_TERMINATED);
- this.ua.destroyTransaction(this);
- }
- }
- }, {
- key: "resend_provisional",
- value: function resend_provisional() {
- if (!this.transport.send(this.last_response)) {
- this.onTransportError();
- }
- } // INVITE Server Transaction RFC 3261 17.2.1.
- }, {
- key: "receiveResponse",
- value: function receiveResponse(status_code, response, onSuccess, onFailure) {
- var _this12 = this;
- if (status_code >= 100 && status_code <= 199) {
- switch (this.state) {
- case C.STATUS_PROCEEDING:
- if (!this.transport.send(response)) {
- this.onTransportError();
- }
- this.last_response = response;
- break;
- }
- }
- if (status_code > 100 && status_code <= 199 && this.state === C.STATUS_PROCEEDING) {
- // Trigger the resendProvisionalTimer only for the first non 100 provisional response.
- if (this.resendProvisionalTimer === null) {
- this.resendProvisionalTimer = setInterval(function () {
- _this12.resend_provisional();
- }, Timers.PROVISIONAL_RESPONSE_INTERVAL);
- }
- } else if (status_code >= 200 && status_code <= 299) {
- switch (this.state) {
- case C.STATUS_PROCEEDING:
- this.stateChanged(C.STATUS_ACCEPTED);
- this.last_response = response;
- this.L = setTimeout(function () {
- _this12.timer_L();
- }, Timers.TIMER_L);
- if (this.resendProvisionalTimer !== null) {
- clearInterval(this.resendProvisionalTimer);
- this.resendProvisionalTimer = null;
- }
- /* falls through */
- case C.STATUS_ACCEPTED:
- // Note that this point will be reached for proceeding this.state also.
- if (!this.transport.send(response)) {
- this.onTransportError();
- if (onFailure) {
- onFailure();
- }
- } else if (onSuccess) {
- onSuccess();
- }
- break;
- }
- } else if (status_code >= 300 && status_code <= 699) {
- switch (this.state) {
- case C.STATUS_PROCEEDING:
- if (this.resendProvisionalTimer !== null) {
- clearInterval(this.resendProvisionalTimer);
- this.resendProvisionalTimer = null;
- }
- if (!this.transport.send(response)) {
- this.onTransportError();
- if (onFailure) {
- onFailure();
- }
- } else {
- this.stateChanged(C.STATUS_COMPLETED);
- this.H = setTimeout(function () {
- _this12.timer_H();
- }, Timers.TIMER_H);
- if (onSuccess) {
- onSuccess();
- }
- }
- break;
- }
- }
- }
- }, {
- key: "C",
- get: function get() {
- return C;
- }
- }]);
- return InviteServerTransaction;
- }(EventEmitter);
- /**
- * INVITE:
- * _true_ if retransmission
- * _false_ new request
- *
- * ACK:
- * _true_ ACK to non2xx response
- * _false_ ACK must be passed to TU (accepted state)
- * ACK to 2xx response
- *
- * CANCEL:
- * _true_ no matching invite transaction
- * _false_ matching invite transaction and no final response sent
- *
- * OTHER:
- * _true_ retransmission
- * _false_ new request
- */
- function checkTransaction(_ref, request) {
- var _transactions = _ref._transactions;
- var tr;
- switch (request.method) {
- case JsSIP_C.INVITE:
- tr = _transactions.ist[request.via_branch];
- if (tr) {
- switch (tr.state) {
- case C.STATUS_PROCEEDING:
- tr.transport.send(tr.last_response);
- break;
- // RFC 6026 7.1 Invite retransmission.
- // Received while in C.STATUS_ACCEPTED state. Absorb it.
- case C.STATUS_ACCEPTED:
- break;
- }
- return true;
- }
- break;
- case JsSIP_C.ACK:
- tr = _transactions.ist[request.via_branch]; // RFC 6026 7.1.
- if (tr) {
- if (tr.state === C.STATUS_ACCEPTED) {
- return false;
- } else if (tr.state === C.STATUS_COMPLETED) {
- tr.state = C.STATUS_CONFIRMED;
- tr.I = setTimeout(function () {
- tr.timer_I();
- }, Timers.TIMER_I);
- return true;
- }
- } // ACK to 2XX Response.
- else {
- return false;
- }
- break;
- case JsSIP_C.CANCEL:
- tr = _transactions.ist[request.via_branch];
- if (tr) {
- request.reply_sl(200);
- if (tr.state === C.STATUS_PROCEEDING) {
- return false;
- } else {
- return true;
- }
- } else {
- request.reply_sl(481);
- return true;
- }
- default:
- // Non-INVITE Server Transaction RFC 3261 17.2.2.
- tr = _transactions.nist[request.via_branch];
- if (tr) {
- switch (tr.state) {
- case C.STATUS_TRYING:
- break;
- case C.STATUS_PROCEEDING:
- case C.STATUS_COMPLETED:
- tr.transport.send(tr.last_response);
- break;
- }
- return true;
- }
- break;
- }
- }
- module.exports = {
- C: C,
- NonInviteClientTransaction: NonInviteClientTransaction,
- InviteClientTransaction: InviteClientTransaction,
- AckClientTransaction: AckClientTransaction,
- NonInviteServerTransaction: NonInviteServerTransaction,
- InviteServerTransaction: InviteServerTransaction,
- checkTransaction: checkTransaction
- };
- }),
- /* 10 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- var JsSIP_C = __webpack_require__(1);
- var DigestAuthentication = __webpack_require__(31);
- var Transactions = __webpack_require__(9);
- var debug = __webpack_require__(0)('JsSIP:RequestSender'); // Default event handlers.
- var EventHandlers = {
- onRequestTimeout: function onRequestTimeout() {},
- onTransportError: function onTransportError() {},
- onReceiveResponse: function onReceiveResponse() {},
- onAuthenticated: function onAuthenticated() {}
- };
- module.exports =
- /*#__PURE__*/
- function () {
- function RequestSender(ua, request, eventHandlers) {
- _classCallCheck(this, RequestSender);
- this._ua = ua;
- this._eventHandlers = eventHandlers;
- this._method = request.method;
- this._request = request;
- this._auth = null;
- this._challenged = false;
- this._staled = false; // Define the undefined handlers.
- for (var handler in EventHandlers) {
- if (Object.prototype.hasOwnProperty.call(EventHandlers, handler)) {
- if (!this._eventHandlers[handler]) {
- this._eventHandlers[handler] = EventHandlers[handler];
- }
- }
- } // If ua is in closing process or even closed just allow sending Bye and ACK.
- if (ua.status === ua.C.STATUS_USER_CLOSED && (this._method !== JsSIP_C.BYE || this._method !== JsSIP_C.ACK)) {
- this._eventHandlers.onTransportError();
- }
- }
- /**
- * Create the client transaction and send the message.
- */
- _createClass(RequestSender, [{
- key: "send",
- value: function send() {
- var _this = this;
- var eventHandlers = {
- onRequestTimeout: function onRequestTimeout() {
- _this._eventHandlers.onRequestTimeout();
- },
- onTransportError: function onTransportError() {
- _this._eventHandlers.onTransportError();
- },
- onReceiveResponse: function onReceiveResponse(response) {
- _this._receiveResponse(response);
- }
- };
- switch (this._method) {
- case 'INVITE':
- this.clientTransaction = new Transactions.InviteClientTransaction(this._ua, this._ua.transport, this._request, eventHandlers);
- break;
- case 'ACK':
- this.clientTransaction = new Transactions.AckClientTransaction(this._ua, this._ua.transport, this._request, eventHandlers);
- break;
- default:
- this.clientTransaction = new Transactions.NonInviteClientTransaction(this._ua, this._ua.transport, this._request, eventHandlers);
- }
- this.clientTransaction.send();
- }
- /**
- * Called from client transaction when receiving a correct response to the request.
- * Authenticate request if needed or pass the response back to the applicant.
- */
- }, {
- key: "_receiveResponse",
- value: function _receiveResponse(response) {
- var challenge;
- var authorization_header_name;
- var status_code = response.status_code;
- /*
- * Authentication
- * Authenticate once. _challenged_ flag used to avoid infinite authentications.
- */
- if ((status_code === 401 || status_code === 407) && (this._ua.configuration.password !== null || this._ua.configuration.ha1 !== null)) {
- // Get and parse the appropriate WWW-Authenticate or Proxy-Authenticate header.
- if (response.status_code === 401) {
- challenge = response.parseHeader('www-authenticate');
- authorization_header_name = 'authorization';
- } else {
- challenge = response.parseHeader('proxy-authenticate');
- authorization_header_name = 'proxy-authorization';
- } // Verify it seems a valid challenge.
- if (!challenge) {
- debug("".concat(response.status_code, " with wrong or missing challenge, cannot authenticate"));
- this._eventHandlers.onReceiveResponse(response);
- return;
- }
- if (!this._challenged || !this._staled && challenge.stale === true) {
- if (!this._auth) {
- this._auth = new DigestAuthentication({
- username: this._ua.configuration.authorization_user,
- password: this._ua.configuration.password,
- realm: this._ua.configuration.realm,
- ha1: this._ua.configuration.ha1
- });
- } // Verify that the challenge is really valid.
- if (!this._auth.authenticate(this._request, challenge)) {
- this._eventHandlers.onReceiveResponse(response);
- return;
- }
- this._challenged = true; // Update ha1 and realm in the UA.
- this._ua.set('realm', this._auth.get('realm'));
- this._ua.set('ha1', this._auth.get('ha1'));
- if (challenge.stale) {
- this._staled = true;
- }
- this._request = this._request.clone();
- this._request.cseq += 1;
- this._request.setHeader('cseq', "".concat(this._request.cseq, " ").concat(this._method));
- this._request.setHeader(authorization_header_name, this._auth.toString());
- this._eventHandlers.onAuthenticated(this._request);
- this.send();
- } else {
- this._eventHandlers.onReceiveResponse(response);
- }
- } else {
- this._eventHandlers.onReceiveResponse(response);
- }
- }
- }]);
- return RequestSender;
- }();
- }),
- /* 11 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- var URI = __webpack_require__(8);
- var Grammar = __webpack_require__(3);
- module.exports =
- /*#__PURE__*/
- function () {
- _createClass(NameAddrHeader, null, [{
- key: "parse",
- /**
- * Parse the given string and returns a NameAddrHeader instance or undefined if
- * it is an invalid NameAddrHeader.
- */
- value: function parse(name_addr_header) {
- name_addr_header = Grammar.parse(name_addr_header, 'Name_Addr_Header');
- if (name_addr_header !== -1) {
- return name_addr_header;
- } else {
- return undefined;
- }
- }
- }]);
- function NameAddrHeader(uri, display_name, parameters) {
- _classCallCheck(this, NameAddrHeader); // Checks.
- if (!uri || !(uri instanceof URI)) {
- throw new TypeError('missing or invalid "uri" parameter');
- } // Initialize parameters.
- this._uri = uri;
- this._parameters = {};
- this._display_name = display_name;
- for (var param in parameters) {
- if (Object.prototype.hasOwnProperty.call(parameters, param)) {
- this.setParam(param, parameters[param]);
- }
- }
- }
- _createClass(NameAddrHeader, [{
- key: "setParam",
- value: function setParam(key, value) {
- if (key) {
- this._parameters[key.toLowerCase()] = typeof value === 'undefined' || value === null ? null : value.toString();
- }
- }
- }, {
- key: "getParam",
- value: function getParam(key) {
- if (key) {
- return this._parameters[key.toLowerCase()];
- }
- }
- }, {
- key: "hasParam",
- value: function hasParam(key) {
- if (key) {
- return this._parameters.hasOwnProperty(key.toLowerCase()) && true || false;
- }
- }
- }, {
- key: "deleteParam",
- value: function deleteParam(parameter) {
- parameter = parameter.toLowerCase();
- if (this._parameters.hasOwnProperty(parameter)) {
- var value = this._parameters[parameter];
- delete this._parameters[parameter];
- return value;
- }
- }
- }, {
- key: "clearParams",
- value: function clearParams() {
- this._parameters = {};
- }
- }, {
- key: "clone",
- value: function clone() {
- return new NameAddrHeader(this._uri.clone(), this._display_name, JSON.parse(JSON.stringify(this._parameters)));
- }
- }, {
- key: "toString",
- value: function toString() {
- var body = this._display_name || this._display_name === 0 ? "\"".concat(this._display_name, "\" ") : '';
- body += "<".concat(this._uri.toString(), ">");
- for (var parameter in this._parameters) {
- if (Object.prototype.hasOwnProperty.call(this._parameters, parameter)) {
- body += ";".concat(parameter);
- if (this._parameters[parameter] !== null) {
- body += "=".concat(this._parameters[parameter]);
- }
- }
- }
- return body;
- }
- }, {
- key: "uri",
- get: function get() {
- return this._uri;
- }
- }, {
- key: "display_name",
- get: function get() {
- return this._display_name;
- },
- set: function set(value) {
- this._display_name = value === 0 ? '0' : value;
- }
- }]);
- return NameAddrHeader;
- }();
- }),
- /* 12 */
- (function(module, exports) {
- module.exports = {"_from":"jssip","_id":"jssip@3.3.3","_inBundle":false,"_integrity":"sha512-SL+JkaY3w0n5Bbg7/NL/3wPTcjnkGM5IKUm6VRYYRyQTDiTR0ezLeqGjWACK2O/brT5l2QfR46AZ1iXMSLl4Dg==","_location":"/jssip","_phantomChildren":{"ms":"2.1.1"},"_requested":{"type":"tag","registry":true,"raw":"jssip","name":"jssip","escapedName":"jssip","rawSpec":"","saveSpec":null,"fetchSpec":"latest"},"_requiredBy":["#USER","/"],"_resolved":"https://registry.npmjs.org/jssip/-/jssip-3.3.3.tgz","_shasum":"d111efe06c926bf6752726668cf9e35f0c2f94fa","_spec":"jssip","_where":"/Users/entronica/eclipse-workspace/phone-js","author":{"name":"José Luis Millán","email":"jmillan@aliax.net","url":"https://github.com/jmillan"},"bugs":{"url":"https://github.com/versatica/JsSIP/issues"},"bundleDependencies":false,"contributors":[{"name":"Iñaki Baz Castillo","email":"ibc@aliax.net","url":"https://github.com/ibc"},{"name":"Saúl Ibarra Corretgé","email":"saghul@gmail.com","url":"https://github.com/saghul"}],"dependencies":{"debug":"^4.1.1","events":"^3.0.0","sdp-transform":"^2.7.0"},"deprecated":false,"description":"the Javascript SIP library","devDependencies":{"@babel/core":"^7.2.2","@babel/preset-env":"^7.2.3","ansi-colors":"^3.2.3","browserify":"^16.2.3","eslint":"^5.11.1","fancy-log":"^1.3.3","gulp":"^4.0.0","gulp-babel":"^8.0.0","gulp-eslint":"^5.0.0","gulp-expect-file":"^1.0.0","gulp-header":"^2.0.7","gulp-nodeunit-runner":"^0.2.2","gulp-plumber":"^1.2.1","gulp-rename":"^1.4.0","gulp-uglify-es":"^1.0.4","pegjs":"^0.7.0","vinyl-buffer":"^1.0.1","vinyl-source-stream":"^2.0.0"},"homepage":"https://jssip.net","keywords":["sip","websocket","webrtc","node","browser","library"],"license":"MIT","main":"lib-es5/JsSIP.js","name":"jssip","repository":{"type":"git","url":"git+https://github.com/versatica/JsSIP.git"},"scripts":{"prepublishOnly":"gulp babel","test":"gulp test"},"title":"JsSIP","version":"3.3.3"}
- }),
- /* 13 */
- (function(module, exports, __webpack_require__) {
- var parser = __webpack_require__(27);
- var writer = __webpack_require__(28);
- exports.write = writer;
- exports.parse = parser.parse;
- exports.parseFmtpConfig = parser.parseFmtpConfig;
- exports.parseParams = parser.parseParams;
- exports.parsePayloads = parser.parsePayloads;
- exports.parseRemoteCandidates = parser.parseRemoteCandidates;
- exports.parseImageAttributes = parser.parseImageAttributes;
- exports.parseSimulcastStreamList = parser.parseSimulcastStreamList;
- }),
- /* 14 */
- (function(module, exports) {
- var grammar = module.exports = {
- v: [{
- name: 'version',
- reg: /^(\d*)$/
- }],
- o: [{
- //o=- 20518 0 IN IP4 203.0.113.1
- // NB: sessionId will be a String in most cases because it is huge
- name: 'origin',
- reg: /^(\S*) (\d*) (\d*) (\S*) IP(\d) (\S*)/,
- names: ['username', 'sessionId', 'sessionVersion', 'netType', 'ipVer', 'address'],
- format: '%s %s %d %s IP%d %s'
- }],
- // default parsing of these only (though some of these feel outdated)
- s: [{
- name: 'name'
- }],
- i: [{
- name: 'description'
- }],
- u: [{
- name: 'uri'
- }],
- e: [{
- name: 'email'
- }],
- p: [{
- name: 'phone'
- }],
- z: [{
- name: 'timezones'
- }],
- // TODO: this one can actually be parsed properly..
- r: [{
- name: 'repeats'
- }],
- // TODO: this one can also be parsed properly
- //k: [{}], // outdated thing ignored
- t: [{
- //t=0 0
- name: 'timing',
- reg: /^(\d*) (\d*)/,
- names: ['start', 'stop'],
- format: '%d %d'
- }],
- c: [{
- //c=IN IP4 10.47.197.26
- name: 'connection',
- reg: /^IN IP(\d) (\S*)/,
- names: ['version', 'ip'],
- format: 'IN IP%d %s'
- }],
- b: [{
- //b=AS:4000
- push: 'bandwidth',
- reg: /^(TIAS|AS|CT|RR|RS):(\d*)/,
- names: ['type', 'limit'],
- format: '%s:%s'
- }],
- m: [{
- //m=video 51744 RTP/AVP 126 97 98 34 31
- // NB: special - pushes to session
- // TODO: rtp/fmtp should be filtered by the payloads found here?
- reg: /^(\w*) (\d*) ([\w\/]*)(?: (.*))?/,
- names: ['type', 'port', 'protocol', 'payloads'],
- format: '%s %d %s %s'
- }],
- a: [{
- //a=rtpmap:110 opus/48000/2
- push: 'rtp',
- reg: /^rtpmap:(\d*) ([\w\-\.]*)(?:\s*\/(\d*)(?:\s*\/(\S*))?)?/,
- names: ['payload', 'codec', 'rate', 'encoding'],
- format: function (o) {
- return o.encoding ? 'rtpmap:%d %s/%s/%s' : o.rate ? 'rtpmap:%d %s/%s' : 'rtpmap:%d %s';
- }
- }, {
- //a=fmtp:108 profile-level-id=24;object=23;bitrate=64000
- //a=fmtp:111 minptime=10; useinbandfec=1
- push: 'fmtp',
- reg: /^fmtp:(\d*) ([\S| ]*)/,
- names: ['payload', 'config'],
- format: 'fmtp:%d %s'
- }, {
- //a=control:streamid=0
- name: 'control',
- reg: /^control:(.*)/,
- format: 'control:%s'
- }, {
- //a=rtcp:65179 IN IP4 193.84.77.194
- name: 'rtcp',
- reg: /^rtcp:(\d*)(?: (\S*) IP(\d) (\S*))?/,
- names: ['port', 'netType', 'ipVer', 'address'],
- format: function (o) {
- return o.address != null ? 'rtcp:%d %s IP%d %s' : 'rtcp:%d';
- }
- }, {
- //a=rtcp-fb:98 trr-int 100
- push: 'rtcpFbTrrInt',
- reg: /^rtcp-fb:(\*|\d*) trr-int (\d*)/,
- names: ['payload', 'value'],
- format: 'rtcp-fb:%d trr-int %d'
- }, {
- //a=rtcp-fb:98 nack rpsi
- push: 'rtcpFb',
- reg: /^rtcp-fb:(\*|\d*) ([\w-_]*)(?: ([\w-_]*))?/,
- names: ['payload', 'type', 'subtype'],
- format: function (o) {
- return o.subtype != null ? 'rtcp-fb:%s %s %s' : 'rtcp-fb:%s %s';
- }
- }, {
- //a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
- //a=extmap:1/recvonly URI-gps-string
- push: 'ext',
- reg: /^extmap:(\d+)(?:\/(\w+))? (\S*)(?: (\S*))?/,
- names: ['value', 'direction', 'uri', 'config'],
- format: function (o) {
- return 'extmap:%d' + (o.direction ? '/%s' : '%v') + ' %s' + (o.config ? ' %s' : '');
- }
- }, {
- //a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32
- push: 'crypto',
- reg: /^crypto:(\d*) ([\w_]*) (\S*)(?: (\S*))?/,
- names: ['id', 'suite', 'config', 'sessionConfig'],
- format: function (o) {
- return o.sessionConfig != null ? 'crypto:%d %s %s %s' : 'crypto:%d %s %s';
- }
- }, {
- //a=setup:actpass
- name: 'setup',
- reg: /^setup:(\w*)/,
- format: 'setup:%s'
- }, {
- //a=mid:1
- name: 'mid',
- reg: /^mid:([^\s]*)/,
- format: 'mid:%s'
- }, {
- //a=msid:0c8b064d-d807-43b4-b434-f92a889d8587 98178685-d409-46e0-8e16-7ef0db0db64a
- name: 'msid',
- reg: /^msid:(.*)/,
- format: 'msid:%s'
- }, {
- //a=ptime:20
- name: 'ptime',
- reg: /^ptime:(\d*)/,
- format: 'ptime:%d'
- }, {
- //a=maxptime:60
- name: 'maxptime',
- reg: /^maxptime:(\d*)/,
- format: 'maxptime:%d'
- }, {
- //a=sendrecv
- name: 'direction',
- reg: /^(sendrecv|recvonly|sendonly|inactive)/
- }, {
- //a=ice-lite
- name: 'icelite',
- reg: /^(ice-lite)/
- }, {
- //a=ice-ufrag:F7gI
- name: 'iceUfrag',
- reg: /^ice-ufrag:(\S*)/,
- format: 'ice-ufrag:%s'
- }, {
- //a=ice-pwd:x9cml/YzichV2+XlhiMu8g
- name: 'icePwd',
- reg: /^ice-pwd:(\S*)/,
- format: 'ice-pwd:%s'
- }, {
- //a=fingerprint:SHA-1 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33
- name: 'fingerprint',
- reg: /^fingerprint:(\S*) (\S*)/,
- names: ['type', 'hash'],
- format: 'fingerprint:%s %s'
- }, {
- //a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host
- //a=candidate:1162875081 1 udp 2113937151 192.168.34.75 60017 typ host generation 0 network-id 3 network-cost 10
- //a=candidate:3289912957 2 udp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 generation 0 network-id 3 network-cost 10
- //a=candidate:229815620 1 tcp 1518280447 192.168.150.19 60017 typ host tcptype active generation 0 network-id 3 network-cost 10
- //a=candidate:3289912957 2 tcp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 tcptype passive generation 0 network-id 3 network-cost 10
- push: 'candidates',
- reg: /^candidate:(\S*) (\d*) (\S*) (\d*) (\S*) (\d*) typ (\S*)(?: raddr (\S*) rport (\d*))?(?: tcptype (\S*))?(?: generation (\d*))?(?: network-id (\d*))?(?: network-cost (\d*))?/,
- names: ['foundation', 'component', 'transport', 'priority', 'ip', 'port', 'type', 'raddr', 'rport', 'tcptype', 'generation', 'network-id', 'network-cost'],
- format: function (o) {
- var str = 'candidate:%s %d %s %d %s %d typ %s';
- str += o.raddr != null ? ' raddr %s rport %d' : '%v%v'; // NB: candidate has three optional chunks, so %void middles one if it's missing
- str += o.tcptype != null ? ' tcptype %s' : '%v';
- if (o.generation != null) {
- str += ' generation %d';
- }
- str += o['network-id'] != null ? ' network-id %d' : '%v';
- str += o['network-cost'] != null ? ' network-cost %d' : '%v';
- return str;
- }
- }, {
- //a=end-of-candidates (keep after the candidates line for readability)
- name: 'endOfCandidates',
- reg: /^(end-of-candidates)/
- }, {
- //a=remote-candidates:1 203.0.113.1 54400 2 203.0.113.1 54401 ...
- name: 'remoteCandidates',
- reg: /^remote-candidates:(.*)/,
- format: 'remote-candidates:%s'
- }, {
- //a=ice-options:google-ice
- name: 'iceOptions',
- reg: /^ice-options:(\S*)/,
- format: 'ice-options:%s'
- }, {
- //a=ssrc:2566107569 cname:t9YU8M1UxTF8Y1A1
- push: 'ssrcs',
- reg: /^ssrc:(\d*) ([\w_-]*)(?::(.*))?/,
- names: ['id', 'attribute', 'value'],
- format: function (o) {
- var str = 'ssrc:%d';
- if (o.attribute != null) {
- str += ' %s';
- if (o.value != null) {
- str += ':%s';
- }
- }
- return str;
- }
- }, {
- //a=ssrc-group:FEC 1 2
- //a=ssrc-group:FEC-FR 3004364195 1080772241
- push: 'ssrcGroups',
- // token-char = %x21 / %x23-27 / %x2A-2B / %x2D-2E / %x30-39 / %x41-5A / %x5E-7E
- reg: /^ssrc-group:([\x21\x23\x24\x25\x26\x27\x2A\x2B\x2D\x2E\w]*) (.*)/,
- names: ['semantics', 'ssrcs'],
- format: 'ssrc-group:%s %s'
- }, {
- //a=msid-semantic: WMS Jvlam5X3SX1OP6pn20zWogvaKJz5Hjf9OnlV
- name: 'msidSemantic',
- reg: /^msid-semantic:\s?(\w*) (\S*)/,
- names: ['semantic', 'token'],
- format: 'msid-semantic: %s %s' // space after ':' is not accidental
- }, {
- //a=group:BUNDLE audio video
- push: 'groups',
- reg: /^group:(\w*) (.*)/,
- names: ['type', 'mids'],
- format: 'group:%s %s'
- }, {
- //a=rtcp-mux
- name: 'rtcpMux',
- reg: /^(rtcp-mux)/
- }, {
- //a=rtcp-rsize
- name: 'rtcpRsize',
- reg: /^(rtcp-rsize)/
- }, {
- //a=sctpmap:5000 webrtc-datachannel 1024
- name: 'sctpmap',
- reg: /^sctpmap:([\w_\/]*) (\S*)(?: (\S*))?/,
- names: ['sctpmapNumber', 'app', 'maxMessageSize'],
- format: function (o) {
- return o.maxMessageSize != null ? 'sctpmap:%s %s %s' : 'sctpmap:%s %s';
- }
- }, {
- //a=x-google-flag:conference
- name: 'xGoogleFlag',
- reg: /^x-google-flag:([^\s]*)/,
- format: 'x-google-flag:%s'
- }, {
- //a=rid:1 send max-width=1280;max-height=720;max-fps=30;depend=0
- push: 'rids',
- reg: /^rid:([\d\w]+) (\w+)(?: ([\S| ]*))?/,
- names: ['id', 'direction', 'params'],
- format: function (o) {
- return o.params ? 'rid:%s %s %s' : 'rid:%s %s';
- }
- }, {
- //a=imageattr:97 send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320] recv [x=330,y=250]
- //a=imageattr:* send [x=800,y=640] recv *
- //a=imageattr:100 recv [x=320,y=240]
- push: 'imageattrs',
- reg: new RegExp( //a=imageattr:97
- '^imageattr:(\\d+|\\*)' + //send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320]
- '[\\s\\t]+(send|recv)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*)' + //recv [x=330,y=250]
- '(?:[\\s\\t]+(recv|send)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*))?'),
- names: ['pt', 'dir1', 'attrs1', 'dir2', 'attrs2'],
- format: function (o) {
- return 'imageattr:%s %s %s' + (o.dir2 ? ' %s %s' : '');
- }
- }, {
- //a=simulcast:send 1,2,3;~4,~5 recv 6;~7,~8
- //a=simulcast:recv 1;4,5 send 6;7
- name: 'simulcast',
- reg: new RegExp( //a=simulcast:
- '^simulcast:' + //send 1,2,3;~4,~5
- '(send|recv) ([a-zA-Z0-9\\-_~;,]+)' + //space + recv 6;~7,~8
- '(?:\\s?(send|recv) ([a-zA-Z0-9\\-_~;,]+))?' + //end
- '$'),
- names: ['dir1', 'list1', 'dir2', 'list2'],
- format: function (o) {
- return 'simulcast:%s %s' + (o.dir2 ? ' %s %s' : '');
- }
- }, {
- //Old simulcast draft 03 (implemented by Firefox)
- // https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-03
- //a=simulcast: recv pt=97;98 send pt=97
- //a=simulcast: send rid=5;6;7 paused=6,7
- name: 'simulcast_03',
- reg: /^simulcast:[\s\t]+([\S+\s\t]+)$/,
- names: ['value'],
- format: 'simulcast: %s'
- }, {
- //a=framerate:25
- //a=framerate:29.97
- name: 'framerate',
- reg: /^framerate:(\d+(?:$|\.\d+))/,
- format: 'framerate:%s'
- }, {
- // RFC4570
- //a=source-filter: incl IN IP4 239.5.2.31 10.1.15.5
- name: 'sourceFilter',
- reg: /^source-filter: *(excl|incl) (\S*) (IP4|IP6|\*) (\S*) (.*)/,
- names: ['filterMode', 'netType', 'addressTypes', 'destAddress', 'srcList'],
- format: 'source-filter: %s %s %s %s %s'
- }, {
- //a=bundle-only
- name: 'bundleOnly',
- reg: /^(bundle-only)/
- }, {
- //a=label:1
- name: 'label',
- reg: /^label:(.+)/,
- format: 'label:%s'
- }, {
- // RFC version 26 for SCTP over DTLS
- // https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-5
- name: 'sctpPort',
- reg: /^sctp-port:(\d+)$/,
- format: 'sctp-port:%s'
- }, {
- // RFC version 26 for SCTP over DTLS
- // https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-6
- name: 'maxMessageSize',
- reg: /^max-message-size:(\d+)$/,
- format: 'max-message-size:%s'
- }, {
- // any a= that we don't understand is kepts verbatim on media.invalid
- push: 'invalid',
- names: ['value']
- }]
- }; // set sensible defaults to avoid polluting the grammar with boring details
- Object.keys(grammar).forEach(function (key) {
- var objs = grammar[key];
- objs.forEach(function (obj) {
- if (!obj.reg) {
- obj.reg = /(.*)/;
- }
- if (!obj.format) {
- obj.format = '%s';
- }
- });
- });
- }),
- /* 15 */
- (function(module, exports) {
- // shim for using process in browser
- var process = module.exports = {}; // cached from whatever global is present so that test runners that stub it
- // don't break things. But we need to wrap it in a try catch in case it is
- // wrapped in strict mode code which doesn't define any globals. It's inside a
- // function because try/catches deoptimize in certain engines.
- var cachedSetTimeout;
- var cachedClearTimeout;
- function defaultSetTimout() {
- throw new Error('setTimeout has not been defined');
- }
- function defaultClearTimeout() {
- throw new Error('clearTimeout has not been defined');
- }
- (function () {
- try {
- if (typeof setTimeout === 'function') {
- cachedSetTimeout = setTimeout;
- } else {
- cachedSetTimeout = defaultSetTimout;
- }
- } catch (e) {
- cachedSetTimeout = defaultSetTimout;
- }
- try {
- if (typeof clearTimeout === 'function') {
- cachedClearTimeout = clearTimeout;
- } else {
- cachedClearTimeout = defaultClearTimeout;
- }
- } catch (e) {
- cachedClearTimeout = defaultClearTimeout;
- }
- })();
- function runTimeout(fun) {
- if (cachedSetTimeout === setTimeout) {
- //normal enviroments in sane situations
- return setTimeout(fun, 0);
- } // if setTimeout wasn't available but was latter defined
- if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
- cachedSetTimeout = setTimeout;
- return setTimeout(fun, 0);
- }
- try {
- // when when somebody has screwed with setTimeout but no I.E. maddness
- return cachedSetTimeout(fun, 0);
- } catch (e) {
- try {
- // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
- return cachedSetTimeout.call(null, fun, 0);
- } catch (e) {
- // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
- return cachedSetTimeout.call(this, fun, 0);
- }
- }
- }
- function runClearTimeout(marker) {
- if (cachedClearTimeout === clearTimeout) {
- //normal enviroments in sane situations
- return clearTimeout(marker);
- } // if clearTimeout wasn't available but was latter defined
- if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
- cachedClearTimeout = clearTimeout;
- return clearTimeout(marker);
- }
- try {
- // when when somebody has screwed with setTimeout but no I.E. maddness
- return cachedClearTimeout(marker);
- } catch (e) {
- try {
- // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
- return cachedClearTimeout.call(null, marker);
- } catch (e) {
- // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
- // Some versions of I.E. have different rules for clearTimeout vs setTimeout
- return cachedClearTimeout.call(this, marker);
- }
- }
- }
- var queue = [];
- var draining = false;
- var currentQueue;
- var queueIndex = -1;
- function cleanUpNextTick() {
- if (!draining || !currentQueue) {
- return;
- }
- draining = false;
- if (currentQueue.length) {
- queue = currentQueue.concat(queue);
- } else {
- queueIndex = -1;
- }
- if (queue.length) {
- drainQueue();
- }
- }
- function drainQueue() {
- if (draining) {
- return;
- }
- var timeout = runTimeout(cleanUpNextTick);
- draining = true;
- var len = queue.length;
- while (len) {
- currentQueue = queue;
- queue = [];
- while (++queueIndex < len) {
- if (currentQueue) {
- currentQueue[queueIndex].run();
- }
- }
- queueIndex = -1;
- len = queue.length;
- }
- currentQueue = null;
- draining = false;
- runClearTimeout(timeout);
- }
- process.nextTick = function (fun) {
- var args = new Array(arguments.length - 1);
- if (arguments.length > 1) {
- for (var i = 1; i < arguments.length; i++) {
- args[i - 1] = arguments[i];
- }
- }
- queue.push(new Item(fun, args));
- if (queue.length === 1 && !draining) {
- runTimeout(drainQueue);
- }
- }; // v8 likes predictible objects
- function Item(fun, array) {
- this.fun = fun;
- this.array = array;
- }
- Item.prototype.run = function () {
- this.fun.apply(null, this.array);
- };
- process.title = 'browser';
- process.browser = true;
- process.env = {};
- process.argv = [];
- process.version = ''; // empty string to avoid regexp issues
- process.versions = {};
- function noop() {}
- process.on = noop;
- process.addListener = noop;
- process.once = noop;
- process.off = noop;
- process.removeListener = noop;
- process.removeAllListeners = noop;
- process.emit = noop;
- process.prependListener = noop;
- process.prependOnceListener = noop;
- process.listeners = function (name) {
- return [];
- };
- process.binding = function (name) {
- throw new Error('process.binding is not supported');
- };
- process.cwd = function () {
- return '/';
- };
- process.chdir = function (dir) {
- throw new Error('process.chdir is not supported');
- };
- process.umask = function () {
- return 0;
- };
- }),
- /* 16 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- var T1 = 500,
- T2 = 4000,
- T4 = 5000;
- module.exports = {
- T1: T1,
- T2: T2,
- T4: T4,
- TIMER_B: 64 * T1,
- TIMER_D: 0 * T1,
- TIMER_F: 64 * T1,
- TIMER_H: 64 * T1,
- TIMER_I: 0 * T1,
- TIMER_J: 0 * T1,
- TIMER_K: 0 * T4,
- TIMER_L: 64 * T1,
- TIMER_M: 64 * T1,
- PROVISIONAL_RESPONSE_INTERVAL: 60000 // See RFC 3261 Section 13.3.1.1
- };
- }),
- /* 17 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _typeof(obj) {
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
- _typeof = function _typeof(obj) {
- return typeof obj;
- };
- } else {
- _typeof = function _typeof(obj) {
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
- };
- }
- return _typeof(obj);
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _possibleConstructorReturn(self, call) {
- if (call && (_typeof(call) === "object" || typeof call === "function")) {
- return call;
- }
- return _assertThisInitialized(self);
- }
- function _assertThisInitialized(self) {
- if (self === void 0) {
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- }
- return self;
- }
- function _getPrototypeOf(o) {
- _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
- return o.__proto__ || Object.getPrototypeOf(o);
- };
- return _getPrototypeOf(o);
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- function _inherits(subClass, superClass) {
- if (typeof superClass !== "function" && superClass !== null) {
- throw new TypeError("Super expression must either be null or a function");
- }
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- writable: true,
- configurable: true
- }
- });
- if (superClass) _setPrototypeOf(subClass, superClass);
- }
- function _setPrototypeOf(o, p) {
- _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
- o.__proto__ = p;
- return o;
- };
- return _setPrototypeOf(o, p);
- }
- /* globals RTCPeerConnection: false, RTCSessionDescription: false */
- var EventEmitter = __webpack_require__(7).EventEmitter;
- var sdp_transform = __webpack_require__(13);
- var JsSIP_C = __webpack_require__(1);
- var Exceptions = __webpack_require__(6);
- var Transactions = __webpack_require__(9);
- var Utils = __webpack_require__(2);
- var Timers = __webpack_require__(16);
- var SIPMessage = __webpack_require__(5);
- var Dialog = __webpack_require__(32);
- var RequestSender = __webpack_require__(10);
- var RTCSession_DTMF = __webpack_require__(34);
- var RTCSession_Info = __webpack_require__(35);
- var RTCSession_ReferNotifier = __webpack_require__(36);
- var RTCSession_ReferSubscriber = __webpack_require__(37);
- var debug = __webpack_require__(0)('JsSIP:RTCSession');
- var debugerror = __webpack_require__(0)('JsSIP:ERROR:RTCSession');
- var PhoneLogger = __webpack_require__(59);
- var PhoneNetwork = __webpack_require__(61);
- debugerror.log = console.warn.bind(console);
- var C = {
- // RTCSession states.
- STATUS_NULL: 0,
- STATUS_INVITE_SENT: 1,
- STATUS_1XX_RECEIVED: 2,
- STATUS_INVITE_RECEIVED: 3,
- STATUS_WAITING_FOR_ANSWER: 4,
- STATUS_ANSWERED: 5,
- STATUS_WAITING_FOR_ACK: 6,
- STATUS_CANCELED: 7,
- STATUS_TERMINATED: 8,
- STATUS_CONFIRMED: 9
- };
- /**
- * Local variables.
- */
- var holdMediaTypes = ['audio', 'video'];
- module.exports =
- /*#__PURE__*/
- function (_EventEmitter) {
- _inherits(RTCSession, _EventEmitter);
- _createClass(RTCSession, null, [{
- key: "C",
- /**
- * Expose C object.
- */
- get: function get() {
- return C;
- }
- }]);
- function RTCSession(ua) {
- var _this;
- _classCallCheck(this, RTCSession);
- debug('new');
- _this = _possibleConstructorReturn(this, _getPrototypeOf(RTCSession).call(this));
- _this._id = null;
- _this._ua = ua;
- _this._status = C.STATUS_NULL;
- _this._dialog = null;
- _this._earlyDialogs = {};
- _this._contact = null;
- _this._from_tag = null;
- _this._to_tag = null; // The RTCPeerConnection instance (public attribute).
- _this._connection = null; // Prevent races on serial PeerConnction operations.
- _this._connectionPromiseQueue = Promise.resolve(); // Incoming/Outgoing request being currently processed.
- _this._request = null; // Cancel state for initial outgoing request.
- _this._is_canceled = false;
- _this._cancel_reason = ''; // RTCSession confirmation flag.
- _this._is_confirmed = false; // Is late SDP being negotiated.
- _this._late_sdp = false; // Default rtcOfferConstraints and rtcAnswerConstrainsts (passed in connect() or answer()).
- _this._rtcOfferConstraints = null;
- _this._rtcAnswerConstraints = null; // Local MediaStream.
- _this._localMediaStream = null;
- _this._localMediaStreamLocallyGenerated = false; // Flag to indicate PeerConnection ready for new actions.
- _this._rtcReady = true; // SIP Timers.
- _this._timers = {
- ackTimer: null,
- expiresTimer: null,
- invite2xxTimer: null,
- userNoAnswerTimer: null
- }; // Session info.
- _this._direction = null;
- _this._local_identity = null;
- _this._remote_identity = null;
- _this._start_time = null;
- _this._end_time = null;
- _this._tones = null; // Mute/Hold state.
- _this._audioMuted = false;
- _this._videoMuted = false;
- _this._localHold = false;
- _this._remoteHold = false; // Session Timers (RFC 4028).
- _this._sessionTimers = {
- enabled: _this._ua.configuration.session_timers,
- refreshMethod: _this._ua.configuration.session_timers_refresh_method,
- defaultExpires: JsSIP_C.SESSION_EXPIRES,
- currentExpires: null,
- running: false,
- refresher: false,
- timer: null // A setTimeout.
- }; // Map of ReferSubscriber instances indexed by the REFER's CSeq number.
- _this._referSubscribers = {}; // Custom session empty object for high level use.
- _this._data = {};
- return _this;
- }
- /**
- * User API
- */
- // Expose RTCSession constants as a property of the RTCSession instance.
- _createClass(RTCSession, [{
- key: "isInProgress",
- value: function isInProgress() {
- switch (this._status) {
- case C.STATUS_NULL:
- case C.STATUS_INVITE_SENT:
- case C.STATUS_1XX_RECEIVED:
- case C.STATUS_INVITE_RECEIVED:
- case C.STATUS_WAITING_FOR_ANSWER:
- return true;
- default:
- return false;
- }
- }
- }, {
- key: "isEstablished",
- value: function isEstablished() {
- switch (this._status) {
- case C.STATUS_ANSWERED:
- case C.STATUS_WAITING_FOR_ACK:
- case C.STATUS_CONFIRMED:
- return true;
- default:
- return false;
- }
- }
- }, {
- key: "isEnded",
- value: function isEnded() {
- switch (this._status) {
- case C.STATUS_CANCELED:
- case C.STATUS_TERMINATED:
- return true;
- default:
- return false;
- }
- }
- }, {
- key: "isMuted",
- value: function isMuted() {
- return {
- audio: this._audioMuted,
- video: this._videoMuted
- };
- }
- }, {
- key: "isOnHold",
- value: function isOnHold() {
- return {
- local: this._localHold,
- remote: this._remoteHold
- };
- }
- }, {
- key: "connect",
- value: function connect(target) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- var initCallback = arguments.length > 2 ? arguments[2] : undefined;
- debug('connect()');
- var originalTarget = target;
- var eventHandlers = options.eventHandlers || {};
- var extraHeaders = Utils.cloneArray(options.extraHeaders);
- var mediaConstraints = options.mediaConstraints || {
- audio: true,
- video: true
- };
- var mediaStream = options.mediaStream || null;
- var pcConfig = options.pcConfig || {
- iceServers: []
- };
- var rtcConstraints = options.rtcConstraints || null;
- var rtcOfferConstraints = options.rtcOfferConstraints || null;
- this._rtcOfferConstraints = rtcOfferConstraints;
- this._rtcAnswerConstraints = options.rtcAnswerConstraints || null;
- this._data = options.data || this._data; // Check target.
- if (target === undefined) {
- throw new TypeError('Not enough arguments');
- } // Check Session Status.
- if (this._status !== C.STATUS_NULL) {
- throw new Exceptions.InvalidStateError(this._status);
- } // Check WebRTC support.
- if (!window.RTCPeerConnection) {
- throw new Exceptions.NotSupportedError('WebRTC not supported');
- } // Check target validity.
- target = this._ua.normalizeTarget(target);
- if (!target) {
- throw new TypeError("Invalid target: ".concat(originalTarget));
- } // Session Timers.
- if (this._sessionTimers.enabled) {
- if (Utils.isDecimal(options.sessionTimersExpires)) {
- if (options.sessionTimersExpires >= JsSIP_C.MIN_SESSION_EXPIRES) {
- this._sessionTimers.defaultExpires = options.sessionTimersExpires;
- } else {
- this._sessionTimers.defaultExpires = JsSIP_C.SESSION_EXPIRES;
- }
- }
- } // Set event handlers.
- for (var event in eventHandlers) {
- if (Object.prototype.hasOwnProperty.call(eventHandlers, event)) {
- this.on(event, eventHandlers[event]);
- }
- } // Session parameter initialization.
- this._from_tag = Utils.newTag(); // Set anonymous property.
- var anonymous = options.anonymous || false;
- var requestParams = {
- from_tag: this._from_tag
- };
- this._contact = this._ua.contact.toString({
- anonymous: anonymous,
- outbound: true
- });
- if (anonymous) {
- requestParams.from_display_name = 'Anonymous';
- requestParams.from_uri = 'sip:anonymous@anonymous.invalid';
- extraHeaders.push("P-Preferred-Identity: ".concat(this._ua.configuration.uri.toString()));
- extraHeaders.push('Privacy: id');
- }
- extraHeaders.push("Contact: ".concat(this._contact));
- extraHeaders.push('Content-Type: application/sdp');
- if (this._sessionTimers.enabled) {
- extraHeaders.push("Session-Expires: ".concat(this._sessionTimers.defaultExpires));
- }
- this._request = new SIPMessage.InitialOutgoingInviteRequest(target, this._ua, requestParams, extraHeaders);
- this._id = this._request.call_id + this._from_tag; // Create a new RTCPeerConnection instance.
- this._createRTCConnection(pcConfig, rtcConstraints); // Set internal properties.
- this._direction = 'outgoing';
- this._local_identity = this._request.from;
- this._remote_identity = this._request.to; // User explicitly provided a newRTCSession callback for this session.
- if (initCallback) {
- initCallback(this);
- }
- this._newRTCSession('local', this._request);
- this._sendInitialRequest(mediaConstraints, rtcOfferConstraints, mediaStream);
- }
- }, {
- key: "init_incoming",
- value: function init_incoming(request, initCallback) {
- var _this2 = this;
- debug('init_incoming()');
- var expires;
- var contentType = request.getHeader('Content-Type'); // Check body and content type.
- if (request.body && contentType !== 'application/sdp') {
- request.reply(415);
- return;
- } // Session parameter initialization.
- this._status = C.STATUS_INVITE_RECEIVED;
- this._from_tag = request.from_tag;
- this._id = request.call_id + this._from_tag;
- this._request = request;
- this._contact = this._ua.contact.toString(); // Get the Expires header value if exists.
- if (request.hasHeader('expires')) {
- expires = request.getHeader('expires') * 1000;
- }
- /* Set the to_tag before
- * replying a response code that will create a dialog.
- */
- request.to_tag = Utils.newTag(); // An error on dialog creation will fire 'failed' event.
- if (!this._createDialog(request, 'UAS', true)) {
- request.reply(500, 'Missing Contact header field');
- return;
- }
- if (request.body) {
- this._late_sdp = false;
- } else {
- this._late_sdp = true;
- }
- this._status = C.STATUS_WAITING_FOR_ANSWER; // Set userNoAnswerTimer.
- this._timers.userNoAnswerTimer = setTimeout(function () {
- request.reply(408);
- _this2._failed('local', null, JsSIP_C.causes.NO_ANSWER);
- }, this._ua.configuration.no_answer_timeout);
- /* Set expiresTimer
- * RFC3261 13.3.1
- */
- if (expires) {
- this._timers.expiresTimer = setTimeout(function () {
- if (_this2._status === C.STATUS_WAITING_FOR_ANSWER) {
- request.reply(487);
- _this2._failed('system', null, JsSIP_C.causes.EXPIRES);
- }
- }, expires);
- } // Set internal properties.
- this._direction = 'incoming';
- this._local_identity = request.to;
- this._remote_identity = request.from; // A init callback was specifically defined.
- if (initCallback) {
- initCallback(this);
- } // Fire 'newRTCSession' event.
- this._newRTCSession('remote', request); // The user may have rejected the call in the 'newRTCSession' event.
- if (this._status === C.STATUS_TERMINATED) {
- return;
- } // Reply 180.
- request.reply(180, null, ["Contact: ".concat(this._contact)]); // Fire 'progress' event.
- // TODO: Document that 'response' field in 'progress' event is null for incoming calls.
- this._progress('local', null);
- }
- /**
- * Answer the call.
- */
- }, {
- key: "answer",
- value: function answer() {
- var _this3 = this;
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- debug('answer()');
- var request = this._request;
- var extraHeaders = Utils.cloneArray(options.extraHeaders);
- var mediaConstraints = options.mediaConstraints || {};
- var mediaStream = options.mediaStream || null;
- var pcConfig = options.pcConfig || {
- iceServers: []
- };
- var rtcConstraints = options.rtcConstraints || null;
- var rtcAnswerConstraints = options.rtcAnswerConstraints || null;
- var tracks;
- var peerHasAudioLine = false;
- var peerHasVideoLine = false;
- var peerOffersFullAudio = false;
- var peerOffersFullVideo = false;
- this._rtcAnswerConstraints = rtcAnswerConstraints;
- this._rtcOfferConstraints = options.rtcOfferConstraints || null;
- this._data = options.data || this._data; // Check Session Direction and Status.
- if (this._direction !== 'incoming') {
- throw new Exceptions.NotSupportedError('"answer" not supported for outgoing RTCSession');
- } // Check Session status.
- if (this._status !== C.STATUS_WAITING_FOR_ANSWER) {
- throw new Exceptions.InvalidStateError(this._status);
- } // Session Timers.
- if (this._sessionTimers.enabled) {
- if (Utils.isDecimal(options.sessionTimersExpires)) {
- if (options.sessionTimersExpires >= JsSIP_C.MIN_SESSION_EXPIRES) {
- this._sessionTimers.defaultExpires = options.sessionTimersExpires;
- } else {
- this._sessionTimers.defaultExpires = JsSIP_C.SESSION_EXPIRES;
- }
- }
- }
- this._status = C.STATUS_ANSWERED; // An error on dialog creation will fire 'failed' event.
- if (!this._createDialog(request, 'UAS')) {
- request.reply(500, 'Error creating dialog');
- return;
- }
- clearTimeout(this._timers.userNoAnswerTimer);
- extraHeaders.unshift("Contact: ".concat(this._contact)); // Determine incoming media from incoming SDP offer (if any).
- var sdp = request.parseSDP(); // Make sure sdp.media is an array, not the case if there is only one media.
- if (!Array.isArray(sdp.media)) {
- sdp.media = [sdp.media];
- } // Go through all medias in SDP to find offered capabilities to answer with.
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
- try {
- for (var _iterator = sdp.media[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var m = _step.value;
- if (m.type === 'audio') {
- peerHasAudioLine = true;
- if (!m.direction || m.direction === 'sendrecv') {
- peerOffersFullAudio = true;
- }
- }
- if (m.type === 'video') {
- peerHasVideoLine = true;
- if (!m.direction || m.direction === 'sendrecv') {
- peerOffersFullVideo = true;
- }
- }
- } // Remove audio from mediaStream if suggested by mediaConstraints.
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator.return != null) {
- _iterator.return();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
- }
- if (mediaStream && mediaConstraints.audio === false) {
- tracks = mediaStream.getAudioTracks();
- var _iteratorNormalCompletion2 = true;
- var _didIteratorError2 = false;
- var _iteratorError2 = undefined;
- try {
- for (var _iterator2 = tracks[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
- var track = _step2.value;
- mediaStream.removeTrack(track);
- }
- } catch (err) {
- _didIteratorError2 = true;
- _iteratorError2 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
- _iterator2.return();
- }
- } finally {
- if (_didIteratorError2) {
- throw _iteratorError2;
- }
- }
- }
- } // Remove video from mediaStream if suggested by mediaConstraints.
- if (mediaStream && mediaConstraints.video === false) {
- tracks = mediaStream.getVideoTracks();
- var _iteratorNormalCompletion3 = true;
- var _didIteratorError3 = false;
- var _iteratorError3 = undefined;
- try {
- for (var _iterator3 = tracks[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
- var _track = _step3.value;
- mediaStream.removeTrack(_track);
- }
- } catch (err) {
- _didIteratorError3 = true;
- _iteratorError3 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
- _iterator3.return();
- }
- } finally {
- if (_didIteratorError3) {
- throw _iteratorError3;
- }
- }
- }
- } // Set audio constraints based on incoming stream if not supplied.
- if (!mediaStream && mediaConstraints.audio === undefined) {
- mediaConstraints.audio = peerOffersFullAudio;
- } // Set video constraints based on incoming stream if not supplied.
- if (!mediaStream && mediaConstraints.video === undefined) {
- mediaConstraints.video = peerOffersFullVideo;
- } // Don't ask for audio if the incoming offer has no audio section.
- if (!mediaStream && !peerHasAudioLine) {
- mediaConstraints.audio = false;
- } // Don't ask for video if the incoming offer has no video section.
- if (!mediaStream && !peerHasVideoLine) {
- mediaConstraints.video = false;
- } // Create a new RTCPeerConnection instance.
- // TODO: This may throw an error, should react.
- this._createRTCConnection(pcConfig, rtcConstraints);
- Promise.resolve() // Handle local MediaStream.
- .then(function () {
- // A local MediaStream is given, use it.
- if (mediaStream) {
- return mediaStream;
- } // Audio and/or video requested, prompt getUserMedia.
- else if (mediaConstraints.audio || mediaConstraints.video) {
- _this3._localMediaStreamLocallyGenerated = true;
- return navigator.mediaDevices.getUserMedia(mediaConstraints).catch(function (error) {
- if (_this3._status === C.STATUS_TERMINATED) {
- throw new Error('terminated');
- }
- request.reply(480);
- _this3._failed('local', null, JsSIP_C.causes.USER_DENIED_MEDIA_ACCESS);
- debugerror('emit "getusermediafailed" [error:%o]', error);
- _this3.emit('getusermediafailed', error);
- throw new Error('getUserMedia() failed');
- });
- }
- }) // Attach MediaStream to RTCPeerconnection.
- .then(function (stream) {
- if (_this3._status === C.STATUS_TERMINATED) {
- throw new Error('terminated');
- }
- _this3._localMediaStream = stream;
- if (stream) {
- var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
- if(isSafari) {
- _this3._connection.addStream(stream);
- } else {
- stream.getTracks().forEach(function (track) {
- _this3._connection.addTrack(track, stream);
- });
- }
- }
- }) // Set remote description.
- .then(function () {
- if (_this3._late_sdp) {
- return;
- }
- var e = {
- originator: 'remote',
- type: 'offer',
- sdp: request.body
- };
- debug('emit "sdp"');
- _this3.emit('sdp', e);
- var offer = new RTCSessionDescription({
- type: 'offer',
- sdp: e.sdp
- });
- _this3._connectionPromiseQueue = _this3._connectionPromiseQueue.then(function () {
- return _this3._connection.setRemoteDescription(offer);
- }).catch(function (error) {
- request.reply(488);
- _this3._failed('system', null, JsSIP_C.causes.WEBRTC_ERROR);
- debugerror('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error);
- _this3.emit('peerconnection:setremotedescriptionfailed', error);
- throw new Error('peerconnection.setRemoteDescription() failed');
- });
- return _this3._connectionPromiseQueue;
- }) // Create local description.
- .then(function () {
- if (_this3._status === C.STATUS_TERMINATED) {
- throw new Error('terminated');
- } // TODO: Is this event already useful?
- _this3._connecting(request);
- if (!_this3._late_sdp) {
- return _this3._createLocalDescription('answer', rtcAnswerConstraints).catch(function () {
- request.reply(500);
- throw new Error('_createLocalDescription() failed');
- });
- } else {
- return _this3._createLocalDescription('offer', _this3._rtcOfferConstraints).catch(function () {
- request.reply(500);
- throw new Error('_createLocalDescription() failed');
- });
- }
- }) // Send reply.
- .then(function (desc) {
- if (_this3._status === C.STATUS_TERMINATED) {
- throw new Error('terminated');
- }
- _this3._handleSessionTimersInIncomingRequest(request, extraHeaders);
- request.reply(200, null, extraHeaders, desc, function () {
- _this3._status = C.STATUS_WAITING_FOR_ACK;
- _this3._setInvite2xxTimer(request, desc);
- _this3._setACKTimer();
- _this3._accepted('local');
- }, function () {
- _this3._failed('system', null, JsSIP_C.causes.CONNECTION_ERROR);
- });
- }).catch(function (error) {
- if (_this3._status === C.STATUS_TERMINATED) {
- return;
- }
- debugerror(error);
- });
- }
- /**
- * Terminate the call.
- */
- }, {
- key: "terminate",
- value: function terminate() {
- var _this4 = this;
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- debug('terminate()');
- var cause = options.cause || JsSIP_C.causes.BYE;
- var extraHeaders = Utils.cloneArray(options.extraHeaders);
- var body = options.body;
- var cancel_reason;
- var status_code = options.status_code;
- var reason_phrase = options.reason_phrase; // Check Session Status.
- if (this._status === C.STATUS_TERMINATED) {
- throw new Exceptions.InvalidStateError(this._status);
- }
- switch (this._status) {
- // - UAC -
- case C.STATUS_NULL:
- case C.STATUS_INVITE_SENT:
- case C.STATUS_1XX_RECEIVED:
- debug('canceling session');
- if (status_code && (status_code < 200 || status_code >= 700)) {
- throw new TypeError("Invalid status_code: ".concat(status_code));
- } else if (status_code) {
- reason_phrase = reason_phrase || JsSIP_C.REASON_PHRASE[status_code] || '';
- cancel_reason = "SIP ;cause=".concat(status_code, " ;text=\"").concat(reason_phrase, "\"");
- } // Check Session Status.
- if (this._status === C.STATUS_NULL || this._status === C.STATUS_INVITE_SENT) {
- this._is_canceled = true;
- this._cancel_reason = cancel_reason;
- } else if (this._status === C.STATUS_1XX_RECEIVED) {
- this._request.cancel(cancel_reason);
- }
- this._status = C.STATUS_CANCELED;
- this._failed('local', null, JsSIP_C.causes.CANCELED);
- break;
- // - UAS -
- case C.STATUS_WAITING_FOR_ANSWER:
- case C.STATUS_ANSWERED:
- debug('rejecting session');
- status_code = status_code || 480;
- if (status_code < 300 || status_code >= 700) {
- throw new TypeError("Invalid status_code: ".concat(status_code));
- }
- this._request.reply(status_code, reason_phrase, extraHeaders, body);
- this._failed('local', null, JsSIP_C.causes.REJECTED);
- break;
- case C.STATUS_WAITING_FOR_ACK:
- case C.STATUS_CONFIRMED:
- debug('terminating session');
- reason_phrase = options.reason_phrase || JsSIP_C.REASON_PHRASE[status_code] || '';
- if (status_code && (status_code < 200 || status_code >= 700)) {
- throw new TypeError("Invalid status_code: ".concat(status_code));
- } else if (status_code) {
- extraHeaders.push("Reason: SIP ;cause=".concat(status_code, "; text=\"").concat(reason_phrase, "\""));
- }
- /* RFC 3261 section 15 (Terminating a session):
- *
- * "...the callee's UA MUST NOT send a BYE on a confirmed dialog
- * until it has received an ACK for its 2xx response or until the server
- * transaction times out."
- */
- if (this._status === C.STATUS_WAITING_FOR_ACK && this._direction === 'incoming' && this._request.server_transaction.state !== Transactions.C.STATUS_TERMINATED) {
- // Save the dialog for later restoration.
- var dialog = this._dialog; // Send the BYE as soon as the ACK is received...
- this.receiveRequest = function (_ref) {
- var method = _ref.method;
- if (method === JsSIP_C.ACK) {
- _this4.sendRequest(JsSIP_C.BYE, {
- extraHeaders: extraHeaders,
- body: body
- });
- dialog.terminate();
- }
- }; // .., or when the INVITE transaction times out
- this._request.server_transaction.on('stateChanged', function () {
- if (_this4._request.server_transaction.state === Transactions.C.STATUS_TERMINATED) {
- _this4.sendRequest(JsSIP_C.BYE, {
- extraHeaders: extraHeaders,
- body: body
- });
- dialog.terminate();
- }
- });
- this._ended('local', null, cause); // Restore the dialog into 'this' in order to be able to send the in-dialog BYE :-).
- this._dialog = dialog; // Restore the dialog into 'ua' so the ACK can reach 'this' session.
- this._ua.newDialog(dialog);
- } else {
- this.sendRequest(JsSIP_C.BYE, {
- extraHeaders: extraHeaders,
- body: body
- });
- this._ended('local', null, cause);
- }
- }
- }
- }, {
- key: "sendDTMF",
- value: function sendDTMF(tones) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- debug('sendDTMF() | tones: %s', tones);
- var position = 0;
- var duration = options.duration || null;
- var interToneGap = options.interToneGap || null;
- if (tones === undefined) {
- throw new TypeError('Not enough arguments');
- } // Check Session Status.
- if (this._status !== C.STATUS_CONFIRMED && this._status !== C.STATUS_WAITING_FOR_ACK) {
- throw new Exceptions.InvalidStateError(this._status);
- } // Convert to string.
- if (typeof tones === 'number') {
- tones = tones.toString();
- } // Check tones.
- if (!tones || typeof tones !== 'string' || !tones.match(/^[0-9A-DR#*,]+$/i)) {
- throw new TypeError("Invalid tones: ".concat(tones));
- } // Check duration.
- if (duration && !Utils.isDecimal(duration)) {
- throw new TypeError("Invalid tone duration: ".concat(duration));
- } else if (!duration) {
- duration = RTCSession_DTMF.C.DEFAULT_DURATION;
- } else if (duration < RTCSession_DTMF.C.MIN_DURATION) {
- debug("\"duration\" value is lower than the minimum allowed, setting it to ".concat(RTCSession_DTMF.C.MIN_DURATION, " milliseconds"));
- duration = RTCSession_DTMF.C.MIN_DURATION;
- } else if (duration > RTCSession_DTMF.C.MAX_DURATION) {
- debug("\"duration\" value is greater than the maximum allowed, setting it to ".concat(RTCSession_DTMF.C.MAX_DURATION, " milliseconds"));
- duration = RTCSession_DTMF.C.MAX_DURATION;
- } else {
- duration = Math.abs(duration);
- }
- options.duration = duration; // Check interToneGap.
- if (interToneGap && !Utils.isDecimal(interToneGap)) {
- throw new TypeError("Invalid interToneGap: ".concat(interToneGap));
- } else if (!interToneGap) {
- interToneGap = RTCSession_DTMF.C.DEFAULT_INTER_TONE_GAP;
- } else if (interToneGap < RTCSession_DTMF.C.MIN_INTER_TONE_GAP) {
- debug("\"interToneGap\" value is lower than the minimum allowed, setting it to ".concat(RTCSession_DTMF.C.MIN_INTER_TONE_GAP, " milliseconds"));
- interToneGap = RTCSession_DTMF.C.MIN_INTER_TONE_GAP;
- } else {
- interToneGap = Math.abs(interToneGap);
- }
- if (this._tones) {
- // Tones are already queued, just add to the queue.
- this._tones += tones;
- return;
- }
- this._tones = tones; // Send the first tone.
- _sendDTMF.call(this);
- function _sendDTMF() {
- var _this5 = this;
- var timeout;
- if (this._status === C.STATUS_TERMINATED || !this._tones || position >= this._tones.length) {
- // Stop sending DTMF.
- this._tones = null;
- return;
- }
- var tone = this._tones[position];
- position += 1;
- if (tone === ',') {
- timeout = 2000;
- } else {
- var dtmf = new RTCSession_DTMF(this);
- options.eventHandlers = {
- onFailed: function onFailed() {
- _this5._tones = null;
- }
- };
- dtmf.send(tone, options);
- timeout = duration + interToneGap;
- } // Set timeout for the next tone.
- setTimeout(_sendDTMF.bind(this), timeout);
- }
- }
- }, {
- key: "sendInfo",
- value: function sendInfo(contentType, body) {
- var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
- debug('sendInfo()'); // Check Session Status.
- if (this._status !== C.STATUS_CONFIRMED && this._status !== C.STATUS_WAITING_FOR_ACK) {
- throw new Exceptions.InvalidStateError(this._status);
- }
- var info = new RTCSession_Info(this);
- info.send(contentType, body, options);
- }
- /**
- * Mute
- */
- }, {
- key: "mute",
- value: function mute() {
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
- audio: true,
- video: false
- };
- debug('mute()');
- var audioMuted = false,
- videoMuted = false;
- if (this._audioMuted === false && options.audio) {
- audioMuted = true;
- this._audioMuted = true;
- this._toggleMuteAudio(true);
- }
- if (this._videoMuted === false && options.video) {
- videoMuted = true;
- this._videoMuted = true;
- this._toggleMuteVideo(true);
- }
- if (audioMuted === true || videoMuted === true) {
- this._onmute({
- audio: audioMuted,
- video: videoMuted
- });
- }
- }
- /**
- * Unmute
- */
- }, {
- key: "unmute",
- value: function unmute() {
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
- audio: true,
- video: true
- };
- debug('unmute()');
- var audioUnMuted = false,
- videoUnMuted = false;
- if (this._audioMuted === true && options.audio) {
- audioUnMuted = true;
- this._audioMuted = false;
- if (this._localHold === false) {
- this._toggleMuteAudio(false);
- }
- }
- if (this._videoMuted === true && options.video) {
- videoUnMuted = true;
- this._videoMuted = false;
- if (this._localHold === false) {
- this._toggleMuteVideo(false);
- }
- }
- if (audioUnMuted === true || videoUnMuted === true) {
- this._onunmute({
- audio: audioUnMuted,
- video: videoUnMuted
- });
- }
- }
- /**
- * Hold
- */
- }, {
- key: "hold",
- value: function hold() {
- var _this6 = this;
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- var done = arguments.length > 1 ? arguments[1] : undefined;
- debug('hold()');
- if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) {
- return false;
- }
- if (this._localHold === true) {
- return false;
- }
- if (!this._isReadyToReOffer()) {
- return false;
- }
- this._localHold = true;
- this._onhold('local');
- var eventHandlers = {
- succeeded: function succeeded() {
- if (done) {
- done();
- }
- },
- failed: function failed() {
- _this6.terminate({
- cause: JsSIP_C.causes.WEBRTC_ERROR,
- status_code: 500,
- reason_phrase: 'Hold Failed'
- });
- }
- };
- if (options.useUpdate) {
- this._sendUpdate({
- sdpOffer: true,
- eventHandlers: eventHandlers,
- extraHeaders: options.extraHeaders
- });
- } else {
- this._sendReinvite({
- eventHandlers: eventHandlers,
- extraHeaders: options.extraHeaders
- });
- }
- return true;
- }
- }, {
- key: "unhold",
- value: function unhold() {
- var _this7 = this;
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- var done = arguments.length > 1 ? arguments[1] : undefined;
- debug('unhold()');
- if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) {
- return false;
- }
- if (this._localHold === false) {
- return false;
- }
- if (!this._isReadyToReOffer()) {
- return false;
- }
- this._localHold = false;
- this._onunhold('local');
- var eventHandlers = {
- succeeded: function succeeded() {
- if (done) {
- done();
- }
- },
- failed: function failed() {
- _this7.terminate({
- cause: JsSIP_C.causes.WEBRTC_ERROR,
- status_code: 500,
- reason_phrase: 'Unhold Failed'
- });
- }
- };
- if (options.useUpdate) {
- this._sendUpdate({
- sdpOffer: true,
- eventHandlers: eventHandlers,
- extraHeaders: options.extraHeaders
- });
- } else {
- this._sendReinvite({
- eventHandlers: eventHandlers,
- extraHeaders: options.extraHeaders
- });
- }
- return true;
- }
- }, {
- key: "renegotiate",
- value: function renegotiate() {
- var _this8 = this;
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- var done = arguments.length > 1 ? arguments[1] : undefined;
- debug('renegotiate()');
- var rtcOfferConstraints = options.rtcOfferConstraints || null;
- if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) {
- return false;
- }
- if (!this._isReadyToReOffer()) {
- return false;
- }
- var eventHandlers = {
- succeeded: function succeeded() {
- if (done) {
- done();
- }
- },
- failed: function failed() {
- _this8.terminate({
- cause: JsSIP_C.causes.WEBRTC_ERROR,
- status_code: 500,
- reason_phrase: 'Media Renegotiation Failed'
- });
- }
- };
- this._setLocalMediaStatus();
- if (options.useUpdate) {
- this._sendUpdate({
- sdpOffer: true,
- eventHandlers: eventHandlers,
- rtcOfferConstraints: rtcOfferConstraints,
- extraHeaders: options.extraHeaders
- });
- } else {
- this._sendReinvite({
- eventHandlers: eventHandlers,
- rtcOfferConstraints: rtcOfferConstraints,
- extraHeaders: options.extraHeaders
- });
- }
- return true;
- }
- /**
- * Refer
- */
- }, {
- key: "refer",
- value: function refer(target, options) {
- var _this9 = this;
- debug('refer()');
- var originalTarget = target;
- if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) {
- return false;
- } // Check target validity.
- target = this._ua.normalizeTarget(target);
- if (!target) {
- throw new TypeError("Invalid target: ".concat(originalTarget));
- }
- var referSubscriber = new RTCSession_ReferSubscriber(this);
- referSubscriber.sendRefer(target, options); // Store in the map.
- var id = referSubscriber.id;
- this._referSubscribers[id] = referSubscriber; // Listen for ending events so we can remove it from the map.
- referSubscriber.on('requestFailed', function () {
- delete _this9._referSubscribers[id];
- });
- referSubscriber.on('accepted', function () {
- delete _this9._referSubscribers[id];
- });
- referSubscriber.on('failed', function () {
- delete _this9._referSubscribers[id];
- });
- return referSubscriber;
- }
- /**
- * Send a generic in-dialog Request
- */
- }, {
- key: "sendRequest",
- value: function sendRequest(method, options) {
- debug('sendRequest()');
- return this._dialog.sendRequest(method, options);
- }
- /**
- * In dialog Request Reception
- */
- }, {
- key: "receiveRequest",
- value: function receiveRequest(request) {
- var _this10 = this;
- debug('receiveRequest()');
- if (request.method === JsSIP_C.CANCEL) {
- /* RFC3261 15 States that a UAS may have accepted an invitation while a CANCEL
- * was in progress and that the UAC MAY continue with the session established by
- * any 2xx response, or MAY terminate with BYE. JsSIP does continue with the
- * established session. So the CANCEL is processed only if the session is not yet
- * established.
- */
- /*
- * Terminate the whole session in case the user didn't accept (or yet send the answer)
- * nor reject the request opening the session.
- */
- if (this._status === C.STATUS_WAITING_FOR_ANSWER || this._status === C.STATUS_ANSWERED) {
- this._status = C.STATUS_CANCELED;
- this._request.reply(487);
- this._failed('remote', request, JsSIP_C.causes.CANCELED);
- }
- } else {
- // Requests arriving here are in-dialog requests.
- switch (request.method) {
- case JsSIP_C.ACK:
- if (this._status !== C.STATUS_WAITING_FOR_ACK) {
- return;
- } // Update signaling status.
- this._status = C.STATUS_CONFIRMED;
- clearTimeout(this._timers.ackTimer);
- clearTimeout(this._timers.invite2xxTimer);
- if (this._late_sdp) {
- if (!request.body) {
- this.terminate({
- cause: JsSIP_C.causes.MISSING_SDP,
- status_code: 400
- });
- break;
- }
- var e = {
- originator: 'remote',
- type: 'answer',
- sdp: request.body
- };
- debug('emit "sdp"');
- this.emit('sdp', e);
- var answer = new RTCSessionDescription({
- type: 'answer',
- sdp: e.sdp
- });
- this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () {
- return _this10._connection.setRemoteDescription(answer);
- }).then(function () {
- if (!_this10._is_confirmed) {
- _this10._confirmed('remote', request);
- }
- }).catch(function (error) {
- _this10.terminate({
- cause: JsSIP_C.causes.BAD_MEDIA_DESCRIPTION,
- status_code: 488
- });
- debugerror('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error);
- _this10.emit('peerconnection:setremotedescriptionfailed', error);
- });
- } else if (!this._is_confirmed) {
- this._confirmed('remote', request);
- }
- break;
- case JsSIP_C.BYE:
- if (this._status === C.STATUS_CONFIRMED) {
- request.reply(200);
- this._ended('remote', request, JsSIP_C.causes.BYE);
- } else if (this._status === C.STATUS_INVITE_RECEIVED) {
- request.reply(200);
- this._request.reply(487, 'BYE Received');
- this._ended('remote', request, JsSIP_C.causes.BYE);
- } else {
- request.reply(403, 'Wrong Status');
- }
- break;
- case JsSIP_C.INVITE:
- if (this._status === C.STATUS_CONFIRMED) {
- if (request.hasHeader('replaces')) {
- this._receiveReplaces(request);
- } else {
- this._receiveReinvite(request);
- }
- } else {
- request.reply(403, 'Wrong Status');
- }
- break;
- case JsSIP_C.INFO:
- if (this._status === C.STATUS_1XX_RECEIVED || this._status === C.STATUS_WAITING_FOR_ANSWER || this._status === C.STATUS_ANSWERED || this._status === C.STATUS_WAITING_FOR_ACK || this._status === C.STATUS_CONFIRMED) {
- var contentType = request.getHeader('content-type');
- if (contentType && contentType.match(/^application\/dtmf-relay/i)) {
- new RTCSession_DTMF(this).init_incoming(request);
- } else if (contentType !== undefined) {
- new RTCSession_Info(this).init_incoming(request);
- } else {
- request.reply(415);
- }
- } else {
- request.reply(403, 'Wrong Status');
- }
- break;
- case JsSIP_C.UPDATE:
- if (this._status === C.STATUS_CONFIRMED) {
- this._receiveUpdate(request);
- } else {
- request.reply(403, 'Wrong Status');
- }
- break;
- case JsSIP_C.REFER:
- if (this._status === C.STATUS_CONFIRMED) {
- this._receiveRefer(request);
- } else {
- request.reply(403, 'Wrong Status');
- }
- break;
- case JsSIP_C.NOTIFY:
- if (this._status === C.STATUS_CONFIRMED) {
- this._receiveNotify(request);
- } else {
- request.reply(403, 'Wrong Status');
- }
- break;
- default:
- request.reply(501);
- }
- }
- }
- /**
- * Session Callbacks
- */
- }, {
- key: "onTransportError",
- value: function onTransportError() {
- debugerror('onTransportError()');
- if (this._status !== C.STATUS_TERMINATED) {
- this.terminate({
- status_code: 500,
- reason_phrase: JsSIP_C.causes.CONNECTION_ERROR,
- cause: JsSIP_C.causes.CONNECTION_ERROR
- });
- }
- }
- }, {
- key: "onRequestTimeout",
- value: function onRequestTimeout() {
- debugerror('onRequestTimeout()');
- if (this._status !== C.STATUS_TERMINATED) {
- this.terminate({
- status_code: 408,
- reason_phrase: JsSIP_C.causes.REQUEST_TIMEOUT,
- cause: JsSIP_C.causes.REQUEST_TIMEOUT
- });
- }
- }
- }, {
- key: "onDialogError",
- value: function onDialogError() {
- debugerror('onDialogError()');
- if (this._status !== C.STATUS_TERMINATED) {
- this.terminate({
- status_code: 500,
- reason_phrase: JsSIP_C.causes.DIALOG_ERROR,
- cause: JsSIP_C.causes.DIALOG_ERROR
- });
- }
- } // Called from DTMF handler.
- }, {
- key: "newDTMF",
- value: function newDTMF(data) {
- debug('newDTMF()');
- this.emit('newDTMF', data);
- } // Called from Info handler.
- }, {
- key: "newInfo",
- value: function newInfo(data) {
- debug('newInfo()');
- this.emit('newInfo', data);
- }
- /**
- * Check if RTCSession is ready for an outgoing re-INVITE or UPDATE with SDP.
- */
- }, {
- key: "_isReadyToReOffer",
- value: function _isReadyToReOffer() {
- if (!this._rtcReady) {
- debug('_isReadyToReOffer() | internal WebRTC status not ready');
- return false;
- } // No established yet.
- if (!this._dialog) {
- debug('_isReadyToReOffer() | session not established yet');
- return false;
- } // Another INVITE transaction is in progress.
- if (this._dialog.uac_pending_reply === true || this._dialog.uas_pending_reply === true) {
- debug('_isReadyToReOffer() | there is another INVITE/UPDATE transaction in progress');
- return false;
- }
- return true;
- }
- }, {
- key: "_close",
- value: function _close() {
- debug('close()');
- if (this._status === C.STATUS_TERMINATED) {
- return;
- }
- this._status = C.STATUS_TERMINATED; // Terminate RTC.
- if (this._connection) {
- try {
- this._connection.close();
- } catch (error) {
- debugerror('close() | error closing the RTCPeerConnection: %o', error);
- }
- } // Close local MediaStream if it was not given by the user.
- if (this._localMediaStream && this._localMediaStreamLocallyGenerated) {
- debug('close() | closing local MediaStream');
- Utils.closeMediaStream(this._localMediaStream);
- } // Terminate signaling.
- // Clear SIP timers.
- for (var timer in this._timers) {
- if (Object.prototype.hasOwnProperty.call(this._timers, timer)) {
- clearTimeout(this._timers[timer]);
- }
- } // Clear Session Timers.
- clearTimeout(this._sessionTimers.timer); // Terminate confirmed dialog.
- if (this._dialog) {
- this._dialog.terminate();
- delete this._dialog;
- } // Terminate early dialogs.
- for (var dialog in this._earlyDialogs) {
- if (Object.prototype.hasOwnProperty.call(this._earlyDialogs, dialog)) {
- this._earlyDialogs[dialog].terminate();
- delete this._earlyDialogs[dialog];
- }
- } // Terminate REFER subscribers.
- for (var subscriber in this._referSubscribers) {
- if (Object.prototype.hasOwnProperty.call(this._referSubscribers, subscriber)) {
- delete this._referSubscribers[subscriber];
- }
- }
- this._ua.destroyRTCSession(this);
- }
- /**
- * Private API.
- */
- /**
- * RFC3261 13.3.1.4
- * Response retransmissions cannot be accomplished by transaction layer
- * since it is destroyed when receiving the first 2xx answer
- */
- }, {
- key: "_setInvite2xxTimer",
- value: function _setInvite2xxTimer(request, body) {
- var timeout = Timers.T1;
- function invite2xxRetransmission() {
- if (this._status !== C.STATUS_WAITING_FOR_ACK) {
- return;
- }
- request.reply(200, null, ["Contact: ".concat(this._contact)], body);
- if (timeout < Timers.T2) {
- timeout = timeout * 2;
- if (timeout > Timers.T2) {
- timeout = Timers.T2;
- }
- }
- this._timers.invite2xxTimer = setTimeout(invite2xxRetransmission.bind(this), timeout);
- }
- this._timers.invite2xxTimer = setTimeout(invite2xxRetransmission.bind(this), timeout);
- }
- /**
- * RFC3261 14.2
- * If a UAS generates a 2xx response and never receives an ACK,
- * it SHOULD generate a BYE to terminate the dialog.
- */
- }, {
- key: "_setACKTimer",
- value: function _setACKTimer() {
- var _this11 = this;
- this._timers.ackTimer = setTimeout(function () {
- if (_this11._status === C.STATUS_WAITING_FOR_ACK) {
- debug('no ACK received, terminating the session');
- clearTimeout(_this11._timers.invite2xxTimer);
- _this11.sendRequest(JsSIP_C.BYE);
- _this11._ended('remote', null, JsSIP_C.causes.NO_ACK);
- }
- }, Timers.TIMER_H);
- }
- }, {
- key: "_createRTCConnection",
- value: function _createRTCConnection(pcConfig, rtcConstraints) {
- var _this12 = this;
- this._connection = new RTCPeerConnection(pcConfig, rtcConstraints);
- this._connection.addEventListener('iceconnectionstatechange', function () {
- var state = _this12._connection.iceConnectionState; // TODO: Do more with different states.
- if (state === 'failed') {
- _this12.terminate({
- cause: JsSIP_C.causes.RTP_TIMEOUT,
- status_code: 408,
- reason_phrase: JsSIP_C.causes.RTP_TIMEOUT
- });
- }
- });
- debug('emit "peerconnection"');
- this.emit('peerconnection', {
- peerconnection: this._connection
- });
- }
- }, {
- key: "_createLocalDescription",
- value: function _createLocalDescription(type, constraints) {
- var _this13 = this;
- debug('createLocalDescription()');
- if (type !== 'offer' && type !== 'answer') throw new Error("createLocalDescription() | invalid type \"".concat(type, "\""));
- var connection = this._connection;
- this._rtcReady = false;
- return Promise.resolve() // Create Offer or Answer.
- .then(function () {
- if (type === 'offer') {
- return connection.createOffer(constraints).catch(function (error) {
- debugerror('emit "peerconnection:createofferfailed" [error:%o]', error);
- _this13.emit('peerconnection:createofferfailed', error);
- return Promise.reject(error);
- });
- } else {
- return connection.createAnswer(constraints).catch(function (error) {
- debugerror('emit "peerconnection:createanswerfailed" [error:%o]', error);
- _this13.emit('peerconnection:createanswerfailed', error);
- return Promise.reject(error);
- });
- }
- }) // Set local description.
- .then(function (desc) {
- return connection.setLocalDescription(desc).catch(function (error) {
- _this13._rtcReady = true;
- debugerror('emit "peerconnection:setlocaldescriptionfailed" [error:%o]', error);
- _this13.emit('peerconnection:setlocaldescriptionfailed', error);
- return Promise.reject(error);
- });
- }).then(function () {
- // Resolve right away if 'pc.iceGatheringState' is 'complete'.
- if (connection.iceGatheringState === 'complete') {
- _this13._rtcReady = true;
- var e = {
- originator: 'local',
- type: type,
- sdp: connection.localDescription.sdp
- };
- debug('emit "sdp"');
- _this13.emit('sdp', e);
- return Promise.resolve(e.sdp);
- } // Add 'pc.onicencandidate' event handler to resolve on last candidate.
- return new Promise(function (resolve) {
- var finished = false;
- var listener;
- var ready = function ready() {
- connection.removeEventListener('icecandidate', listener);
- finished = true;
- _this13._rtcReady = true;
- var e = {
- originator: 'local',
- type: type,
- sdp: connection.localDescription.sdp
- };
- debug('emit "sdp"');
- _this13.emit('sdp', e);
- resolve(e.sdp);
- };
- connection.addEventListener('icecandidate', listener = function listener(event) {
- var candidate = event.candidate;
- if (candidate) {
- _this13.emit('icecandidate', {
- candidate: candidate,
- ready: ready
- });
- } else if (!finished) {
- ready();
- }
- });
- });
- });
- }
- /**
- * Dialog Management
- */
- }, {
- key: "_createDialog",
- value: function _createDialog(message, type, early) {
- var local_tag = type === 'UAS' ? message.to_tag : message.from_tag;
- var remote_tag = type === 'UAS' ? message.from_tag : message.to_tag;
- var id = message.call_id + local_tag + remote_tag;
- var early_dialog = this._earlyDialogs[id]; // Early Dialog.
- if (early) {
- if (early_dialog) {
- return true;
- } else {
- early_dialog = new Dialog(this, message, type, Dialog.C.STATUS_EARLY); // Dialog has been successfully created.
- if (early_dialog.error) {
- debug(early_dialog.error);
- this._failed('remote', message, JsSIP_C.causes.INTERNAL_ERROR);
- return false;
- } else {
- this._earlyDialogs[id] = early_dialog;
- return true;
- }
- }
- } // Confirmed Dialog.
- else {
- this._from_tag = message.from_tag;
- this._to_tag = message.to_tag; // In case the dialog is in _early_ state, update it.
- if (early_dialog) {
- early_dialog.update(message, type);
- this._dialog = early_dialog;
- delete this._earlyDialogs[id];
- return true;
- } // Otherwise, create a _confirmed_ dialog.
- var dialog = new Dialog(this, message, type);
- if (dialog.error) {
- debug(dialog.error);
- this._failed('remote', message, JsSIP_C.causes.INTERNAL_ERROR);
- return false;
- } else {
- this._dialog = dialog;
- return true;
- }
- }
- }
- /**
- * In dialog INVITE Reception
- */
- }, {
- key: "_receiveReinvite",
- value: function _receiveReinvite(request) {
- var _this14 = this;
- debug('receiveReinvite()');
- var contentType = request.getHeader('Content-Type');
- var data = {
- request: request,
- callback: undefined,
- reject: reject.bind(this)
- };
- var rejected = false;
- function reject() {
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- rejected = true;
- var status_code = options.status_code || 403;
- var reason_phrase = options.reason_phrase || '';
- var extraHeaders = Utils.cloneArray(options.extraHeaders);
- if (this._status !== C.STATUS_CONFIRMED) {
- return false;
- }
- if (status_code < 300 || status_code >= 700) {
- throw new TypeError("Invalid status_code: ".concat(status_code));
- }
- request.reply(status_code, reason_phrase, extraHeaders);
- } // Emit 'reinvite'.
- this.emit('reinvite', data);
- if (rejected) {
- return;
- }
- this._late_sdp = false; // Request without SDP.
- if (!request.body) {
- this._late_sdp = true;
- this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () {
- return _this14._createLocalDescription('offer', _this14._rtcOfferConstraints);
- }).then(function (sdp) {
- sendAnswer.call(_this14, sdp);
- }).catch(function () {
- request.reply(500);
- });
- return;
- } // Request with SDP.
- if (contentType !== 'application/sdp') {
- debug('invalid Content-Type');
- request.reply(415);
- return;
- }
- this._processInDialogSdpOffer(request) // Send answer.
- .then(function (desc) {
- if (_this14._status === C.STATUS_TERMINATED) {
- return;
- }
- sendAnswer.call(_this14, desc);
- }).catch(function (error) {
- debugerror(error);
- });
- function sendAnswer(desc) {
- var _this15 = this;
- var extraHeaders = ["Contact: ".concat(this._contact)];
- this._handleSessionTimersInIncomingRequest(request, extraHeaders);
- if (this._late_sdp) {
- desc = this._mangleOffer(desc);
- }
- request.reply(200, null, extraHeaders, desc, function () {
- _this15._status = C.STATUS_WAITING_FOR_ACK;
- _this15._setInvite2xxTimer(request, desc);
- _this15._setACKTimer();
- }); // If callback is given execute it.
- if (typeof data.callback === 'function') {
- data.callback();
- }
- }
- }
- /**
- * In dialog UPDATE Reception
- */
- }, {
- key: "_receiveUpdate",
- value: function _receiveUpdate(request) {
- var _this16 = this;
- debug('receiveUpdate()');
- var contentType = request.getHeader('Content-Type');
- var data = {
- request: request,
- callback: undefined,
- reject: reject.bind(this)
- };
- var rejected = false;
- function reject() {
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- rejected = true;
- var status_code = options.status_code || 403;
- var reason_phrase = options.reason_phrase || '';
- var extraHeaders = Utils.cloneArray(options.extraHeaders);
- if (this._status !== C.STATUS_CONFIRMED) {
- return false;
- }
- if (status_code < 300 || status_code >= 700) {
- throw new TypeError("Invalid status_code: ".concat(status_code));
- }
- request.reply(status_code, reason_phrase, extraHeaders);
- } // Emit 'update'.
- this.emit('update', data);
- if (rejected) {
- return;
- }
- if (!request.body) {
- sendAnswer.call(this, null);
- return;
- }
- if (contentType !== 'application/sdp') {
- debug('invalid Content-Type');
- request.reply(415);
- return;
- }
- this._processInDialogSdpOffer(request) // Send answer.
- .then(function (desc) {
- if (_this16._status === C.STATUS_TERMINATED) {
- return;
- }
- sendAnswer.call(_this16, desc);
- }).catch(function (error) {
- debugerror(error);
- });
- function sendAnswer(desc) {
- var extraHeaders = ["Contact: ".concat(this._contact)];
- this._handleSessionTimersInIncomingRequest(request, extraHeaders);
- request.reply(200, null, extraHeaders, desc); // If callback is given execute it.
- if (typeof data.callback === 'function') {
- data.callback();
- }
- }
- }
- }, {
- key: "_processInDialogSdpOffer",
- value: function _processInDialogSdpOffer(request) {
- var _this17 = this;
- debug('_processInDialogSdpOffer()');
- var sdp = request.parseSDP();
- var hold = false;
- var _iteratorNormalCompletion4 = true;
- var _didIteratorError4 = false;
- var _iteratorError4 = undefined;
- try {
- for (var _iterator4 = sdp.media[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
- var m = _step4.value;
- if (holdMediaTypes.indexOf(m.type) === -1) {
- continue;
- }
- var direction = m.direction || sdp.direction || 'sendrecv';
- if (direction === 'sendonly' || direction === 'inactive') {
- hold = true;
- } // If at least one of the streams is active don't emit 'hold'.
- else {
- hold = false;
- break;
- }
- }
- } catch (err) {
- _didIteratorError4 = true;
- _iteratorError4 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
- _iterator4.return();
- }
- } finally {
- if (_didIteratorError4) {
- throw _iteratorError4;
- }
- }
- }
- var e = {
- originator: 'remote',
- type: 'offer',
- sdp: request.body
- };
- debug('emit "sdp"');
- this.emit('sdp', e);
- var offer = new RTCSessionDescription({
- type: 'offer',
- sdp: e.sdp
- });
- this._connectionPromiseQueue = this._connectionPromiseQueue // Set remote description.
- .then(function () {
- if (_this17._status === C.STATUS_TERMINATED) {
- throw new Error('terminated');
- }
- return _this17._connection.setRemoteDescription(offer).catch(function (error) {
- request.reply(488);
- debugerror('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error);
- _this17.emit('peerconnection:setremotedescriptionfailed', error);
- throw new Error('peerconnection.setRemoteDescription() failed');
- });
- }).then(function () {
- if (_this17._status === C.STATUS_TERMINATED) {
- throw new Error('terminated');
- }
- if (_this17._remoteHold === true && hold === false) {
- _this17._remoteHold = false;
- _this17._onunhold('remote');
- } else if (_this17._remoteHold === false && hold === true) {
- _this17._remoteHold = true;
- _this17._onhold('remote');
- }
- }) // Create local description.
- .then(function () {
- if (_this17._status === C.STATUS_TERMINATED) {
- throw new Error('terminated');
- }
- return _this17._createLocalDescription('answer', _this17._rtcAnswerConstraints).catch(function () {
- request.reply(500);
- throw new Error('_createLocalDescription() failed');
- });
- });
- return this._connectionPromiseQueue;
- }
- /**
- * In dialog Refer Reception
- */
- }, {
- key: "_receiveRefer",
- value: function _receiveRefer(request) {
- var _this18 = this;
- debug('receiveRefer()');
- if (!request.refer_to) {
- debug('no Refer-To header field present in REFER');
- request.reply(400);
- return;
- }
- if (request.refer_to.uri.scheme !== JsSIP_C.SIP) {
- debug('Refer-To header field points to a non-SIP URI scheme');
- request.reply(416);
- return;
- } // Reply before the transaction timer expires.
- request.reply(202);
- var notifier = new RTCSession_ReferNotifier(this, request.cseq);
- debug('emit "refer"'); // Emit 'refer'.
- this.emit('refer', {
- request: request,
- accept: function accept(initCallback, options) {
- _accept.call(_this18, initCallback, options);
- },
- reject: function reject() {
- _reject.call(_this18);
- }
- });
- function _accept(initCallback) {
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- initCallback = typeof initCallback === 'function' ? initCallback : null;
- if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) {
- return false;
- }
- var session = new RTCSession(this._ua);
- session.on('progress', function (_ref2) {
- var response = _ref2.response;
- notifier.notify(response.status_code, response.reason_phrase);
- });
- session.on('accepted', function (_ref3) {
- var response = _ref3.response;
- notifier.notify(response.status_code, response.reason_phrase);
- });
- session.on('_failed', function (_ref4) {
- var message = _ref4.message,
- cause = _ref4.cause;
- if (message) {
- notifier.notify(message.status_code, message.reason_phrase);
- } else {
- notifier.notify(487, cause);
- }
- }); // Consider the Replaces header present in the Refer-To URI.
- if (request.refer_to.uri.hasHeader('replaces')) {
- var replaces = decodeURIComponent(request.refer_to.uri.getHeader('replaces'));
- options.extraHeaders = Utils.cloneArray(options.extraHeaders);
- options.extraHeaders.push("Replaces: ".concat(replaces));
- }
- session.connect(request.refer_to.uri.toAor(), options, initCallback);
- }
- function _reject() {
- notifier.notify(603);
- }
- }
- /**
- * In dialog Notify Reception
- */
- }, {
- key: "_receiveNotify",
- value: function _receiveNotify(request) {
- debug('receiveNotify()');
- if (!request.event) {
- request.reply(400);
- }
- switch (request.event.event) {
- case 'refer':
- {
- var id;
- var referSubscriber;
- if (request.event.params && request.event.params.id) {
- id = request.event.params.id;
- referSubscriber = this._referSubscribers[id];
- } else if (Object.keys(this._referSubscribers).length === 1) {
- referSubscriber = this._referSubscribers[Object.keys(this._referSubscribers)[0]];
- } else {
- request.reply(400, 'Missing event id parameter');
- return;
- }
- if (!referSubscriber) {
- request.reply(481, 'Subscription does not exist');
- return;
- }
- referSubscriber.receiveNotify(request);
- request.reply(200);
- break;
- }
- default:
- {
- request.reply(489);
- }
- }
- }
- /**
- * INVITE with Replaces Reception
- */
- }, {
- key: "_receiveReplaces",
- value: function _receiveReplaces(request) {
- var _this20 = this;
- debug('receiveReplaces()');
- function _accept2(initCallback) {
- var _this19 = this;
- if (this._status !== C.STATUS_WAITING_FOR_ACK && this._status !== C.STATUS_CONFIRMED) {
- return false;
- }
- var session = new RTCSession(this._ua); // Terminate the current session when the new one is confirmed.
- session.on('confirmed', function () {
- _this19.terminate();
- });
- session.init_incoming(request, initCallback);
- }
- function _reject2() {
- debug('Replaced INVITE rejected by the user');
- request.reply(486);
- } // Emit 'replace'.
- this.emit('replaces', {
- request: request,
- accept: function accept(initCallback) {
- _accept2.call(_this20, initCallback);
- },
- reject: function reject() {
- _reject2.call(_this20);
- }
- });
- }
- /**
- * Initial Request Sender
- */
- }, {
- key: "_sendInitialRequest",
- value: function _sendInitialRequest(mediaConstraints, rtcOfferConstraints, mediaStream) {
- var _this21 = this;
- var request_sender = new RequestSender(this._ua, this._request, {
- onRequestTimeout: function onRequestTimeout() {
- _this21.onRequestTimeout();
- },
- onTransportError: function onTransportError() {
- _this21.onTransportError();
- },
- // Update the request on authentication.
- onAuthenticated: function onAuthenticated(request) {
- _this21._request = request;
- },
- onReceiveResponse: function onReceiveResponse(response) {
- _this21._receiveInviteResponse(response);
- }
- }); // This Promise is resolved within the next iteration, so the app has now
- // a chance to set events such as 'peerconnection' and 'connecting'.
- Promise.resolve() // Get a stream if required.
- .then(function () {
- // A stream is given, let the app set events such as 'peerconnection' and 'connecting'.
- if (mediaStream) {
- return mediaStream;
- } // Request for user media access.
- else if (mediaConstraints.audio || mediaConstraints.video) {
- _this21._localMediaStreamLocallyGenerated = true;
- return navigator.mediaDevices.getUserMedia(mediaConstraints).catch(function (error) {
- if (_this21._status === C.STATUS_TERMINATED) {
- throw new Error('terminated');
- }
- _this21._failed('local', null, JsSIP_C.causes.USER_DENIED_MEDIA_ACCESS);
- debugerror('emit "getusermediafailed" [error:%o]', error);
- _this21.emit('getusermediafailed', error);
- throw error;
- });
- }
- }).then(function (stream) {
- if (_this21._status === C.STATUS_TERMINATED) {
- throw new Error('terminated');
- }
- _this21._localMediaStream = stream;
- if (stream) {
- var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
- if(isSafari) {
- _this21._connection.addStream(stream);
- } else {
- stream.getTracks().forEach(function (track) {
- _this21._connection.addTrack(track, stream);
- });
- }
- } // TODO: should this be triggered here?
- _this21._connecting(_this21._request);
- return _this21._createLocalDescription('offer', rtcOfferConstraints).catch(function (error) {
- _this21._failed('local', null, JsSIP_C.causes.WEBRTC_ERROR);
- throw error;
- });
- }).then(function (desc) {
- if (_this21._is_canceled || _this21._status === C.STATUS_TERMINATED) {
- throw new Error('terminated');
- }
- _this21._request.body = desc;
- _this21._status = C.STATUS_INVITE_SENT;
- debug('emit "sending" [request:%o]', _this21._request); // Emit 'sending' so the app can mangle the body before the request is sent.
- _this21.emit('sending', {
- request: _this21._request
- });
- request_sender.send();
- }).catch(function (error) {
- if (_this21._status === C.STATUS_TERMINATED) {
- return;
- }
- debugerror(error);
- });
- }
- /**
- * Reception of Response for Initial INVITE
- */
- }, {
- key: "_receiveInviteResponse",
- value: function _receiveInviteResponse(response) {
- var _this22 = this;
- debug('receiveInviteResponse()'); // Handle 2XX retransmissions and responses from forked requests.
- if (this._dialog && response.status_code >= 200 && response.status_code <= 299) {
- /*
- * If it is a retransmission from the endpoint that established
- * the dialog, send an ACK
- */
- if (this._dialog.id.call_id === response.call_id && this._dialog.id.local_tag === response.from_tag && this._dialog.id.remote_tag === response.to_tag) {
- this.sendRequest(JsSIP_C.ACK);
- return;
- } // If not, send an ACK and terminate.
- else {
- var dialog = new Dialog(this, response, 'UAC');
- if (dialog.error !== undefined) {
- debug(dialog.error);
- return;
- }
- this.sendRequest(JsSIP_C.ACK);
- this.sendRequest(JsSIP_C.BYE);
- return;
- }
- } // Proceed to cancellation if the user requested.
- if (this._is_canceled) {
- if (response.status_code >= 100 && response.status_code < 200) {
- this._request.cancel(this._cancel_reason);
- } else if (response.status_code >= 200 && response.status_code < 299) {
- this._acceptAndTerminate(response);
- }
- return;
- }
- if (this._status !== C.STATUS_INVITE_SENT && this._status !== C.STATUS_1XX_RECEIVED) {
- return;
- }
- switch (true) {
- case /^100$/.test(response.status_code):
- this._status = C.STATUS_1XX_RECEIVED;
- break;
- case /^1[0-9]{2}$/.test(response.status_code):
- {
- // Do nothing with 1xx responses without To tag.
- if (!response.to_tag) {
- debug('1xx response received without to tag');
- break;
- } // Create Early Dialog if 1XX comes with contact.
- if (response.hasHeader('contact')) {
- // An error on dialog creation will fire 'failed' event.
- if (!this._createDialog(response, 'UAC', true)) {
- break;
- }
- }
- this._status = C.STATUS_1XX_RECEIVED;
- this._progress('remote', response);
- if (!response.body) {
- break;
- }
- var e = {
- originator: 'remote',
- type: 'answer',
- sdp: response.body
- };
- debug('emit "sdp"');
- this.emit('sdp', e);
- var answer = new RTCSessionDescription({
- type: 'answer',
- sdp: e.sdp
- });
- this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () {
- return _this22._connection.setRemoteDescription(answer);
- }).catch(function (error) {
- debugerror('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error);
- _this22.emit('peerconnection:setremotedescriptionfailed', error);
- });
- break;
- }
- case /^2[0-9]{2}$/.test(response.status_code):
- {
- this._status = C.STATUS_CONFIRMED;
- if (!response.body) {
- this._acceptAndTerminate(response, 400, JsSIP_C.causes.MISSING_SDP);
- this._failed('remote', response, JsSIP_C.causes.BAD_MEDIA_DESCRIPTION);
- break;
- } // An error on dialog creation will fire 'failed' event.
- if (!this._createDialog(response, 'UAC')) {
- break;
- }
- var _e = {
- originator: 'remote',
- type: 'answer',
- sdp: response.body
- };
- debug('emit "sdp"');
- this.emit('sdp', _e);
- var _answer = new RTCSessionDescription({
- type: 'answer',
- sdp: _e.sdp
- });
- this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () {
- // Be ready for 200 with SDP after a 180/183 with SDP.
- // We created a SDP 'answer' for it, so check the current signaling state.
- if (_this22._connection.signalingState === 'stable') {
- return _this22._connection.createOffer(_this22._rtcOfferConstraints).then(function (offer) {
- return _this22._connection.setLocalDescription(offer);
- }).catch(function (error) {
- _this22._acceptAndTerminate(response, 500, error.toString());
- _this22._failed('local', response, JsSIP_C.causes.WEBRTC_ERROR);
- });
- }
- }).then(function () {
- _this22._connection.setRemoteDescription(_answer).then(function () {
- // Handle Session Timers.
- _this22._handleSessionTimersInIncomingResponse(response);
- _this22._accepted('remote', response);
- _this22.sendRequest(JsSIP_C.ACK);
- _this22._confirmed('local', null);
- }).catch(function (error) {
- _this22._acceptAndTerminate(response, 488, 'Not Acceptable Here');
- _this22._failed('remote', response, JsSIP_C.causes.BAD_MEDIA_DESCRIPTION);
- debugerror('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error);
- _this22.emit('peerconnection:setremotedescriptionfailed', error);
- });
- });
- break;
- }
- default:
- {
- var cause = Utils.sipErrorCause(response.status_code);
- this._failed('remote', response, cause);
- }
- }
- }
- /**
- * Send Re-INVITE
- */
- }, {
- key: "_sendReinvite",
- value: function _sendReinvite() {
- var _this23 = this;
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- debug('sendReinvite()');
- var extraHeaders = Utils.cloneArray(options.extraHeaders);
- var eventHandlers = options.eventHandlers || {};
- var rtcOfferConstraints = options.rtcOfferConstraints || this._rtcOfferConstraints || null;
- var succeeded = false;
- extraHeaders.push("Contact: ".concat(this._contact));
- extraHeaders.push('Content-Type: application/sdp'); // Session Timers.
- if (this._sessionTimers.running) {
- extraHeaders.push("Session-Expires: ".concat(this._sessionTimers.currentExpires, ";refresher=").concat(this._sessionTimers.refresher ? 'uac' : 'uas'));
- }
- this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () {
- return _this23._createLocalDescription('offer', rtcOfferConstraints);
- }).then(function (sdp) {
- sdp = _this23._mangleOffer(sdp);
- var e = {
- originator: 'local',
- type: 'offer',
- sdp: sdp
- };
- debug('emit "sdp"');
- _this23.emit('sdp', e);
- _this23.sendRequest(JsSIP_C.INVITE, {
- extraHeaders: extraHeaders,
- body: sdp,
- eventHandlers: {
- onSuccessResponse: function onSuccessResponse(response) {
- onSucceeded.call(_this23, response);
- succeeded = true;
- },
- onErrorResponse: function onErrorResponse(response) {
- onFailed.call(_this23, response);
- },
- onTransportError: function onTransportError() {
- _this23.onTransportError(); // Do nothing because session ends.
- },
- onRequestTimeout: function onRequestTimeout() {
- _this23.onRequestTimeout(); // Do nothing because session ends.
- },
- onDialogError: function onDialogError() {
- _this23.onDialogError(); // Do nothing because session ends.
- }
- }
- });
- }).catch(function () {
- onFailed();
- });
- function onSucceeded(response) {
- var _this24 = this;
- if (this._status === C.STATUS_TERMINATED) {
- return;
- }
- this.sendRequest(JsSIP_C.ACK); // If it is a 2XX retransmission exit now.
- if (succeeded) {
- return;
- } // Handle Session Timers.
- this._handleSessionTimersInIncomingResponse(response); // Must have SDP answer.
- if (!response.body) {
- onFailed.call(this);
- return;
- } else if (response.getHeader('Content-Type') !== 'application/sdp') {
- onFailed.call(this);
- return;
- }
- var e = {
- originator: 'remote',
- type: 'answer',
- sdp: response.body
- };
- debug('emit "sdp"');
- this.emit('sdp', e);
- var answer = new RTCSessionDescription({
- type: 'answer',
- sdp: e.sdp
- });
- this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () {
- return _this24._connection.setRemoteDescription(answer);
- }).then(function () {
- if (eventHandlers.succeeded) {
- eventHandlers.succeeded(response);
- }
- }).catch(function (error) {
- onFailed.call(_this24);
- debugerror('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error);
- _this24.emit('peerconnection:setremotedescriptionfailed', error);
- });
- }
- function onFailed(response) {
- if (eventHandlers.failed) {
- eventHandlers.failed(response);
- }
- }
- }
- /**
- * Send UPDATE
- */
- }, {
- key: "_sendUpdate",
- value: function _sendUpdate() {
- var _this25 = this;
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- debug('sendUpdate()');
- var extraHeaders = Utils.cloneArray(options.extraHeaders);
- var eventHandlers = options.eventHandlers || {};
- var rtcOfferConstraints = options.rtcOfferConstraints || this._rtcOfferConstraints || null;
- var sdpOffer = options.sdpOffer || false;
- var succeeded = false;
- extraHeaders.push("Contact: ".concat(this._contact)); // Session Timers.
- if (this._sessionTimers.running) {
- extraHeaders.push("Session-Expires: ".concat(this._sessionTimers.currentExpires, ";refresher=").concat(this._sessionTimers.refresher ? 'uac' : 'uas'));
- }
- if (sdpOffer) {
- extraHeaders.push('Content-Type: application/sdp');
- this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () {
- return _this25._createLocalDescription('offer', rtcOfferConstraints);
- }).then(function (sdp) {
- sdp = _this25._mangleOffer(sdp);
- var e = {
- originator: 'local',
- type: 'offer',
- sdp: sdp
- };
- debug('emit "sdp"');
- _this25.emit('sdp', e);
- _this25.sendRequest(JsSIP_C.UPDATE, {
- extraHeaders: extraHeaders,
- body: sdp,
- eventHandlers: {
- onSuccessResponse: function onSuccessResponse(response) {
- onSucceeded.call(_this25, response);
- succeeded = true;
- },
- onErrorResponse: function onErrorResponse(response) {
- onFailed.call(_this25, response);
- },
- onTransportError: function onTransportError() {
- _this25.onTransportError(); // Do nothing because session ends.
- },
- onRequestTimeout: function onRequestTimeout() {
- _this25.onRequestTimeout(); // Do nothing because session ends.
- },
- onDialogError: function onDialogError() {
- _this25.onDialogError(); // Do nothing because session ends.
- }
- }
- });
- }).catch(function () {
- onFailed.call(_this25);
- });
- } // No SDP.
- else {
- this.sendRequest(JsSIP_C.UPDATE, {
- extraHeaders: extraHeaders,
- eventHandlers: {
- onSuccessResponse: function onSuccessResponse(response) {
- onSucceeded.call(_this25, response);
- },
- onErrorResponse: function onErrorResponse(response) {
- onFailed.call(_this25, response);
- },
- onTransportError: function onTransportError() {
- _this25.onTransportError(); // Do nothing because session ends.
- },
- onRequestTimeout: function onRequestTimeout() {
- _this25.onRequestTimeout(); // Do nothing because session ends.
- },
- onDialogError: function onDialogError() {
- _this25.onDialogError(); // Do nothing because session ends.
- }
- }
- });
- }
- function onSucceeded(response) {
- var _this26 = this;
- if (this._status === C.STATUS_TERMINATED) {
- return;
- } // If it is a 2XX retransmission exit now.
- if (succeeded) {
- return;
- } // Handle Session Timers.
- this._handleSessionTimersInIncomingResponse(response); // Must have SDP answer.
- if (sdpOffer) {
- if (!response.body) {
- onFailed.call(this);
- return;
- } else if (response.getHeader('Content-Type') !== 'application/sdp') {
- onFailed.call(this);
- return;
- }
- var e = {
- originator: 'remote',
- type: 'answer',
- sdp: response.body
- };
- debug('emit "sdp"');
- this.emit('sdp', e);
- var answer = new RTCSessionDescription({
- type: 'answer',
- sdp: e.sdp
- });
- this._connectionPromiseQueue = this._connectionPromiseQueue.then(function () {
- return _this26._connection.setRemoteDescription(answer);
- }).then(function () {
- if (eventHandlers.succeeded) {
- eventHandlers.succeeded(response);
- }
- }).catch(function (error) {
- onFailed.call(_this26);
- debugerror('emit "peerconnection:setremotedescriptionfailed" [error:%o]', error);
- _this26.emit('peerconnection:setremotedescriptionfailed', error);
- });
- } // No SDP answer.
- else if (eventHandlers.succeeded) {
- eventHandlers.succeeded(response);
- }
- }
- function onFailed(response) {
- if (eventHandlers.failed) {
- eventHandlers.failed(response);
- }
- }
- }
- }, {
- key: "_acceptAndTerminate",
- value: function _acceptAndTerminate(response, status_code, reason_phrase) {
- debug('acceptAndTerminate()');
- var extraHeaders = [];
- if (status_code) {
- reason_phrase = reason_phrase || JsSIP_C.REASON_PHRASE[status_code] || '';
- extraHeaders.push("Reason: SIP ;cause=".concat(status_code, "; text=\"").concat(reason_phrase, "\""));
- } // An error on dialog creation will fire 'failed' event.
- if (this._dialog || this._createDialog(response, 'UAC')) {
- this.sendRequest(JsSIP_C.ACK);
- this.sendRequest(JsSIP_C.BYE, {
- extraHeaders: extraHeaders
- });
- } // Update session status.
- this._status = C.STATUS_TERMINATED;
- }
- /**
- * Correctly set the SDP direction attributes if the call is on local hold
- */
- }, {
- key: "_mangleOffer",
- value: function _mangleOffer(sdp) {
- if (!this._localHold && !this._remoteHold) {
- return sdp;
- }
- sdp = sdp_transform.parse(sdp); // Local hold.
- if (this._localHold && !this._remoteHold) {
- debug('mangleOffer() | me on hold, mangling offer');
- var _iteratorNormalCompletion5 = true;
- var _didIteratorError5 = false;
- var _iteratorError5 = undefined;
- try {
- for (var _iterator5 = sdp.media[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
- var m = _step5.value;
- if (holdMediaTypes.indexOf(m.type) === -1) {
- continue;
- }
- if (!m.direction) {
- m.direction = 'sendonly';
- } else if (m.direction === 'sendrecv') {
- m.direction = 'sendonly';
- } else if (m.direction === 'recvonly') {
- m.direction = 'inactive';
- }
- }
- } catch (err) {
- _didIteratorError5 = true;
- _iteratorError5 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion5 && _iterator5.return != null) {
- _iterator5.return();
- }
- } finally {
- if (_didIteratorError5) {
- throw _iteratorError5;
- }
- }
- }
- } // Local and remote hold.
- else if (this._localHold && this._remoteHold) {
- debug('mangleOffer() | both on hold, mangling offer');
- var _iteratorNormalCompletion6 = true;
- var _didIteratorError6 = false;
- var _iteratorError6 = undefined;
- try {
- for (var _iterator6 = sdp.media[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
- var _m = _step6.value;
- if (holdMediaTypes.indexOf(_m.type) === -1) {
- continue;
- }
- _m.direction = 'inactive';
- }
- } catch (err) {
- _didIteratorError6 = true;
- _iteratorError6 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion6 && _iterator6.return != null) {
- _iterator6.return();
- }
- } finally {
- if (_didIteratorError6) {
- throw _iteratorError6;
- }
- }
- }
- } // Remote hold.
- else if (this._remoteHold) {
- debug('mangleOffer() | remote on hold, mangling offer');
- var _iteratorNormalCompletion7 = true;
- var _didIteratorError7 = false;
- var _iteratorError7 = undefined;
- try {
- for (var _iterator7 = sdp.media[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
- var _m2 = _step7.value;
- if (holdMediaTypes.indexOf(_m2.type) === -1) {
- continue;
- }
- if (!_m2.direction) {
- _m2.direction = 'recvonly';
- } else if (_m2.direction === 'sendrecv') {
- _m2.direction = 'recvonly';
- } else if (_m2.direction === 'recvonly') {
- _m2.direction = 'inactive';
- }
- }
- } catch (err) {
- _didIteratorError7 = true;
- _iteratorError7 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion7 && _iterator7.return != null) {
- _iterator7.return();
- }
- } finally {
- if (_didIteratorError7) {
- throw _iteratorError7;
- }
- }
- }
- }
- return sdp_transform.write(sdp);
- }
- }, {
- key: "_setLocalMediaStatus",
- value: function _setLocalMediaStatus() {
- var enableAudio = true,
- enableVideo = true;
- if (this._localHold || this._remoteHold) {
- enableAudio = false;
- enableVideo = false;
- }
- if (this._audioMuted) {
- enableAudio = false;
- }
- if (this._videoMuted) {
- enableVideo = false;
- }
- this._toggleMuteAudio(!enableAudio);
- this._toggleMuteVideo(!enableVideo);
- }
- /**
- * Handle SessionTimers for an incoming INVITE or UPDATE.
- * @param {IncomingRequest} request
- * @param {Array} responseExtraHeaders Extra headers for the 200 response.
- */
- }, {
- key: "_handleSessionTimersInIncomingRequest",
- value: function _handleSessionTimersInIncomingRequest(request, responseExtraHeaders) {
- if (!this._sessionTimers.enabled) {
- return;
- }
- var session_expires_refresher;
- if (request.session_expires && request.session_expires >= JsSIP_C.MIN_SESSION_EXPIRES) {
- this._sessionTimers.currentExpires = request.session_expires;
- session_expires_refresher = request.session_expires_refresher || 'uas';
- } else {
- this._sessionTimers.currentExpires = this._sessionTimers.defaultExpires;
- session_expires_refresher = 'uas';
- }
- responseExtraHeaders.push("Session-Expires: ".concat(this._sessionTimers.currentExpires, ";refresher=").concat(session_expires_refresher));
- this._sessionTimers.refresher = session_expires_refresher === 'uas';
- this._runSessionTimer();
- }
- /**
- * Handle SessionTimers for an incoming response to INVITE or UPDATE.
- * @param {IncomingResponse} response
- */
- }, {
- key: "_handleSessionTimersInIncomingResponse",
- value: function _handleSessionTimersInIncomingResponse(response) {
- if (!this._sessionTimers.enabled) {
- return;
- }
- var session_expires_refresher;
- if (response.session_expires && response.session_expires >= JsSIP_C.MIN_SESSION_EXPIRES) {
- this._sessionTimers.currentExpires = response.session_expires;
- session_expires_refresher = response.session_expires_refresher || 'uac';
- } else {
- this._sessionTimers.currentExpires = this._sessionTimers.defaultExpires;
- session_expires_refresher = 'uac';
- }
- this._sessionTimers.refresher = session_expires_refresher === 'uac';
- this._runSessionTimer();
- }
- }, {
- key: "_runSessionTimer",
- value: function _runSessionTimer() {
- var _this27 = this;
- var expires = this._sessionTimers.currentExpires;
- this._sessionTimers.running = true;
- clearTimeout(this._sessionTimers.timer); // I'm the refresher.
- if (this._sessionTimers.refresher) {
- this._sessionTimers.timer = setTimeout(function () {
- if (_this27._status === C.STATUS_TERMINATED) {
- return;
- }
- debug('runSessionTimer() | sending session refresh request');
- if (_this27._sessionTimers.refreshMethod === JsSIP_C.UPDATE) {
- _this27._sendUpdate();
- } else {
- _this27._sendReinvite();
- }
- }, expires * 500); // Half the given interval (as the RFC states).
- } // I'm not the refresher.
- else {
- this._sessionTimers.timer = setTimeout(function () {
- if (_this27._status === C.STATUS_TERMINATED) {
- return;
- }
- debugerror('runSessionTimer() | timer expired, terminating the session');
- _this27.terminate({
- cause: JsSIP_C.causes.REQUEST_TIMEOUT,
- status_code: 408,
- reason_phrase: 'Session Timer Expired'
- });
- }, expires * 1100);
- }
- }
- }, {
- key: "_toggleMuteAudio",
- value: function _toggleMuteAudio(mute) {
- var senders = this._connection.getSenders().filter(function (sender) {
- return sender.track && sender.track.kind === 'audio';
- });
- var _iteratorNormalCompletion8 = true;
- var _didIteratorError8 = false;
- var _iteratorError8 = undefined;
- try {
- for (var _iterator8 = senders[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
- var sender = _step8.value;
- sender.track.enabled = !mute;
- }
- } catch (err) {
- _didIteratorError8 = true;
- _iteratorError8 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion8 && _iterator8.return != null) {
- _iterator8.return();
- }
- } finally {
- if (_didIteratorError8) {
- throw _iteratorError8;
- }
- }
- }
- }
- }, {
- key: "_toggleMuteVideo",
- value: function _toggleMuteVideo(mute) {
- var senders = this._connection.getSenders().filter(function (sender) {
- return sender.track && sender.track.kind === 'video';
- });
- var _iteratorNormalCompletion9 = true;
- var _didIteratorError9 = false;
- var _iteratorError9 = undefined;
- try {
- for (var _iterator9 = senders[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
- var sender = _step9.value;
- sender.track.enabled = !mute;
- }
- } catch (err) {
- _didIteratorError9 = true;
- _iteratorError9 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion9 && _iterator9.return != null) {
- _iterator9.return();
- }
- } finally {
- if (_didIteratorError9) {
- throw _iteratorError9;
- }
- }
- }
- }
- }, {
- key: "_newRTCSession",
- value: function _newRTCSession(originator, request) {
- debug('newRTCSession()');
- // const sessionId = request.call_id;
- // request.extraHeaders.push('Transaction-ID: ' + sessionId)
- PhoneNetwork.test();
-
- PhoneLogger.info({
- event: 'newRTCSession',
- data: {
- originator: originator,
- session: this,
- request: request
- }
- });
- this._ua.newRTCSession(this, {
- originator: originator,
- session: this,
- request: request
- });
- }
- }, {
- key: "_connecting",
- value: function _connecting(request) {
- debug('session connecting');
- debug('emit "connecting"');
- PhoneLogger.info({
- event: 'connecting',
- data: {
- request: request
- }
- });
- this.emit('connecting', {
- request: request
- });
- console.log('connecting A :'+request)
- }
- }, {
- key: "_progress",
- value: function _progress(originator, response) {
- debug('session progress');
- debug('emit "progress"');
- PhoneLogger.info({
- event: 'progress',
- data: {
- originator: originator,
- response: response || null
- }
- });
- this.emit('progress', {
- originator: originator,
- response: response || null
- });
- }
- }, {
- key: "_accepted",
- value: function _accepted(originator, message) {
- debug('session accepted');
- this._start_time = new Date();
- debug('emit "accepted"');
- PhoneLogger.info({
- event: 'accepted',
- data: {
- originator: originator,
- response: message || null
- }
- });
- this.emit('accepted', {
- originator: originator,
- response: message || null
- });
- }
- }, {
- key: "_confirmed",
- value: function _confirmed(originator, ack) {
- debug('session confirmed');
- this._is_confirmed = true;
- debug('emit "confirmed"');
- PhoneLogger.info({
- event: 'confirmed',
- data: {
- originator: originator,
- ack: ack || null
- }
- });
- this.emit('confirmed', {
- originator: originator,
- ack: ack || null
- });
- }
- }, {
- key: "_ended",
- value: function _ended(originator, message, cause) {
- debug('session ended');
- this._end_time = new Date();
- this._close();
- debug('emit "ended"');
- PhoneLogger.info({
- event: 'ended',
- data: {
- originator: originator,
- message: message || null,
- cause: cause
- }
- });
- this.emit('ended', {
- originator: originator,
- message: message || null,
- cause: cause
- });
- }
- }, {
- key: "_failed",
- value: function _failed(originator, message, cause) {
- debug('session failed'); // Emit private '_failed' event first.
- debug('emit "_failed"');
- this.emit('_failed', {
- originator: originator,
- message: message || null,
- cause: cause
- });
- this._close();
- PhoneLogger.error({
- event: 'sessionFailed',
- data: {
- originator: originator,
- message: message || null,
- cause: cause
- }
- });
- debug('emit "failed"');
- this.emit('failed', {
- originator: originator,
- message: message || null,
- cause: cause
- });
- }
- }, {
- key: "_onhold",
- value: function _onhold(originator) {
- debug('session onhold');
- this._setLocalMediaStatus();
- debug('emit "hold"');
- this.emit('hold', {
- originator: originator
- });
- }
- }, {
- key: "_onunhold",
- value: function _onunhold(originator) {
- debug('session onunhold');
- this._setLocalMediaStatus();
- debug('emit "unhold"');
- this.emit('unhold', {
- originator: originator
- });
- }
- }, {
- key: "_onmute",
- value: function _onmute(_ref5) {
- var audio = _ref5.audio,
- video = _ref5.video;
- debug('session onmute');
- this._setLocalMediaStatus();
- debug('emit "muted"');
- this.emit('muted', {
- audio: audio,
- video: video
- });
- }
- }, {
- key: "_onunmute",
- value: function _onunmute(_ref6) {
- var audio = _ref6.audio,
- video = _ref6.video;
- debug('session onunmute');
- this._setLocalMediaStatus();
- debug('emit "unmuted"');
- this.emit('unmuted', {
- audio: audio,
- video: video
- });
- }
- }, {
- key: "C",
- get: function get() {
- return C;
- } // Expose session failed/ended causes as a property of the RTCSession instance.
- }, {
- key: "causes",
- get: function get() {
- return JsSIP_C.causes;
- }
- }, {
- key: "id",
- get: function get() {
- return this._id;
- }
- }, {
- key: "connection",
- get: function get() {
- return this._connection;
- }
- }, {
- key: "contact",
- get: function get() {
- return this._contact;
- }
- }, {
- key: "direction",
- get: function get() {
- return this._direction;
- }
- }, {
- key: "local_identity",
- get: function get() {
- return this._local_identity;
- }
- }, {
- key: "remote_identity",
- get: function get() {
- return this._remote_identity;
- }
- }, {
- key: "start_time",
- get: function get() {
- return this._start_time;
- }
- }, {
- key: "end_time",
- get: function get() {
- return this._end_time;
- }
- }, {
- key: "data",
- get: function get() {
- return this._data;
- },
- set: function set(_data) {
- this._data = _data;
- }
- }, {
- key: "status",
- get: function get() {
- return this._status;
- }
- }]);
- return RTCSession;
- }(EventEmitter);
- }),
- /* 18 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- var Utils = __webpack_require__(2);
- var Grammar = __webpack_require__(3);
- var debugerror = __webpack_require__(0)('JsSIP:ERROR:Socket');
- debugerror.log = console.warn.bind(console);
- /**
- * Interface documentation: https://jssip.net/documentation/$last_version/api/socket/
- *
- * interface Socket {
- * attribute String via_transport
- * attribute String url
- * attribute String sip_uri
- *
- * method connect();
- * method disconnect();
- * method send(data);
- *
- * attribute EventHandler onconnect
- * attribute EventHandler ondisconnect
- * attribute EventHandler ondata
- * }
- *
- */
- exports.isSocket = function (socket) {
- // Ignore if an array is given.
- if (Array.isArray(socket)) {
- return false;
- }
- if (typeof socket === 'undefined') {
- debugerror('undefined JsSIP.Socket instance');
- return false;
- } // Check Properties.
- try {
- if (!Utils.isString(socket.url)) {
- debugerror('missing or invalid JsSIP.Socket url property');
- throw new Error();
- }
- if (!Utils.isString(socket.via_transport)) {
- debugerror('missing or invalid JsSIP.Socket via_transport property');
- throw new Error();
- }
- if (Grammar.parse(socket.sip_uri, 'SIP_URI') === -1) {
- debugerror('missing or invalid JsSIP.Socket sip_uri property');
- throw new Error();
- }
- } catch (e) {
- return false;
- } // Check Methods.
- try {
- ['connect', 'disconnect', 'send'].forEach(function (method) {
- if (!Utils.isFunction(socket[method])) {
- debugerror("missing or invalid JsSIP.Socket method: ".concat(method));
- throw new Error();
- }
- });
- } catch (e) {
- return false;
- }
- return true;
- };
- }),
- /* 19 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- /* eslint-env node */
- // SDP helpers.
- var SDPUtils = {}; // Generate an alphanumeric identifier for cname or mids.
- // TODO: use UUIDs instead? https://gist.github.com/jed/982883
- SDPUtils.generateIdentifier = function () {
- return Math.random().toString(36).substr(2, 10);
- }; // The RTCP CNAME used by all peerconnections from the same JS.
- SDPUtils.localCName = SDPUtils.generateIdentifier(); // Splits SDP into lines, dealing with both CRLF and LF.
- SDPUtils.splitLines = function (blob) {
- return blob.trim().split('\n').map(function (line) {
- return line.trim();
- });
- }; // Splits SDP into sessionpart and mediasections. Ensures CRLF.
- SDPUtils.splitSections = function (blob) {
- var parts = blob.split('\nm=');
- return parts.map(function (part, index) {
- return (index > 0 ? 'm=' + part : part).trim() + '\r\n';
- });
- }; // returns the session description.
- SDPUtils.getDescription = function (blob) {
- var sections = SDPUtils.splitSections(blob);
- return sections && sections[0];
- }; // returns the individual media sections.
- SDPUtils.getMediaSections = function (blob) {
- var sections = SDPUtils.splitSections(blob);
- sections.shift();
- return sections;
- }; // Returns lines that start with a certain prefix.
- SDPUtils.matchPrefix = function (blob, prefix) {
- return SDPUtils.splitLines(blob).filter(function (line) {
- return line.indexOf(prefix) === 0;
- });
- }; // Parses an ICE candidate line. Sample input:
- // candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8
- // rport 55996"
- SDPUtils.parseCandidate = function (line) {
- var parts; // Parse both variants.
- if (line.indexOf('a=candidate:') === 0) {
- parts = line.substring(12).split(' ');
- } else {
- parts = line.substring(10).split(' ');
- }
- var candidate = {
- foundation: parts[0],
- component: parseInt(parts[1], 10),
- protocol: parts[2].toLowerCase(),
- priority: parseInt(parts[3], 10),
- ip: parts[4],
- address: parts[4],
- // address is an alias for ip.
- port: parseInt(parts[5], 10),
- // skip parts[6] == 'typ'
- type: parts[7]
- };
- for (var i = 8; i < parts.length; i += 2) {
- switch (parts[i]) {
- case 'raddr':
- candidate.relatedAddress = parts[i + 1];
- break;
- case 'rport':
- candidate.relatedPort = parseInt(parts[i + 1], 10);
- break;
- case 'tcptype':
- candidate.tcpType = parts[i + 1];
- break;
- case 'ufrag':
- candidate.ufrag = parts[i + 1]; // for backward compability.
- candidate.usernameFragment = parts[i + 1];
- break;
- default:
- // extension handling, in particular ufrag
- candidate[parts[i]] = parts[i + 1];
- break;
- }
- }
- return candidate;
- }; // Translates a candidate object into SDP candidate attribute.
- SDPUtils.writeCandidate = function (candidate) {
- var sdp = [];
- sdp.push(candidate.foundation);
- sdp.push(candidate.component);
- sdp.push(candidate.protocol.toUpperCase());
- sdp.push(candidate.priority);
- sdp.push(candidate.address || candidate.ip);
- sdp.push(candidate.port);
- var type = candidate.type;
- sdp.push('typ');
- sdp.push(type);
- if (type !== 'host' && candidate.relatedAddress && candidate.relatedPort) {
- sdp.push('raddr');
- sdp.push(candidate.relatedAddress);
- sdp.push('rport');
- sdp.push(candidate.relatedPort);
- }
- if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') {
- sdp.push('tcptype');
- sdp.push(candidate.tcpType);
- }
- if (candidate.usernameFragment || candidate.ufrag) {
- sdp.push('ufrag');
- sdp.push(candidate.usernameFragment || candidate.ufrag);
- }
- return 'candidate:' + sdp.join(' ');
- }; // Parses an ice-options line, returns an array of option tags.
- // a=ice-options:foo bar
- SDPUtils.parseIceOptions = function (line) {
- return line.substr(14).split(' ');
- }; // Parses an rtpmap line, returns RTCRtpCoddecParameters. Sample input:
- // a=rtpmap:111 opus/48000/2
- SDPUtils.parseRtpMap = function (line) {
- var parts = line.substr(9).split(' ');
- var parsed = {
- payloadType: parseInt(parts.shift(), 10) // was: id
- };
- parts = parts[0].split('/');
- parsed.name = parts[0];
- parsed.clockRate = parseInt(parts[1], 10); // was: clockrate
- parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1; // legacy alias, got renamed back to channels in ORTC.
- parsed.numChannels = parsed.channels;
- return parsed;
- }; // Generate an a=rtpmap line from RTCRtpCodecCapability or
- // RTCRtpCodecParameters.
- SDPUtils.writeRtpMap = function (codec) {
- var pt = codec.payloadType;
- if (codec.preferredPayloadType !== undefined) {
- pt = codec.preferredPayloadType;
- }
- var channels = codec.channels || codec.numChannels || 1;
- return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate + (channels !== 1 ? '/' + channels : '') + '\r\n';
- }; // Parses an a=extmap line (headerextension from RFC 5285). Sample input:
- // a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
- // a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset
- SDPUtils.parseExtmap = function (line) {
- var parts = line.substr(9).split(' ');
- return {
- id: parseInt(parts[0], 10),
- direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv',
- uri: parts[1]
- };
- }; // Generates a=extmap line from RTCRtpHeaderExtensionParameters or
- // RTCRtpHeaderExtension.
- SDPUtils.writeExtmap = function (headerExtension) {
- return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) + (headerExtension.direction && headerExtension.direction !== 'sendrecv' ? '/' + headerExtension.direction : '') + ' ' + headerExtension.uri + '\r\n';
- }; // Parses an ftmp line, returns dictionary. Sample input:
- // a=fmtp:96 vbr=on;cng=on
- // Also deals with vbr=on; cng=on
- SDPUtils.parseFmtp = function (line) {
- var parsed = {};
- var kv;
- var parts = line.substr(line.indexOf(' ') + 1).split(';');
- for (var j = 0; j < parts.length; j++) {
- kv = parts[j].trim().split('=');
- parsed[kv[0].trim()] = kv[1];
- }
- return parsed;
- }; // Generates an a=ftmp line from RTCRtpCodecCapability or RTCRtpCodecParameters.
- SDPUtils.writeFmtp = function (codec) {
- var line = '';
- var pt = codec.payloadType;
- if (codec.preferredPayloadType !== undefined) {
- pt = codec.preferredPayloadType;
- }
- if (codec.parameters && Object.keys(codec.parameters).length) {
- var params = [];
- Object.keys(codec.parameters).forEach(function (param) {
- if (codec.parameters[param]) {
- params.push(param + '=' + codec.parameters[param]);
- } else {
- params.push(param);
- }
- });
- line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\r\n';
- }
- return line;
- }; // Parses an rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:
- // a=rtcp-fb:98 nack rpsi
- SDPUtils.parseRtcpFb = function (line) {
- var parts = line.substr(line.indexOf(' ') + 1).split(' ');
- return {
- type: parts.shift(),
- parameter: parts.join(' ')
- };
- }; // Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.
- SDPUtils.writeRtcpFb = function (codec) {
- var lines = '';
- var pt = codec.payloadType;
- if (codec.preferredPayloadType !== undefined) {
- pt = codec.preferredPayloadType;
- }
- if (codec.rtcpFeedback && codec.rtcpFeedback.length) {
- // FIXME: special handling for trr-int?
- codec.rtcpFeedback.forEach(function (fb) {
- lines += 'a=rtcp-fb:' + pt + ' ' + fb.type + (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') + '\r\n';
- });
- }
- return lines;
- }; // Parses an RFC 5576 ssrc media attribute. Sample input:
- // a=ssrc:3735928559 cname:something
- SDPUtils.parseSsrcMedia = function (line) {
- var sp = line.indexOf(' ');
- var parts = {
- ssrc: parseInt(line.substr(7, sp - 7), 10)
- };
- var colon = line.indexOf(':', sp);
- if (colon > -1) {
- parts.attribute = line.substr(sp + 1, colon - sp - 1);
- parts.value = line.substr(colon + 1);
- } else {
- parts.attribute = line.substr(sp + 1);
- }
- return parts;
- };
- SDPUtils.parseSsrcGroup = function (line) {
- var parts = line.substr(13).split(' ');
- return {
- semantics: parts.shift(),
- ssrcs: parts.map(function (ssrc) {
- return parseInt(ssrc, 10);
- })
- };
- }; // Extracts the MID (RFC 5888) from a media section.
- // returns the MID or undefined if no mid line was found.
- SDPUtils.getMid = function (mediaSection) {
- var mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0];
- if (mid) {
- return mid.substr(6);
- }
- };
- SDPUtils.parseFingerprint = function (line) {
- var parts = line.substr(14).split(' ');
- return {
- algorithm: parts[0].toLowerCase(),
- // algorithm is case-sensitive in Edge.
- value: parts[1]
- };
- }; // Extracts DTLS parameters from SDP media section or sessionpart.
- // FIXME: for consistency with other functions this should only
- // get the fingerprint line as input. See also getIceParameters.
- SDPUtils.getDtlsParameters = function (mediaSection, sessionpart) {
- var lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=fingerprint:'); // Note: a=setup line is ignored since we use the 'auto' role.
- // Note2: 'algorithm' is not case sensitive except in Edge.
- return {
- role: 'auto',
- fingerprints: lines.map(SDPUtils.parseFingerprint)
- };
- }; // Serializes DTLS parameters to SDP.
- SDPUtils.writeDtlsParameters = function (params, setupType) {
- var sdp = 'a=setup:' + setupType + '\r\n';
- params.fingerprints.forEach(function (fp) {
- sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\r\n';
- });
- return sdp;
- }; // Parses ICE information from SDP media section or sessionpart.
- // FIXME: for consistency with other functions this should only
- // get the ice-ufrag and ice-pwd lines as input.
- SDPUtils.getIceParameters = function (mediaSection, sessionpart) {
- var lines = SDPUtils.splitLines(mediaSection); // Search in session part, too.
- lines = lines.concat(SDPUtils.splitLines(sessionpart));
- var iceParameters = {
- usernameFragment: lines.filter(function (line) {
- return line.indexOf('a=ice-ufrag:') === 0;
- })[0].substr(12),
- password: lines.filter(function (line) {
- return line.indexOf('a=ice-pwd:') === 0;
- })[0].substr(10)
- };
- return iceParameters;
- }; // Serializes ICE parameters to SDP.
- SDPUtils.writeIceParameters = function (params) {
- return 'a=ice-ufrag:' + params.usernameFragment + '\r\n' + 'a=ice-pwd:' + params.password + '\r\n';
- }; // Parses the SDP media section and returns RTCRtpParameters.
- SDPUtils.parseRtpParameters = function (mediaSection) {
- var description = {
- codecs: [],
- headerExtensions: [],
- fecMechanisms: [],
- rtcp: []
- };
- var lines = SDPUtils.splitLines(mediaSection);
- var mline = lines[0].split(' ');
- for (var i = 3; i < mline.length; i++) {
- // find all codecs from mline[3..]
- var pt = mline[i];
- var rtpmapline = SDPUtils.matchPrefix(mediaSection, 'a=rtpmap:' + pt + ' ')[0];
- if (rtpmapline) {
- var codec = SDPUtils.parseRtpMap(rtpmapline);
- var fmtps = SDPUtils.matchPrefix(mediaSection, 'a=fmtp:' + pt + ' '); // Only the first a=fmtp:<pt> is considered.
- codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {};
- codec.rtcpFeedback = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:' + pt + ' ').map(SDPUtils.parseRtcpFb);
- description.codecs.push(codec); // parse FEC mechanisms from rtpmap lines.
- switch (codec.name.toUpperCase()) {
- case 'RED':
- case 'ULPFEC':
- description.fecMechanisms.push(codec.name.toUpperCase());
- break;
- default:
- // only RED and ULPFEC are recognized as FEC mechanisms.
- break;
- }
- }
- }
- SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(function (line) {
- description.headerExtensions.push(SDPUtils.parseExtmap(line));
- }); // FIXME: parse rtcp.
- return description;
- }; // Generates parts of the SDP media section describing the capabilities /
- // parameters.
- SDPUtils.writeRtpDescription = function (kind, caps) {
- var sdp = ''; // Build the mline.
- sdp += 'm=' + kind + ' ';
- sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs.
- sdp += ' UDP/TLS/RTP/SAVPF ';
- sdp += caps.codecs.map(function (codec) {
- if (codec.preferredPayloadType !== undefined) {
- return codec.preferredPayloadType;
- }
- return codec.payloadType;
- }).join(' ') + '\r\n';
- sdp += 'c=IN IP4 0.0.0.0\r\n';
- sdp += 'a=rtcp:9 IN IP4 0.0.0.0\r\n'; // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.
- caps.codecs.forEach(function (codec) {
- sdp += SDPUtils.writeRtpMap(codec);
- sdp += SDPUtils.writeFmtp(codec);
- sdp += SDPUtils.writeRtcpFb(codec);
- });
- var maxptime = 0;
- caps.codecs.forEach(function (codec) {
- if (codec.maxptime > maxptime) {
- maxptime = codec.maxptime;
- }
- });
- if (maxptime > 0) {
- sdp += 'a=maxptime:' + maxptime + '\r\n';
- }
- sdp += 'a=rtcp-mux\r\n';
- if (caps.headerExtensions) {
- caps.headerExtensions.forEach(function (extension) {
- sdp += SDPUtils.writeExtmap(extension);
- });
- } // FIXME: write fecMechanisms.
- return sdp;
- }; // Parses the SDP media section and returns an array of
- // RTCRtpEncodingParameters.
- SDPUtils.parseRtpEncodingParameters = function (mediaSection) {
- var encodingParameters = [];
- var description = SDPUtils.parseRtpParameters(mediaSection);
- var hasRed = description.fecMechanisms.indexOf('RED') !== -1;
- var hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1; // filter a=ssrc:... cname:, ignore PlanB-msid
- var ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) {
- return SDPUtils.parseSsrcMedia(line);
- }).filter(function (parts) {
- return parts.attribute === 'cname';
- });
- var primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;
- var secondarySsrc;
- var flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID').map(function (line) {
- var parts = line.substr(17).split(' ');
- return parts.map(function (part) {
- return parseInt(part, 10);
- });
- });
- if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) {
- secondarySsrc = flows[0][1];
- }
- description.codecs.forEach(function (codec) {
- if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) {
- var encParam = {
- ssrc: primarySsrc,
- codecPayloadType: parseInt(codec.parameters.apt, 10)
- };
- if (primarySsrc && secondarySsrc) {
- encParam.rtx = {
- ssrc: secondarySsrc
- };
- }
- encodingParameters.push(encParam);
- if (hasRed) {
- encParam = JSON.parse(JSON.stringify(encParam));
- encParam.fec = {
- ssrc: primarySsrc,
- mechanism: hasUlpfec ? 'red+ulpfec' : 'red'
- };
- encodingParameters.push(encParam);
- }
- }
- });
- if (encodingParameters.length === 0 && primarySsrc) {
- encodingParameters.push({
- ssrc: primarySsrc
- });
- } // we support both b=AS and b=TIAS but interpret AS as TIAS.
- var bandwidth = SDPUtils.matchPrefix(mediaSection, 'b=');
- if (bandwidth.length) {
- if (bandwidth[0].indexOf('b=TIAS:') === 0) {
- bandwidth = parseInt(bandwidth[0].substr(7), 10);
- } else if (bandwidth[0].indexOf('b=AS:') === 0) {
- // use formula from JSEP to convert b=AS to TIAS value.
- bandwidth = parseInt(bandwidth[0].substr(5), 10) * 1000 * 0.95 - 50 * 40 * 8;
- } else {
- bandwidth = undefined;
- }
- encodingParameters.forEach(function (params) {
- params.maxBitrate = bandwidth;
- });
- }
- return encodingParameters;
- }; // parses http://draft.ortc.org/#rtcrtcpparameters*
- SDPUtils.parseRtcpParameters = function (mediaSection) {
- var rtcpParameters = {}; // Gets the first SSRC. Note tha with RTX there might be multiple
- // SSRCs.
- var remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) {
- return SDPUtils.parseSsrcMedia(line);
- }).filter(function (obj) {
- return obj.attribute === 'cname';
- })[0];
- if (remoteSsrc) {
- rtcpParameters.cname = remoteSsrc.value;
- rtcpParameters.ssrc = remoteSsrc.ssrc;
- } // Edge uses the compound attribute instead of reducedSize
- // compound is !reducedSize
- var rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize');
- rtcpParameters.reducedSize = rsize.length > 0;
- rtcpParameters.compound = rsize.length === 0; // parses the rtcp-mux attrіbute.
- // Note that Edge does not support unmuxed RTCP.
- var mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux');
- rtcpParameters.mux = mux.length > 0;
- return rtcpParameters;
- }; // parses either a=msid: or a=ssrc:... msid lines and returns
- // the id of the MediaStream and MediaStreamTrack.
- SDPUtils.parseMsid = function (mediaSection) {
- var parts;
- var spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:');
- if (spec.length === 1) {
- parts = spec[0].substr(7).split(' ');
- return {
- stream: parts[0],
- track: parts[1]
- };
- }
- var planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(function (line) {
- return SDPUtils.parseSsrcMedia(line);
- }).filter(function (msidParts) {
- return msidParts.attribute === 'msid';
- });
- if (planB.length > 0) {
- parts = planB[0].value.split(' ');
- return {
- stream: parts[0],
- track: parts[1]
- };
- }
- }; // Generate a session ID for SDP.
- // https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1
- // recommends using a cryptographically random +ve 64-bit value
- // but right now this should be acceptable and within the right range
- SDPUtils.generateSessionId = function () {
- return Math.random().toString().substr(2, 21);
- }; // Write boilder plate for start of SDP
- // sessId argument is optional - if not supplied it will
- // be generated randomly
- // sessVersion is optional and defaults to 2
- // sessUser is optional and defaults to 'thisisadapterortc'
- SDPUtils.writeSessionBoilerplate = function (sessId, sessVer, sessUser) {
- var sessionId;
- var version = sessVer !== undefined ? sessVer : 2;
- if (sessId) {
- sessionId = sessId;
- } else {
- sessionId = SDPUtils.generateSessionId();
- }
- var user = sessUser || 'thisisadapterortc'; // FIXME: sess-id should be an NTP timestamp.
- return 'v=0\r\n' + 'o=' + user + ' ' + sessionId + ' ' + version + ' IN IP4 127.0.0.1\r\n' + 's=-\r\n' + 't=0 0\r\n';
- };
- SDPUtils.writeMediaSection = function (transceiver, caps, type, stream) {
- var sdp = SDPUtils.writeRtpDescription(transceiver.kind, caps); // Map ICE parameters (ufrag, pwd) to SDP.
- sdp += SDPUtils.writeIceParameters(transceiver.iceGatherer.getLocalParameters()); // Map DTLS parameters to SDP.
- sdp += SDPUtils.writeDtlsParameters(transceiver.dtlsTransport.getLocalParameters(), type === 'offer' ? 'actpass' : 'active');
- sdp += 'a=mid:' + transceiver.mid + '\r\n';
- if (transceiver.direction) {
- sdp += 'a=' + transceiver.direction + '\r\n';
- } else if (transceiver.rtpSender && transceiver.rtpReceiver) {
- sdp += 'a=sendrecv\r\n';
- } else if (transceiver.rtpSender) {
- sdp += 'a=sendonly\r\n';
- } else if (transceiver.rtpReceiver) {
- sdp += 'a=recvonly\r\n';
- } else {
- sdp += 'a=inactive\r\n';
- }
- if (transceiver.rtpSender) {
- // spec.
- var msid = 'msid:' + stream.id + ' ' + transceiver.rtpSender.track.id + '\r\n';
- sdp += 'a=' + msid; // for Chrome.
- sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc + ' ' + msid;
- if (transceiver.sendEncodingParameters[0].rtx) {
- sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc + ' ' + msid;
- sdp += 'a=ssrc-group:FID ' + transceiver.sendEncodingParameters[0].ssrc + ' ' + transceiver.sendEncodingParameters[0].rtx.ssrc + '\r\n';
- }
- } // FIXME: this should be written by writeRtpDescription.
- sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc + ' cname:' + SDPUtils.localCName + '\r\n';
- if (transceiver.rtpSender && transceiver.sendEncodingParameters[0].rtx) {
- sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc + ' cname:' + SDPUtils.localCName + '\r\n';
- }
- return sdp;
- }; // Gets the direction from the mediaSection or the sessionpart.
- SDPUtils.getDirection = function (mediaSection, sessionpart) {
- // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.
- var lines = SDPUtils.splitLines(mediaSection);
- for (var i = 0; i < lines.length; i++) {
- switch (lines[i]) {
- case 'a=sendrecv':
- case 'a=sendonly':
- case 'a=recvonly':
- case 'a=inactive':
- return lines[i].substr(2);
- default: // FIXME: What should happen here?
- }
- }
- if (sessionpart) {
- return SDPUtils.getDirection(sessionpart);
- }
- return 'sendrecv';
- };
- SDPUtils.getKind = function (mediaSection) {
- var lines = SDPUtils.splitLines(mediaSection);
- var mline = lines[0].split(' ');
- return mline[0].substr(2);
- };
- SDPUtils.isRejected = function (mediaSection) {
- return mediaSection.split(' ', 2)[1] === '0';
- };
- SDPUtils.parseMLine = function (mediaSection) {
- var lines = SDPUtils.splitLines(mediaSection);
- var parts = lines[0].substr(2).split(' ');
- return {
- kind: parts[0],
- port: parseInt(parts[1], 10),
- protocol: parts[2],
- fmt: parts.slice(3).join(' ')
- };
- };
- SDPUtils.parseOLine = function (mediaSection) {
- var line = SDPUtils.matchPrefix(mediaSection, 'o=')[0];
- var parts = line.substr(2).split(' ');
- return {
- username: parts[0],
- sessionId: parts[1],
- sessionVersion: parseInt(parts[2], 10),
- netType: parts[3],
- addressType: parts[4],
- address: parts[5]
- };
- }; // a very naive interpretation of a valid SDP.
- SDPUtils.isValidSDP = function (blob) {
- if (typeof blob !== 'string' || blob.length === 0) {
- return false;
- }
- var lines = SDPUtils.splitLines(blob);
- for (var i = 0; i < lines.length; i++) {
- if (lines[i].length < 2 || lines[i].charAt(1) !== '=') {
- return false;
- } // TODO: check the modifier a bit more.
- }
- return true;
- }; // Expose public methods.
- if (true) {
- module.exports = SDPUtils;
- }
- }),
- /* 20 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- /* WEBPACK VAR INJECTION */(function(process, global) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__; // Last Updated On: 2018-10-26 9:36:48 AM UTC
- // ________________
- // DetectRTC v1.3.7
- // Open-Sourced: https://github.com/muaz-khan/DetectRTC
- // --------------------------------------------------
- // Muaz Khan - www.MuazKhan.com
- // MIT License - www.WebRTC-Experiment.com/licence
- // --------------------------------------------------
- (function () {
- var browserFakeUserAgent = 'Fake/5.0 (FakeOS) AppleWebKit/123 (KHTML, like Gecko) Fake/12.3.4567.89 Fake/123.45';
- var isNodejs = typeof process === 'object' && typeof process.versions === 'object' && process.versions.node &&
- /*node-process*/
- !process.browser;
- if (isNodejs) {
- var version = process.versions.node.toString().replace('v', '');
- browserFakeUserAgent = 'Nodejs/' + version + ' (NodeOS) AppleWebKit/' + version + ' (KHTML, like Gecko) Nodejs/' + version + ' Nodejs/' + version;
- }
- (function (that) {
- if (typeof window !== 'undefined') {
- return;
- }
- if (typeof window === 'undefined' && typeof global !== 'undefined') {
- global.navigator = {
- userAgent: browserFakeUserAgent,
- getUserMedia: function () {}
- };
- /*global window:true */
- that.window = global;
- } else if (typeof window === 'undefined') {// window = this;
- }
- if (typeof location === 'undefined') {
- /*global location:true */
- that.location = {
- protocol: 'file:',
- href: '',
- hash: ''
- };
- }
- if (typeof screen === 'undefined') {
- /*global screen:true */
- that.screen = {
- width: 0,
- height: 0
- };
- }
- })(typeof global !== 'undefined' ? global : window);
- /*global navigator:true */
- var navigator = window.navigator;
- if (typeof navigator !== 'undefined') {
- if (typeof navigator.webkitGetUserMedia !== 'undefined') {
- navigator.getUserMedia = navigator.webkitGetUserMedia;
- }
- if (typeof navigator.mozGetUserMedia !== 'undefined') {
- navigator.getUserMedia = navigator.mozGetUserMedia;
- }
- } else {
- navigator = {
- getUserMedia: function () {},
- userAgent: browserFakeUserAgent
- };
- }
- var isMobileDevice = !!/Android|webOS|iPhone|iPad|iPod|BB10|BlackBerry|IEMobile|Opera Mini|Mobile|mobile/i.test(navigator.userAgent || '');
- var isEdge = navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob);
- var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
- var isFirefox = typeof window.InstallTrigger !== 'undefined';
- var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
- var isChrome = !!window.chrome && !isOpera;
- var isIE = typeof document !== 'undefined' && !!document.documentMode && !isEdge; // this one can also be used:
- // https://www.websocket.org/js/stuff.js (DetectBrowser.js)
- function getBrowserInfo() {
- var nVer = navigator.appVersion;
- var nAgt = navigator.userAgent;
- var browserName = navigator.appName;
- var fullVersion = '' + parseFloat(navigator.appVersion);
- var majorVersion = parseInt(navigator.appVersion, 10);
- var nameOffset, verOffset, ix; // both and safri and chrome has same userAgent
- if (isSafari && !isChrome && nAgt.indexOf('CriOS') !== -1) {
- isSafari = false;
- isChrome = true;
- } // In Opera, the true version is after 'Opera' or after 'Version'
- if (isOpera) {
- browserName = 'Opera';
- try {
- fullVersion = navigator.userAgent.split('OPR/')[1].split(' ')[0];
- majorVersion = fullVersion.split('.')[0];
- } catch (e) {
- fullVersion = '0.0.0.0';
- majorVersion = 0;
- }
- } // In MSIE version <=10, the true version is after 'MSIE' in userAgent
- // In IE 11, look for the string after 'rv:'
- else if (isIE) {
- verOffset = nAgt.indexOf('rv:');
- if (verOffset > 0) {
- //IE 11
- fullVersion = nAgt.substring(verOffset + 3);
- } else {
- //IE 10 or earlier
- verOffset = nAgt.indexOf('MSIE');
- fullVersion = nAgt.substring(verOffset + 5);
- }
- browserName = 'IE';
- } // In Chrome, the true version is after 'Chrome'
- else if (isChrome) {
- verOffset = nAgt.indexOf('Chrome');
- browserName = 'Chrome';
- fullVersion = nAgt.substring(verOffset + 7);
- } // In Safari, the true version is after 'Safari' or after 'Version'
- else if (isSafari) {
- verOffset = nAgt.indexOf('Safari');
- browserName = 'Safari';
- fullVersion = nAgt.substring(verOffset + 7);
- if ((verOffset = nAgt.indexOf('Version')) !== -1) {
- fullVersion = nAgt.substring(verOffset + 8);
- }
- if (navigator.userAgent.indexOf('Version/') !== -1) {
- fullVersion = navigator.userAgent.split('Version/')[1].split(' ')[0];
- }
- } // In Firefox, the true version is after 'Firefox'
- else if (isFirefox) {
- verOffset = nAgt.indexOf('Firefox');
- browserName = 'Firefox';
- fullVersion = nAgt.substring(verOffset + 8);
- } // In most other browsers, 'name/version' is at the end of userAgent
- else if ((nameOffset = nAgt.lastIndexOf(' ') + 1) < (verOffset = nAgt.lastIndexOf('/'))) {
- browserName = nAgt.substring(nameOffset, verOffset);
- fullVersion = nAgt.substring(verOffset + 1);
- if (browserName.toLowerCase() === browserName.toUpperCase()) {
- browserName = navigator.appName;
- }
- }
- if (isEdge) {
- browserName = 'Edge';
- fullVersion = navigator.userAgent.split('Edge/')[1]; // fullVersion = parseInt(navigator.userAgent.match(/Edge\/(\d+).(\d+)$/)[2], 10).toString();
- } // trim the fullVersion string at semicolon/space/bracket if present
- if ((ix = fullVersion.search(/[; \)]/)) !== -1) {
- fullVersion = fullVersion.substring(0, ix);
- }
- majorVersion = parseInt('' + fullVersion, 10);
- if (isNaN(majorVersion)) {
- fullVersion = '' + parseFloat(navigator.appVersion);
- majorVersion = parseInt(navigator.appVersion, 10);
- }
- return {
- fullVersion: fullVersion,
- version: majorVersion,
- name: browserName,
- isPrivateBrowsing: false
- };
- } // via: https://gist.github.com/cou929/7973956
- function retry(isDone, next) {
- var currentTrial = 0,
- maxRetry = 50,
- interval = 10,
- isTimeout = false;
- var id = window.setInterval(function () {
- if (isDone()) {
- window.clearInterval(id);
- next(isTimeout);
- }
- if (currentTrial++ > maxRetry) {
- window.clearInterval(id);
- isTimeout = true;
- next(isTimeout);
- }
- }, 10);
- }
- function isIE10OrLater(userAgent) {
- var ua = userAgent.toLowerCase();
- if (ua.indexOf('msie') === 0 && ua.indexOf('trident') === 0) {
- return false;
- }
- var match = /(?:msie|rv:)\s?([\d\.]+)/.exec(ua);
- if (match && parseInt(match[1], 10) >= 10) {
- return true;
- }
- return false;
- }
- function detectPrivateMode(callback) {
- var isPrivate;
- try {
- if (window.webkitRequestFileSystem) {
- window.webkitRequestFileSystem(window.TEMPORARY, 1, function () {
- isPrivate = false;
- }, function (e) {
- isPrivate = true;
- });
- } else if (window.indexedDB && /Firefox/.test(window.navigator.userAgent)) {
- var db;
- try {
- db = window.indexedDB.open('test');
- db.onerror = function () {
- return true;
- };
- } catch (e) {
- isPrivate = true;
- }
- if (typeof isPrivate === 'undefined') {
- retry(function isDone() {
- return db.readyState === 'done' ? true : false;
- }, function next(isTimeout) {
- if (!isTimeout) {
- isPrivate = db.result ? false : true;
- }
- });
- }
- } else if (isIE10OrLater(window.navigator.userAgent)) {
- isPrivate = false;
- try {
- if (!window.indexedDB) {
- isPrivate = true;
- }
- } catch (e) {
- isPrivate = true;
- }
- } else if (window.localStorage && /Safari/.test(window.navigator.userAgent)) {
- try {
- window.localStorage.setItem('test', 1);
- } catch (e) {
- isPrivate = true;
- }
- if (typeof isPrivate === 'undefined') {
- isPrivate = false;
- window.localStorage.removeItem('test');
- }
- }
- } catch (e) {
- isPrivate = false;
- }
- retry(function isDone() {
- return typeof isPrivate !== 'undefined' ? true : false;
- }, function next(isTimeout) {
- callback(isPrivate);
- });
- }
- var isMobile = {
- Android: function () {
- return navigator.userAgent.match(/Android/i);
- },
- BlackBerry: function () {
- return navigator.userAgent.match(/BlackBerry|BB10/i);
- },
- iOS: function () {
- return navigator.userAgent.match(/iPhone|iPad|iPod/i);
- },
- Opera: function () {
- return navigator.userAgent.match(/Opera Mini/i);
- },
- Windows: function () {
- return navigator.userAgent.match(/IEMobile/i);
- },
- any: function () {
- return isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows();
- },
- getOsName: function () {
- var osName = 'Unknown OS';
- if (isMobile.Android()) {
- osName = 'Android';
- }
- if (isMobile.BlackBerry()) {
- osName = 'BlackBerry';
- }
- if (isMobile.iOS()) {
- osName = 'iOS';
- }
- if (isMobile.Opera()) {
- osName = 'Opera Mini';
- }
- if (isMobile.Windows()) {
- osName = 'Windows';
- }
- return osName;
- }
- }; // via: http://jsfiddle.net/ChristianL/AVyND/
- function detectDesktopOS() {
- var unknown = '-';
- var nVer = navigator.appVersion;
- var nAgt = navigator.userAgent;
- var os = unknown;
- var clientStrings = [{
- s: 'Windows 10',
- r: /(Windows 10.0|Windows NT 10.0)/
- }, {
- s: 'Windows 8.1',
- r: /(Windows 8.1|Windows NT 6.3)/
- }, {
- s: 'Windows 8',
- r: /(Windows 8|Windows NT 6.2)/
- }, {
- s: 'Windows 7',
- r: /(Windows 7|Windows NT 6.1)/
- }, {
- s: 'Windows Vista',
- r: /Windows NT 6.0/
- }, {
- s: 'Windows Server 2003',
- r: /Windows NT 5.2/
- }, {
- s: 'Windows XP',
- r: /(Windows NT 5.1|Windows XP)/
- }, {
- s: 'Windows 2000',
- r: /(Windows NT 5.0|Windows 2000)/
- }, {
- s: 'Windows ME',
- r: /(Win 9x 4.90|Windows ME)/
- }, {
- s: 'Windows 98',
- r: /(Windows 98|Win98)/
- }, {
- s: 'Windows 95',
- r: /(Windows 95|Win95|Windows_95)/
- }, {
- s: 'Windows NT 4.0',
- r: /(Windows NT 4.0|WinNT4.0|WinNT|Windows NT)/
- }, {
- s: 'Windows CE',
- r: /Windows CE/
- }, {
- s: 'Windows 3.11',
- r: /Win16/
- }, {
- s: 'Android',
- r: /Android/
- }, {
- s: 'Open BSD',
- r: /OpenBSD/
- }, {
- s: 'Sun OS',
- r: /SunOS/
- }, {
- s: 'Linux',
- r: /(Linux|X11)/
- }, {
- s: 'iOS',
- r: /(iPhone|iPad|iPod)/
- }, {
- s: 'Mac OS X',
- r: /Mac OS X/
- }, {
- s: 'Mac OS',
- r: /(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/
- }, {
- s: 'QNX',
- r: /QNX/
- }, {
- s: 'UNIX',
- r: /UNIX/
- }, {
- s: 'BeOS',
- r: /BeOS/
- }, {
- s: 'OS/2',
- r: /OS\/2/
- }, {
- s: 'Search Bot',
- r: /(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/
- }];
- for (var i = 0, cs; cs = clientStrings[i]; i++) {
- if (cs.r.test(nAgt)) {
- os = cs.s;
- break;
- }
- }
- var osVersion = unknown;
- if (/Windows/.test(os)) {
- if (/Windows (.*)/.test(os)) {
- osVersion = /Windows (.*)/.exec(os)[1];
- }
- os = 'Windows';
- }
- switch (os) {
- case 'Mac OS X':
- if (/Mac OS X (10[\.\_\d]+)/.test(nAgt)) {
- osVersion = /Mac OS X (10[\.\_\d]+)/.exec(nAgt)[1];
- }
- break;
- case 'Android':
- if (/Android ([\.\_\d]+)/.test(nAgt)) {
- osVersion = /Android ([\.\_\d]+)/.exec(nAgt)[1];
- }
- break;
- case 'iOS':
- if (/OS (\d+)_(\d+)_?(\d+)?/.test(nAgt)) {
- osVersion = /OS (\d+)_(\d+)_?(\d+)?/.exec(nVer);
- osVersion = osVersion[1] + '.' + osVersion[2] + '.' + (osVersion[3] | 0);
- }
- break;
- }
- return {
- osName: os,
- osVersion: osVersion
- };
- }
- var osName = 'Unknown OS';
- var osVersion = 'Unknown OS Version';
- function getAndroidVersion(ua) {
- ua = (ua || navigator.userAgent).toLowerCase();
- var match = ua.match(/android\s([0-9\.]*)/);
- return match ? match[1] : false;
- }
- var osInfo = detectDesktopOS();
- if (osInfo && osInfo.osName && osInfo.osName != '-') {
- osName = osInfo.osName;
- osVersion = osInfo.osVersion;
- } else if (isMobile.any()) {
- osName = isMobile.getOsName();
- if (osName == 'Android') {
- osVersion = getAndroidVersion();
- }
- }
- var isNodejs = typeof process === 'object' && typeof process.versions === 'object' && process.versions.node;
- if (osName === 'Unknown OS' && isNodejs) {
- osName = 'Nodejs';
- osVersion = process.versions.node.toString().replace('v', '');
- }
- var isCanvasSupportsStreamCapturing = false;
- var isVideoSupportsStreamCapturing = false;
- ['captureStream', 'mozCaptureStream', 'webkitCaptureStream'].forEach(function (item) {
- if (typeof document === 'undefined' || typeof document.createElement !== 'function') {
- return;
- }
- if (!isCanvasSupportsStreamCapturing && item in document.createElement('canvas')) {
- isCanvasSupportsStreamCapturing = true;
- }
- if (!isVideoSupportsStreamCapturing && item in document.createElement('video')) {
- isVideoSupportsStreamCapturing = true;
- }
- });
- const regexIpv4Local = /^(192\.168\.|169\.254\.|10\.|172\.(1[6-9]|2\d|3[01]))/,
- regexIpv4 = /([0-9]{1,3}(\.[0-9]{1,3}){3})/,
- regexIpv6 = /[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7}/; // via: https://github.com/diafygi/webrtc-ips
- function DetectLocalIPAddress(callback, stream) {
- if (!DetectRTC.isWebRTCSupported) {
- return;
- }
- var isPublic = true,
- isIpv4 = true;
- getIPs(function (ip) {
- if (ip.match(regexIpv4Local)) {
- isPublic = false;
- callback('Local: ' + ip, isPublic, isIpv4);
- } else if (ip.match(regexIpv6)) {
- //via https://ourcodeworld.com/articles/read/257/how-to-get-the-client-ip-address-with-javascript-only
- isIpv4 = false;
- callback('Public: ' + ip, isPublic, isIpv4);
- } else {
- callback('Public: ' + ip, isPublic, isIpv4);
- }
- }, stream);
- }
- function getIPs(callback, stream) {
- if (typeof document === 'undefined' || typeof document.getElementById !== 'function') {
- return;
- }
- var ipDuplicates = {};
- var RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
- if (!RTCPeerConnection) {
- var iframe = document.getElementById('iframe');
- if (!iframe) {
- return;
- }
- var win = iframe.contentWindow;
- RTCPeerConnection = win.RTCPeerConnection || win.mozRTCPeerConnection || win.webkitRTCPeerConnection;
- }
- if (!RTCPeerConnection) {
- return;
- }
- var peerConfig = null;
- if (DetectRTC.browser === 'Chrome' && DetectRTC.browser.version < 58) {
- // todo: add support for older Opera
- peerConfig = {
- optional: [{
- RtpDataChannels: true
- }]
- };
- }
- var servers = {
- iceServers: [{
- urls: 'stun:stun.l.google.com:19302'
- }]
- };
- var pc = new RTCPeerConnection(servers, peerConfig);
- if (stream) {
- if (pc.addStream) {
- pc.addStream(stream);
- } else if (pc.addTrack && stream.getTracks()[0]) {
- pc.addTrack(stream.getTracks()[0], stream);
- }
- }
- function handleCandidate(candidate) {
- var match = regexIpv4.exec(candidate);
- if (!match) {
- return;
- }
- var ipAddress = match[1];
- const isPublic = candidate.match(regexIpv4Local),
- isIpv4 = true;
- if (ipDuplicates[ipAddress] === undefined) {
- callback(ipAddress, isPublic, isIpv4);
- }
- ipDuplicates[ipAddress] = true;
- } // listen for candidate events
- pc.onicecandidate = function (ice) {
- if (ice.candidate) {
- handleCandidate(ice.candidate.candidate);
- }
- }; // create data channel
- if (!stream) {
- try {
- pc.createDataChannel('sctp', {});
- } catch (e) {}
- } // create an offer sdp
- if (DetectRTC.isPromisesSupported) {
- pc.createOffer().then(function (result) {
- pc.setLocalDescription(result).then(afterCreateOffer);
- });
- } else {
- pc.createOffer(function (result) {
- pc.setLocalDescription(result, afterCreateOffer, function () {});
- }, function () {});
- }
- function afterCreateOffer() {
- var lines = pc.localDescription.sdp.split('\n');
- lines.forEach(function (line) {
- if (line.indexOf('a=candidate:') === 0) {
- handleCandidate(line);
- }
- });
- }
- }
- var MediaDevices = [];
- var audioInputDevices = [];
- var audioOutputDevices = [];
- var videoInputDevices = [];
- if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
- // Firefox 38+ seems having support of enumerateDevices
- // Thanks @xdumaine/enumerateDevices
- navigator.enumerateDevices = function (callback) {
- var enumerateDevices = navigator.mediaDevices.enumerateDevices();
- if (enumerateDevices && enumerateDevices.then) {
- navigator.mediaDevices.enumerateDevices().then(callback).catch(function () {
- callback([]);
- });
- } else {
- callback([]);
- }
- };
- } // Media Devices detection
- var canEnumerate = false;
- /*global MediaStreamTrack:true */
- if (typeof MediaStreamTrack !== 'undefined' && 'getSources' in MediaStreamTrack) {
- canEnumerate = true;
- } else if (navigator.mediaDevices && !!navigator.mediaDevices.enumerateDevices) {
- canEnumerate = true;
- }
- var hasMicrophone = false;
- var hasSpeakers = false;
- var hasWebcam = false;
- var isWebsiteHasMicrophonePermissions = false;
- var isWebsiteHasWebcamPermissions = false; // http://dev.w3.org/2011/webrtc/editor/getusermedia.html#mediadevices
- function checkDeviceSupport(callback) {
- if (!canEnumerate) {
- if (callback) {
- callback();
- }
- return;
- }
- if (!navigator.enumerateDevices && window.MediaStreamTrack && window.MediaStreamTrack.getSources) {
- navigator.enumerateDevices = window.MediaStreamTrack.getSources.bind(window.MediaStreamTrack);
- }
- if (!navigator.enumerateDevices && navigator.enumerateDevices) {
- navigator.enumerateDevices = navigator.enumerateDevices.bind(navigator);
- }
- if (!navigator.enumerateDevices) {
- if (callback) {
- callback();
- }
- return;
- }
- MediaDevices = [];
- audioInputDevices = [];
- audioOutputDevices = [];
- videoInputDevices = [];
- hasMicrophone = false;
- hasSpeakers = false;
- hasWebcam = false;
- isWebsiteHasMicrophonePermissions = false;
- isWebsiteHasWebcamPermissions = false; // to prevent duplication
- var alreadyUsedDevices = {};
- navigator.enumerateDevices(function (devices) {
- devices.forEach(function (_device) {
- var device = {};
- for (var d in _device) {
- try {
- if (typeof _device[d] !== 'function') {
- device[d] = _device[d];
- }
- } catch (e) {}
- }
- if (alreadyUsedDevices[device.deviceId + device.label + device.kind]) {
- return;
- } // if it is MediaStreamTrack.getSources
- if (device.kind === 'audio') {
- device.kind = 'audioinput';
- }
- if (device.kind === 'video') {
- device.kind = 'videoinput';
- }
- if (!device.deviceId) {
- device.deviceId = device.id;
- }
- if (!device.id) {
- device.id = device.deviceId;
- }
- if (!device.label) {
- device.isCustomLabel = true;
- if (device.kind === 'videoinput') {
- device.label = 'Camera ' + (videoInputDevices.length + 1);
- } else if (device.kind === 'audioinput') {
- device.label = 'Microphone ' + (audioInputDevices.length + 1);
- } else if (device.kind === 'audiooutput') {
- device.label = 'Speaker ' + (audioOutputDevices.length + 1);
- } else {
- device.label = 'Please invoke getUserMedia once.';
- }
- if (typeof DetectRTC !== 'undefined' && DetectRTC.browser.isChrome && DetectRTC.browser.version >= 46 && !/^(https:|chrome-extension:)$/g.test(location.protocol || '')) {
- if (typeof document !== 'undefined' && typeof document.domain === 'string' && document.domain.search && document.domain.search(/localhost|127.0./g) === -1) {
- device.label = 'HTTPs is required to get label of this ' + device.kind + ' device.';
- }
- }
- } else {
- // Firefox on Android still returns empty label
- if (device.kind === 'videoinput' && !isWebsiteHasWebcamPermissions) {
- isWebsiteHasWebcamPermissions = true;
- }
- if (device.kind === 'audioinput' && !isWebsiteHasMicrophonePermissions) {
- isWebsiteHasMicrophonePermissions = true;
- }
- }
- if (device.kind === 'audioinput') {
- hasMicrophone = true;
- if (audioInputDevices.indexOf(device) === -1) {
- audioInputDevices.push(device);
- }
- }
- if (device.kind === 'audiooutput') {
- hasSpeakers = true;
- if (audioOutputDevices.indexOf(device) === -1) {
- audioOutputDevices.push(device);
- }
- }
- if (device.kind === 'videoinput') {
- hasWebcam = true;
- if (videoInputDevices.indexOf(device) === -1) {
- videoInputDevices.push(device);
- }
- } // there is no 'videoouput' in the spec.
- MediaDevices.push(device);
- alreadyUsedDevices[device.deviceId + device.label + device.kind] = device;
- });
- if (typeof DetectRTC !== 'undefined') {
- // to sync latest outputs
- DetectRTC.MediaDevices = MediaDevices;
- DetectRTC.hasMicrophone = hasMicrophone;
- DetectRTC.hasSpeakers = hasSpeakers;
- DetectRTC.hasWebcam = hasWebcam;
- DetectRTC.isWebsiteHasWebcamPermissions = isWebsiteHasWebcamPermissions;
- DetectRTC.isWebsiteHasMicrophonePermissions = isWebsiteHasMicrophonePermissions;
- DetectRTC.audioInputDevices = audioInputDevices;
- DetectRTC.audioOutputDevices = audioOutputDevices;
- DetectRTC.videoInputDevices = videoInputDevices;
- }
- if (callback) {
- callback();
- }
- });
- }
- var DetectRTC = window.DetectRTC || {}; // ----------
- // DetectRTC.browser.name || DetectRTC.browser.version || DetectRTC.browser.fullVersion
- DetectRTC.browser = getBrowserInfo();
- detectPrivateMode(function (isPrivateBrowsing) {
- DetectRTC.browser.isPrivateBrowsing = !!isPrivateBrowsing;
- }); // DetectRTC.isChrome || DetectRTC.isFirefox || DetectRTC.isEdge
- DetectRTC.browser['is' + DetectRTC.browser.name] = true; // -----------
- DetectRTC.osName = osName;
- DetectRTC.osVersion = osVersion;
- var isNodeWebkit = typeof process === 'object' && typeof process.versions === 'object' && process.versions['node-webkit']; // --------- Detect if system supports WebRTC 1.0 or WebRTC 1.1.
- var isWebRTCSupported = false;
- ['RTCPeerConnection', 'webkitRTCPeerConnection', 'mozRTCPeerConnection', 'RTCIceGatherer'].forEach(function (item) {
- if (isWebRTCSupported) {
- return;
- }
- if (item in window) {
- isWebRTCSupported = true;
- }
- });
- DetectRTC.isWebRTCSupported = isWebRTCSupported; //-------
- DetectRTC.isORTCSupported = typeof RTCIceGatherer !== 'undefined'; // --------- Detect if system supports screen capturing API
- var isScreenCapturingSupported = false;
- if (DetectRTC.browser.isChrome && DetectRTC.browser.version >= 35) {
- isScreenCapturingSupported = true;
- } else if (DetectRTC.browser.isFirefox && DetectRTC.browser.version >= 34) {
- isScreenCapturingSupported = true;
- } else if (DetectRTC.browser.isEdge && DetectRTC.browser.version >= 17) {
- isScreenCapturingSupported = true; // navigator.getDisplayMedia
- } else if (DetectRTC.osName === 'Android' && DetectRTC.browser.isChrome) {
- isScreenCapturingSupported = true;
- }
- if (!/^(https:|chrome-extension:)$/g.test(location.protocol || '')) {
- var isNonLocalHost = typeof document !== 'undefined' && typeof document.domain === 'string' && document.domain.search && document.domain.search(/localhost|127.0./g) === -1;
- if (isNonLocalHost && (DetectRTC.browser.isChrome || DetectRTC.browser.isEdge || DetectRTC.browser.isOpera)) {
- isScreenCapturingSupported = false;
- } else if (DetectRTC.browser.isFirefox) {
- isScreenCapturingSupported = false;
- }
- }
- DetectRTC.isScreenCapturingSupported = isScreenCapturingSupported; // --------- Detect if WebAudio API are supported
- var webAudio = {
- isSupported: false,
- isCreateMediaStreamSourceSupported: false
- };
- ['AudioContext', 'webkitAudioContext', 'mozAudioContext', 'msAudioContext'].forEach(function (item) {
- if (webAudio.isSupported) {
- return;
- }
- if (item in window) {
- webAudio.isSupported = true;
- if (window[item] && 'createMediaStreamSource' in window[item].prototype) {
- webAudio.isCreateMediaStreamSourceSupported = true;
- }
- }
- });
- DetectRTC.isAudioContextSupported = webAudio.isSupported;
- DetectRTC.isCreateMediaStreamSourceSupported = webAudio.isCreateMediaStreamSourceSupported; // ---------- Detect if SCTP/RTP channels are supported.
- var isRtpDataChannelsSupported = false;
- if (DetectRTC.browser.isChrome && DetectRTC.browser.version > 31) {
- isRtpDataChannelsSupported = true;
- }
- DetectRTC.isRtpDataChannelsSupported = isRtpDataChannelsSupported;
- var isSCTPSupportd = false;
- if (DetectRTC.browser.isFirefox && DetectRTC.browser.version > 28) {
- isSCTPSupportd = true;
- } else if (DetectRTC.browser.isChrome && DetectRTC.browser.version > 25) {
- isSCTPSupportd = true;
- } else if (DetectRTC.browser.isOpera && DetectRTC.browser.version >= 11) {
- isSCTPSupportd = true;
- }
- DetectRTC.isSctpDataChannelsSupported = isSCTPSupportd; // ---------
- DetectRTC.isMobileDevice = isMobileDevice; // "isMobileDevice" boolean is defined in "getBrowserInfo.js"
- // ------
- var isGetUserMediaSupported = false;
- if (navigator.getUserMedia) {
- isGetUserMediaSupported = true;
- } else if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
- isGetUserMediaSupported = true;
- }
- if (DetectRTC.browser.isChrome && DetectRTC.browser.version >= 46 && !/^(https:|chrome-extension:)$/g.test(location.protocol || '')) {
- if (typeof document !== 'undefined' && typeof document.domain === 'string' && document.domain.search && document.domain.search(/localhost|127.0./g) === -1) {
- isGetUserMediaSupported = 'Requires HTTPs';
- }
- }
- if (DetectRTC.osName === 'Nodejs') {
- isGetUserMediaSupported = false;
- }
- DetectRTC.isGetUserMediaSupported = isGetUserMediaSupported;
- var displayResolution = '';
- if (screen.width) {
- var width = screen.width ? screen.width : '';
- var height = screen.height ? screen.height : '';
- displayResolution += '' + width + ' x ' + height;
- }
- DetectRTC.displayResolution = displayResolution;
- function getAspectRatio(w, h) {
- function gcd(a, b) {
- return b == 0 ? a : gcd(b, a % b);
- }
- var r = gcd(w, h);
- return w / r / (h / r);
- }
- DetectRTC.displayAspectRatio = getAspectRatio(screen.width, screen.height).toFixed(2); // ----------
- DetectRTC.isCanvasSupportsStreamCapturing = isCanvasSupportsStreamCapturing;
- DetectRTC.isVideoSupportsStreamCapturing = isVideoSupportsStreamCapturing;
- if (DetectRTC.browser.name == 'Chrome' && DetectRTC.browser.version >= 53) {
- if (!DetectRTC.isCanvasSupportsStreamCapturing) {
- DetectRTC.isCanvasSupportsStreamCapturing = 'Requires chrome flag: enable-experimental-web-platform-features';
- }
- if (!DetectRTC.isVideoSupportsStreamCapturing) {
- DetectRTC.isVideoSupportsStreamCapturing = 'Requires chrome flag: enable-experimental-web-platform-features';
- }
- } // ------
- DetectRTC.DetectLocalIPAddress = DetectLocalIPAddress;
- DetectRTC.isWebSocketsSupported = 'WebSocket' in window && 2 === window.WebSocket.CLOSING;
- DetectRTC.isWebSocketsBlocked = !DetectRTC.isWebSocketsSupported;
- if (DetectRTC.osName === 'Nodejs') {
- DetectRTC.isWebSocketsSupported = true;
- DetectRTC.isWebSocketsBlocked = false;
- }
- DetectRTC.checkWebSocketsSupport = function (callback) {
- callback = callback || function () {};
- try {
- var starttime;
- var websocket = new WebSocket('wss://echo.websocket.org:443/');
- websocket.onopen = function () {
- DetectRTC.isWebSocketsBlocked = false;
- starttime = new Date().getTime();
- websocket.send('ping');
- };
- websocket.onmessage = function () {
- DetectRTC.WebsocketLatency = new Date().getTime() - starttime + 'ms';
- callback();
- websocket.close();
- websocket = null;
- };
- websocket.onerror = function () {
- DetectRTC.isWebSocketsBlocked = true;
- callback();
- };
- } catch (e) {
- DetectRTC.isWebSocketsBlocked = true;
- callback();
- }
- }; // -------
- DetectRTC.load = function (callback) {
- callback = callback || function () {};
- checkDeviceSupport(callback);
- }; // check for microphone/camera support!
- if (typeof checkDeviceSupport === 'function') {// checkDeviceSupport();
- }
- if (typeof MediaDevices !== 'undefined') {
- DetectRTC.MediaDevices = MediaDevices;
- } else {
- DetectRTC.MediaDevices = [];
- }
- DetectRTC.hasMicrophone = hasMicrophone;
- DetectRTC.hasSpeakers = hasSpeakers;
- DetectRTC.hasWebcam = hasWebcam;
- DetectRTC.isWebsiteHasWebcamPermissions = isWebsiteHasWebcamPermissions;
- DetectRTC.isWebsiteHasMicrophonePermissions = isWebsiteHasMicrophonePermissions;
- DetectRTC.audioInputDevices = audioInputDevices;
- DetectRTC.audioOutputDevices = audioOutputDevices;
- DetectRTC.videoInputDevices = videoInputDevices; // ------
- var isSetSinkIdSupported = false;
- if (typeof document !== 'undefined' && typeof document.createElement === 'function' && 'setSinkId' in document.createElement('video')) {
- isSetSinkIdSupported = true;
- }
- DetectRTC.isSetSinkIdSupported = isSetSinkIdSupported; // -----
- var isRTPSenderReplaceTracksSupported = false;
- if (DetectRTC.browser.isFirefox && typeof mozRTCPeerConnection !== 'undefined'
- /*&& DetectRTC.browser.version > 39*/
- ) {
- /*global mozRTCPeerConnection:true */
- if ('getSenders' in mozRTCPeerConnection.prototype) {
- isRTPSenderReplaceTracksSupported = true;
- }
- } else if (DetectRTC.browser.isChrome && typeof webkitRTCPeerConnection !== 'undefined') {
- /*global webkitRTCPeerConnection:true */
- if ('getSenders' in webkitRTCPeerConnection.prototype) {
- isRTPSenderReplaceTracksSupported = true;
- }
- }
- DetectRTC.isRTPSenderReplaceTracksSupported = isRTPSenderReplaceTracksSupported; //------
- var isRemoteStreamProcessingSupported = false;
- if (DetectRTC.browser.isFirefox && DetectRTC.browser.version > 38) {
- isRemoteStreamProcessingSupported = true;
- }
- DetectRTC.isRemoteStreamProcessingSupported = isRemoteStreamProcessingSupported; //-------
- var isApplyConstraintsSupported = false;
- /*global MediaStreamTrack:true */
- if (typeof MediaStreamTrack !== 'undefined' && 'applyConstraints' in MediaStreamTrack.prototype) {
- isApplyConstraintsSupported = true;
- }
- DetectRTC.isApplyConstraintsSupported = isApplyConstraintsSupported; //-------
- var isMultiMonitorScreenCapturingSupported = false;
- if (DetectRTC.browser.isFirefox && DetectRTC.browser.version >= 43) {
- // version 43 merely supports platforms for multi-monitors
- // version 44 will support exact multi-monitor selection i.e. you can select any monitor for screen capturing.
- isMultiMonitorScreenCapturingSupported = true;
- }
- DetectRTC.isMultiMonitorScreenCapturingSupported = isMultiMonitorScreenCapturingSupported;
- DetectRTC.isPromisesSupported = !!('Promise' in window); // version is generated by "grunt"
- DetectRTC.version = '1.3.7';
- if (typeof DetectRTC === 'undefined') {
- window.DetectRTC = {};
- }
- var MediaStream = window.MediaStream;
- if (typeof MediaStream === 'undefined' && typeof webkitMediaStream !== 'undefined') {
- MediaStream = webkitMediaStream;
- }
- if (typeof MediaStream !== 'undefined' && typeof MediaStream === 'function') {
- DetectRTC.MediaStream = Object.keys(MediaStream.prototype);
- } else DetectRTC.MediaStream = false;
- if (typeof MediaStreamTrack !== 'undefined') {
- DetectRTC.MediaStreamTrack = Object.keys(MediaStreamTrack.prototype);
- } else DetectRTC.MediaStreamTrack = false;
- var RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
- if (typeof RTCPeerConnection !== 'undefined') {
- DetectRTC.RTCPeerConnection = Object.keys(RTCPeerConnection.prototype);
- } else DetectRTC.RTCPeerConnection = false;
- window.DetectRTC = DetectRTC;
- if (true
- /* && !!module.exports*/
- ) {
- module.exports = DetectRTC;
- }
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () {
- return DetectRTC;
- }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
- __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- }
- })();
- /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(15), __webpack_require__(21)))
- }),
- /* 21 */
- (function(module, exports) {
- var g; // This works in non-strict mode
- g = function () {
- return this;
- }();
- try {
- // This works if eval is allowed (see CSP)
- g = g || Function("return this")() || (1, eval)("this");
- } catch (e) {
- // This works if the window reference is available
- if (typeof window === "object") g = window;
- } // g can still be undefined, but nothing to do about it...
- // We return undefined, instead of nothing here, so it's
- // easier to handle this case. if(!global) { ...}
- module.exports = g;
- }),
- /* 22 */
- (function(module, exports, __webpack_require__) {
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
- * jQuery JavaScript Library v3.3.1
- * https://jquery.com/
- *
- * Includes Sizzle.js
- * https://sizzlejs.com/
- *
- * Copyright JS Foundation and other contributors
- * Released under the MIT license
- * https://jquery.org/license
- *
- * Date: 2018-01-20T17:24Z
- */
- (function (global, factory) {
- "use strict";
- if (typeof module === "object" && typeof module.exports === "object") {
- // For CommonJS and CommonJS-like environments where a proper `window`
- // is present, execute the factory and get jQuery.
- // For environments that do not have a `window` with a `document`
- // (such as Node.js), expose a factory as module.exports.
- // This accentuates the need for the creation of a real `window`.
- // e.g. var jQuery = require("jquery")(window);
- // See ticket #14549 for more info.
- module.exports = global.document ? factory(global, true) : function (w) {
- if (!w.document) {
- throw new Error("jQuery requires a window with a document");
- }
- return factory(w);
- };
- } else {
- factory(global);
- } // Pass this if window is not defined yet
- })(typeof window !== "undefined" ? window : this, function (window, noGlobal) {
- // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
- // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
- // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
- // enough that all such attempts are guarded in a try block.
- "use strict";
- var arr = [];
- var document = window.document;
- var getProto = Object.getPrototypeOf;
- var slice = arr.slice;
- var concat = arr.concat;
- var push = arr.push;
- var indexOf = arr.indexOf;
- var class2type = {};
- var toString = class2type.toString;
- var hasOwn = class2type.hasOwnProperty;
- var fnToString = hasOwn.toString;
- var ObjectFunctionString = fnToString.call(Object);
- var support = {};
- var isFunction = function isFunction(obj) {
- // Support: Chrome <=57, Firefox <=52
- // In some browsers, typeof returns "function" for HTML <object> elements
- // (i.e., `typeof document.createElement( "object" ) === "function"`).
- // We don't want to classify *any* DOM node as a function.
- return typeof obj === "function" && typeof obj.nodeType !== "number";
- };
- var isWindow = function isWindow(obj) {
- return obj != null && obj === obj.window;
- };
- var preservedScriptAttributes = {
- type: true,
- src: true,
- noModule: true
- };
- function DOMEval(code, doc, node) {
- doc = doc || document;
- var i,
- script = doc.createElement("script");
- script.text = code;
- if (node) {
- for (i in preservedScriptAttributes) {
- if (node[i]) {
- script[i] = node[i];
- }
- }
- }
- doc.head.appendChild(script).parentNode.removeChild(script);
- }
- function toType(obj) {
- if (obj == null) {
- return obj + "";
- } // Support: Android <=2.3 only (functionish RegExp)
- return typeof obj === "object" || typeof obj === "function" ? class2type[toString.call(obj)] || "object" : typeof obj;
- }
- /* global Symbol */
- // Defining this global in .eslintrc.json would create a danger of using the global
- // unguarded in another place, it seems safer to define global only for this module
- var version = "3.3.1",
- // Define a local copy of jQuery
- jQuery = function (selector, context) {
- // The jQuery object is actually just the init constructor 'enhanced'
- // Need init if jQuery is called (just allow error to be thrown if not included)
- return new jQuery.fn.init(selector, context);
- },
- // Support: Android <=4.0 only
- // Make sure we trim BOM and NBSP
- rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
- jQuery.fn = jQuery.prototype = {
- // The current version of jQuery being used
- jquery: version,
- constructor: jQuery,
- // The default length of a jQuery object is 0
- length: 0,
- toArray: function () {
- return slice.call(this);
- },
- // Get the Nth element in the matched element set OR
- // Get the whole matched element set as a clean array
- get: function (num) {
- // Return all the elements in a clean array
- if (num == null) {
- return slice.call(this);
- } // Return just the one element from the set
- return num < 0 ? this[num + this.length] : this[num];
- },
- // Take an array of elements and push it onto the stack
- // (returning the new matched element set)
- pushStack: function (elems) {
- // Build a new jQuery matched element set
- var ret = jQuery.merge(this.constructor(), elems); // Add the old object onto the stack (as a reference)
- ret.prevObject = this; // Return the newly-formed element set
- return ret;
- },
- // Execute a callback for every element in the matched set.
- each: function (callback) {
- return jQuery.each(this, callback);
- },
- map: function (callback) {
- return this.pushStack(jQuery.map(this, function (elem, i) {
- return callback.call(elem, i, elem);
- }));
- },
- slice: function () {
- return this.pushStack(slice.apply(this, arguments));
- },
- first: function () {
- return this.eq(0);
- },
- last: function () {
- return this.eq(-1);
- },
- eq: function (i) {
- var len = this.length,
- j = +i + (i < 0 ? len : 0);
- return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
- },
- end: function () {
- return this.prevObject || this.constructor();
- },
- // For internal use only.
- // Behaves like an Array's method, not like a jQuery method.
- push: push,
- sort: arr.sort,
- splice: arr.splice
- };
- jQuery.extend = jQuery.fn.extend = function () {
- var options,
- name,
- src,
- copy,
- copyIsArray,
- clone,
- target = arguments[0] || {},
- i = 1,
- length = arguments.length,
- deep = false; // Handle a deep copy situation
- if (typeof target === "boolean") {
- deep = target; // Skip the boolean and the target
- target = arguments[i] || {};
- i++;
- } // Handle case when target is a string or something (possible in deep copy)
- if (typeof target !== "object" && !isFunction(target)) {
- target = {};
- } // Extend jQuery itself if only one argument is passed
- if (i === length) {
- target = this;
- i--;
- }
- for (; i < length; i++) {
- // Only deal with non-null/undefined values
- if ((options = arguments[i]) != null) {
- // Extend the base object
- for (name in options) {
- src = target[name];
- copy = options[name]; // Prevent never-ending loop
- if (target === copy) {
- continue;
- } // Recurse if we're merging plain objects or arrays
- if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {
- if (copyIsArray) {
- copyIsArray = false;
- clone = src && Array.isArray(src) ? src : [];
- } else {
- clone = src && jQuery.isPlainObject(src) ? src : {};
- } // Never move original objects, clone them
- target[name] = jQuery.extend(deep, clone, copy); // Don't bring in undefined values
- } else if (copy !== undefined) {
- target[name] = copy;
- }
- }
- }
- } // Return the modified object
- return target;
- };
- jQuery.extend({
- // Unique for each copy of jQuery on the page
- expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""),
- // Assume jQuery is ready without the ready module
- isReady: true,
- error: function (msg) {
- throw new Error(msg);
- },
- noop: function () {},
- isPlainObject: function (obj) {
- var proto, Ctor; // Detect obvious negatives
- // Use toString instead of jQuery.type to catch host objects
- if (!obj || toString.call(obj) !== "[object Object]") {
- return false;
- }
- proto = getProto(obj); // Objects with no prototype (e.g., `Object.create( null )`) are plain
- if (!proto) {
- return true;
- } // Objects with prototype are plain iff they were constructed by a global Object function
- Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
- return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
- },
- isEmptyObject: function (obj) {
- /* eslint-disable no-unused-vars */
- // See https://github.com/eslint/eslint/issues/6125
- var name;
- for (name in obj) {
- return false;
- }
- return true;
- },
- // Evaluates a script in a global context
- globalEval: function (code) {
- DOMEval(code);
- },
- each: function (obj, callback) {
- var length,
- i = 0;
- if (isArrayLike(obj)) {
- length = obj.length;
- for (; i < length; i++) {
- if (callback.call(obj[i], i, obj[i]) === false) {
- break;
- }
- }
- } else {
- for (i in obj) {
- if (callback.call(obj[i], i, obj[i]) === false) {
- break;
- }
- }
- }
- return obj;
- },
- // Support: Android <=4.0 only
- trim: function (text) {
- return text == null ? "" : (text + "").replace(rtrim, "");
- },
- // results is for internal usage only
- makeArray: function (arr, results) {
- var ret = results || [];
- if (arr != null) {
- if (isArrayLike(Object(arr))) {
- jQuery.merge(ret, typeof arr === "string" ? [arr] : arr);
- } else {
- push.call(ret, arr);
- }
- }
- return ret;
- },
- inArray: function (elem, arr, i) {
- return arr == null ? -1 : indexOf.call(arr, elem, i);
- },
- // Support: Android <=4.0 only, PhantomJS 1 only
- // push.apply(_, arraylike) throws on ancient WebKit
- merge: function (first, second) {
- var len = +second.length,
- j = 0,
- i = first.length;
- for (; j < len; j++) {
- first[i++] = second[j];
- }
- first.length = i;
- return first;
- },
- grep: function (elems, callback, invert) {
- var callbackInverse,
- matches = [],
- i = 0,
- length = elems.length,
- callbackExpect = !invert; // Go through the array, only saving the items
- // that pass the validator function
- for (; i < length; i++) {
- callbackInverse = !callback(elems[i], i);
- if (callbackInverse !== callbackExpect) {
- matches.push(elems[i]);
- }
- }
- return matches;
- },
- // arg is for internal usage only
- map: function (elems, callback, arg) {
- var length,
- value,
- i = 0,
- ret = []; // Go through the array, translating each of the items to their new values
- if (isArrayLike(elems)) {
- length = elems.length;
- for (; i < length; i++) {
- value = callback(elems[i], i, arg);
- if (value != null) {
- ret.push(value);
- }
- } // Go through every key on the object,
- } else {
- for (i in elems) {
- value = callback(elems[i], i, arg);
- if (value != null) {
- ret.push(value);
- }
- }
- } // Flatten any nested arrays
- return concat.apply([], ret);
- },
- // A global GUID counter for objects
- guid: 1,
- // jQuery.support is not used in Core but other projects attach their
- // properties to it so it needs to exist.
- support: support
- });
- if (typeof Symbol === "function") {
- jQuery.fn[Symbol.iterator] = arr[Symbol.iterator];
- } // Populate the class2type map
- jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), function (i, name) {
- class2type["[object " + name + "]"] = name.toLowerCase();
- });
- function isArrayLike(obj) {
- // Support: real iOS 8.2 only (not reproducible in simulator)
- // `in` check used to prevent JIT error (gh-2145)
- // hasOwn isn't used here due to false negatives
- // regarding Nodelist length in IE
- var length = !!obj && "length" in obj && obj.length,
- type = toType(obj);
- if (isFunction(obj) || isWindow(obj)) {
- return false;
- }
- return type === "array" || length === 0 || typeof length === "number" && length > 0 && length - 1 in obj;
- }
- var Sizzle =
- /*!
- * Sizzle CSS Selector Engine v2.3.3
- * https://sizzlejs.com/
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2016-08-08
- */
- function (window) {
- var i,
- support,
- Expr,
- getText,
- isXML,
- tokenize,
- compile,
- select,
- outermostContext,
- sortInput,
- hasDuplicate,
- // Local document vars
- setDocument,
- document,
- docElem,
- documentIsHTML,
- rbuggyQSA,
- rbuggyMatches,
- matches,
- contains,
- // Instance-specific data
- expando = "sizzle" + 1 * new Date(),
- preferredDoc = window.document,
- dirruns = 0,
- done = 0,
- classCache = createCache(),
- tokenCache = createCache(),
- compilerCache = createCache(),
- sortOrder = function (a, b) {
- if (a === b) {
- hasDuplicate = true;
- }
- return 0;
- },
- // Instance methods
- hasOwn = {}.hasOwnProperty,
- arr = [],
- pop = arr.pop,
- push_native = arr.push,
- push = arr.push,
- slice = arr.slice,
- // Use a stripped-down indexOf as it's faster than native
- // https://jsperf.com/thor-indexof-vs-for/5
- indexOf = function (list, elem) {
- var i = 0,
- len = list.length;
- for (; i < len; i++) {
- if (list[i] === elem) {
- return i;
- }
- }
- return -1;
- },
- booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
- // Regular expressions
- // http://www.w3.org/TR/css3-selectors/#whitespace
- whitespace = "[\\x20\\t\\r\\n\\f]",
- // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
- identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
- // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
- attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2)
- "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
- "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]",
- pseudos = ":(" + identifier + ")(?:\\((" + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
- // 1. quoted (capture 3; capture 4 or capture 5)
- "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + // 2. simple (capture 6)
- "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + // 3. anything else (capture 2)
- ".*" + ")\\)|)",
- // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
- rwhitespace = new RegExp(whitespace + "+", "g"),
- rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g"),
- rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"),
- rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"),
- rattributeQuotes = new RegExp("=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g"),
- rpseudo = new RegExp(pseudos),
- ridentifier = new RegExp("^" + identifier + "$"),
- matchExpr = {
- "ID": new RegExp("^#(" + identifier + ")"),
- "CLASS": new RegExp("^\\.(" + identifier + ")"),
- "TAG": new RegExp("^(" + identifier + "|[*])"),
- "ATTR": new RegExp("^" + attributes),
- "PSEUDO": new RegExp("^" + pseudos),
- "CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i"),
- "bool": new RegExp("^(?:" + booleans + ")$", "i"),
- // For use in libraries implementing .is()
- // We use this for POS matching in `select`
- "needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i")
- },
- rinputs = /^(?:input|select|textarea|button)$/i,
- rheader = /^h\d$/i,
- rnative = /^[^{]+\{\s*\[native \w/,
- // Easily-parseable/retrievable ID or TAG or CLASS selectors
- rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
- rsibling = /[+~]/,
- // CSS escapes
- // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
- runescape = new RegExp("\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig"),
- funescape = function (_, escaped, escapedWhitespace) {
- var high = "0x" + escaped - 0x10000; // NaN means non-codepoint
- // Support: Firefox<24
- // Workaround erroneous numeric interpretation of +"0x"
- return high !== high || escapedWhitespace ? escaped : high < 0 ? // BMP codepoint
- String.fromCharCode(high + 0x10000) : // Supplemental Plane codepoint (surrogate pair)
- String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);
- },
- // CSS string/identifier serialization
- // https://drafts.csswg.org/cssom/#common-serializing-idioms
- rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
- fcssescape = function (ch, asCodePoint) {
- if (asCodePoint) {
- // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
- if (ch === "\0") {
- return "\uFFFD";
- } // Control characters and (dependent upon position) numbers get escaped as code points
- return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " ";
- } // Other potentially-special ASCII characters get backslash-escaped
- return "\\" + ch;
- },
- // Used for iframes
- // See setDocument()
- // Removing the function wrapper causes a "Permission Denied"
- // error in IE
- unloadHandler = function () {
- setDocument();
- },
- disabledAncestor = addCombinator(function (elem) {
- return elem.disabled === true && ("form" in elem || "label" in elem);
- }, {
- dir: "parentNode",
- next: "legend"
- }); // Optimize for push.apply( _, NodeList )
- try {
- push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes); // Support: Android<4.0
- // Detect silently failing push.apply
- arr[preferredDoc.childNodes.length].nodeType;
- } catch (e) {
- push = {
- apply: arr.length ? // Leverage slice if possible
- function (target, els) {
- push_native.apply(target, slice.call(els));
- } : // Support: IE<9
- // Otherwise append directly
- function (target, els) {
- var j = target.length,
- i = 0; // Can't trust NodeList.length
- while (target[j++] = els[i++]) {}
- target.length = j - 1;
- }
- };
- }
- function Sizzle(selector, context, results, seed) {
- var m,
- i,
- elem,
- nid,
- match,
- groups,
- newSelector,
- newContext = context && context.ownerDocument,
- // nodeType defaults to 9, since context defaults to document
- nodeType = context ? context.nodeType : 9;
- results = results || []; // Return early from calls with invalid selector or context
- if (typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {
- return results;
- } // Try to shortcut find operations (as opposed to filters) in HTML documents
- if (!seed) {
- if ((context ? context.ownerDocument || context : preferredDoc) !== document) {
- setDocument(context);
- }
- context = context || document;
- if (documentIsHTML) {
- // If the selector is sufficiently simple, try using a "get*By*" DOM method
- // (excepting DocumentFragment context, where the methods don't exist)
- if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {
- // ID selector
- if (m = match[1]) {
- // Document context
- if (nodeType === 9) {
- if (elem = context.getElementById(m)) {
- // Support: IE, Opera, Webkit
- // TODO: identify versions
- // getElementById can match elements by name instead of ID
- if (elem.id === m) {
- results.push(elem);
- return results;
- }
- } else {
- return results;
- } // Element context
- } else {
- // Support: IE, Opera, Webkit
- // TODO: identify versions
- // getElementById can match elements by name instead of ID
- if (newContext && (elem = newContext.getElementById(m)) && contains(context, elem) && elem.id === m) {
- results.push(elem);
- return results;
- }
- } // Type selector
- } else if (match[2]) {
- push.apply(results, context.getElementsByTagName(selector));
- return results; // Class selector
- } else if ((m = match[3]) && support.getElementsByClassName && context.getElementsByClassName) {
- push.apply(results, context.getElementsByClassName(m));
- return results;
- }
- } // Take advantage of querySelectorAll
- if (support.qsa && !compilerCache[selector + " "] && (!rbuggyQSA || !rbuggyQSA.test(selector))) {
- if (nodeType !== 1) {
- newContext = context;
- newSelector = selector; // qSA looks outside Element context, which is not what we want
- // Thanks to Andrew Dupont for this workaround technique
- // Support: IE <=8
- // Exclude object elements
- } else if (context.nodeName.toLowerCase() !== "object") {
- // Capture the context ID, setting it first if necessary
- if (nid = context.getAttribute("id")) {
- nid = nid.replace(rcssescape, fcssescape);
- } else {
- context.setAttribute("id", nid = expando);
- } // Prefix every selector in the list
- groups = tokenize(selector);
- i = groups.length;
- while (i--) {
- groups[i] = "#" + nid + " " + toSelector(groups[i]);
- }
- newSelector = groups.join(","); // Expand context for sibling selectors
- newContext = rsibling.test(selector) && testContext(context.parentNode) || context;
- }
- if (newSelector) {
- try {
- push.apply(results, newContext.querySelectorAll(newSelector));
- return results;
- } catch (qsaError) {} finally {
- if (nid === expando) {
- context.removeAttribute("id");
- }
- }
- }
- }
- }
- } // All others
- return select(selector.replace(rtrim, "$1"), context, results, seed);
- }
- /**
- * Create key-value caches of limited size
- * @returns {function(string, object)} Returns the Object data after storing it on itself with
- * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
- * deleting the oldest entry
- */
- function createCache() {
- var keys = [];
- function cache(key, value) {
- // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
- if (keys.push(key + " ") > Expr.cacheLength) {
- // Only keep the most recent entries
- delete cache[keys.shift()];
- }
- return cache[key + " "] = value;
- }
- return cache;
- }
- /**
- * Mark a function for special use by Sizzle
- * @param {Function} fn The function to mark
- */
- function markFunction(fn) {
- fn[expando] = true;
- return fn;
- }
- /**
- * Support testing using an element
- * @param {Function} fn Passed the created element and returns a boolean result
- */
- function assert(fn) {
- var el = document.createElement("fieldset");
- try {
- return !!fn(el);
- } catch (e) {
- return false;
- } finally {
- // Remove from its parent by default
- if (el.parentNode) {
- el.parentNode.removeChild(el);
- } // release memory in IE
- el = null;
- }
- }
- /**
- * Adds the same handler for all of the specified attrs
- * @param {String} attrs Pipe-separated list of attributes
- * @param {Function} handler The method that will be applied
- */
- function addHandle(attrs, handler) {
- var arr = attrs.split("|"),
- i = arr.length;
- while (i--) {
- Expr.attrHandle[arr[i]] = handler;
- }
- }
- /**
- * Checks document order of two siblings
- * @param {Element} a
- * @param {Element} b
- * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
- */
- function siblingCheck(a, b) {
- var cur = b && a,
- diff = cur && a.nodeType === 1 && b.nodeType === 1 && a.sourceIndex - b.sourceIndex; // Use IE sourceIndex if available on both nodes
- if (diff) {
- return diff;
- } // Check if b follows a
- if (cur) {
- while (cur = cur.nextSibling) {
- if (cur === b) {
- return -1;
- }
- }
- }
- return a ? 1 : -1;
- }
- /**
- * Returns a function to use in pseudos for input types
- * @param {String} type
- */
- function createInputPseudo(type) {
- return function (elem) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === type;
- };
- }
- /**
- * Returns a function to use in pseudos for buttons
- * @param {String} type
- */
- function createButtonPseudo(type) {
- return function (elem) {
- var name = elem.nodeName.toLowerCase();
- return (name === "input" || name === "button") && elem.type === type;
- };
- }
- /**
- * Returns a function to use in pseudos for :enabled/:disabled
- * @param {Boolean} disabled true for :disabled; false for :enabled
- */
- function createDisabledPseudo(disabled) {
- // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
- return function (elem) {
- // Only certain elements can match :enabled or :disabled
- // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
- // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
- if ("form" in elem) {
- // Check for inherited disabledness on relevant non-disabled elements:
- // * listed form-associated elements in a disabled fieldset
- // https://html.spec.whatwg.org/multipage/forms.html#category-listed
- // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
- // * option elements in a disabled optgroup
- // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
- // All such elements have a "form" property.
- if (elem.parentNode && elem.disabled === false) {
- // Option elements defer to a parent optgroup if present
- if ("label" in elem) {
- if ("label" in elem.parentNode) {
- return elem.parentNode.disabled === disabled;
- } else {
- return elem.disabled === disabled;
- }
- } // Support: IE 6 - 11
- // Use the isDisabled shortcut property to check for disabled fieldset ancestors
- return elem.isDisabled === disabled || // Where there is no isDisabled, check manually
- /* jshint -W018 */
- elem.isDisabled !== !disabled && disabledAncestor(elem) === disabled;
- }
- return elem.disabled === disabled; // Try to winnow out elements that can't be disabled before trusting the disabled property.
- // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
- // even exist on them, let alone have a boolean value.
- } else if ("label" in elem) {
- return elem.disabled === disabled;
- } // Remaining elements are neither :enabled nor :disabled
- return false;
- };
- }
- /**
- * Returns a function to use in pseudos for positionals
- * @param {Function} fn
- */
- function createPositionalPseudo(fn) {
- return markFunction(function (argument) {
- argument = +argument;
- return markFunction(function (seed, matches) {
- var j,
- matchIndexes = fn([], seed.length, argument),
- i = matchIndexes.length; // Match elements found at the specified indexes
- while (i--) {
- if (seed[j = matchIndexes[i]]) {
- seed[j] = !(matches[j] = seed[j]);
- }
- }
- });
- });
- }
- /**
- * Checks a node for validity as a Sizzle context
- * @param {Element|Object=} context
- * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
- */
- function testContext(context) {
- return context && typeof context.getElementsByTagName !== "undefined" && context;
- } // Expose support vars for convenience
- support = Sizzle.support = {};
- /**
- * Detects XML nodes
- * @param {Element|Object} elem An element or a document
- * @returns {Boolean} True iff elem is a non-HTML XML node
- */
- isXML = Sizzle.isXML = function (elem) {
- // documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
- var documentElement = elem && (elem.ownerDocument || elem).documentElement;
- return documentElement ? documentElement.nodeName !== "HTML" : false;
- };
- /**
- * Sets document-related variables once based on the current document
- * @param {Element|Object} [doc] An element or document object to use to set the document
- * @returns {Object} Returns the current document
- */
- setDocument = Sizzle.setDocument = function (node) {
- var hasCompare,
- subWindow,
- doc = node ? node.ownerDocument || node : preferredDoc; // Return early if doc is invalid or already selected
- if (doc === document || doc.nodeType !== 9 || !doc.documentElement) {
- return document;
- } // Update global variables
- document = doc;
- docElem = document.documentElement;
- documentIsHTML = !isXML(document); // Support: IE 9-11, Edge
- // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
- if (preferredDoc !== document && (subWindow = document.defaultView) && subWindow.top !== subWindow) {
- // Support: IE 11, Edge
- if (subWindow.addEventListener) {
- subWindow.addEventListener("unload", unloadHandler, false); // Support: IE 9 - 10 only
- } else if (subWindow.attachEvent) {
- subWindow.attachEvent("onunload", unloadHandler);
- }
- }
- /* Attributes
- ---------------------------------------------------------------------- */
- // Support: IE<8
- // Verify that getAttribute really returns attributes and not properties
- // (excepting IE8 booleans)
- support.attributes = assert(function (el) {
- el.className = "i";
- return !el.getAttribute("className");
- });
- /* getElement(s)By*
- ---------------------------------------------------------------------- */
- // Check if getElementsByTagName("*") returns only elements
- support.getElementsByTagName = assert(function (el) {
- el.appendChild(document.createComment(""));
- return !el.getElementsByTagName("*").length;
- }); // Support: IE<9
- support.getElementsByClassName = rnative.test(document.getElementsByClassName); // Support: IE<10
- // Check if getElementById returns elements by name
- // The broken getElementById methods don't pick up programmatically-set names,
- // so use a roundabout getElementsByName test
- support.getById = assert(function (el) {
- docElem.appendChild(el).id = expando;
- return !document.getElementsByName || !document.getElementsByName(expando).length;
- }); // ID filter and find
- if (support.getById) {
- Expr.filter["ID"] = function (id) {
- var attrId = id.replace(runescape, funescape);
- return function (elem) {
- return elem.getAttribute("id") === attrId;
- };
- };
- Expr.find["ID"] = function (id, context) {
- if (typeof context.getElementById !== "undefined" && documentIsHTML) {
- var elem = context.getElementById(id);
- return elem ? [elem] : [];
- }
- };
- } else {
- Expr.filter["ID"] = function (id) {
- var attrId = id.replace(runescape, funescape);
- return function (elem) {
- var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
- return node && node.value === attrId;
- };
- }; // Support: IE 6 - 7 only
- // getElementById is not reliable as a find shortcut
- Expr.find["ID"] = function (id, context) {
- if (typeof context.getElementById !== "undefined" && documentIsHTML) {
- var node,
- i,
- elems,
- elem = context.getElementById(id);
- if (elem) {
- // Verify the id attribute
- node = elem.getAttributeNode("id");
- if (node && node.value === id) {
- return [elem];
- } // Fall back on getElementsByName
- elems = context.getElementsByName(id);
- i = 0;
- while (elem = elems[i++]) {
- node = elem.getAttributeNode("id");
- if (node && node.value === id) {
- return [elem];
- }
- }
- }
- return [];
- }
- };
- } // Tag
- Expr.find["TAG"] = support.getElementsByTagName ? function (tag, context) {
- if (typeof context.getElementsByTagName !== "undefined") {
- return context.getElementsByTagName(tag); // DocumentFragment nodes don't have gEBTN
- } else if (support.qsa) {
- return context.querySelectorAll(tag);
- }
- } : function (tag, context) {
- var elem,
- tmp = [],
- i = 0,
- // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
- results = context.getElementsByTagName(tag); // Filter out possible comments
- if (tag === "*") {
- while (elem = results[i++]) {
- if (elem.nodeType === 1) {
- tmp.push(elem);
- }
- }
- return tmp;
- }
- return results;
- }; // Class
- Expr.find["CLASS"] = support.getElementsByClassName && function (className, context) {
- if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) {
- return context.getElementsByClassName(className);
- }
- };
- /* QSA/matchesSelector
- ---------------------------------------------------------------------- */
- // QSA and matchesSelector support
- // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
- rbuggyMatches = []; // qSa(:focus) reports false when true (Chrome 21)
- // We allow this because of a bug in IE8/9 that throws an error
- // whenever `document.activeElement` is accessed on an iframe
- // So, we allow :focus to pass through QSA all the time to avoid the IE error
- // See https://bugs.jquery.com/ticket/13378
- rbuggyQSA = [];
- if (support.qsa = rnative.test(document.querySelectorAll)) {
- // Build QSA regex
- // Regex strategy adopted from Diego Perini
- assert(function (el) {
- // Select is set to empty string on purpose
- // This is to test IE's treatment of not explicitly
- // setting a boolean content attribute,
- // since its presence should be enough
- // https://bugs.jquery.com/ticket/12359
- docElem.appendChild(el).innerHTML = "<a id='" + expando + "'></a>" + "<select id='" + expando + "-\r\\' msallowcapture=''>" + "<option selected=''></option></select>"; // Support: IE8, Opera 11-12.16
- // Nothing should be selected when empty strings follow ^= or $= or *=
- // The test attribute must be unknown in Opera but "safe" for WinRT
- // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
- if (el.querySelectorAll("[msallowcapture^='']").length) {
- rbuggyQSA.push("[*^$]=" + whitespace + "*(?:''|\"\")");
- } // Support: IE8
- // Boolean attributes and "value" are not treated correctly
- if (!el.querySelectorAll("[selected]").length) {
- rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")");
- } // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
- if (!el.querySelectorAll("[id~=" + expando + "-]").length) {
- rbuggyQSA.push("~=");
- } // Webkit/Opera - :checked should return selected option elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- // IE8 throws error here and will not see later tests
- if (!el.querySelectorAll(":checked").length) {
- rbuggyQSA.push(":checked");
- } // Support: Safari 8+, iOS 8+
- // https://bugs.webkit.org/show_bug.cgi?id=136851
- // In-page `selector#id sibling-combinator selector` fails
- if (!el.querySelectorAll("a#" + expando + "+*").length) {
- rbuggyQSA.push(".#.+[+~]");
- }
- });
- assert(function (el) {
- el.innerHTML = "<a href='' disabled='disabled'></a>" + "<select disabled='disabled'><option/></select>"; // Support: Windows 8 Native Apps
- // The type and name attributes are restricted during .innerHTML assignment
- var input = document.createElement("input");
- input.setAttribute("type", "hidden");
- el.appendChild(input).setAttribute("name", "D"); // Support: IE8
- // Enforce case-sensitivity of name attribute
- if (el.querySelectorAll("[name=d]").length) {
- rbuggyQSA.push("name" + whitespace + "*[*^$|!~]?=");
- } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
- // IE8 throws error here and will not see later tests
- if (el.querySelectorAll(":enabled").length !== 2) {
- rbuggyQSA.push(":enabled", ":disabled");
- } // Support: IE9-11+
- // IE's :disabled selector does not pick up the children of disabled fieldsets
- docElem.appendChild(el).disabled = true;
- if (el.querySelectorAll(":disabled").length !== 2) {
- rbuggyQSA.push(":enabled", ":disabled");
- } // Opera 10-11 does not throw on post-comma invalid pseudos
- el.querySelectorAll("*,:x");
- rbuggyQSA.push(",.*:");
- });
- }
- if (support.matchesSelector = rnative.test(matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector)) {
- assert(function (el) {
- // Check to see if it's possible to do matchesSelector
- // on a disconnected node (IE 9)
- support.disconnectedMatch = matches.call(el, "*"); // This should fail with an exception
- // Gecko does not error, returns false instead
- matches.call(el, "[s!='']:x");
- rbuggyMatches.push("!=", pseudos);
- });
- }
- rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));
- rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|"));
- /* Contains
- ---------------------------------------------------------------------- */
- hasCompare = rnative.test(docElem.compareDocumentPosition); // Element contains another
- // Purposefully self-exclusive
- // As in, an element does not contain itself
- contains = hasCompare || rnative.test(docElem.contains) ? function (a, b) {
- var adown = a.nodeType === 9 ? a.documentElement : a,
- bup = b && b.parentNode;
- return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16));
- } : function (a, b) {
- if (b) {
- while (b = b.parentNode) {
- if (b === a) {
- return true;
- }
- }
- }
- return false;
- };
- /* Sorting
- ---------------------------------------------------------------------- */
- // Document order sorting
- sortOrder = hasCompare ? function (a, b) {
- // Flag for duplicate removal
- if (a === b) {
- hasDuplicate = true;
- return 0;
- } // Sort on method existence if only one input has compareDocumentPosition
- var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
- if (compare) {
- return compare;
- } // Calculate position if both inputs belong to the same document
- compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : // Otherwise we know they are disconnected
- 1; // Disconnected nodes
- if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) {
- // Choose the first element that is related to our preferred document
- if (a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) {
- return -1;
- }
- if (b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) {
- return 1;
- } // Maintain original order
- return sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0;
- }
- return compare & 4 ? -1 : 1;
- } : function (a, b) {
- // Exit early if the nodes are identical
- if (a === b) {
- hasDuplicate = true;
- return 0;
- }
- var cur,
- i = 0,
- aup = a.parentNode,
- bup = b.parentNode,
- ap = [a],
- bp = [b]; // Parentless nodes are either documents or disconnected
- if (!aup || !bup) {
- return a === document ? -1 : b === document ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0; // If the nodes are siblings, we can do a quick check
- } else if (aup === bup) {
- return siblingCheck(a, b);
- } // Otherwise we need full lists of their ancestors for comparison
- cur = a;
- while (cur = cur.parentNode) {
- ap.unshift(cur);
- }
- cur = b;
- while (cur = cur.parentNode) {
- bp.unshift(cur);
- } // Walk down the tree looking for a discrepancy
- while (ap[i] === bp[i]) {
- i++;
- }
- return i ? // Do a sibling check if the nodes have a common ancestor
- siblingCheck(ap[i], bp[i]) : // Otherwise nodes in our document sort first
- ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0;
- };
- return document;
- };
- Sizzle.matches = function (expr, elements) {
- return Sizzle(expr, null, null, elements);
- };
- Sizzle.matchesSelector = function (elem, expr) {
- // Set document vars if needed
- if ((elem.ownerDocument || elem) !== document) {
- setDocument(elem);
- } // Make sure that attribute selectors are quoted
- expr = expr.replace(rattributeQuotes, "='$1']");
- if (support.matchesSelector && documentIsHTML && !compilerCache[expr + " "] && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) {
- try {
- var ret = matches.call(elem, expr); // IE 9's matchesSelector returns false on disconnected nodes
- if (ret || support.disconnectedMatch || // As well, disconnected nodes are said to be in a document
- // fragment in IE 9
- elem.document && elem.document.nodeType !== 11) {
- return ret;
- }
- } catch (e) {}
- }
- return Sizzle(expr, document, null, [elem]).length > 0;
- };
- Sizzle.contains = function (context, elem) {
- // Set document vars if needed
- if ((context.ownerDocument || context) !== document) {
- setDocument(context);
- }
- return contains(context, elem);
- };
- Sizzle.attr = function (elem, name) {
- // Set document vars if needed
- if ((elem.ownerDocument || elem) !== document) {
- setDocument(elem);
- }
- var fn = Expr.attrHandle[name.toLowerCase()],
- // Don't get fooled by Object.prototype properties (jQuery #13807)
- val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined;
- return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null;
- };
- Sizzle.escape = function (sel) {
- return (sel + "").replace(rcssescape, fcssescape);
- };
- Sizzle.error = function (msg) {
- throw new Error("Syntax error, unrecognized expression: " + msg);
- };
- /**
- * Document sorting and removing duplicates
- * @param {ArrayLike} results
- */
- Sizzle.uniqueSort = function (results) {
- var elem,
- duplicates = [],
- j = 0,
- i = 0; // Unless we *know* we can detect duplicates, assume their presence
- hasDuplicate = !support.detectDuplicates;
- sortInput = !support.sortStable && results.slice(0);
- results.sort(sortOrder);
- if (hasDuplicate) {
- while (elem = results[i++]) {
- if (elem === results[i]) {
- j = duplicates.push(i);
- }
- }
- while (j--) {
- results.splice(duplicates[j], 1);
- }
- } // Clear input after sorting to release objects
- // See https://github.com/jquery/sizzle/pull/225
- sortInput = null;
- return results;
- };
- /**
- * Utility function for retrieving the text value of an array of DOM nodes
- * @param {Array|Element} elem
- */
- getText = Sizzle.getText = function (elem) {
- var node,
- ret = "",
- i = 0,
- nodeType = elem.nodeType;
- if (!nodeType) {
- // If no nodeType, this is expected to be an array
- while (node = elem[i++]) {
- // Do not traverse comment nodes
- ret += getText(node);
- }
- } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
- // Use textContent for elements
- // innerText usage removed for consistency of new lines (jQuery #11153)
- if (typeof elem.textContent === "string") {
- return elem.textContent;
- } else {
- // Traverse its children
- for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
- ret += getText(elem);
- }
- }
- } else if (nodeType === 3 || nodeType === 4) {
- return elem.nodeValue;
- } // Do not include comment or processing instruction nodes
- return ret;
- };
- Expr = Sizzle.selectors = {
- // Can be adjusted by the user
- cacheLength: 50,
- createPseudo: markFunction,
- match: matchExpr,
- attrHandle: {},
- find: {},
- relative: {
- ">": {
- dir: "parentNode",
- first: true
- },
- " ": {
- dir: "parentNode"
- },
- "+": {
- dir: "previousSibling",
- first: true
- },
- "~": {
- dir: "previousSibling"
- }
- },
- preFilter: {
- "ATTR": function (match) {
- match[1] = match[1].replace(runescape, funescape); // Move the given value to match[3] whether quoted or unquoted
- match[3] = (match[3] || match[4] || match[5] || "").replace(runescape, funescape);
- if (match[2] === "~=") {
- match[3] = " " + match[3] + " ";
- }
- return match.slice(0, 4);
- },
- "CHILD": function (match) {
- /* matches from matchExpr["CHILD"]
- 1 type (only|nth|...)
- 2 what (child|of-type)
- 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
- 4 xn-component of xn+y argument ([+-]?\d*n|)
- 5 sign of xn-component
- 6 x of xn-component
- 7 sign of y-component
- 8 y of y-component
- */
- match[1] = match[1].toLowerCase();
- if (match[1].slice(0, 3) === "nth") {
- // nth-* requires argument
- if (!match[3]) {
- Sizzle.error(match[0]);
- } // numeric x and y parameters for Expr.filter.CHILD
- // remember that false/true cast respectively to 0/1
- match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd"));
- match[5] = +(match[7] + match[8] || match[3] === "odd"); // other types prohibit arguments
- } else if (match[3]) {
- Sizzle.error(match[0]);
- }
- return match;
- },
- "PSEUDO": function (match) {
- var excess,
- unquoted = !match[6] && match[2];
- if (matchExpr["CHILD"].test(match[0])) {
- return null;
- } // Accept quoted arguments as-is
- if (match[3]) {
- match[2] = match[4] || match[5] || ""; // Strip excess characters from unquoted arguments
- } else if (unquoted && rpseudo.test(unquoted) && ( // Get excess from tokenize (recursively)
- excess = tokenize(unquoted, true)) && ( // advance to the next closing parenthesis
- excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) {
- // excess is a negative index
- match[0] = match[0].slice(0, excess);
- match[2] = unquoted.slice(0, excess);
- } // Return only captures needed by the pseudo filter method (type and argument)
- return match.slice(0, 3);
- }
- },
- filter: {
- "TAG": function (nodeNameSelector) {
- var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
- return nodeNameSelector === "*" ? function () {
- return true;
- } : function (elem) {
- return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
- };
- },
- "CLASS": function (className) {
- var pattern = classCache[className + " "];
- return pattern || (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && classCache(className, function (elem) {
- return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "");
- });
- },
- "ATTR": function (name, operator, check) {
- return function (elem) {
- var result = Sizzle.attr(elem, name);
- if (result == null) {
- return operator === "!=";
- }
- if (!operator) {
- return true;
- }
- result += "";
- return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf(check) === 0 : operator === "*=" ? check && result.indexOf(check) > -1 : operator === "$=" ? check && result.slice(-check.length) === check : operator === "~=" ? (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1 : operator === "|=" ? result === check || result.slice(0, check.length + 1) === check + "-" : false;
- };
- },
- "CHILD": function (type, what, argument, first, last) {
- var simple = type.slice(0, 3) !== "nth",
- forward = type.slice(-4) !== "last",
- ofType = what === "of-type";
- return first === 1 && last === 0 ? // Shortcut for :nth-*(n)
- function (elem) {
- return !!elem.parentNode;
- } : function (elem, context, xml) {
- var cache,
- uniqueCache,
- outerCache,
- node,
- nodeIndex,
- start,
- dir = simple !== forward ? "nextSibling" : "previousSibling",
- parent = elem.parentNode,
- name = ofType && elem.nodeName.toLowerCase(),
- useCache = !xml && !ofType,
- diff = false;
- if (parent) {
- // :(first|last|only)-(child|of-type)
- if (simple) {
- while (dir) {
- node = elem;
- while (node = node[dir]) {
- if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) {
- return false;
- }
- } // Reverse direction for :only-* (if we haven't yet done so)
- start = dir = type === "only" && !start && "nextSibling";
- }
- return true;
- }
- start = [forward ? parent.firstChild : parent.lastChild]; // non-xml :nth-child(...) stores cache data on `parent`
- if (forward && useCache) {
- // Seek `elem` from a previously-cached index
- // ...in a gzip-friendly way
- node = parent;
- outerCache = node[expando] || (node[expando] = {}); // Support: IE <9 only
- // Defend against cloned attroperties (jQuery gh-1709)
- uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});
- cache = uniqueCache[type] || [];
- nodeIndex = cache[0] === dirruns && cache[1];
- diff = nodeIndex && cache[2];
- node = nodeIndex && parent.childNodes[nodeIndex];
- while (node = ++nodeIndex && node && node[dir] || ( // Fallback to seeking `elem` from the start
- diff = nodeIndex = 0) || start.pop()) {
- // When found, cache indexes on `parent` and break
- if (node.nodeType === 1 && ++diff && node === elem) {
- uniqueCache[type] = [dirruns, nodeIndex, diff];
- break;
- }
- }
- } else {
- // Use previously-cached element index if available
- if (useCache) {
- // ...in a gzip-friendly way
- node = elem;
- outerCache = node[expando] || (node[expando] = {}); // Support: IE <9 only
- // Defend against cloned attroperties (jQuery gh-1709)
- uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});
- cache = uniqueCache[type] || [];
- nodeIndex = cache[0] === dirruns && cache[1];
- diff = nodeIndex;
- } // xml :nth-child(...)
- // or :nth-last-child(...) or :nth(-last)?-of-type(...)
- if (diff === false) {
- // Use the same loop as above to seek `elem` from the start
- while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
- if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) {
- // Cache the index of each encountered element
- if (useCache) {
- outerCache = node[expando] || (node[expando] = {}); // Support: IE <9 only
- // Defend against cloned attroperties (jQuery gh-1709)
- uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});
- uniqueCache[type] = [dirruns, diff];
- }
- if (node === elem) {
- break;
- }
- }
- }
- }
- } // Incorporate the offset, then check against cycle size
- diff -= last;
- return diff === first || diff % first === 0 && diff / first >= 0;
- }
- };
- },
- "PSEUDO": function (pseudo, argument) {
- // pseudo-class names are case-insensitive
- // http://www.w3.org/TR/selectors/#pseudo-classes
- // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
- // Remember that setFilters inherits from pseudos
- var args,
- fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error("unsupported pseudo: " + pseudo); // The user may use createPseudo to indicate that
- // arguments are needed to create the filter function
- // just as Sizzle does
- if (fn[expando]) {
- return fn(argument);
- } // But maintain support for old signatures
- if (fn.length > 1) {
- args = [pseudo, pseudo, "", argument];
- return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) {
- var idx,
- matched = fn(seed, argument),
- i = matched.length;
- while (i--) {
- idx = indexOf(seed, matched[i]);
- seed[idx] = !(matches[idx] = matched[i]);
- }
- }) : function (elem) {
- return fn(elem, 0, args);
- };
- }
- return fn;
- }
- },
- pseudos: {
- // Potentially complex pseudos
- "not": markFunction(function (selector) {
- // Trim the selector passed to compile
- // to avoid treating leading and trailing
- // spaces as combinators
- var input = [],
- results = [],
- matcher = compile(selector.replace(rtrim, "$1"));
- return matcher[expando] ? markFunction(function (seed, matches, context, xml) {
- var elem,
- unmatched = matcher(seed, null, xml, []),
- i = seed.length; // Match elements unmatched by `matcher`
- while (i--) {
- if (elem = unmatched[i]) {
- seed[i] = !(matches[i] = elem);
- }
- }
- }) : function (elem, context, xml) {
- input[0] = elem;
- matcher(input, null, xml, results); // Don't keep the element (issue #299)
- input[0] = null;
- return !results.pop();
- };
- }),
- "has": markFunction(function (selector) {
- return function (elem) {
- return Sizzle(selector, elem).length > 0;
- };
- }),
- "contains": markFunction(function (text) {
- text = text.replace(runescape, funescape);
- return function (elem) {
- return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1;
- };
- }),
- // "Whether an element is represented by a :lang() selector
- // is based solely on the element's language value
- // being equal to the identifier C,
- // or beginning with the identifier C immediately followed by "-".
- // The matching of C against the element's language value is performed case-insensitively.
- // The identifier C does not have to be a valid language name."
- // http://www.w3.org/TR/selectors/#lang-pseudo
- "lang": markFunction(function (lang) {
- // lang value must be a valid identifier
- if (!ridentifier.test(lang || "")) {
- Sizzle.error("unsupported lang: " + lang);
- }
- lang = lang.replace(runescape, funescape).toLowerCase();
- return function (elem) {
- var elemLang;
- do {
- if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) {
- elemLang = elemLang.toLowerCase();
- return elemLang === lang || elemLang.indexOf(lang + "-") === 0;
- }
- } while ((elem = elem.parentNode) && elem.nodeType === 1);
- return false;
- };
- }),
- // Miscellaneous
- "target": function (elem) {
- var hash = window.location && window.location.hash;
- return hash && hash.slice(1) === elem.id;
- },
- "root": function (elem) {
- return elem === docElem;
- },
- "focus": function (elem) {
- return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
- },
- // Boolean properties
- "enabled": createDisabledPseudo(false),
- "disabled": createDisabledPseudo(true),
- "checked": function (elem) {
- // In CSS3, :checked should return both checked and selected elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- var nodeName = elem.nodeName.toLowerCase();
- return nodeName === "input" && !!elem.checked || nodeName === "option" && !!elem.selected;
- },
- "selected": function (elem) {
- // Accessing this property makes selected-by-default
- // options in Safari work properly
- if (elem.parentNode) {
- elem.parentNode.selectedIndex;
- }
- return elem.selected === true;
- },
- // Contents
- "empty": function (elem) {
- // http://www.w3.org/TR/selectors/#empty-pseudo
- // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
- // but not by others (comment: 8; processing instruction: 7; etc.)
- // nodeType < 6 works because attributes (2) do not appear as children
- for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
- if (elem.nodeType < 6) {
- return false;
- }
- }
- return true;
- },
- "parent": function (elem) {
- return !Expr.pseudos["empty"](elem);
- },
- // Element/input types
- "header": function (elem) {
- return rheader.test(elem.nodeName);
- },
- "input": function (elem) {
- return rinputs.test(elem.nodeName);
- },
- "button": function (elem) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === "button" || name === "button";
- },
- "text": function (elem) {
- var attr;
- return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && ( // Support: IE<8
- // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
- (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text");
- },
- // Position-in-collection
- "first": createPositionalPseudo(function () {
- return [0];
- }),
- "last": createPositionalPseudo(function (matchIndexes, length) {
- return [length - 1];
- }),
- "eq": createPositionalPseudo(function (matchIndexes, length, argument) {
- return [argument < 0 ? argument + length : argument];
- }),
- "even": createPositionalPseudo(function (matchIndexes, length) {
- var i = 0;
- for (; i < length; i += 2) {
- matchIndexes.push(i);
- }
- return matchIndexes;
- }),
- "odd": createPositionalPseudo(function (matchIndexes, length) {
- var i = 1;
- for (; i < length; i += 2) {
- matchIndexes.push(i);
- }
- return matchIndexes;
- }),
- "lt": createPositionalPseudo(function (matchIndexes, length, argument) {
- var i = argument < 0 ? argument + length : argument;
- for (; --i >= 0;) {
- matchIndexes.push(i);
- }
- return matchIndexes;
- }),
- "gt": createPositionalPseudo(function (matchIndexes, length, argument) {
- var i = argument < 0 ? argument + length : argument;
- for (; ++i < length;) {
- matchIndexes.push(i);
- }
- return matchIndexes;
- })
- }
- };
- Expr.pseudos["nth"] = Expr.pseudos["eq"]; // Add button/input type pseudos
- for (i in {
- radio: true,
- checkbox: true,
- file: true,
- password: true,
- image: true
- }) {
- Expr.pseudos[i] = createInputPseudo(i);
- }
- for (i in {
- submit: true,
- reset: true
- }) {
- Expr.pseudos[i] = createButtonPseudo(i);
- } // Easy API for creating new setFilters
- function setFilters() {}
- setFilters.prototype = Expr.filters = Expr.pseudos;
- Expr.setFilters = new setFilters();
- tokenize = Sizzle.tokenize = function (selector, parseOnly) {
- var matched,
- match,
- tokens,
- type,
- soFar,
- groups,
- preFilters,
- cached = tokenCache[selector + " "];
- if (cached) {
- return parseOnly ? 0 : cached.slice(0);
- }
- soFar = selector;
- groups = [];
- preFilters = Expr.preFilter;
- while (soFar) {
- // Comma and first run
- if (!matched || (match = rcomma.exec(soFar))) {
- if (match) {
- // Don't consume trailing commas as valid
- soFar = soFar.slice(match[0].length) || soFar;
- }
- groups.push(tokens = []);
- }
- matched = false; // Combinators
- if (match = rcombinators.exec(soFar)) {
- matched = match.shift();
- tokens.push({
- value: matched,
- // Cast descendant combinators to space
- type: match[0].replace(rtrim, " ")
- });
- soFar = soFar.slice(matched.length);
- } // Filters
- for (type in Expr.filter) {
- if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) {
- matched = match.shift();
- tokens.push({
- value: matched,
- type: type,
- matches: match
- });
- soFar = soFar.slice(matched.length);
- }
- }
- if (!matched) {
- break;
- }
- } // Return the length of the invalid excess
- // if we're just parsing
- // Otherwise, throw an error or return tokens
- return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) : // Cache the tokens
- tokenCache(selector, groups).slice(0);
- };
- function toSelector(tokens) {
- var i = 0,
- len = tokens.length,
- selector = "";
- for (; i < len; i++) {
- selector += tokens[i].value;
- }
- return selector;
- }
- function addCombinator(matcher, combinator, base) {
- var dir = combinator.dir,
- skip = combinator.next,
- key = skip || dir,
- checkNonElements = base && key === "parentNode",
- doneName = done++;
- return combinator.first ? // Check against closest ancestor/preceding element
- function (elem, context, xml) {
- while (elem = elem[dir]) {
- if (elem.nodeType === 1 || checkNonElements) {
- return matcher(elem, context, xml);
- }
- }
- return false;
- } : // Check against all ancestor/preceding elements
- function (elem, context, xml) {
- var oldCache,
- uniqueCache,
- outerCache,
- newCache = [dirruns, doneName]; // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
- if (xml) {
- while (elem = elem[dir]) {
- if (elem.nodeType === 1 || checkNonElements) {
- if (matcher(elem, context, xml)) {
- return true;
- }
- }
- }
- } else {
- while (elem = elem[dir]) {
- if (elem.nodeType === 1 || checkNonElements) {
- outerCache = elem[expando] || (elem[expando] = {}); // Support: IE <9 only
- // Defend against cloned attroperties (jQuery gh-1709)
- uniqueCache = outerCache[elem.uniqueID] || (outerCache[elem.uniqueID] = {});
- if (skip && skip === elem.nodeName.toLowerCase()) {
- elem = elem[dir] || elem;
- } else if ((oldCache = uniqueCache[key]) && oldCache[0] === dirruns && oldCache[1] === doneName) {
- // Assign to newCache so results back-propagate to previous elements
- return newCache[2] = oldCache[2];
- } else {
- // Reuse newcache so results back-propagate to previous elements
- uniqueCache[key] = newCache; // A match means we're done; a fail means we have to keep checking
- if (newCache[2] = matcher(elem, context, xml)) {
- return true;
- }
- }
- }
- }
- }
- return false;
- };
- }
- function elementMatcher(matchers) {
- return matchers.length > 1 ? function (elem, context, xml) {
- var i = matchers.length;
- while (i--) {
- if (!matchers[i](elem, context, xml)) {
- return false;
- }
- }
- return true;
- } : matchers[0];
- }
- function multipleContexts(selector, contexts, results) {
- var i = 0,
- len = contexts.length;
- for (; i < len; i++) {
- Sizzle(selector, contexts[i], results);
- }
- return results;
- }
- function condense(unmatched, map, filter, context, xml) {
- var elem,
- newUnmatched = [],
- i = 0,
- len = unmatched.length,
- mapped = map != null;
- for (; i < len; i++) {
- if (elem = unmatched[i]) {
- if (!filter || filter(elem, context, xml)) {
- newUnmatched.push(elem);
- if (mapped) {
- map.push(i);
- }
- }
- }
- }
- return newUnmatched;
- }
- function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
- if (postFilter && !postFilter[expando]) {
- postFilter = setMatcher(postFilter);
- }
- if (postFinder && !postFinder[expando]) {
- postFinder = setMatcher(postFinder, postSelector);
- }
- return markFunction(function (seed, results, context, xml) {
- var temp,
- i,
- elem,
- preMap = [],
- postMap = [],
- preexisting = results.length,
- // Get initial elements from seed or context
- elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []),
- // Prefilter to get matcher input, preserving a map for seed-results synchronization
- matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems,
- matcherOut = matcher ? // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
- postFinder || (seed ? preFilter : preexisting || postFilter) ? // ...intermediate processing is necessary
- [] : // ...otherwise use results directly
- results : matcherIn; // Find primary matches
- if (matcher) {
- matcher(matcherIn, matcherOut, context, xml);
- } // Apply postFilter
- if (postFilter) {
- temp = condense(matcherOut, postMap);
- postFilter(temp, [], context, xml); // Un-match failing elements by moving them back to matcherIn
- i = temp.length;
- while (i--) {
- if (elem = temp[i]) {
- matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
- }
- }
- }
- if (seed) {
- if (postFinder || preFilter) {
- if (postFinder) {
- // Get the final matcherOut by condensing this intermediate into postFinder contexts
- temp = [];
- i = matcherOut.length;
- while (i--) {
- if (elem = matcherOut[i]) {
- // Restore matcherIn since elem is not yet a final match
- temp.push(matcherIn[i] = elem);
- }
- }
- postFinder(null, matcherOut = [], temp, xml);
- } // Move matched elements from seed to results to keep them synchronized
- i = matcherOut.length;
- while (i--) {
- if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) {
- seed[temp] = !(results[temp] = elem);
- }
- }
- } // Add elements to results, through postFinder if defined
- } else {
- matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut);
- if (postFinder) {
- postFinder(null, results, matcherOut, xml);
- } else {
- push.apply(results, matcherOut);
- }
- }
- });
- }
- function matcherFromTokens(tokens) {
- var checkContext,
- matcher,
- j,
- len = tokens.length,
- leadingRelative = Expr.relative[tokens[0].type],
- implicitRelative = leadingRelative || Expr.relative[" "],
- i = leadingRelative ? 1 : 0,
- // The foundational matcher ensures that elements are reachable from top-level context(s)
- matchContext = addCombinator(function (elem) {
- return elem === checkContext;
- }, implicitRelative, true),
- matchAnyContext = addCombinator(function (elem) {
- return indexOf(checkContext, elem) > -1;
- }, implicitRelative, true),
- matchers = [function (elem, context, xml) {
- var ret = !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml)); // Avoid hanging onto element (issue #299)
- checkContext = null;
- return ret;
- }];
- for (; i < len; i++) {
- if (matcher = Expr.relative[tokens[i].type]) {
- matchers = [addCombinator(elementMatcher(matchers), matcher)];
- } else {
- matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches); // Return special upon seeing a positional matcher
- if (matcher[expando]) {
- // Find the next relative operator (if any) for proper handling
- j = ++i;
- for (; j < len; j++) {
- if (Expr.relative[tokens[j].type]) {
- break;
- }
- }
- return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector( // If the preceding token was a descendant combinator, insert an implicit any-element `*`
- tokens.slice(0, i - 1).concat({
- value: tokens[i - 2].type === " " ? "*" : ""
- })).replace(rtrim, "$1"), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens));
- }
- matchers.push(matcher);
- }
- }
- return elementMatcher(matchers);
- }
- function matcherFromGroupMatchers(elementMatchers, setMatchers) {
- var bySet = setMatchers.length > 0,
- byElement = elementMatchers.length > 0,
- superMatcher = function (seed, context, xml, results, outermost) {
- var elem,
- j,
- matcher,
- matchedCount = 0,
- i = "0",
- unmatched = seed && [],
- setMatched = [],
- contextBackup = outermostContext,
- // We must always have either seed elements or outermost context
- elems = seed || byElement && Expr.find["TAG"]("*", outermost),
- // Use integer dirruns iff this is the outermost matcher
- dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1,
- len = elems.length;
- if (outermost) {
- outermostContext = context === document || context || outermost;
- } // Add elements passing elementMatchers directly to results
- // Support: IE<9, Safari
- // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
- for (; i !== len && (elem = elems[i]) != null; i++) {
- if (byElement && elem) {
- j = 0;
- if (!context && elem.ownerDocument !== document) {
- setDocument(elem);
- xml = !documentIsHTML;
- }
- while (matcher = elementMatchers[j++]) {
- if (matcher(elem, context || document, xml)) {
- results.push(elem);
- break;
- }
- }
- if (outermost) {
- dirruns = dirrunsUnique;
- }
- } // Track unmatched elements for set filters
- if (bySet) {
- // They will have gone through all possible matchers
- if (elem = !matcher && elem) {
- matchedCount--;
- } // Lengthen the array for every element, matched or not
- if (seed) {
- unmatched.push(elem);
- }
- }
- } // `i` is now the count of elements visited above, and adding it to `matchedCount`
- // makes the latter nonnegative.
- matchedCount += i; // Apply set filters to unmatched elements
- // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
- // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
- // no element matchers and no seed.
- // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
- // case, which will result in a "00" `matchedCount` that differs from `i` but is also
- // numerically zero.
- if (bySet && i !== matchedCount) {
- j = 0;
- while (matcher = setMatchers[j++]) {
- matcher(unmatched, setMatched, context, xml);
- }
- if (seed) {
- // Reintegrate element matches to eliminate the need for sorting
- if (matchedCount > 0) {
- while (i--) {
- if (!(unmatched[i] || setMatched[i])) {
- setMatched[i] = pop.call(results);
- }
- }
- } // Discard index placeholder values to get only actual matches
- setMatched = condense(setMatched);
- } // Add matches to results
- push.apply(results, setMatched); // Seedless set matches succeeding multiple successful matchers stipulate sorting
- if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) {
- Sizzle.uniqueSort(results);
- }
- } // Override manipulation of globals by nested matchers
- if (outermost) {
- dirruns = dirrunsUnique;
- outermostContext = contextBackup;
- }
- return unmatched;
- };
- return bySet ? markFunction(superMatcher) : superMatcher;
- }
- compile = Sizzle.compile = function (selector, match
- /* Internal Use Only */
- ) {
- var i,
- setMatchers = [],
- elementMatchers = [],
- cached = compilerCache[selector + " "];
- if (!cached) {
- // Generate a function of recursive functions that can be used to check each element
- if (!match) {
- match = tokenize(selector);
- }
- i = match.length;
- while (i--) {
- cached = matcherFromTokens(match[i]);
- if (cached[expando]) {
- setMatchers.push(cached);
- } else {
- elementMatchers.push(cached);
- }
- } // Cache the compiled function
- cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers)); // Save selector and tokenization
- cached.selector = selector;
- }
- return cached;
- };
- /**
- * A low-level selection function that works with Sizzle's compiled
- * selector functions
- * @param {String|Function} selector A selector or a pre-compiled
- * selector function built with Sizzle.compile
- * @param {Element} context
- * @param {Array} [results]
- * @param {Array} [seed] A set of elements to match against
- */
- select = Sizzle.select = function (selector, context, results, seed) {
- var i,
- tokens,
- token,
- type,
- find,
- compiled = typeof selector === "function" && selector,
- match = !seed && tokenize(selector = compiled.selector || selector);
- results = results || []; // Try to minimize operations if there is only one selector in the list and no seed
- // (the latter of which guarantees us context)
- if (match.length === 1) {
- // Reduce context if the leading compound selector is an ID
- tokens = match[0] = match[0].slice(0);
- if (tokens.length > 2 && (token = tokens[0]).type === "ID" && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {
- context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0];
- if (!context) {
- return results; // Precompiled matchers will still verify ancestry, so step up a level
- } else if (compiled) {
- context = context.parentNode;
- }
- selector = selector.slice(tokens.shift().value.length);
- } // Fetch a seed set for right-to-left matching
- i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length;
- while (i--) {
- token = tokens[i]; // Abort if we hit a combinator
- if (Expr.relative[type = token.type]) {
- break;
- }
- if (find = Expr.find[type]) {
- // Search, expanding context for leading sibling combinators
- if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testContext(context.parentNode) || context)) {
- // If seed is empty or no tokens remain, we can return early
- tokens.splice(i, 1);
- selector = seed.length && toSelector(tokens);
- if (!selector) {
- push.apply(results, seed);
- return results;
- }
- break;
- }
- }
- }
- } // Compile and execute a filtering function if one is not provided
- // Provide `match` to avoid retokenization if we modified the selector above
- (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, !context || rsibling.test(selector) && testContext(context.parentNode) || context);
- return results;
- }; // One-time assignments
- // Sort stability
- support.sortStable = expando.split("").sort(sortOrder).join("") === expando; // Support: Chrome 14-35+
- // Always assume duplicates if they aren't passed to the comparison function
- support.detectDuplicates = !!hasDuplicate; // Initialize against the default document
- setDocument(); // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
- // Detached nodes confoundingly follow *each other*
- support.sortDetached = assert(function (el) {
- // Should return 1, but returns 4 (following)
- return el.compareDocumentPosition(document.createElement("fieldset")) & 1;
- }); // Support: IE<8
- // Prevent attribute/property "interpolation"
- // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
- if (!assert(function (el) {
- el.innerHTML = "<a href='#'></a>";
- return el.firstChild.getAttribute("href") === "#";
- })) {
- addHandle("type|href|height|width", function (elem, name, isXML) {
- if (!isXML) {
- return elem.getAttribute(name, name.toLowerCase() === "type" ? 1 : 2);
- }
- });
- } // Support: IE<9
- // Use defaultValue in place of getAttribute("value")
- if (!support.attributes || !assert(function (el) {
- el.innerHTML = "<input/>";
- el.firstChild.setAttribute("value", "");
- return el.firstChild.getAttribute("value") === "";
- })) {
- addHandle("value", function (elem, name, isXML) {
- if (!isXML && elem.nodeName.toLowerCase() === "input") {
- return elem.defaultValue;
- }
- });
- } // Support: IE<9
- // Use getAttributeNode to fetch booleans when getAttribute lies
- if (!assert(function (el) {
- return el.getAttribute("disabled") == null;
- })) {
- addHandle(booleans, function (elem, name, isXML) {
- var val;
- if (!isXML) {
- return elem[name] === true ? name.toLowerCase() : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null;
- }
- });
- }
- return Sizzle;
- }(window);
- jQuery.find = Sizzle;
- jQuery.expr = Sizzle.selectors; // Deprecated
- jQuery.expr[":"] = jQuery.expr.pseudos;
- jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
- jQuery.text = Sizzle.getText;
- jQuery.isXMLDoc = Sizzle.isXML;
- jQuery.contains = Sizzle.contains;
- jQuery.escapeSelector = Sizzle.escape;
- var dir = function (elem, dir, until) {
- var matched = [],
- truncate = until !== undefined;
- while ((elem = elem[dir]) && elem.nodeType !== 9) {
- if (elem.nodeType === 1) {
- if (truncate && jQuery(elem).is(until)) {
- break;
- }
- matched.push(elem);
- }
- }
- return matched;
- };
- var siblings = function (n, elem) {
- var matched = [];
- for (; n; n = n.nextSibling) {
- if (n.nodeType === 1 && n !== elem) {
- matched.push(n);
- }
- }
- return matched;
- };
- var rneedsContext = jQuery.expr.match.needsContext;
- function nodeName(elem, name) {
- return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
- }
- ;
- var rsingleTag = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i; // Implement the identical functionality for filter and not
- function winnow(elements, qualifier, not) {
- if (isFunction(qualifier)) {
- return jQuery.grep(elements, function (elem, i) {
- return !!qualifier.call(elem, i, elem) !== not;
- });
- } // Single element
- if (qualifier.nodeType) {
- return jQuery.grep(elements, function (elem) {
- return elem === qualifier !== not;
- });
- } // Arraylike of elements (jQuery, arguments, Array)
- if (typeof qualifier !== "string") {
- return jQuery.grep(elements, function (elem) {
- return indexOf.call(qualifier, elem) > -1 !== not;
- });
- } // Filtered directly for both simple and complex selectors
- return jQuery.filter(qualifier, elements, not);
- }
- jQuery.filter = function (expr, elems, not) {
- var elem = elems[0];
- if (not) {
- expr = ":not(" + expr + ")";
- }
- if (elems.length === 1 && elem.nodeType === 1) {
- return jQuery.find.matchesSelector(elem, expr) ? [elem] : [];
- }
- return jQuery.find.matches(expr, jQuery.grep(elems, function (elem) {
- return elem.nodeType === 1;
- }));
- };
- jQuery.fn.extend({
- find: function (selector) {
- var i,
- ret,
- len = this.length,
- self = this;
- if (typeof selector !== "string") {
- return this.pushStack(jQuery(selector).filter(function () {
- for (i = 0; i < len; i++) {
- if (jQuery.contains(self[i], this)) {
- return true;
- }
- }
- }));
- }
- ret = this.pushStack([]);
- for (i = 0; i < len; i++) {
- jQuery.find(selector, self[i], ret);
- }
- return len > 1 ? jQuery.uniqueSort(ret) : ret;
- },
- filter: function (selector) {
- return this.pushStack(winnow(this, selector || [], false));
- },
- not: function (selector) {
- return this.pushStack(winnow(this, selector || [], true));
- },
- is: function (selector) {
- return !!winnow(this, // If this is a positional/relative selector, check membership in the returned set
- // so $("p:first").is("p:last") won't return true for a doc with two "p".
- typeof selector === "string" && rneedsContext.test(selector) ? jQuery(selector) : selector || [], false).length;
- }
- }); // Initialize a jQuery object
- // A central reference to the root jQuery(document)
- var rootjQuery,
- // A simple way to check for HTML strings
- // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
- // Strict HTML recognition (#11290: must start with <)
- // Shortcut simple #id case for speed
- rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
- init = jQuery.fn.init = function (selector, context, root) {
- var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false)
- if (!selector) {
- return this;
- } // Method init() accepts an alternate rootjQuery
- // so migrate can support jQuery.sub (gh-2101)
- root = root || rootjQuery; // Handle HTML strings
- if (typeof selector === "string") {
- if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {
- // Assume that strings that start and end with <> are HTML and skip the regex check
- match = [null, selector, null];
- } else {
- match = rquickExpr.exec(selector);
- } // Match html or make sure no context is specified for #id
- if (match && (match[1] || !context)) {
- // HANDLE: $(html) -> $(array)
- if (match[1]) {
- context = context instanceof jQuery ? context[0] : context; // Option to run scripts is true for back-compat
- // Intentionally let the error be thrown if parseHTML is not present
- jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, true)); // HANDLE: $(html, props)
- if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
- for (match in context) {
- // Properties of context are called as methods if possible
- if (isFunction(this[match])) {
- this[match](context[match]); // ...and otherwise set as attributes
- } else {
- this.attr(match, context[match]);
- }
- }
- }
- return this; // HANDLE: $(#id)
- } else {
- elem = document.getElementById(match[2]);
- if (elem) {
- // Inject the element directly into the jQuery object
- this[0] = elem;
- this.length = 1;
- }
- return this;
- } // HANDLE: $(expr, $(...))
- } else if (!context || context.jquery) {
- return (context || root).find(selector); // HANDLE: $(expr, context)
- // (which is just equivalent to: $(context).find(expr)
- } else {
- return this.constructor(context).find(selector);
- } // HANDLE: $(DOMElement)
- } else if (selector.nodeType) {
- this[0] = selector;
- this.length = 1;
- return this; // HANDLE: $(function)
- // Shortcut for document ready
- } else if (isFunction(selector)) {
- return root.ready !== undefined ? root.ready(selector) : // Execute immediately if ready is not present
- selector(jQuery);
- }
- return jQuery.makeArray(selector, this);
- }; // Give the init function the jQuery prototype for later instantiation
- init.prototype = jQuery.fn; // Initialize central reference
- rootjQuery = jQuery(document);
- var rparentsprev = /^(?:parents|prev(?:Until|All))/,
- // Methods guaranteed to produce a unique set when starting from a unique set
- guaranteedUnique = {
- children: true,
- contents: true,
- next: true,
- prev: true
- };
- jQuery.fn.extend({
- has: function (target) {
- var targets = jQuery(target, this),
- l = targets.length;
- return this.filter(function () {
- var i = 0;
- for (; i < l; i++) {
- if (jQuery.contains(this, targets[i])) {
- return true;
- }
- }
- });
- },
- closest: function (selectors, context) {
- var cur,
- i = 0,
- l = this.length,
- matched = [],
- targets = typeof selectors !== "string" && jQuery(selectors); // Positional selectors never match, since there's no _selection_ context
- if (!rneedsContext.test(selectors)) {
- for (; i < l; i++) {
- for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {
- // Always skip document fragments
- if (cur.nodeType < 11 && (targets ? targets.index(cur) > -1 : // Don't pass non-elements to Sizzle
- cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors))) {
- matched.push(cur);
- break;
- }
- }
- }
- }
- return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched);
- },
- // Determine the position of an element within the set
- index: function (elem) {
- // No argument, return index in parent
- if (!elem) {
- return this[0] && this[0].parentNode ? this.first().prevAll().length : -1;
- } // Index in selector
- if (typeof elem === "string") {
- return indexOf.call(jQuery(elem), this[0]);
- } // Locate the position of the desired element
- return indexOf.call(this, // If it receives a jQuery object, the first element is used
- elem.jquery ? elem[0] : elem);
- },
- add: function (selector, context) {
- return this.pushStack(jQuery.uniqueSort(jQuery.merge(this.get(), jQuery(selector, context))));
- },
- addBack: function (selector) {
- return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector));
- }
- });
- function sibling(cur, dir) {
- while ((cur = cur[dir]) && cur.nodeType !== 1) {}
- return cur;
- }
- jQuery.each({
- parent: function (elem) {
- var parent = elem.parentNode;
- return parent && parent.nodeType !== 11 ? parent : null;
- },
- parents: function (elem) {
- return dir(elem, "parentNode");
- },
- parentsUntil: function (elem, i, until) {
- return dir(elem, "parentNode", until);
- },
- next: function (elem) {
- return sibling(elem, "nextSibling");
- },
- prev: function (elem) {
- return sibling(elem, "previousSibling");
- },
- nextAll: function (elem) {
- return dir(elem, "nextSibling");
- },
- prevAll: function (elem) {
- return dir(elem, "previousSibling");
- },
- nextUntil: function (elem, i, until) {
- return dir(elem, "nextSibling", until);
- },
- prevUntil: function (elem, i, until) {
- return dir(elem, "previousSibling", until);
- },
- siblings: function (elem) {
- return siblings((elem.parentNode || {}).firstChild, elem);
- },
- children: function (elem) {
- return siblings(elem.firstChild);
- },
- contents: function (elem) {
- if (nodeName(elem, "iframe")) {
- return elem.contentDocument;
- } // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
- // Treat the template element as a regular one in browsers that
- // don't support it.
- if (nodeName(elem, "template")) {
- elem = elem.content || elem;
- }
- return jQuery.merge([], elem.childNodes);
- }
- }, function (name, fn) {
- jQuery.fn[name] = function (until, selector) {
- var matched = jQuery.map(this, fn, until);
- if (name.slice(-5) !== "Until") {
- selector = until;
- }
- if (selector && typeof selector === "string") {
- matched = jQuery.filter(selector, matched);
- }
- if (this.length > 1) {
- // Remove duplicates
- if (!guaranteedUnique[name]) {
- jQuery.uniqueSort(matched);
- } // Reverse order for parents* and prev-derivatives
- if (rparentsprev.test(name)) {
- matched.reverse();
- }
- }
- return this.pushStack(matched);
- };
- });
- var rnothtmlwhite = /[^\x20\t\r\n\f]+/g; // Convert String-formatted options into Object-formatted ones
- function createOptions(options) {
- var object = {};
- jQuery.each(options.match(rnothtmlwhite) || [], function (_, flag) {
- object[flag] = true;
- });
- return object;
- }
- /*
- * Create a callback list using the following parameters:
- *
- * options: an optional list of space-separated options that will change how
- * the callback list behaves or a more traditional option object
- *
- * By default a callback list will act like an event callback list and can be
- * "fired" multiple times.
- *
- * Possible options:
- *
- * once: will ensure the callback list can only be fired once (like a Deferred)
- *
- * memory: will keep track of previous values and will call any callback added
- * after the list has been fired right away with the latest "memorized"
- * values (like a Deferred)
- *
- * unique: will ensure a callback can only be added once (no duplicate in the list)
- *
- * stopOnFalse: interrupt callings when a callback returns false
- *
- */
- jQuery.Callbacks = function (options) {
- // Convert options from String-formatted to Object-formatted if needed
- // (we check in cache first)
- options = typeof options === "string" ? createOptions(options) : jQuery.extend({}, options);
- var // Flag to know if list is currently firing
- firing,
- // Last fire value for non-forgettable lists
- memory,
- // Flag to know if list was already fired
- fired,
- // Flag to prevent firing
- locked,
- // Actual callback list
- list = [],
- // Queue of execution data for repeatable lists
- queue = [],
- // Index of currently firing callback (modified by add/remove as needed)
- firingIndex = -1,
- // Fire callbacks
- fire = function () {
- // Enforce single-firing
- locked = locked || options.once; // Execute callbacks for all pending executions,
- // respecting firingIndex overrides and runtime changes
- fired = firing = true;
- for (; queue.length; firingIndex = -1) {
- memory = queue.shift();
- while (++firingIndex < list.length) {
- // Run callback and check for early termination
- if (list[firingIndex].apply(memory[0], memory[1]) === false && options.stopOnFalse) {
- // Jump to end and forget the data so .add doesn't re-fire
- firingIndex = list.length;
- memory = false;
- }
- }
- } // Forget the data if we're done with it
- if (!options.memory) {
- memory = false;
- }
- firing = false; // Clean up if we're done firing for good
- if (locked) {
- // Keep an empty list if we have data for future add calls
- if (memory) {
- list = []; // Otherwise, this object is spent
- } else {
- list = "";
- }
- }
- },
- // Actual Callbacks object
- self = {
- // Add a callback or a collection of callbacks to the list
- add: function () {
- if (list) {
- // If we have memory from a past run, we should fire after adding
- if (memory && !firing) {
- firingIndex = list.length - 1;
- queue.push(memory);
- }
- (function add(args) {
- jQuery.each(args, function (_, arg) {
- if (isFunction(arg)) {
- if (!options.unique || !self.has(arg)) {
- list.push(arg);
- }
- } else if (arg && arg.length && toType(arg) !== "string") {
- // Inspect recursively
- add(arg);
- }
- });
- })(arguments);
- if (memory && !firing) {
- fire();
- }
- }
- return this;
- },
- // Remove a callback from the list
- remove: function () {
- jQuery.each(arguments, function (_, arg) {
- var index;
- while ((index = jQuery.inArray(arg, list, index)) > -1) {
- list.splice(index, 1); // Handle firing indexes
- if (index <= firingIndex) {
- firingIndex--;
- }
- }
- });
- return this;
- },
- // Check if a given callback is in the list.
- // If no argument is given, return whether or not list has callbacks attached.
- has: function (fn) {
- return fn ? jQuery.inArray(fn, list) > -1 : list.length > 0;
- },
- // Remove all callbacks from the list
- empty: function () {
- if (list) {
- list = [];
- }
- return this;
- },
- // Disable .fire and .add
- // Abort any current/pending executions
- // Clear all callbacks and values
- disable: function () {
- locked = queue = [];
- list = memory = "";
- return this;
- },
- disabled: function () {
- return !list;
- },
- // Disable .fire
- // Also disable .add unless we have memory (since it would have no effect)
- // Abort any pending executions
- lock: function () {
- locked = queue = [];
- if (!memory && !firing) {
- list = memory = "";
- }
- return this;
- },
- locked: function () {
- return !!locked;
- },
- // Call all callbacks with the given context and arguments
- fireWith: function (context, args) {
- if (!locked) {
- args = args || [];
- args = [context, args.slice ? args.slice() : args];
- queue.push(args);
- if (!firing) {
- fire();
- }
- }
- return this;
- },
- // Call all the callbacks with the given arguments
- fire: function () {
- self.fireWith(this, arguments);
- return this;
- },
- // To know if the callbacks have already been called at least once
- fired: function () {
- return !!fired;
- }
- };
- return self;
- };
- function Identity(v) {
- return v;
- }
- function Thrower(ex) {
- throw ex;
- }
- function adoptValue(value, resolve, reject, noValue) {
- var method;
- try {
- // Check for promise aspect first to privilege synchronous behavior
- if (value && isFunction(method = value.promise)) {
- method.call(value).done(resolve).fail(reject); // Other thenables
- } else if (value && isFunction(method = value.then)) {
- method.call(value, resolve, reject); // Other non-thenables
- } else {
- // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
- // * false: [ value ].slice( 0 ) => resolve( value )
- // * true: [ value ].slice( 1 ) => resolve()
- resolve.apply(undefined, [value].slice(noValue));
- } // For Promises/A+, convert exceptions into rejections
- // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
- // Deferred#then to conditionally suppress rejection.
- } catch (value) {
- // Support: Android 4.0 only
- // Strict mode functions invoked without .call/.apply get global-object context
- reject.apply(undefined, [value]);
- }
- }
- jQuery.extend({
- Deferred: function (func) {
- var tuples = [// action, add listener, callbacks,
- // ... .then handlers, argument index, [final state]
- ["notify", "progress", jQuery.Callbacks("memory"), jQuery.Callbacks("memory"), 2], ["resolve", "done", jQuery.Callbacks("once memory"), jQuery.Callbacks("once memory"), 0, "resolved"], ["reject", "fail", jQuery.Callbacks("once memory"), jQuery.Callbacks("once memory"), 1, "rejected"]],
- state = "pending",
- promise = {
- state: function () {
- return state;
- },
- always: function () {
- deferred.done(arguments).fail(arguments);
- return this;
- },
- "catch": function (fn) {
- return promise.then(null, fn);
- },
- // Keep pipe for back-compat
- pipe: function ()
- /* fnDone, fnFail, fnProgress */
- {
- var fns = arguments;
- return jQuery.Deferred(function (newDefer) {
- jQuery.each(tuples, function (i, tuple) {
- // Map tuples (progress, done, fail) to arguments (done, fail, progress)
- var fn = isFunction(fns[tuple[4]]) && fns[tuple[4]]; // deferred.progress(function() { bind to newDefer or newDefer.notify })
- // deferred.done(function() { bind to newDefer or newDefer.resolve })
- // deferred.fail(function() { bind to newDefer or newDefer.reject })
- deferred[tuple[1]](function () {
- var returned = fn && fn.apply(this, arguments);
- if (returned && isFunction(returned.promise)) {
- returned.promise().progress(newDefer.notify).done(newDefer.resolve).fail(newDefer.reject);
- } else {
- newDefer[tuple[0] + "With"](this, fn ? [returned] : arguments);
- }
- });
- });
- fns = null;
- }).promise();
- },
- then: function (onFulfilled, onRejected, onProgress) {
- var maxDepth = 0;
- function resolve(depth, deferred, handler, special) {
- return function () {
- var that = this,
- args = arguments,
- mightThrow = function () {
- var returned, then; // Support: Promises/A+ section 2.3.3.3.3
- // https://promisesaplus.com/#point-59
- // Ignore double-resolution attempts
- if (depth < maxDepth) {
- return;
- }
- returned = handler.apply(that, args); // Support: Promises/A+ section 2.3.1
- // https://promisesaplus.com/#point-48
- if (returned === deferred.promise()) {
- throw new TypeError("Thenable self-resolution");
- } // Support: Promises/A+ sections 2.3.3.1, 3.5
- // https://promisesaplus.com/#point-54
- // https://promisesaplus.com/#point-75
- // Retrieve `then` only once
- then = returned && ( // Support: Promises/A+ section 2.3.4
- // https://promisesaplus.com/#point-64
- // Only check objects and functions for thenability
- typeof returned === "object" || typeof returned === "function") && returned.then; // Handle a returned thenable
- if (isFunction(then)) {
- // Special processors (notify) just wait for resolution
- if (special) {
- then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special)); // Normal processors (resolve) also hook into progress
- } else {
- // ...and disregard older resolution values
- maxDepth++;
- then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special), resolve(maxDepth, deferred, Identity, deferred.notifyWith));
- } // Handle all other returned values
- } else {
- // Only substitute handlers pass on context
- // and multiple values (non-spec behavior)
- if (handler !== Identity) {
- that = undefined;
- args = [returned];
- } // Process the value(s)
- // Default process is resolve
- (special || deferred.resolveWith)(that, args);
- }
- },
- // Only normal processors (resolve) catch and reject exceptions
- process = special ? mightThrow : function () {
- try {
- mightThrow();
- } catch (e) {
- if (jQuery.Deferred.exceptionHook) {
- jQuery.Deferred.exceptionHook(e, process.stackTrace);
- } // Support: Promises/A+ section 2.3.3.3.4.1
- // https://promisesaplus.com/#point-61
- // Ignore post-resolution exceptions
- if (depth + 1 >= maxDepth) {
- // Only substitute handlers pass on context
- // and multiple values (non-spec behavior)
- if (handler !== Thrower) {
- that = undefined;
- args = [e];
- }
- deferred.rejectWith(that, args);
- }
- }
- }; // Support: Promises/A+ section 2.3.3.3.1
- // https://promisesaplus.com/#point-57
- // Re-resolve proterminatemises immediately to dodge false rejection from
- // subsequent errors
- if (depth) {
- process();
- } else {
- // Call an optional hook to record the stack, in case of exception
- // since it's otherwise lost when execution goes async
- if (jQuery.Deferred.getStackHook) {
- process.stackTrace = jQuery.Deferred.getStackHook();
- }
- window.setTimeout(process);
- }
- };
- }
- return jQuery.Deferred(function (newDefer) {
- // progress_handlers.add( ... )
- tuples[0][3].add(resolve(0, newDefer, isFunction(onProgress) ? onProgress : Identity, newDefer.notifyWith)); // fulfilled_handlers.add( ... )
- tuples[1][3].add(resolve(0, newDefer, isFunction(onFulfilled) ? onFulfilled : Identity)); // rejected_handlers.add( ... )
- tuples[2][3].add(resolve(0, newDefer, isFunction(onRejected) ? onRejected : Thrower));
- }).promise();
- },
- // Get a promise for this deferred
- // If obj is provided, the promise aspect is added to the object
- promise: function (obj) {
- return obj != null ? jQuery.extend(obj, promise) : promise;
- }
- },
- deferred = {}; // Add list-specific methods
- jQuery.each(tuples, function (i, tuple) {
- var list = tuple[2],
- stateString = tuple[5]; // promise.progress = list.add
- // promise.done = list.add
- // promise.fail = list.add
- promise[tuple[1]] = list.add; // Handle state
- if (stateString) {
- list.add(function () {
- // state = "resolved" (i.e., fulfilled)
- // state = "rejected"
- state = stateString;
- }, // rejected_callbacks.disable
- // fulfilled_callbacks.disable
- tuples[3 - i][2].disable, // rejected_handlers.disable
- // fulfilled_handlers.disable
- tuples[3 - i][3].disable, // progress_callbacks.lock
- tuples[0][2].lock, // progress_handlers.lock
- tuples[0][3].lock);
- } // progress_handlers.fire
- // fulfilled_handlers.fire
- // rejected_handlers.fire
- list.add(tuple[3].fire); // deferred.notify = function() { deferred.notifyWith(...) }
- // deferred.resolve = function() { deferred.resolveWith(...) }
- // deferred.reject = function() { deferred.rejectWith(...) }
- deferred[tuple[0]] = function () {
- deferred[tuple[0] + "With"](this === deferred ? undefined : this, arguments);
- return this;
- }; // deferred.notifyWith = list.fireWith
- // deferred.resolveWith = list.fireWith
- // deferred.rejectWith = list.fireWith
- deferred[tuple[0] + "With"] = list.fireWith;
- }); // Make the deferred a promise
- promise.promise(deferred); // Call given func if any
- if (func) {
- func.call(deferred, deferred);
- } // All done!
- return deferred;
- },
- // Deferred helper
- when: function (singleValue) {
- var // count of uncompleted subordinates
- remaining = arguments.length,
- // count of unprocessed arguments
- i = remaining,
- // subordinate fulfillment data
- resolveContexts = Array(i),
- resolveValues = slice.call(arguments),
- // the master Deferred
- master = jQuery.Deferred(),
- // subordinate callback factory
- updateFunc = function (i) {
- return function (value) {
- resolveContexts[i] = this;
- resolveValues[i] = arguments.length > 1 ? slice.call(arguments) : value;
- if (! --remaining) {
- master.resolveWith(resolveContexts, resolveValues);
- }
- };
- }; // Single- and empty arguments are adopted like Promise.resolve
- if (remaining <= 1) {
- adoptValue(singleValue, master.done(updateFunc(i)).resolve, master.reject, !remaining); // Use .then() to unwrap secondary thenables (cf. gh-3000)
- if (master.state() === "pending" || isFunction(resolveValues[i] && resolveValues[i].then)) {
- return master.then();
- }
- } // Multiple arguments are aggregated like Promise.all array elements
- while (i--) {
- adoptValue(resolveValues[i], updateFunc(i), master.reject);
- }
- return master.promise();
- }
- }); // These usually indicate a programmer mistake during development,
- // warn about them ASAP rather than swallowing them by default.
- var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
- jQuery.Deferred.exceptionHook = function (error, stack) {
- // Support: IE 8 - 9 only
- // Console exists when dev tools are open, which can happen at any time
- if (window.console && window.console.warn && error && rerrorNames.test(error.name)) {
- window.console.warn("jQuery.Deferred exception: " + error.message, error.stack, stack);
- }
- };
- jQuery.readyException = function (error) {
- window.setTimeout(function () {
- throw error;
- });
- }; // The deferred used on DOM ready
- var readyList = jQuery.Deferred();
- jQuery.fn.ready = function (fn) {
- readyList.then(fn) // Wrap jQuery.readyException in a function so that the lookup
- // happens at the time of error handling instead of callback
- // registration.
- .catch(function (error) {
- jQuery.readyException(error);
- });
- return this;
- };
- jQuery.extend({
- // Is the DOM ready to be used? Set to true once it occurs.
- isReady: false,
- // A counter to track how many items to wait for before
- // the ready event fires. See #6781
- readyWait: 1,
- // Handle when the DOM is ready
- ready: function (wait) {
- // Abort if there are pending holds or we're already ready
- if (wait === true ? --jQuery.readyWait : jQuery.isReady) {
- return;
- } // Remember that the DOM is ready
- jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be
- if (wait !== true && --jQuery.readyWait > 0) {
- return;
- } // If there are functions bound, to execute
- readyList.resolveWith(document, [jQuery]);
- }
- });
- jQuery.ready.then = readyList.then; // The ready event handler and self cleanup method
- function completed() {
- document.removeEventListener("DOMContentLoaded", completed);
- window.removeEventListener("load", completed);
- jQuery.ready();
- } // Catch cases where $(document).ready() is called
- // after the browser event has already occurred.
- // Support: IE <=9 - 10 only
- // Older IE sometimes signals "interactive" too soon
- if (document.readyState === "complete" || document.readyState !== "loading" && !document.documentElement.doScroll) {
- // Handle it asynchronously to allow scripts the opportunity to delay ready
- window.setTimeout(jQuery.ready);
- } else {
- // Use the handy event callback
- document.addEventListener("DOMContentLoaded", completed); // A fallback to window.onload, that will always work
- window.addEventListener("load", completed);
- } // Multifunctional method to get and set values of a collection
- // The value/s can optionally be executed if it's a function
- var access = function (elems, fn, key, value, chainable, emptyGet, raw) {
- var i = 0,
- len = elems.length,
- bulk = key == null; // Sets many values
- if (toType(key) === "object") {
- chainable = true;
- for (i in key) {
- access(elems, fn, i, key[i], true, emptyGet, raw);
- } // Sets one value
- } else if (value !== undefined) {
- chainable = true;
- if (!isFunction(value)) {
- raw = true;
- }
- if (bulk) {
- // Bulk operations run against the entire set
- if (raw) {
- fn.call(elems, value);
- fn = null; // ...except when executing function values
- } else {
- bulk = fn;
- fn = function (elem, key, value) {
- return bulk.call(jQuery(elem), value);
- };
- }
- }
- if (fn) {
- for (; i < len; i++) {
- fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key)));
- }
- }
- }
- if (chainable) {
- return elems;
- } // Gets
- if (bulk) {
- return fn.call(elems);
- }
- return len ? fn(elems[0], key) : emptyGet;
- }; // Matches dashed string for camelizing
- var rmsPrefix = /^-ms-/,
- rdashAlpha = /-([a-z])/g; // Used by camelCase as callback to replace()
- function fcamelCase(all, letter) {
- return letter.toUpperCase();
- } // Convert dashed to camelCase; used by the css and data modules
- // Support: IE <=9 - 11, Edge 12 - 15
- // Microsoft forgot to hump their vendor prefix (#9572)
- function camelCase(string) {
- return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase);
- }
- var acceptData = function (owner) {
- // Accepts only:
- // - Node
- // - Node.ELEMENT_NODE
- // - Node.DOCUMENT_NODE
- // - Object
- // - Any
- return owner.nodeType === 1 || owner.nodeType === 9 || !+owner.nodeType;
- };
- function Data() {
- this.expando = jQuery.expando + Data.uid++;
- }
- Data.uid = 1;
- Data.prototype = {
- cache: function (owner) {
- // Check if the owner object already has a cache
- var value = owner[this.expando]; // If not, create one
- if (!value) {
- value = {}; // We can accept data for non-element nodes in modern browsers,
- // but we should not, see #8335.
- // Always return an empty object.
- if (acceptData(owner)) {
- // If it is a node unlikely to be stringify-ed or looped over
- // use plain assignment
- if (owner.nodeType) {
- owner[this.expando] = value; // Otherwise secure it in a non-enumerable property
- // configurable must be true to allow the property to be
- // deleted when data is removed
- } else {
- Object.defineProperty(owner, this.expando, {
- value: value,
- configurable: true
- });
- }
- }
- }
- return value;
- },
- set: function (owner, data, value) {
- var prop,
- cache = this.cache(owner); // Handle: [ owner, key, value ] args
- // Always use camelCase key (gh-2257)
- if (typeof data === "string") {
- cache[camelCase(data)] = value; // Handle: [ owner, { properties } ] args
- } else {
- // Copy the properties one-by-one to the cache object
- for (prop in data) {
- cache[camelCase(prop)] = data[prop];
- }
- }
- return cache;
- },
- get: function (owner, key) {
- return key === undefined ? this.cache(owner) : // Always use camelCase key (gh-2257)
- owner[this.expando] && owner[this.expando][camelCase(key)];
- },
- access: function (owner, key, value) {
- // In cases where either:
- //
- // 1. No key was specified
- // 2. A string key was specified, but no value provided
- //
- // Take the "read" path and allow the get method to determine
- // which value to return, respectively either:
- //
- // 1. The entire cache object
- // 2. The data stored at the key
- //
- if (key === undefined || key && typeof key === "string" && value === undefined) {
- return this.get(owner, key);
- } // When the key is not a string, or both a key and value
- // are specified, set or extend (existing objects) with either:
- //
- // 1. An object of properties
- // 2. A key and value
- //
- this.set(owner, key, value); // Since the "set" path can have two possible entry points
- // return the expected data based on which path was taken[*]
- return value !== undefined ? value : key;
- },
- remove: function (owner, key) {
- var i,
- cache = owner[this.expando];
- if (cache === undefined) {
- return;
- }
- if (key !== undefined) {
- // Support array or space separated string of keys
- if (Array.isArray(key)) {
- // If key is an array of keys...
- // We always set camelCase keys, so remove that.
- key = key.map(camelCase);
- } else {
- key = camelCase(key); // If a key with the spaces exists, use it.
- // Otherwise, create an array by matching non-whitespace
- key = key in cache ? [key] : key.match(rnothtmlwhite) || [];
- }
- i = key.length;
- while (i--) {
- delete cache[key[i]];
- }
- } // Remove the expando if there's no more data
- if (key === undefined || jQuery.isEmptyObject(cache)) {
- // Support: Chrome <=35 - 45
- // Webkit & Blink performance suffers when deleting properties
- // from DOM nodes, so set to undefined instead
- // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
- if (owner.nodeType) {
- owner[this.expando] = undefined;
- } else {
- delete owner[this.expando];
- }
- }
- },
- hasData: function (owner) {
- var cache = owner[this.expando];
- return cache !== undefined && !jQuery.isEmptyObject(cache);
- }
- };
- var dataPriv = new Data();
- var dataUser = new Data(); // Implementation Summary
- //
- // 1. Enforce API surface and semantic compatibility with 1.9.x branch
- // 2. Improve the module's maintainability by reducing the storage
- // paths to a single mechanism.
- // 3. Use the same single mechanism to support "private" and "user" data.
- // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
- // 5. Avoid exposing implementation details on user objects (eg. expando properties)
- // 6. Provide a clear path for implementation upgrade to WeakMap in 2014
- var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
- rmultiDash = /[A-Z]/g;
- function getData(data) {
- if (data === "true") {
- return true;
- }
- if (data === "false") {
- return false;
- }
- if (data === "null") {
- return null;
- } // Only convert to a number if it doesn't change the string
- if (data === +data + "") {
- return +data;
- }
- if (rbrace.test(data)) {
- return JSON.parse(data);
- }
- return data;
- }
- function dataAttr(elem, key, data) {
- var name; // If nothing was found internally, try to fetch any
- // data from the HTML5 data-* attribute
- if (data === undefined && elem.nodeType === 1) {
- name = "data-" + key.replace(rmultiDash, "-$&").toLowerCase();
- data = elem.getAttribute(name);
- if (typeof data === "string") {
- try {
- data = getData(data);
- } catch (e) {} // Make sure we set the data so it isn't changed later
- dataUser.set(elem, key, data);
- } else {
- data = undefined;
- }
- }
- return data;
- }
- jQuery.extend({
- hasData: function (elem) {
- return dataUser.hasData(elem) || dataPriv.hasData(elem);
- },
- data: function (elem, name, data) {
- return dataUser.access(elem, name, data);
- },
- removeData: function (elem, name) {
- dataUser.remove(elem, name);
- },
- // TODO: Now that all calls to _data and _removeData have been replaced
- // with direct calls to dataPriv methods, these can be deprecated.
- _data: function (elem, name, data) {
- return dataPriv.access(elem, name, data);
- },
- _removeData: function (elem, name) {
- dataPriv.remove(elem, name);
- }
- });
- jQuery.fn.extend({
- data: function (key, value) {
- var i,
- name,
- data,
- elem = this[0],
- attrs = elem && elem.attributes; // Gets all values
- if (key === undefined) {
- if (this.length) {
- data = dataUser.get(elem);
- if (elem.nodeType === 1 && !dataPriv.get(elem, "hasDataAttrs")) {
- i = attrs.length;
- while (i--) {
- // Support: IE 11 only
- // The attrs elements can be null (#14894)
- if (attrs[i]) {
- name = attrs[i].name;
- if (name.indexOf("data-") === 0) {
- name = camelCase(name.slice(5));
- dataAttr(elem, name, data[name]);
- }
- }
- }
- dataPriv.set(elem, "hasDataAttrs", true);
- }
- }
- return data;
- } // Sets multiple values
- if (typeof key === "object") {
- return this.each(function () {
- dataUser.set(this, key);
- });
- }
- return access(this, function (value) {
- var data; // The calling jQuery object (element matches) is not empty
- // (and therefore has an element appears at this[ 0 ]) and the
- // `value` parameter was not undefined. An empty jQuery object
- // will result in `undefined` for elem = this[ 0 ] which will
- // throw an exception if an attempt to read a data cache is made.
- if (elem && value === undefined) {
- // Attempt to get data from the cache
- // The key will always be camelCased in Data
- data = dataUser.get(elem, key);
- if (data !== undefined) {
- return data;
- } // Attempt to "discover" the data in
- // HTML5 custom data-* attrs
- data = dataAttr(elem, key);
- if (data !== undefined) {
- return data;
- } // We tried really hard, but the data doesn't exist.
- return;
- } // Set the data...
- this.each(function () {
- // We always store the camelCased key
- dataUser.set(this, key, value);
- });
- }, null, value, arguments.length > 1, null, true);
- },
- removeData: function (key) {
- return this.each(function () {
- dataUser.remove(this, key);
- });
- }
- });
- jQuery.extend({
- queue: function (elem, type, data) {
- var queue;
- if (elem) {
- type = (type || "fx") + "queue";
- queue = dataPriv.get(elem, type); // Speed up dequeue by getting out quickly if this is just a lookup
- if (data) {
- if (!queue || Array.isArray(data)) {
- queue = dataPriv.access(elem, type, jQuery.makeArray(data));
- } else {
- queue.push(data);
- }
- }
- return queue || [];
- }
- },
- dequeue: function (elem, type) {
- type = type || "fx";
- var queue = jQuery.queue(elem, type),
- startLength = queue.length,
- fn = queue.shift(),
- hooks = jQuery._queueHooks(elem, type),
- next = function () {
- jQuery.dequeue(elem, type);
- }; // If the fx queue is dequeued, always remove the progress sentinel
- if (fn === "inprogress") {
- fn = queue.shift();
- startLength--;
- }
- if (fn) {
- // Add a progress sentinel to prevent the fx queue from being
- // automatically dequeued
- if (type === "fx") {
- queue.unshift("inprogress");
- } // Clear up the last queue stop function
- delete hooks.stop;
- fn.call(elem, next, hooks);
- }
- if (!startLength && hooks) {
- hooks.empty.fire();
- }
- },
- // Not public - generate a queueHooks object, or return the current one
- _queueHooks: function (elem, type) {
- var key = type + "queueHooks";
- return dataPriv.get(elem, key) || dataPriv.access(elem, key, {
- empty: jQuery.Callbacks("once memory").add(function () {
- dataPriv.remove(elem, [type + "queue", key]);
- })
- });
- }
- });
- jQuery.fn.extend({
- queue: function (type, data) {
- var setter = 2;
- if (typeof type !== "string") {
- data = type;
- type = "fx";
- setter--;
- }
- if (arguments.length < setter) {
- return jQuery.queue(this[0], type);
- }
- return data === undefined ? this : this.each(function () {
- var queue = jQuery.queue(this, type, data); // Ensure a hooks for this queue
- jQuery._queueHooks(this, type);
- if (type === "fx" && queue[0] !== "inprogress") {
- jQuery.dequeue(this, type);
- }
- });
- },
- dequeue: function (type) {
- return this.each(function () {
- jQuery.dequeue(this, type);
- });
- },
- clearQueue: function (type) {
- return this.queue(type || "fx", []);
- },
- // Get a promise resolved when queues of a certain type
- // are emptied (fx is the type by default)
- promise: function (type, obj) {
- var tmp,
- count = 1,
- defer = jQuery.Deferred(),
- elements = this,
- i = this.length,
- resolve = function () {
- if (! --count) {
- defer.resolveWith(elements, [elements]);
- }
- };
- if (typeof type !== "string") {
- obj = type;
- type = undefined;
- }
- type = type || "fx";
- while (i--) {
- tmp = dataPriv.get(elements[i], type + "queueHooks");
- if (tmp && tmp.empty) {
- count++;
- tmp.empty.add(resolve);
- }
- }
- resolve();
- return defer.promise(obj);
- }
- });
- var pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source;
- var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i");
- var cssExpand = ["Top", "Right", "Bottom", "Left"];
- var isHiddenWithinTree = function (elem, el) {
- // isHiddenWithinTree might be called from jQuery#filter function;
- // in that case, element will be second argument
- elem = el || elem; // Inline style trumps all
- return elem.style.display === "none" || elem.style.display === "" && // Otherwise, check computed style
- // Support: Firefox <=43 - 45
- // Disconnected elements can have computed display: none, so first confirm that elem is
- // in the document.
- jQuery.contains(elem.ownerDocument, elem) && jQuery.css(elem, "display") === "none";
- };
- var swap = function (elem, options, callback, args) {
- var ret,
- name,
- old = {}; // Remember the old values, and insert the new ones
- for (name in options) {
- old[name] = elem.style[name];
- elem.style[name] = options[name];
- }
- ret = callback.apply(elem, args || []); // Revert the old values
- for (name in options) {
- elem.style[name] = old[name];
- }
- return ret;
- };
- function adjustCSS(elem, prop, valueParts, tween) {
- var adjusted,
- scale,
- maxIterations = 20,
- currentValue = tween ? function () {
- return tween.cur();
- } : function () {
- return jQuery.css(elem, prop, "");
- },
- initial = currentValue(),
- unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? "" : "px"),
- // Starting value computation is required for potential unit mismatches
- initialInUnit = (jQuery.cssNumber[prop] || unit !== "px" && +initial) && rcssNum.exec(jQuery.css(elem, prop));
- if (initialInUnit && initialInUnit[3] !== unit) {
- // Support: Firefox <=54
- // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
- initial = initial / 2; // Trust units reported by jQuery.css
- unit = unit || initialInUnit[3]; // Iteratively approximate from a nonzero starting point
- initialInUnit = +initial || 1;
- while (maxIterations--) {
- // Evaluate and update our best guess (doubling guesses that zero out).
- // Finish if the scale equals or crosses 1 (making the old*new product non-positive).
- jQuery.style(elem, prop, initialInUnit + unit);
- if ((1 - scale) * (1 - (scale = currentValue() / initial || 0.5)) <= 0) {
- maxIterations = 0;
- }
- initialInUnit = initialInUnit / scale;
- }
- initialInUnit = initialInUnit * 2;
- jQuery.style(elem, prop, initialInUnit + unit); // Make sure we update the tween properties later on
- valueParts = valueParts || [];
- }
- if (valueParts) {
- initialInUnit = +initialInUnit || +initial || 0; // Apply relative offset (+=/-=) if specified
- adjusted = valueParts[1] ? initialInUnit + (valueParts[1] + 1) * valueParts[2] : +valueParts[2];
- if (tween) {
- tween.unit = unit;
- tween.start = initialInUnit;
- tween.end = adjusted;
- }
- }
- return adjusted;
- }
- var defaultDisplayMap = {};
- function getDefaultDisplay(elem) {
- var temp,
- doc = elem.ownerDocument,
- nodeName = elem.nodeName,
- display = defaultDisplayMap[nodeName];
- if (display) {
- return display;
- }
- temp = doc.body.appendChild(doc.createElement(nodeName));
- display = jQuery.css(temp, "display");
- temp.parentNode.removeChild(temp);
- if (display === "none") {
- display = "block";
- }
- defaultDisplayMap[nodeName] = display;
- return display;
- }
- function showHide(elements, show) {
- var display,
- elem,
- values = [],
- index = 0,
- length = elements.length; // Determine new display value for elements that need to change
- for (; index < length; index++) {
- elem = elements[index];
- if (!elem.style) {
- continue;
- }
- display = elem.style.display;
- if (show) {
- // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
- // check is required in this first loop unless we have a nonempty display value (either
- // inline or about-to-be-restored)
- if (display === "none") {
- values[index] = dataPriv.get(elem, "display") || null;
- if (!values[index]) {
- elem.style.display = "";
- }
- }
- if (elem.style.display === "" && isHiddenWithinTree(elem)) {
- values[index] = getDefaultDisplay(elem);
- }
- } else {
- if (display !== "none") {
- values[index] = "none"; // Remember what we're overwriting
- dataPriv.set(elem, "display", display);
- }
- }
- } // Set the display of the elements in a second loop to avoid constant reflow
- for (index = 0; index < length; index++) {
- if (values[index] != null) {
- elements[index].style.display = values[index];
- }
- }
- return elements;
- }
- jQuery.fn.extend({
- show: function () {
- return showHide(this, true);
- },
- hide: function () {
- return showHide(this);
- },
- toggle: function (state) {
- if (typeof state === "boolean") {
- return state ? this.show() : this.hide();
- }
- return this.each(function () {
- if (isHiddenWithinTree(this)) {
- jQuery(this).show();
- } else {
- jQuery(this).hide();
- }
- });
- }
- });
- var rcheckableType = /^(?:checkbox|radio)$/i;
- var rtagName = /<([a-z][^\/\0>\x20\t\r\n\f]+)/i;
- var rscriptType = /^$|^module$|\/(?:java|ecma)script/i; // We have to close these tags to support XHTML (#13200)
- var wrapMap = {
- // Support: IE <=9 only
- option: [1, "<select multiple='multiple'>", "</select>"],
- // XHTML parsers do not magically insert elements in the
- // same way that tag soup parsers do. So we cannot shorten
- // this by omitting <tbody> or other required elements.
- thead: [1, "<table>", "</table>"],
- col: [2, "<table><colgroup>", "</colgroup></table>"],
- tr: [2, "<table><tbody>", "</tbody></table>"],
- td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
- _default: [0, "", ""]
- }; // Support: IE <=9 only
- wrapMap.optgroup = wrapMap.option;
- wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
- wrapMap.th = wrapMap.td;
- function getAll(context, tag) {
- // Support: IE <=9 - 11 only
- // Use typeof to avoid zero-argument method invocation on host objects (#15151)
- var ret;
- if (typeof context.getElementsByTagName !== "undefined") {
- ret = context.getElementsByTagName(tag || "*");
- } else if (typeof context.querySelectorAll !== "undefined") {
- ret = context.querySelectorAll(tag || "*");
- } else {
- ret = [];
- }
- if (tag === undefined || tag && nodeName(context, tag)) {
- return jQuery.merge([context], ret);
- }
- return ret;
- } // Mark scripts as having already been evaluated
- function setGlobalEval(elems, refElements) {
- var i = 0,
- l = elems.length;
- for (; i < l; i++) {
- dataPriv.set(elems[i], "globalEval", !refElements || dataPriv.get(refElements[i], "globalEval"));
- }
- }
- var rhtml = /<|&#?\w+;/;
- function buildFragment(elems, context, scripts, selection, ignored) {
- var elem,
- tmp,
- tag,
- wrap,
- contains,
- j,
- fragment = context.createDocumentFragment(),
- nodes = [],
- i = 0,
- l = elems.length;
- for (; i < l; i++) {
- elem = elems[i];
- if (elem || elem === 0) {
- // Add nodes directly
- if (toType(elem) === "object") {
- // Support: Android <=4.0 only, PhantomJS 1 only
- // push.apply(_, arraylike) throws on ancient WebKit
- jQuery.merge(nodes, elem.nodeType ? [elem] : elem); // Convert non-html into a text node
- } else if (!rhtml.test(elem)) {
- nodes.push(context.createTextNode(elem)); // Convert html into DOM nodes
- } else {
- tmp = tmp || fragment.appendChild(context.createElement("div")); // Deserialize a standard representation
- tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase();
- wrap = wrapMap[tag] || wrapMap._default;
- tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2]; // Descend through wrappers to the right content
- j = wrap[0];
- while (j--) {
- tmp = tmp.lastChild;
- } // Support: Android <=4.0 only, PhantomJS 1 only
- // push.apply(_, arraylike) throws on ancient WebKit
- jQuery.merge(nodes, tmp.childNodes); // Remember the top-level container
- tmp = fragment.firstChild; // Ensure the created nodes are orphaned (#12392)
- tmp.textContent = "";
- }
- }
- } // Remove wrapper from fragment
- fragment.textContent = "";
- i = 0;
- while (elem = nodes[i++]) {
- // Skip elements already in the context collection (trac-4087)
- if (selection && jQuery.inArray(elem, selection) > -1) {
- if (ignored) {
- ignored.push(elem);
- }
- continue;
- }
- contains = jQuery.contains(elem.ownerDocument, elem); // Append to fragment
- tmp = getAll(fragment.appendChild(elem), "script"); // Preserve script evaluation history
- if (contains) {
- setGlobalEval(tmp);
- } // Capture executables
- if (scripts) {
- j = 0;
- while (elem = tmp[j++]) {
- if (rscriptType.test(elem.type || "")) {
- scripts.push(elem);
- }
- }
- }
- }
- return fragment;
- }
- (function () {
- var fragment = document.createDocumentFragment(),
- div = fragment.appendChild(document.createElement("div")),
- input = document.createElement("input"); // Support: Android 4.0 - 4.3 only
- // Check state lost if the name is set (#11217)
- // Support: Windows Web Apps (WWA)
- // `name` and `type` must use .setAttribute for WWA (#14901)
- input.setAttribute("type", "radio");
- input.setAttribute("checked", "checked");
- input.setAttribute("name", "t");
- div.appendChild(input); // Support: Android <=4.1 only
- // Older WebKit doesn't clone checked state correctly in fragments
- support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked; // Support: IE <=11 only
- // Make sure textarea (and checkbox) defaultValue is properly cloned
- div.innerHTML = "<textarea>x</textarea>";
- support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue;
- })();
- var documentElement = document.documentElement;
- var rkeyEvent = /^key/,
- rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
- rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
- function returnTrue() {
- return true;
- }
- function returnFalse() {
- return false;
- } // Support: IE <=9 only
- // See #13393 for more info
- function safeActiveElement() {
- try {
- return document.activeElement;
- } catch (err) {}
- }
- function on(elem, types, selector, data, fn, one) {
- var origFn, type; // Types can be a map of types/handlers
- if (typeof types === "object") {
- // ( types-Object, selector, data )
- if (typeof selector !== "string") {
- // ( types-Object, data )
- data = data || selector;
- selector = undefined;
- }
- for (type in types) {
- on(elem, type, selector, data, types[type], one);
- }
- return elem;
- }
- if (data == null && fn == null) {
- // ( types, fn )
- fn = selector;
- data = selector = undefined;
- } else if (fn == null) {
- if (typeof selector === "string") {
- // ( types, selector, fn )
- fn = data;
- data = undefined;
- } else {
- // ( types, data, fn )
- fn = data;
- data = selector;
- selector = undefined;
- }
- }
- if (fn === false) {
- fn = returnFalse;
- } else if (!fn) {
- return elem;
- }
- if (one === 1) {
- origFn = fn;
- fn = function (event) {
- // Can use an empty set, since event contains the info
- jQuery().off(event);
- return origFn.apply(this, arguments);
- }; // Use same guid so caller can remove using origFn
- fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
- }
- return elem.each(function () {
- jQuery.event.add(this, types, fn, data, selector);
- });
- }
- /*
- * Helper functions for managing events -- not part of the public interface.
- * Props to Dean Edwards' addEvent library for many of the ideas.
- */
- jQuery.event = {
- global: {},
- add: function (elem, types, handler, data, selector) {
- var handleObjIn,
- eventHandle,
- tmp,
- events,
- t,
- handleObj,
- special,
- handlers,
- type,
- namespaces,
- origType,
- elemData = dataPriv.get(elem); // Don't attach events to noData or text/comment nodes (but allow plain objects)
- if (!elemData) {
- return;
- } // Caller can pass in an object of custom data in lieu of the handler
- if (handler.handler) {
- handleObjIn = handler;
- handler = handleObjIn.handler;
- selector = handleObjIn.selector;
- } // Ensure that invalid selectors throw exceptions at attach time
- // Evaluate against documentElement in case elem is a non-element node (e.g., document)
- if (selector) {
- jQuery.find.matchesSelector(documentElement, selector);
- } // Make sure that the handler has a unique ID, used to find/remove it later
- if (!handler.guid) {
- handler.guid = jQuery.guid++;
- } // Init the element's event structure and main handler, if this is the first
- if (!(events = elemData.events)) {
- events = elemData.events = {};
- }
- if (!(eventHandle = elemData.handle)) {
- eventHandle = elemData.handle = function (e) {
- // Discard the second event of a jQuery.event.trigger() and
- // when an event is called after a page has unloaded
- return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply(elem, arguments) : undefined;
- };
- } // Handle multiple events separated by a space
- types = (types || "").match(rnothtmlwhite) || [""];
- t = types.length;
- while (t--) {
- tmp = rtypenamespace.exec(types[t]) || [];
- type = origType = tmp[1];
- namespaces = (tmp[2] || "").split(".").sort(); // There *must* be a type, no attaching namespace-only handlers
- if (!type) {
- continue;
- } // If event changes its type, use the special event handlers for the changed type
- special = jQuery.event.special[type] || {}; // If selector defined, determine special event api type, otherwise given type
- type = (selector ? special.delegateType : special.bindType) || type; // Update special based on newly reset type
- special = jQuery.event.special[type] || {}; // handleObj is passed to all event handlers
- handleObj = jQuery.extend({
- type: type,
- origType: origType,
- data: data,
- handler: handler,
- guid: handler.guid,
- selector: selector,
- needsContext: selector && jQuery.expr.match.needsContext.test(selector),
- namespace: namespaces.join(".")
- }, handleObjIn); // Init the event handler queue if we're the first
- if (!(handlers = events[type])) {
- handlers = events[type] = [];
- handlers.delegateCount = 0; // Only use addEventListener if the special events handler returns false
- if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {
- if (elem.addEventListener) {
- elem.addEventListener(type, eventHandle);
- }
- }
- }
- if (special.add) {
- special.add.call(elem, handleObj);
- if (!handleObj.handler.guid) {
- handleObj.handler.guid = handler.guid;
- }
- } // Add to the element's handler list, delegates in front
- if (selector) {
- handlers.splice(handlers.delegateCount++, 0, handleObj);
- } else {
- handlers.push(handleObj);
- } // Keep track of which events have ever been used, for event optimization
- jQuery.event.global[type] = true;
- }
- },
- // Detach an event or set of events from an element
- remove: function (elem, types, handler, selector, mappedTypes) {
- var j,
- origCount,
- tmp,
- events,
- t,
- handleObj,
- special,
- handlers,
- type,
- namespaces,
- origType,
- elemData = dataPriv.hasData(elem) && dataPriv.get(elem);
- if (!elemData || !(events = elemData.events)) {
- return;
- } // Once for each type.namespace in types; type may be omitted
- types = (types || "").match(rnothtmlwhite) || [""];
- t = types.length;
- while (t--) {
- tmp = rtypenamespace.exec(types[t]) || [];
- type = origType = tmp[1];
- namespaces = (tmp[2] || "").split(".").sort(); // Unbind all events (on this namespace, if provided) for the element
- if (!type) {
- for (type in events) {
- jQuery.event.remove(elem, type + types[t], handler, selector, true);
- }
- continue;
- }
- special = jQuery.event.special[type] || {};
- type = (selector ? special.delegateType : special.bindType) || type;
- handlers = events[type] || [];
- tmp = tmp[2] && new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)"); // Remove matching events
- origCount = j = handlers.length;
- while (j--) {
- handleObj = handlers[j];
- if ((mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || selector === "**" && handleObj.selector)) {
- handlers.splice(j, 1);
- if (handleObj.selector) {
- handlers.delegateCount--;
- }
- if (special.remove) {
- special.remove.call(elem, handleObj);
- }
- }
- } // Remove generic event handler if we removed something and no more handlers exist
- // (avoids potential for endless recursion during removal of special event handlers)
- if (origCount && !handlers.length) {
- if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) {
- jQuery.removeEvent(elem, type, elemData.handle);
- }
- delete events[type];
- }
- } // Remove data and the expando if it's no longer used
- if (jQuery.isEmptyObject(events)) {
- dataPriv.remove(elem, "handle events");
- }
- },
- dispatch: function (nativeEvent) {
- // Make a writable jQuery.Event from the native event object
- var event = jQuery.event.fix(nativeEvent);
- var i,
- j,
- ret,
- matched,
- handleObj,
- handlerQueue,
- args = new Array(arguments.length),
- handlers = (dataPriv.get(this, "events") || {})[event.type] || [],
- special = jQuery.event.special[event.type] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event
- args[0] = event;
- for (i = 1; i < arguments.length; i++) {
- args[i] = arguments[i];
- }
- event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired
- if (special.preDispatch && special.preDispatch.call(this, event) === false) {
- return;
- } // Determine handlers
- handlerQueue = jQuery.event.handlers.call(this, event, handlers); // Run delegates first; they may want to stop propagation beneath us
- i = 0;
- while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {
- event.currentTarget = matched.elem;
- j = 0;
- while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) {
- // Triggered event must either 1) have no namespace, or 2) have namespace(s)
- // a subset or equal to those in the bound event (both can have no namespace).
- if (!event.rnamespace || event.rnamespace.test(handleObj.namespace)) {
- event.handleObj = handleObj;
- event.data = handleObj.data;
- ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply(matched.elem, args);
- if (ret !== undefined) {
- if ((event.result = ret) === false) {
- event.preventDefault();
- event.stopPropagation();
- }
- }
- }
- }
- } // Call the postDispatch hook for the mapped type
- if (special.postDispatch) {
- special.postDispatch.call(this, event);
- }
- return event.result;
- },
- handlers: function (event, handlers) {
- var i,
- handleObj,
- sel,
- matchedHandlers,
- matchedSelectors,
- handlerQueue = [],
- delegateCount = handlers.delegateCount,
- cur = event.target; // Find delegate handlers
- if (delegateCount && // Support: IE <=9
- // Black-hole SVG <use> instance trees (trac-13180)
- cur.nodeType && // Support: Firefox <=42
- // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
- // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
- // Support: IE 11 only
- // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
- !(event.type === "click" && event.button >= 1)) {
- for (; cur !== this; cur = cur.parentNode || this) {
- // Don't check non-elements (#13208)
- // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
- if (cur.nodeType === 1 && !(event.type === "click" && cur.disabled === true)) {
- matchedHandlers = [];
- matchedSelectors = {};
- for (i = 0; i < delegateCount; i++) {
- handleObj = handlers[i]; // Don't conflict with Object.prototype properties (#13203)
- sel = handleObj.selector + " ";
- if (matchedSelectors[sel] === undefined) {
- matchedSelectors[sel] = handleObj.needsContext ? jQuery(sel, this).index(cur) > -1 : jQuery.find(sel, this, null, [cur]).length;
- }
- if (matchedSelectors[sel]) {
- matchedHandlers.push(handleObj);
- }
- }
- if (matchedHandlers.length) {
- handlerQueue.push({
- elem: cur,
- handlers: matchedHandlers
- });
- }
- }
- }
- } // Add the remaining (directly-bound) handlers
- cur = this;
- if (delegateCount < handlers.length) {
- handlerQueue.push({
- elem: cur,
- handlers: handlers.slice(delegateCount)
- });
- }
- return handlerQueue;
- },
- addProp: function (name, hook) {
- Object.defineProperty(jQuery.Event.prototype, name, {
- enumerable: true,
- configurable: true,
- get: isFunction(hook) ? function () {
- if (this.originalEvent) {
- return hook(this.originalEvent);
- }
- } : function () {
- if (this.originalEvent) {
- return this.originalEvent[name];
- }
- },
- set: function (value) {
- Object.defineProperty(this, name, {
- enumerable: true,
- configurable: true,
- writable: true,
- value: value
- });
- }
- });
- },
- fix: function (originalEvent) {
- return originalEvent[jQuery.expando] ? originalEvent : new jQuery.Event(originalEvent);
- },
- special: {
- load: {
- // Prevent triggered image.load events from bubbling to window.load
- noBubble: true
- },
- focus: {
- // Fire native event if possible so blur/focus sequence is correct
- trigger: function () {
- if (this !== safeActiveElement() && this.focus) {
- this.focus();
- return false;
- }
- },
- delegateType: "focusin"
- },
- blur: {
- trigger: function () {
- if (this === safeActiveElement() && this.blur) {
- this.blur();
- return false;
- }
- },
- delegateType: "focusout"
- },
- click: {
- // For checkbox, fire native event so checked state will be right
- trigger: function () {
- if (this.type === "checkbox" && this.click && nodeName(this, "input")) {
- this.click();
- return false;
- }
- },
- // For cross-browser consistency, don't fire native .click() on links
- _default: function (event) {
- return nodeName(event.target, "a");
- }
- },
- beforeunload: {
- postDispatch: function (event) {
- // Support: Firefox 20+
- // Firefox doesn't alert if the returnValue field is not set.
- if (event.result !== undefined && event.originalEvent) {
- event.originalEvent.returnValue = event.result;
- }
- }
- }
- }
- };
- jQuery.removeEvent = function (elem, type, handle) {
- // This "if" is needed for plain objects
- if (elem.removeEventListener) {
- elem.removeEventListener(type, handle);
- }
- };
- jQuery.Event = function (src, props) {
- // Allow instantiation without the 'new' keyword
- if (!(this instanceof jQuery.Event)) {
- return new jQuery.Event(src, props);
- } // Event object
- if (src && src.type) {
- this.originalEvent = src;
- this.type = src.type; // Events bubbling up the document may have been marked as prevented
- // by a handler lower down the tree; reflect the correct value.
- this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && // Support: Android <=2.3 only
- src.returnValue === false ? returnTrue : returnFalse; // Create target properties
- // Support: Safari <=6 - 7 only
- // Target should not be a text node (#504, #13143)
- this.target = src.target && src.target.nodeType === 3 ? src.target.parentNode : src.target;
- this.currentTarget = src.currentTarget;
- this.relatedTarget = src.relatedTarget; // Event type
- } else {
- this.type = src;
- } // Put explicitly provided properties onto the event object
- if (props) {
- jQuery.extend(this, props);
- } // Create a timestamp if incoming event doesn't have one
- this.timeStamp = src && src.timeStamp || Date.now(); // Mark it as fixed
- this[jQuery.expando] = true;
- }; // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
- // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
- jQuery.Event.prototype = {
- constructor: jQuery.Event,
- isDefaultPrevented: returnFalse,
- isPropagationStopped: returnFalse,
- isImmediatePropagationStopped: returnFalse,
- isSimulated: false,
- preventDefault: function () {
- var e = this.originalEvent;
- this.isDefaultPrevented = returnTrue;
- if (e && !this.isSimulated) {
- e.preventDefault();
- }
- },
- stopPropagation: function () {
- var e = this.originalEvent;
- this.isPropagationStopped = returnTrue;
- if (e && !this.isSimulated) {
- e.stopPropagation();
- }
- },
- stopImmediatePropagation: function () {
- var e = this.originalEvent;
- this.isImmediatePropagationStopped = returnTrue;
- if (e && !this.isSimulated) {
- e.stopImmediatePropagation();
- }
- this.stopPropagation();
- }
- }; // Includes all common event props including KeyEvent and MouseEvent specific props
- jQuery.each({
- altKey: true,
- bubbles: true,
- cancelable: true,
- changedTouches: true,
- ctrlKey: true,
- detail: true,
- eventPhase: true,
- metaKey: true,
- pageX: true,
- pageY: true,
- shiftKey: true,
- view: true,
- "char": true,
- charCode: true,
- key: true,
- keyCode: true,
- button: true,
- buttons: true,
- clientX: true,
- clientY: true,
- offsetX: true,
- offsetY: true,
- pointerId: true,
- pointerType: true,
- screenX: true,
- screenY: true,
- targetTouches: true,
- toElement: true,
- touches: true,
- which: function (event) {
- var button = event.button; // Add which for key events
- if (event.which == null && rkeyEvent.test(event.type)) {
- return event.charCode != null ? event.charCode : event.keyCode;
- } // Add which for click: 1 === left; 2 === middle; 3 === right
- if (!event.which && button !== undefined && rmouseEvent.test(event.type)) {
- if (button & 1) {
- return 1;
- }
- if (button & 2) {
- return 3;
- }
- if (button & 4) {
- return 2;
- }
- return 0;
- }
- return event.which;
- }
- }, jQuery.event.addProp); // Create mouseenter/leave events using mouseover/out and event-time checks
- // so that event delegation works in jQuery.
- // Do the same for pointerenter/pointerleave and pointerover/pointerout
- //
- // Support: Safari 7 only
- // Safari sends mouseenter too often; see:
- // https://bugs.chromium.org/p/chromium/issues/detail?id=470258
- // for the description of the bug (it existed in older Chrome versions as well).
- jQuery.each({
- mouseenter: "mouseover",
- mouseleave: "mouseout",
- pointerenter: "pointerover",
- pointerleave: "pointerout"
- }, function (orig, fix) {
- jQuery.event.special[orig] = {
- delegateType: fix,
- bindType: fix,
- handle: function (event) {
- var ret,
- target = this,
- related = event.relatedTarget,
- handleObj = event.handleObj; // For mouseenter/leave call the handler if related is outside the target.
- // NB: No relatedTarget if the mouse left/entered the browser window
- if (!related || related !== target && !jQuery.contains(target, related)) {
- event.type = handleObj.origType;
- ret = handleObj.handler.apply(this, arguments);
- event.type = fix;
- }
- return ret;
- }
- };
- });
- jQuery.fn.extend({
- on: function (types, selector, data, fn) {
- return on(this, types, selector, data, fn);
- },
- one: function (types, selector, data, fn) {
- return on(this, types, selector, data, fn, 1);
- },
- off: function (types, selector, fn) {
- var handleObj, type;
- if (types && types.preventDefault && types.handleObj) {
- // ( event ) dispatched jQuery.Event
- handleObj = types.handleObj;
- jQuery(types.delegateTarget).off(handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler);
- return this;
- }
- if (typeof types === "object") {
- // ( types-object [, selector] )
- for (type in types) {
- this.off(type, selector, types[type]);
- }
- return this;
- }
- if (selector === false || typeof selector === "function") {
- // ( types [, fn] )
- fn = selector;
- selector = undefined;
- }
- if (fn === false) {
- fn = returnFalse;
- }
- return this.each(function () {
- jQuery.event.remove(this, types, fn, selector);
- });
- }
- });
- var
- /* eslint-disable max-len */
- // See https://github.com/eslint/eslint/issues/3229
- rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
- /* eslint-enable */
- // Support: IE <=10 - 11, Edge 12 - 13 only
- // In IE/Edge using regex groups here causes severe slowdowns.
- // See https://connect.microsoft.com/IE/feedback/details/1736512/
- rnoInnerhtml = /<script|<style|<link/i,
- // checked="checked" or checked
- rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
- rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; // Prefer a tbody over its parent table for containing new rows
- function manipulationTarget(elem, content) {
- if (nodeName(elem, "table") && nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr")) {
- return jQuery(elem).children("tbody")[0] || elem;
- }
- return elem;
- } // Replace/restore the type attribute of script elements for safe DOM manipulation
- function disableScript(elem) {
- elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
- return elem;
- }
- function restoreScript(elem) {
- if ((elem.type || "").slice(0, 5) === "true/") {
- elem.type = elem.type.slice(5);
- } else {
- elem.removeAttribute("type");
- }
- return elem;
- }
- function cloneCopyEvent(src, dest) {
- var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
- if (dest.nodeType !== 1) {
- return;
- } // 1. Copy private data: events, handlers, etc.
- if (dataPriv.hasData(src)) {
- pdataOld = dataPriv.access(src);
- pdataCur = dataPriv.set(dest, pdataOld);
- events = pdataOld.events;
- if (events) {
- delete pdataCur.handle;
- pdataCur.events = {};
- for (type in events) {
- for (i = 0, l = events[type].length; i < l; i++) {
- jQuery.event.add(dest, type, events[type][i]);
- }
- }
- }
- } // 2. Copy user data
- if (dataUser.hasData(src)) {
- udataOld = dataUser.access(src);
- udataCur = jQuery.extend({}, udataOld);
- dataUser.set(dest, udataCur);
- }
- } // Fix IE bugs, see support tests
- function fixInput(src, dest) {
- var nodeName = dest.nodeName.toLowerCase(); // Fails to persist the checked state of a cloned checkbox or radio button.
- if (nodeName === "input" && rcheckableType.test(src.type)) {
- dest.checked = src.checked; // Fails to return the selected option to the default selected state when cloning options
- } else if (nodeName === "input" || nodeName === "textarea") {
- dest.defaultValue = src.defaultValue;
- }
- }
- function domManip(collection, args, callback, ignored) {
- // Flatten any nested arrays
- args = concat.apply([], args);
- var fragment,
- first,
- scripts,
- hasScripts,
- node,
- doc,
- i = 0,
- l = collection.length,
- iNoClone = l - 1,
- value = args[0],
- valueIsFunction = isFunction(value); // We can't cloneNode fragments that contain checked, in WebKit
- if (valueIsFunction || l > 1 && typeof value === "string" && !support.checkClone && rchecked.test(value)) {
- return collection.each(function (index) {
- var self = collection.eq(index);
- if (valueIsFunction) {
- args[0] = value.call(this, index, self.html());
- }
- domManip(self, args, callback, ignored);
- });
- }
- if (l) {
- fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored);
- first = fragment.firstChild;
- if (fragment.childNodes.length === 1) {
- fragment = first;
- } // Require either new content or an interest in ignored elements to invoke the callback
- if (first || ignored) {
- scripts = jQuery.map(getAll(fragment, "script"), disableScript);
- hasScripts = scripts.length; // Use the original fragment for the last item
- // instead of the first because it can end up
- // being emptied incorrectly in certain situations (#8070).
- for (; i < l; i++) {
- node = fragment;
- if (i !== iNoClone) {
- node = jQuery.clone(node, true, true); // Keep references to cloned scripts for later restoration
- if (hasScripts) {
- // Support: Android <=4.0 only, PhantomJS 1 only
- // push.apply(_, arraylike) throws on ancient WebKit
- jQuery.merge(scripts, getAll(node, "script"));
- }
- }
- callback.call(collection[i], node, i);
- }
- if (hasScripts) {
- doc = scripts[scripts.length - 1].ownerDocument; // Reenable scripts
- jQuery.map(scripts, restoreScript); // Evaluate executable scripts on first document insertion
- for (i = 0; i < hasScripts; i++) {
- node = scripts[i];
- if (rscriptType.test(node.type || "") && !dataPriv.access(node, "globalEval") && jQuery.contains(doc, node)) {
- if (node.src && (node.type || "").toLowerCase() !== "module") {
- // Optional AJAX dependency, but won't run scripts if not present
- if (jQuery._evalUrl) {
- jQuery._evalUrl(node.src);
- }
- } else {
- DOMEval(node.textContent.replace(rcleanScript, ""), doc, node);
- }
- }
- }
- }
- }
- }
- return collection;
- }
- function remove(elem, selector, keepData) {
- var node,
- nodes = selector ? jQuery.filter(selector, elem) : elem,
- i = 0;
- for (; (node = nodes[i]) != null; i++) {
- if (!keepData && node.nodeType === 1) {
- jQuery.cleanData(getAll(node));
- }
- if (node.parentNode) {
- if (keepData && jQuery.contains(node.ownerDocument, node)) {
- setGlobalEval(getAll(node, "script"));
- }
- node.parentNode.removeChild(node);
- }
- }
- return elem;
- }
- jQuery.extend({
- htmlPrefilter: function (html) {
- return html.replace(rxhtmlTag, "<$1></$2>");
- },
- clone: function (elem, dataAndEvents, deepDataAndEvents) {
- var i,
- l,
- srcElements,
- destElements,
- clone = elem.cloneNode(true),
- inPage = jQuery.contains(elem.ownerDocument, elem); // Fix IE cloning issues
- if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem)) {
- // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
- destElements = getAll(clone);
- srcElements = getAll(elem);
- for (i = 0, l = srcElements.length; i < l; i++) {
- fixInput(srcElements[i], destElements[i]);
- }
- } // Copy the events from the original to the clone
- if (dataAndEvents) {
- if (deepDataAndEvents) {
- srcElements = srcElements || getAll(elem);
- destElements = destElements || getAll(clone);
- for (i = 0, l = srcElements.length; i < l; i++) {
- cloneCopyEvent(srcElements[i], destElements[i]);
- }
- } else {
- cloneCopyEvent(elem, clone);
- }
- } // Preserve script evaluation history
- destElements = getAll(clone, "script");
- if (destElements.length > 0) {
- setGlobalEval(destElements, !inPage && getAll(elem, "script"));
- } // Return the cloned set
- return clone;
- },
- cleanData: function (elems) {
- var data,
- elem,
- type,
- special = jQuery.event.special,
- i = 0;
- for (; (elem = elems[i]) !== undefined; i++) {
- if (acceptData(elem)) {
- if (data = elem[dataPriv.expando]) {
- if (data.events) {
- for (type in data.events) {
- if (special[type]) {
- jQuery.event.remove(elem, type); // This is a shortcut to avoid jQuery.event.remove's overhead
- } else {
- jQuery.removeEvent(elem, type, data.handle);
- }
- }
- } // Support: Chrome <=35 - 45+
- // Assign undefined instead of using delete, see Data#remove
- elem[dataPriv.expando] = undefined;
- }
- if (elem[dataUser.expando]) {
- // Support: Chrome <=35 - 45+
- // Assign undefined instead of using delete, see Data#remove
- elem[dataUser.expando] = undefined;
- }
- }
- }
- }
- });
- jQuery.fn.extend({
- detach: function (selector) {
- return remove(this, selector, true);
- },
- remove: function (selector) {
- return remove(this, selector);
- },
- text: function (value) {
- return access(this, function (value) {
- return value === undefined ? jQuery.text(this) : this.empty().each(function () {
- if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
- this.textContent = value;
- }
- });
- }, null, value, arguments.length);
- },
- append: function () {
- return domManip(this, arguments, function (elem) {
- if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
- var target = manipulationTarget(this, elem);
- target.appendChild(elem);
- }
- });
- },
- prepend: function () {
- return domManip(this, arguments, function (elem) {
- if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
- var target = manipulationTarget(this, elem);
- target.insertBefore(elem, target.firstChild);
- }
- });
- },
- before: function () {
- return domManip(this, arguments, function (elem) {
- if (this.parentNode) {
- this.parentNode.insertBefore(elem, this);
- }
- });
- },
- after: function () {
- return domManip(this, arguments, function (elem) {
- if (this.parentNode) {
- this.parentNode.insertBefore(elem, this.nextSibling);
- }
- });
- },
- empty: function () {
- var elem,
- i = 0;
- for (; (elem = this[i]) != null; i++) {
- if (elem.nodeType === 1) {
- // Prevent memory leaks
- jQuery.cleanData(getAll(elem, false)); // Remove any remaining nodes
- elem.textContent = "";
- }
- }
- return this;
- },
- clone: function (dataAndEvents, deepDataAndEvents) {
- dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
- deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
- return this.map(function () {
- return jQuery.clone(this, dataAndEvents, deepDataAndEvents);
- });
- },
- html: function (value) {
- return access(this, function (value) {
- var elem = this[0] || {},
- i = 0,
- l = this.length;
- if (value === undefined && elem.nodeType === 1) {
- return elem.innerHTML;
- } // See if we can take a shortcut and just use innerHTML
- if (typeof value === "string" && !rnoInnerhtml.test(value) && !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) {
- value = jQuery.htmlPrefilter(value);
- try {
- for (; i < l; i++) {
- elem = this[i] || {}; // Remove element nodes and prevent memory leaks
- if (elem.nodeType === 1) {
- jQuery.cleanData(getAll(elem, false));
- elem.innerHTML = value;
- }
- }
- elem = 0; // If using innerHTML throws an exception, use the fallback method
- } catch (e) {}
- }
- if (elem) {
- this.empty().append(value);
- }
- }, null, value, arguments.length);
- },
- replaceWith: function () {
- var ignored = []; // Make the changes, replacing each non-ignored context element with the new content
- return domManip(this, arguments, function (elem) {
- var parent = this.parentNode;
- if (jQuery.inArray(this, ignored) < 0) {
- jQuery.cleanData(getAll(this));
- if (parent) {
- parent.replaceChild(elem, this);
- }
- } // Force callback invocation
- }, ignored);
- }
- });
- jQuery.each({
- appendTo: "append",
- prependTo: "prepend",
- insertBefore: "before",
- insertAfter: "after",
- replaceAll: "replaceWith"
- }, function (name, original) {
- jQuery.fn[name] = function (selector) {
- var elems,
- ret = [],
- insert = jQuery(selector),
- last = insert.length - 1,
- i = 0;
- for (; i <= last; i++) {
- elems = i === last ? this : this.clone(true);
- jQuery(insert[i])[original](elems); // Support: Android <=4.0 only, PhantomJS 1 only
- // .get() because push.apply(_, arraylike) throws on ancient WebKit
- push.apply(ret, elems.get());
- }
- return this.pushStack(ret);
- };
- });
- var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i");
- var getStyles = function (elem) {
- // Support: IE <=11 only, Firefox <=30 (#15098, #14150)
- // IE throws on elements created in popups
- // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
- var view = elem.ownerDocument.defaultView;
- if (!view || !view.opener) {
- view = window;
- }
- return view.getComputedStyle(elem);
- };
- var rboxStyle = new RegExp(cssExpand.join("|"), "i");
- (function () {
- // Executing both pixelPosition & boxSizingReliable tests require only one layout
- // so they're executed at the same time to save the second computation.
- function computeStyleTests() {
- // This is a singleton, we need to execute it only once
- if (!div) {
- return;
- }
- container.style.cssText = "position:absolute;left:-11111px;width:60px;" + "margin-top:1px;padding:0;border:0";
- div.style.cssText = "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + "margin:auto;border:1px;padding:1px;" + "width:60%;top:1%";
- documentElement.appendChild(container).appendChild(div);
- var divStyle = window.getComputedStyle(div);
- pixelPositionVal = divStyle.top !== "1%"; // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
- reliableMarginLeftVal = roundPixelMeasures(divStyle.marginLeft) === 12; // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
- // Some styles come back with percentage values, even though they shouldn't
- div.style.right = "60%";
- pixelBoxStylesVal = roundPixelMeasures(divStyle.right) === 36; // Support: IE 9 - 11 only
- // Detect misreporting of content dimensions for box-sizing:border-box elements
- boxSizingReliableVal = roundPixelMeasures(divStyle.width) === 36; // Support: IE 9 only
- // Detect overflow:scroll screwiness (gh-3699)
- div.style.position = "absolute";
- scrollboxSizeVal = div.offsetWidth === 36 || "absolute";
- documentElement.removeChild(container); // Nullify the div so it wouldn't be stored in the memory and
- // it will also be a sign that checks already performed
- div = null;
- }
- function roundPixelMeasures(measure) {
- return Math.round(parseFloat(measure));
- }
- var pixelPositionVal,
- boxSizingReliableVal,
- scrollboxSizeVal,
- pixelBoxStylesVal,
- reliableMarginLeftVal,
- container = document.createElement("div"),
- div = document.createElement("div"); // Finish early in limited (non-browser) environments
- if (!div.style) {
- return;
- } // Support: IE <=9 - 11 only
- // Style of cloned element affects source element cloned (#8908)
- div.style.backgroundClip = "content-box";
- div.cloneNode(true).style.backgroundClip = "";
- support.clearCloneStyle = div.style.backgroundClip === "content-box";
- jQuery.extend(support, {
- boxSizingReliable: function () {
- computeStyleTests();
- return boxSizingReliableVal;
- },
- pixelBoxStyles: function () {
- computeStyleTests();
- return pixelBoxStylesVal;
- },
- pixelPosition: function () {
- computeStyleTests();
- return pixelPositionVal;
- },
- reliableMarginLeft: function () {
- computeStyleTests();
- return reliableMarginLeftVal;
- },
- scrollboxSize: function () {
- computeStyleTests();
- return scrollboxSizeVal;
- }
- });
- })();
- function curCSS(elem, name, computed) {
- var width,
- minWidth,
- maxWidth,
- ret,
- // Support: Firefox 51+
- // Retrieving style before computed somehow
- // fixes an issue with getting wrong values
- // on detached elements
- style = elem.style;
- computed = computed || getStyles(elem); // getPropertyValue is needed for:
- // .css('filter') (IE 9 only, #12537)
- // .css('--customProperty) (#3144)
- if (computed) {
- ret = computed.getPropertyValue(name) || computed[name];
- if (ret === "" && !jQuery.contains(elem.ownerDocument, elem)) {
- ret = jQuery.style(elem, name);
- } // A tribute to the "awesome hack by Dean Edwards"
- // Android Browser returns percentage for some values,
- // but width seems to be reliably pixels.
- // This is against the CSSOM draft spec:
- // https://drafts.csswg.org/cssom/#resolved-values
- if (!support.pixelBoxStyles() && rnumnonpx.test(ret) && rboxStyle.test(name)) {
- // Remember the original values
- width = style.width;
- minWidth = style.minWidth;
- maxWidth = style.maxWidth; // Put in the new values to get a computed value out
- style.minWidth = style.maxWidth = style.width = ret;
- ret = computed.width; // Revert the changed values
- style.width = width;
- style.minWidth = minWidth;
- style.maxWidth = maxWidth;
- }
- }
- return ret !== undefined ? // Support: IE <=9 - 11 only
- // IE returns zIndex value as an integer.
- ret + "" : ret;
- }
- function addGetHookIf(conditionFn, hookFn) {
- // Define the hook, we'll check on the first run if it's really needed.
- return {
- get: function () {
- if (conditionFn()) {
- // Hook not needed (or it's not possible to use it due
- // to missing dependency), remove it.
- delete this.get;
- return;
- } // Hook needed; redefine it so that the support test is not executed again.
- return (this.get = hookFn).apply(this, arguments);
- }
- };
- }
- var // Swappable if display is none or starts with table
- // except "table", "table-cell", or "table-caption"
- // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
- rdisplayswap = /^(none|table(?!-c[ea]).+)/,
- rcustomProp = /^--/,
- cssShow = {
- position: "absolute",
- visibility: "hidden",
- display: "block"
- },
- cssNormalTransform = {
- letterSpacing: "0",
- fontWeight: "400"
- },
- cssPrefixes = ["Webkit", "Moz", "ms"],
- emptyStyle = document.createElement("div").style; // Return a css property mapped to a potentially vendor prefixed property
- function vendorPropName(name) {
- // Shortcut for names that are not vendor prefixed
- if (name in emptyStyle) {
- return name;
- } // Check for vendor prefixed names
- var capName = name[0].toUpperCase() + name.slice(1),
- i = cssPrefixes.length;
- while (i--) {
- name = cssPrefixes[i] + capName;
- if (name in emptyStyle) {
- return name;
- }
- }
- } // Return a property mapped along what jQuery.cssProps suggests or to
- // a vendor prefixed property.
- function finalPropName(name) {
- var ret = jQuery.cssProps[name];
- if (!ret) {
- ret = jQuery.cssProps[name] = vendorPropName(name) || name;
- }
- return ret;
- }
- function setPositiveNumber(elem, value, subtract) {
- // Any relative (+/-) values have already been
- // normalized at this point
- var matches = rcssNum.exec(value);
- return matches ? // Guard against undefined "subtract", e.g., when used as in cssHooks
- Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || "px") : value;
- }
- function boxModelAdjustment(elem, dimension, box, isBorderBox, styles, computedVal) {
- var i = dimension === "width" ? 1 : 0,
- extra = 0,
- delta = 0; // Adjustment may not be necessary
- if (box === (isBorderBox ? "border" : "content")) {
- return 0;
- }
- for (; i < 4; i += 2) {
- // Both box models exclude margin
- if (box === "margin") {
- delta += jQuery.css(elem, box + cssExpand[i], true, styles);
- } // If we get here with a content-box, we're seeking "padding" or "border" or "margin"
- if (!isBorderBox) {
- // Add padding
- delta += jQuery.css(elem, "padding" + cssExpand[i], true, styles); // For "border" or "margin", add border
- if (box !== "padding") {
- delta += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); // But still keep track of it otherwise
- } else {
- extra += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
- } // If we get here with a border-box (content + padding + border), we're seeking "content" or
- // "padding" or "margin"
- } else {
- // For "content", subtract padding
- if (box === "content") {
- delta -= jQuery.css(elem, "padding" + cssExpand[i], true, styles);
- } // For "content" or "padding", subtract border
- if (box !== "margin") {
- delta -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
- }
- }
- } // Account for positive content-box scroll gutter when requested by providing computedVal
- if (!isBorderBox && computedVal >= 0) {
- // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
- // Assuming integer scroll gutter, subtract the rest and round down
- delta += Math.max(0, Math.ceil(elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - computedVal - delta - extra - 0.5));
- }
- return delta;
- }
- function getWidthOrHeight(elem, dimension, extra) {
- // Start with computed style
- var styles = getStyles(elem),
- val = curCSS(elem, dimension, styles),
- isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box",
- valueIsBorderBox = isBorderBox; // Support: Firefox <=54
- // Return a confounding non-pixel value or feign ignorance, as appropriate.
- if (rnumnonpx.test(val)) {
- if (!extra) {
- return val;
- }
- val = "auto";
- } // Check for style in case a browser which returns unreliable values
- // for getComputedStyle silently falls back to the reliable elem.style
- valueIsBorderBox = valueIsBorderBox && (support.boxSizingReliable() || val === elem.style[dimension]); // Fall back to offsetWidth/offsetHeight when value is "auto"
- // This happens for inline elements with no explicit setting (gh-3571)
- // Support: Android <=4.1 - 4.3 only
- // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
- if (val === "auto" || !parseFloat(val) && jQuery.css(elem, "display", false, styles) === "inline") {
- val = elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)]; // offsetWidth/offsetHeight provide border-box values
- valueIsBorderBox = true;
- } // Normalize "" and auto
- val = parseFloat(val) || 0; // Adjust for the element's box model
- return val + boxModelAdjustment(elem, dimension, extra || (isBorderBox ? "border" : "content"), valueIsBorderBox, styles, // Provide the current computed size to request scroll gutter calculation (gh-3589)
- val) + "px";
- }
- jQuery.extend({
- // Add in style property hooks for overriding the default
- // behavior of getting and setting a style property
- cssHooks: {
- opacity: {
- get: function (elem, computed) {
- if (computed) {
- // We should always get a number back from opacity
- var ret = curCSS(elem, "opacity");
- return ret === "" ? "1" : ret;
- }
- }
- }
- },
- // Don't automatically add "px" to these possibly-unitless properties
- cssNumber: {
- "animationIterationCount": true,
- "columnCount": true,
- "fillOpacity": true,
- "flexGrow": true,
- "flexShrink": true,
- "fontWeight": true,
- "lineHeight": true,
- "opacity": true,
- "order": true,
- "orphans": true,
- "widows": true,
- "zIndex": true,
- "zoom": true
- },
- // Add in properties whose names you wish to fix before
- // setting or getting the value
- cssProps: {},
- // Get and set the style property on a DOM Node
- style: function (elem, name, value, extra) {
- // Don't set styles on text and comment nodes
- if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) {
- return;
- } // Make sure that we're working with the right name
- var ret,
- type,
- hooks,
- origName = camelCase(name),
- isCustomProp = rcustomProp.test(name),
- style = elem.style; // Make sure that we're working with the right name. We don't
- // want to query the value if it is a CSS custom property
- // since they are user-defined.
- if (!isCustomProp) {
- name = finalPropName(origName);
- } // Gets hook for the prefixed version, then unprefixed version
- hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; // Check if we're setting a value
- if (value !== undefined) {
- type = typeof value; // Convert "+=" or "-=" to relative numbers (#7345)
- if (type === "string" && (ret = rcssNum.exec(value)) && ret[1]) {
- value = adjustCSS(elem, name, ret); // Fixes bug #9237
- type = "number";
- } // Make sure that null and NaN values aren't set (#7116)
- if (value == null || value !== value) {
- return;
- } // If a number was passed in, add the unit (except for certain CSS properties)
- if (type === "number") {
- value += ret && ret[3] || (jQuery.cssNumber[origName] ? "" : "px");
- } // background-* props affect original clone's values
- if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) {
- style[name] = "inherit";
- } // If a hook was provided, use that value, otherwise just set the specified value
- if (!hooks || !("set" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) {
- if (isCustomProp) {
- style.setProperty(name, value);
- } else {
- style[name] = value;
- }
- }
- } else {
- // If a hook was provided get the non-computed value from there
- if (hooks && "get" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) {
- return ret;
- } // Otherwise just get the value from the style object
- return style[name];
- }
- },
- css: function (elem, name, extra, styles) {
- var val,
- num,
- hooks,
- origName = camelCase(name),
- isCustomProp = rcustomProp.test(name); // Make sure that we're working with the right name. We don't
- // want to modify the value if it is a CSS custom property
- // since they are user-defined.
- if (!isCustomProp) {
- name = finalPropName(origName);
- } // Try prefixed name followed by the unprefixed name
- hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; // If a hook was provided get the computed value from there
- if (hooks && "get" in hooks) {
- val = hooks.get(elem, true, extra);
- } // Otherwise, if a way to get the computed value exists, use that
- if (val === undefined) {
- val = curCSS(elem, name, styles);
- } // Convert "normal" to computed value
- if (val === "normal" && name in cssNormalTransform) {
- val = cssNormalTransform[name];
- } // Make numeric if forced or a qualifier was provided and val looks numeric
- if (extra === "" || extra) {
- num = parseFloat(val);
- return extra === true || isFinite(num) ? num || 0 : val;
- }
- return val;
- }
- });
- jQuery.each(["height", "width"], function (i, dimension) {
- jQuery.cssHooks[dimension] = {
- get: function (elem, computed, extra) {
- if (computed) {
- // Certain elements can have dimension info if we invisibly show them
- // but it must have a current display style that would benefit
- return rdisplayswap.test(jQuery.css(elem, "display")) && ( // Support: Safari 8+
- // Table columns in Safari have non-zero offsetWidth & zero
- // getBoundingClientRect().width unless display is changed.
- // Support: IE <=11 only
- // Running getBoundingClientRect on a disconnected node
- // in IE throws an error.
- !elem.getClientRects().length || !elem.getBoundingClientRect().width) ? swap(elem, cssShow, function () {
- return getWidthOrHeight(elem, dimension, extra);
- }) : getWidthOrHeight(elem, dimension, extra);
- }
- },
- set: function (elem, value, extra) {
- var matches,
- styles = getStyles(elem),
- isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box",
- subtract = extra && boxModelAdjustment(elem, dimension, extra, isBorderBox, styles); // Account for unreliable border-box dimensions by comparing offset* to computed and
- // faking a content-box to get border and padding (gh-3699)
- if (isBorderBox && support.scrollboxSize() === styles.position) {
- subtract -= Math.ceil(elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - parseFloat(styles[dimension]) - boxModelAdjustment(elem, dimension, "border", false, styles) - 0.5);
- } // Convert to pixels if value adjustment is needed
- if (subtract && (matches = rcssNum.exec(value)) && (matches[3] || "px") !== "px") {
- elem.style[dimension] = value;
- value = jQuery.css(elem, dimension);
- }
- return setPositiveNumber(elem, value, subtract);
- }
- };
- });
- jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft, function (elem, computed) {
- if (computed) {
- return (parseFloat(curCSS(elem, "marginLeft")) || elem.getBoundingClientRect().left - swap(elem, {
- marginLeft: 0
- }, function () {
- return elem.getBoundingClientRect().left;
- })) + "px";
- }
- }); // These hooks are used by animate to expand properties
- jQuery.each({
- margin: "",
- padding: "",
- border: "Width"
- }, function (prefix, suffix) {
- jQuery.cssHooks[prefix + suffix] = {
- expand: function (value) {
- var i = 0,
- expanded = {},
- // Assumes a single number if not a string
- parts = typeof value === "string" ? value.split(" ") : [value];
- for (; i < 4; i++) {
- expanded[prefix + cssExpand[i] + suffix] = parts[i] || parts[i - 2] || parts[0];
- }
- return expanded;
- }
- };
- if (prefix !== "margin") {
- jQuery.cssHooks[prefix + suffix].set = setPositiveNumber;
- }
- });
- jQuery.fn.extend({
- css: function (name, value) {
- return access(this, function (elem, name, value) {
- var styles,
- len,
- map = {},
- i = 0;
- if (Array.isArray(name)) {
- styles = getStyles(elem);
- len = name.length;
- for (; i < len; i++) {
- map[name[i]] = jQuery.css(elem, name[i], false, styles);
- }
- return map;
- }
- return value !== undefined ? jQuery.style(elem, name, value) : jQuery.css(elem, name);
- }, name, value, arguments.length > 1);
- }
- });
- function Tween(elem, options, prop, end, easing) {
- return new Tween.prototype.init(elem, options, prop, end, easing);
- }
- jQuery.Tween = Tween;
- Tween.prototype = {
- constructor: Tween,
- init: function (elem, options, prop, end, easing, unit) {
- this.elem = elem;
- this.prop = prop;
- this.easing = easing || jQuery.easing._default;
- this.options = options;
- this.start = this.now = this.cur();
- this.end = end;
- this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px");
- },
- cur: function () {
- var hooks = Tween.propHooks[this.prop];
- return hooks && hooks.get ? hooks.get(this) : Tween.propHooks._default.get(this);
- },
- run: function (percent) {
- var eased,
- hooks = Tween.propHooks[this.prop];
- if (this.options.duration) {
- this.pos = eased = jQuery.easing[this.easing](percent, this.options.duration * percent, 0, 1, this.options.duration);
- } else {
- this.pos = eased = percent;
- }
- this.now = (this.end - this.start) * eased + this.start;
- if (this.options.step) {
- this.options.step.call(this.elem, this.now, this);
- }
- if (hooks && hooks.set) {
- hooks.set(this);
- } else {
- Tween.propHooks._default.set(this);
- }
- return this;
- }
- };
- Tween.prototype.init.prototype = Tween.prototype;
- Tween.propHooks = {
- _default: {
- get: function (tween) {
- var result; // Use a property on the element directly when it is not a DOM element,
- // or when there is no matching style property that exists.
- if (tween.elem.nodeType !== 1 || tween.elem[tween.prop] != null && tween.elem.style[tween.prop] == null) {
- return tween.elem[tween.prop];
- } // Passing an empty string as a 3rd parameter to .css will automatically
- // attempt a parseFloat and fallback to a string if the parse fails.
- // Simple values such as "10px" are parsed to Float;
- // complex values such as "rotate(1rad)" are returned as-is.
- result = jQuery.css(tween.elem, tween.prop, ""); // Empty strings, null, undefined and "auto" are converted to 0.
- return !result || result === "auto" ? 0 : result;
- },
- set: function (tween) {
- // Use step hook for back compat.
- // Use cssHook if its there.
- // Use .style if available and use plain properties where available.
- if (jQuery.fx.step[tween.prop]) {
- jQuery.fx.step[tween.prop](tween);
- } else if (tween.elem.nodeType === 1 && (tween.elem.style[jQuery.cssProps[tween.prop]] != null || jQuery.cssHooks[tween.prop])) {
- jQuery.style(tween.elem, tween.prop, tween.now + tween.unit);
- } else {
- tween.elem[tween.prop] = tween.now;
- }
- }
- }
- }; // Support: IE <=9 only
- // Panic based approach to setting things on disconnected nodes
- Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
- set: function (tween) {
- if (tween.elem.nodeType && tween.elem.parentNode) {
- tween.elem[tween.prop] = tween.now;
- }
- }
- };
- jQuery.easing = {
- linear: function (p) {
- return p;
- },
- swing: function (p) {
- return 0.5 - Math.cos(p * Math.PI) / 2;
- },
- _default: "swing"
- };
- jQuery.fx = Tween.prototype.init; // Back compat <1.8 extension point
- jQuery.fx.step = {};
- var fxNow,
- inProgress,
- rfxtypes = /^(?:toggle|show|hide)$/,
- rrun = /queueHooks$/;
- function schedule() {
- if (inProgress) {
- if (document.hidden === false && window.requestAnimationFrame) {
- window.requestAnimationFrame(schedule);
- } else {
- window.setTimeout(schedule, jQuery.fx.interval);
- }
- jQuery.fx.tick();
- }
- } // Animations created synchronously will run synchronously
- function createFxNow() {
- window.setTimeout(function () {
- fxNow = undefined;
- });
- return fxNow = Date.now();
- } // Generate parameters to create a standard animation
- function genFx(type, includeWidth) {
- var which,
- i = 0,
- attrs = {
- height: type
- }; // If we include width, step value is 1 to do all cssExpand values,
- // otherwise step value is 2 to skip over Left and Right
- includeWidth = includeWidth ? 1 : 0;
- for (; i < 4; i += 2 - includeWidth) {
- which = cssExpand[i];
- attrs["margin" + which] = attrs["padding" + which] = type;
- }
- if (includeWidth) {
- attrs.opacity = attrs.width = type;
- }
- return attrs;
- }
- function createTween(value, prop, animation) {
- var tween,
- collection = (Animation.tweeners[prop] || []).concat(Animation.tweeners["*"]),
- index = 0,
- length = collection.length;
- for (; index < length; index++) {
- if (tween = collection[index].call(animation, prop, value)) {
- // We're done with this property
- return tween;
- }
- }
- }
- function defaultPrefilter(elem, props, opts) {
- var prop,
- value,
- toggle,
- hooks,
- oldfire,
- propTween,
- restoreDisplay,
- display,
- isBox = "width" in props || "height" in props,
- anim = this,
- orig = {},
- style = elem.style,
- hidden = elem.nodeType && isHiddenWithinTree(elem),
- dataShow = dataPriv.get(elem, "fxshow"); // Queue-skipping animations hijack the fx hooks
- if (!opts.queue) {
- hooks = jQuery._queueHooks(elem, "fx");
- if (hooks.unqueued == null) {
- hooks.unqueued = 0;
- oldfire = hooks.empty.fire;
- hooks.empty.fire = function () {
- if (!hooks.unqueued) {
- oldfire();
- }
- };
- }
- hooks.unqueued++;
- anim.always(function () {
- // Ensure the complete handler is called before this completes
- anim.always(function () {
- hooks.unqueued--;
- if (!jQuery.queue(elem, "fx").length) {
- hooks.empty.fire();
- }
- });
- });
- } // Detect show/hide animations
- for (prop in props) {
- value = props[prop];
- if (rfxtypes.test(value)) {
- delete props[prop];
- toggle = toggle || value === "toggle";
- if (value === (hidden ? "hide" : "show")) {
- // Pretend to be hidden if this is a "show" and
- // there is still data from a stopped show/hide
- if (value === "show" && dataShow && dataShow[prop] !== undefined) {
- hidden = true; // Ignore all other no-op show/hide data
- } else {
- continue;
- }
- }
- orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop);
- }
- } // Bail out if this is a no-op like .hide().hide()
- propTween = !jQuery.isEmptyObject(props);
- if (!propTween && jQuery.isEmptyObject(orig)) {
- return;
- } // Restrict "overflow" and "display" styles during box animations
- if (isBox && elem.nodeType === 1) {
- // Support: IE <=9 - 11, Edge 12 - 15
- // Record all 3 overflow attributes because IE does not infer the shorthand
- // from identically-valued overflowX and overflowY and Edge just mirrors
- // the overflowX value there.
- opts.overflow = [style.overflow, style.overflowX, style.overflowY]; // Identify a display type, preferring old show/hide data over the CSS cascade
- restoreDisplay = dataShow && dataShow.display;
- if (restoreDisplay == null) {
- restoreDisplay = dataPriv.get(elem, "display");
- }
- display = jQuery.css(elem, "display");
- if (display === "none") {
- if (restoreDisplay) {
- display = restoreDisplay;
- } else {
- // Get nonempty value(s) by temporarily forcing visibility
- showHide([elem], true);
- restoreDisplay = elem.style.display || restoreDisplay;
- display = jQuery.css(elem, "display");
- showHide([elem]);
- }
- } // Animate inline elements as inline-block
- if (display === "inline" || display === "inline-block" && restoreDisplay != null) {
- if (jQuery.css(elem, "float") === "none") {
- // Restore the original display value at the end of pure show/hide animations
- if (!propTween) {
- anim.done(function () {
- style.display = restoreDisplay;
- });
- if (restoreDisplay == null) {
- display = style.display;
- restoreDisplay = display === "none" ? "" : display;
- }
- }
- style.display = "inline-block";
- }
- }
- }
- if (opts.overflow) {
- style.overflow = "hidden";
- anim.always(function () {
- style.overflow = opts.overflow[0];
- style.overflowX = opts.overflow[1];
- style.overflowY = opts.overflow[2];
- });
- } // Implement show/hide animations
- propTween = false;
- for (prop in orig) {
- // General show/hide setup for this element animation
- if (!propTween) {
- if (dataShow) {
- if ("hidden" in dataShow) {
- hidden = dataShow.hidden;
- }
- } else {
- dataShow = dataPriv.access(elem, "fxshow", {
- display: restoreDisplay
- });
- } // Store hidden/visible for toggle so `.stop().toggle()` "reverses"
- if (toggle) {
- dataShow.hidden = !hidden;
- } // Show elements before animating them
- if (hidden) {
- showHide([elem], true);
- }
- /* eslint-disable no-loop-func */
- anim.done(function () {
- /* eslint-enable no-loop-func */
- // The final step of a "hide" animation is actually hiding the element
- if (!hidden) {
- showHide([elem]);
- }
- dataPriv.remove(elem, "fxshow");
- for (prop in orig) {
- jQuery.style(elem, prop, orig[prop]);
- }
- });
- } // Per-property setup
- propTween = createTween(hidden ? dataShow[prop] : 0, prop, anim);
- if (!(prop in dataShow)) {
- dataShow[prop] = propTween.start;
- if (hidden) {
- propTween.end = propTween.start;
- propTween.start = 0;
- }
- }
- }
- }
- function propFilter(props, specialEasing) {
- var index, name, easing, value, hooks; // camelCase, specialEasing and expand cssHook pass
- for (index in props) {
- name = camelCase(index);
- easing = specialEasing[name];
- value = props[index];
- if (Array.isArray(value)) {
- easing = value[1];
- value = props[index] = value[0];
- }
- if (index !== name) {
- props[name] = value;
- delete props[index];
- }
- hooks = jQuery.cssHooks[name];
- if (hooks && "expand" in hooks) {
- value = hooks.expand(value);
- delete props[name]; // Not quite $.extend, this won't overwrite existing keys.
- // Reusing 'index' because we have the correct "name"
- for (index in value) {
- if (!(index in props)) {
- props[index] = value[index];
- specialEasing[index] = easing;
- }
- }
- } else {
- specialEasing[name] = easing;
- }
- }
- }
- function Animation(elem, properties, options) {
- var result,
- stopped,
- index = 0,
- length = Animation.prefilters.length,
- deferred = jQuery.Deferred().always(function () {
- // Don't match elem in the :animated selector
- delete tick.elem;
- }),
- tick = function () {
- if (stopped) {
- return false;
- }
- var currentTime = fxNow || createFxNow(),
- remaining = Math.max(0, animation.startTime + animation.duration - currentTime),
- // Support: Android 2.3 only
- // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
- temp = remaining / animation.duration || 0,
- percent = 1 - temp,
- index = 0,
- length = animation.tweens.length;
- for (; index < length; index++) {
- animation.tweens[index].run(percent);
- }
- deferred.notifyWith(elem, [animation, percent, remaining]); // If there's more to do, yield
- if (percent < 1 && length) {
- return remaining;
- } // If this was an empty animation, synthesize a final progress notification
- if (!length) {
- deferred.notifyWith(elem, [animation, 1, 0]);
- } // Resolve the animation and report its conclusion
- deferred.resolveWith(elem, [animation]);
- return false;
- },
- animation = deferred.promise({
- elem: elem,
- props: jQuery.extend({}, properties),
- opts: jQuery.extend(true, {
- specialEasing: {},
- easing: jQuery.easing._default
- }, options),
- originalProperties: properties,
- originalOptions: options,
- startTime: fxNow || createFxNow(),
- duration: options.duration,
- tweens: [],
- createTween: function (prop, end) {
- var tween = jQuery.Tween(elem, animation.opts, prop, end, animation.opts.specialEasing[prop] || animation.opts.easing);
- animation.tweens.push(tween);
- return tween;
- },
- stop: function (gotoEnd) {
- var index = 0,
- // If we are going to the end, we want to run all the tweens
- // otherwise we skip this part
- length = gotoEnd ? animation.tweens.length : 0;
- if (stopped) {
- return this;
- }
- stopped = true;
- for (; index < length; index++) {
- animation.tweens[index].run(1);
- } // Resolve when we played the last frame; otherwise, reject
- if (gotoEnd) {
- deferred.notifyWith(elem, [animation, 1, 0]);
- deferred.resolveWith(elem, [animation, gotoEnd]);
- } else {
- deferred.rejectWith(elem, [animation, gotoEnd]);
- }
- return this;
- }
- }),
- props = animation.props;
- propFilter(props, animation.opts.specialEasing);
- for (; index < length; index++) {
- result = Animation.prefilters[index].call(animation, elem, props, animation.opts);
- if (result) {
- if (isFunction(result.stop)) {
- jQuery._queueHooks(animation.elem, animation.opts.queue).stop = result.stop.bind(result);
- }
- return result;
- }
- }
- jQuery.map(props, createTween, animation);
- if (isFunction(animation.opts.start)) {
- animation.opts.start.call(elem, animation);
- } // Attach callbacks from options
- animation.progress(animation.opts.progress).done(animation.opts.done, animation.opts.complete).fail(animation.opts.fail).always(animation.opts.always);
- jQuery.fx.timer(jQuery.extend(tick, {
- elem: elem,
- anim: animation,
- queue: animation.opts.queue
- }));
- return animation;
- }
- jQuery.Animation = jQuery.extend(Animation, {
- tweeners: {
- "*": [function (prop, value) {
- var tween = this.createTween(prop, value);
- adjustCSS(tween.elem, prop, rcssNum.exec(value), tween);
- return tween;
- }]
- },
- tweener: function (props, callback) {
- if (isFunction(props)) {
- callback = props;
- props = ["*"];
- } else {
- props = props.match(rnothtmlwhite);
- }
- var prop,
- index = 0,
- length = props.length;
- for (; index < length; index++) {
- prop = props[index];
- Animation.tweeners[prop] = Animation.tweeners[prop] || [];
- Animation.tweeners[prop].unshift(callback);
- }
- },
- prefilters: [defaultPrefilter],
- prefilter: function (callback, prepend) {
- if (prepend) {
- Animation.prefilters.unshift(callback);
- } else {
- Animation.prefilters.push(callback);
- }
- }
- });
- jQuery.speed = function (speed, easing, fn) {
- var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
- complete: fn || !fn && easing || isFunction(speed) && speed,
- duration: speed,
- easing: fn && easing || easing && !isFunction(easing) && easing
- }; // Go to the end state if fx are off
- if (jQuery.fx.off) {
- opt.duration = 0;
- } else {
- if (typeof opt.duration !== "number") {
- if (opt.duration in jQuery.fx.speeds) {
- opt.duration = jQuery.fx.speeds[opt.duration];
- } else {
- opt.duration = jQuery.fx.speeds._default;
- }
- }
- } // Normalize opt.queue - true/undefined/null -> "fx"
- if (opt.queue == null || opt.queue === true) {
- opt.queue = "fx";
- } // Queueing
- opt.old = opt.complete;
- opt.complete = function () {
- if (isFunction(opt.old)) {
- opt.old.call(this);
- }
- if (opt.queue) {
- jQuery.dequeue(this, opt.queue);
- }
- };
- return opt;
- };
- jQuery.fn.extend({
- fadeTo: function (speed, to, easing, callback) {
- // Show any hidden elements after setting opacity to 0
- return this.filter(isHiddenWithinTree).css("opacity", 0).show() // Animate to the value specified
- .end().animate({
- opacity: to
- }, speed, easing, callback);
- },
- animate: function (prop, speed, easing, callback) {
- var empty = jQuery.isEmptyObject(prop),
- optall = jQuery.speed(speed, easing, callback),
- doAnimation = function () {
- // Operate on a copy of prop so per-property easing won't be lost
- var anim = Animation(this, jQuery.extend({}, prop), optall); // Empty animations, or finishing resolves immediately
- if (empty || dataPriv.get(this, "finish")) {
- anim.stop(true);
- }
- };
- doAnimation.finish = doAnimation;
- return empty || optall.queue === false ? this.each(doAnimation) : this.queue(optall.queue, doAnimation);
- },
- stop: function (type, clearQueue, gotoEnd) {
- var stopQueue = function (hooks) {
- var stop = hooks.stop;
- delete hooks.stop;
- stop(gotoEnd);
- };
- if (typeof type !== "string") {
- gotoEnd = clearQueue;
- clearQueue = type;
- type = undefined;
- }
- if (clearQueue && type !== false) {
- this.queue(type || "fx", []);
- }
- return this.each(function () {
- var dequeue = true,
- index = type != null && type + "queueHooks",
- timers = jQuery.timers,
- data = dataPriv.get(this);
- if (index) {
- if (data[index] && data[index].stop) {
- stopQueue(data[index]);
- }
- } else {
- for (index in data) {
- if (data[index] && data[index].stop && rrun.test(index)) {
- stopQueue(data[index]);
- }
- }
- }
- for (index = timers.length; index--;) {
- if (timers[index].elem === this && (type == null || timers[index].queue === type)) {
- timers[index].anim.stop(gotoEnd);
- dequeue = false;
- timers.splice(index, 1);
- }
- } // Start the next in the queue if the last step wasn't forced.
- // Timers currently will call their complete callbacks, which
- // will dequeue but only if they were gotoEnd.
- if (dequeue || !gotoEnd) {
- jQuery.dequeue(this, type);
- }
- });
- },
- finish: function (type) {
- if (type !== false) {
- type = type || "fx";
- }
- return this.each(function () {
- var index,
- data = dataPriv.get(this),
- queue = data[type + "queue"],
- hooks = data[type + "queueHooks"],
- timers = jQuery.timers,
- length = queue ? queue.length : 0; // Enable finishing flag on private data
- data.finish = true; // Empty the queue first
- jQuery.queue(this, type, []);
- if (hooks && hooks.stop) {
- hooks.stop.call(this, true);
- } // Look for any active animations, and finish them
- for (index = timers.length; index--;) {
- if (timers[index].elem === this && timers[index].queue === type) {
- timers[index].anim.stop(true);
- timers.splice(index, 1);
- }
- } // Look for any animations in the old queue and finish them
- for (index = 0; index < length; index++) {
- if (queue[index] && queue[index].finish) {
- queue[index].finish.call(this);
- }
- } // Turn off finishing flag
- delete data.finish;
- });
- }
- });
- jQuery.each(["toggle", "show", "hide"], function (i, name) {
- var cssFn = jQuery.fn[name];
- jQuery.fn[name] = function (speed, easing, callback) {
- return speed == null || typeof speed === "boolean" ? cssFn.apply(this, arguments) : this.animate(genFx(name, true), speed, easing, callback);
- };
- }); // Generate shortcuts for custom animations
- jQuery.each({
- slideDown: genFx("show"),
- slideUp: genFx("hide"),
- slideToggle: genFx("toggle"),
- fadeIn: {
- opacity: "show"
- },
- fadeOut: {
- opacity: "hide"
- },
- fadeToggle: {
- opacity: "toggle"
- }
- }, function (name, props) {
- jQuery.fn[name] = function (speed, easing, callback) {
- return this.animate(props, speed, easing, callback);
- };
- });
- jQuery.timers = [];
- jQuery.fx.tick = function () {
- var timer,
- i = 0,
- timers = jQuery.timers;
- fxNow = Date.now();
- for (; i < timers.length; i++) {
- timer = timers[i]; // Run the timer and safely remove it when done (allowing for external removal)
- if (!timer() && timers[i] === timer) {
- timers.splice(i--, 1);
- }
- }
- if (!timers.length) {
- jQuery.fx.stop();
- }
- fxNow = undefined;
- };
- jQuery.fx.timer = function (timer) {
- jQuery.timers.push(timer);
- jQuery.fx.start();
- };
- jQuery.fx.interval = 13;
- jQuery.fx.start = function () {
- if (inProgress) {
- return;
- }
- inProgress = true;
- schedule();
- };
- jQuery.fx.stop = function () {
- inProgress = null;
- };
- jQuery.fx.speeds = {
- slow: 600,
- fast: 200,
- // Default speed
- _default: 400
- }; // Based off of the plugin by Clint Helfers, with permission.
- // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
- jQuery.fn.delay = function (time, type) {
- time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
- type = type || "fx";
- return this.queue(type, function (next, hooks) {
- var timeout = window.setTimeout(next, time);
- hooks.stop = function () {
- window.clearTimeout(timeout);
- };
- });
- };
- (function () {
- var input = document.createElement("input"),
- select = document.createElement("select"),
- opt = select.appendChild(document.createElement("option"));
- input.type = "checkbox"; // Support: Android <=4.3 only
- // Default value for a checkbox should be "on"
- support.checkOn = input.value !== ""; // Support: IE <=11 only
- // Must access selectedIndex to make default options select
- support.optSelected = opt.selected; // Support: IE <=11 only
- // An input loses its value after becoming a radio
- input = document.createElement("input");
- input.value = "t";
- input.type = "radio";
- support.radioValue = input.value === "t";
- })();
- var boolHook,
- attrHandle = jQuery.expr.attrHandle;
- jQuery.fn.extend({
- attr: function (name, value) {
- return access(this, jQuery.attr, name, value, arguments.length > 1);
- },
- removeAttr: function (name) {
- return this.each(function () {
- jQuery.removeAttr(this, name);
- });
- }
- });
- jQuery.extend({
- attr: function (elem, name, value) {
- var ret,
- hooks,
- nType = elem.nodeType; // Don't get/set attributes on text, comment and attribute nodes
- if (nType === 3 || nType === 8 || nType === 2) {
- return;
- } // Fallback to prop when attributes are not supported
- if (typeof elem.getAttribute === "undefined") {
- return jQuery.prop(elem, name, value);
- } // Attribute hooks are determined by the lowercase version
- // Grab necessary hook if one is defined
- if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
- hooks = jQuery.attrHooks[name.toLowerCase()] || (jQuery.expr.match.bool.test(name) ? boolHook : undefined);
- }
- if (value !== undefined) {
- if (value === null) {
- jQuery.removeAttr(elem, name);
- return;
- }
- if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {
- return ret;
- }
- elem.setAttribute(name, value + "");
- return value;
- }
- if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
- return ret;
- }
- ret = jQuery.find.attr(elem, name); // Non-existent attributes return null, we normalize to undefined
- return ret == null ? undefined : ret;
- },
- attrHooks: {
- type: {
- set: function (elem, value) {
- if (!support.radioValue && value === "radio" && nodeName(elem, "input")) {
- var val = elem.value;
- elem.setAttribute("type", value);
- if (val) {
- elem.value = val;
- }
- return value;
- }
- }
- }
- },
- removeAttr: function (elem, value) {
- var name,
- i = 0,
- // Attribute names can contain non-HTML whitespace characters
- // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
- attrNames = value && value.match(rnothtmlwhite);
- if (attrNames && elem.nodeType === 1) {
- while (name = attrNames[i++]) {
- elem.removeAttribute(name);
- }
- }
- }
- }); // Hooks for boolean attributes
- boolHook = {
- set: function (elem, value, name) {
- if (value === false) {
- // Remove boolean attributes when set to false
- jQuery.removeAttr(elem, name);
- } else {
- elem.setAttribute(name, name);
- }
- return name;
- }
- };
- jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (i, name) {
- var getter = attrHandle[name] || jQuery.find.attr;
- attrHandle[name] = function (elem, name, isXML) {
- var ret,
- handle,
- lowercaseName = name.toLowerCase();
- if (!isXML) {
- // Avoid an infinite loop by temporarily removing this function from the getter
- handle = attrHandle[lowercaseName];
- attrHandle[lowercaseName] = ret;
- ret = getter(elem, name, isXML) != null ? lowercaseName : null;
- attrHandle[lowercaseName] = handle;
- }
- return ret;
- };
- });
- var rfocusable = /^(?:input|select|textarea|button)$/i,
- rclickable = /^(?:a|area)$/i;
- jQuery.fn.extend({
- prop: function (name, value) {
- return access(this, jQuery.prop, name, value, arguments.length > 1);
- },
- removeProp: function (name) {
- return this.each(function () {
- delete this[jQuery.propFix[name] || name];
- });
- }
- });
- jQuery.extend({
- prop: function (elem, name, value) {
- var ret,
- hooks,
- nType = elem.nodeType; // Don't get/set properties on text, comment and attribute nodes
- if (nType === 3 || nType === 8 || nType === 2) {
- return;
- }
- if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
- // Fix name and attach hooks
- name = jQuery.propFix[name] || name;
- hooks = jQuery.propHooks[name];
- }
- if (value !== undefined) {
- if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {
- return ret;
- }
- return elem[name] = value;
- }
- if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
- return ret;
- }
- return elem[name];
- },
- propHooks: {
- tabIndex: {
- get: function (elem) {
- // Support: IE <=9 - 11 only
- // elem.tabIndex doesn't always return the
- // correct value when it hasn't been explicitly set
- // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
- // Use proper attribute retrieval(#12072)
- var tabindex = jQuery.find.attr(elem, "tabindex");
- if (tabindex) {
- return parseInt(tabindex, 10);
- }
- if (rfocusable.test(elem.nodeName) || rclickable.test(elem.nodeName) && elem.href) {
- return 0;
- }
- return -1;
- }
- }
- },
- propFix: {
- "for": "htmlFor",
- "class": "className"
- }
- }); // Support: IE <=11 only
- // Accessing the selectedIndex property
- // forces the browser to respect setting selected
- // on the option
- // The getter ensures a default option is selected
- // when in an optgroup
- // eslint rule "no-unused-expressions" is disabled for this code
- // since it considers such accessions noop
- if (!support.optSelected) {
- jQuery.propHooks.selected = {
- get: function (elem) {
- /* eslint no-unused-expressions: "off" */
- var parent = elem.parentNode;
- if (parent && parent.parentNode) {
- parent.parentNode.selectedIndex;
- }
- return null;
- },
- set: function (elem) {
- /* eslint no-unused-expressions: "off" */
- var parent = elem.parentNode;
- if (parent) {
- parent.selectedIndex;
- if (parent.parentNode) {
- parent.parentNode.selectedIndex;
- }
- }
- }
- };
- }
- jQuery.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () {
- jQuery.propFix[this.toLowerCase()] = this;
- }); // Strip and collapse whitespace according to HTML spec
- // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
- function stripAndCollapse(value) {
- var tokens = value.match(rnothtmlwhite) || [];
- return tokens.join(" ");
- }
- function getClass(elem) {
- return elem.getAttribute && elem.getAttribute("class") || "";
- }
- function classesToArray(value) {
- if (Array.isArray(value)) {
- return value;
- }
- if (typeof value === "string") {
- return value.match(rnothtmlwhite) || [];
- }
- return [];
- }
- jQuery.fn.extend({
- addClass: function (value) {
- var classes,
- elem,
- cur,
- curValue,
- clazz,
- j,
- finalValue,
- i = 0;
- if (isFunction(value)) {
- return this.each(function (j) {
- jQuery(this).addClass(value.call(this, j, getClass(this)));
- });
- }
- classes = classesToArray(value);
- if (classes.length) {
- while (elem = this[i++]) {
- curValue = getClass(elem);
- cur = elem.nodeType === 1 && " " + stripAndCollapse(curValue) + " ";
- if (cur) {
- j = 0;
- while (clazz = classes[j++]) {
- if (cur.indexOf(" " + clazz + " ") < 0) {
- cur += clazz + " ";
- }
- } // Only assign if different to avoid unneeded rendering.
- finalValue = stripAndCollapse(cur);
- if (curValue !== finalValue) {
- elem.setAttribute("class", finalValue);
- }
- }
- }
- }
- return this;
- },
- removeClass: function (value) {
- var classes,
- elem,
- cur,
- curValue,
- clazz,
- j,
- finalValue,
- i = 0;
- if (isFunction(value)) {
- return this.each(function (j) {
- jQuery(this).removeClass(value.call(this, j, getClass(this)));
- });
- }
- if (!arguments.length) {
- return this.attr("class", "");
- }
- classes = classesToArray(value);
- if (classes.length) {
- while (elem = this[i++]) {
- curValue = getClass(elem); // This expression is here for better compressibility (see addClass)
- cur = elem.nodeType === 1 && " " + stripAndCollapse(curValue) + " ";
- if (cur) {
- j = 0;
- while (clazz = classes[j++]) {
- // Remove *all* instances
- while (cur.indexOf(" " + clazz + " ") > -1) {
- cur = cur.replace(" " + clazz + " ", " ");
- }
- } // Only assign if different to avoid unneeded rendering.
- finalValue = stripAndCollapse(cur);
- if (curValue !== finalValue) {
- elem.setAttribute("class", finalValue);
- }
- }
- }
- }
- return this;
- },
- toggleClass: function (value, stateVal) {
- var type = typeof value,
- isValidValue = type === "string" || Array.isArray(value);
- if (typeof stateVal === "boolean" && isValidValue) {
- return stateVal ? this.addClass(value) : this.removeClass(value);
- }
- if (isFunction(value)) {
- return this.each(function (i) {
- jQuery(this).toggleClass(value.call(this, i, getClass(this), stateVal), stateVal);
- });
- }
- return this.each(function () {
- var className, i, self, classNames;
- if (isValidValue) {
- // Toggle individual class names
- i = 0;
- self = jQuery(this);
- classNames = classesToArray(value);
- while (className = classNames[i++]) {
- // Check each className given, space separated list
- if (self.hasClass(className)) {
- self.removeClass(className);
- } else {
- self.addClass(className);
- }
- } // Toggle whole class name
- } else if (value === undefined || type === "boolean") {
- className = getClass(this);
- if (className) {
- // Store className if set
- dataPriv.set(this, "__className__", className);
- } // If the element has a class name or if we're passed `false`,
- // then remove the whole classname (if there was one, the above saved it).
- // Otherwise bring back whatever was previously saved (if anything),
- // falling back to the empty string if nothing was stored.
- if (this.setAttribute) {
- this.setAttribute("class", className || value === false ? "" : dataPriv.get(this, "__className__") || "");
- }
- }
- });
- },
- hasClass: function (selector) {
- var className,
- elem,
- i = 0;
- className = " " + selector + " ";
- while (elem = this[i++]) {
- if (elem.nodeType === 1 && (" " + stripAndCollapse(getClass(elem)) + " ").indexOf(className) > -1) {
- return true;
- }
- }
- return false;
- }
- });
- var rreturn = /\r/g;
- jQuery.fn.extend({
- val: function (value) {
- var hooks,
- ret,
- valueIsFunction,
- elem = this[0];
- if (!arguments.length) {
- if (elem) {
- hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()];
- if (hooks && "get" in hooks && (ret = hooks.get(elem, "value")) !== undefined) {
- return ret;
- }
- ret = elem.value; // Handle most common string cases
- if (typeof ret === "string") {
- return ret.replace(rreturn, "");
- } // Handle cases where value is null/undef or number
- return ret == null ? "" : ret;
- }
- return;
- }
- valueIsFunction = isFunction(value);
- return this.each(function (i) {
- var val;
- if (this.nodeType !== 1) {
- return;
- }
- if (valueIsFunction) {
- val = value.call(this, i, jQuery(this).val());
- } else {
- val = value;
- } // Treat null/undefined as ""; convert numbers to string
- if (val == null) {
- val = "";
- } else if (typeof val === "number") {
- val += "";
- } else if (Array.isArray(val)) {
- val = jQuery.map(val, function (value) {
- return value == null ? "" : value + "";
- });
- }
- hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()]; // If set returns undefined, fall back to normal setting
- if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) {
- this.value = val;
- }
- });
- }
- });
- jQuery.extend({
- valHooks: {
- option: {
- get: function (elem) {
- var val = jQuery.find.attr(elem, "value");
- return val != null ? val : // Support: IE <=10 - 11 only
- // option.text throws exceptions (#14686, #14858)
- // Strip and collapse whitespace
- // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
- stripAndCollapse(jQuery.text(elem));
- }
- },
- select: {
- get: function (elem) {
- var value,
- option,
- i,
- options = elem.options,
- index = elem.selectedIndex,
- one = elem.type === "select-one",
- values = one ? null : [],
- max = one ? index + 1 : options.length;
- if (index < 0) {
- i = max;
- } else {
- i = one ? index : 0;
- } // Loop through all the selected options
- for (; i < max; i++) {
- option = options[i]; // Support: IE <=9 only
- // IE8-9 doesn't update selected after form reset (#2551)
- if ((option.selected || i === index) && // Don't return options that are disabled or in a disabled optgroup
- !option.disabled && (!option.parentNode.disabled || !nodeName(option.parentNode, "optgroup"))) {
- // Get the specific value for the option
- value = jQuery(option).val(); // We don't need an array for one selects
- if (one) {
- return value;
- } // Multi-Selects return an array
- values.push(value);
- }
- }
- return values;
- },
- set: function (elem, value) {
- var optionSet,
- option,
- options = elem.options,
- values = jQuery.makeArray(value),
- i = options.length;
- while (i--) {
- option = options[i];
- /* eslint-disable no-cond-assign */
- if (option.selected = jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1) {
- optionSet = true;
- }
- /* eslint-enable no-cond-assign */
- } // Force browsers to behave consistently when non-matching value is set
- if (!optionSet) {
- elem.selectedIndex = -1;
- }
- return values;
- }
- }
- }
- }); // Radios and checkboxes getter/setter
- jQuery.each(["radio", "checkbox"], function () {
- jQuery.valHooks[this] = {
- set: function (elem, value) {
- if (Array.isArray(value)) {
- return elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1;
- }
- }
- };
- if (!support.checkOn) {
- jQuery.valHooks[this].get = function (elem) {
- return elem.getAttribute("value") === null ? "on" : elem.value;
- };
- }
- }); // Return jQuery for attributes-only inclusion
- support.focusin = "onfocusin" in window;
- var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
- stopPropagationCallback = function (e) {
- e.stopPropagation();
- };
- jQuery.extend(jQuery.event, {
- trigger: function (event, data, elem, onlyHandlers) {
- var i,
- cur,
- tmp,
- bubbleType,
- ontype,
- handle,
- special,
- lastElement,
- eventPath = [elem || document],
- type = hasOwn.call(event, "type") ? event.type : event,
- namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : [];
- cur = lastElement = tmp = elem = elem || document; // Don't do events on text and comment nodes
- if (elem.nodeType === 3 || elem.nodeType === 8) {
- return;
- } // focus/blur morphs to focusin/out; ensure we're not firing them right now
- if (rfocusMorph.test(type + jQuery.event.triggered)) {
- return;
- }
- if (type.indexOf(".") > -1) {
- // Namespaced trigger; create a regexp to match event type in handle()
- namespaces = type.split(".");
- type = namespaces.shift();
- namespaces.sort();
- }
- ontype = type.indexOf(":") < 0 && "on" + type; // Caller can pass in a jQuery.Event object, Object, or just an event type string
- event = event[jQuery.expando] ? event : new jQuery.Event(type, typeof event === "object" && event); // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
- event.isTrigger = onlyHandlers ? 2 : 3;
- event.namespace = namespaces.join(".");
- event.rnamespace = event.namespace ? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; // Clean up the event in case it is being reused
- event.result = undefined;
- if (!event.target) {
- event.target = elem;
- } // Clone any incoming data and prepend the event, creating the handler arg list
- data = data == null ? [event] : jQuery.makeArray(data, [event]); // Allow special events to draw outside the lines
- special = jQuery.event.special[type] || {};
- if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {
- return;
- } // Determine event propagation path in advance, per W3C events spec (#9951)
- // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
- if (!onlyHandlers && !special.noBubble && !isWindow(elem)) {
- bubbleType = special.delegateType || type;
- if (!rfocusMorph.test(bubbleType + type)) {
- cur = cur.parentNode;
- }
- for (; cur; cur = cur.parentNode) {
- eventPath.push(cur);
- tmp = cur;
- } // Only add window if we got to document (e.g., not plain obj or detached DOM)
- if (tmp === (elem.ownerDocument || document)) {
- eventPath.push(tmp.defaultView || tmp.parentWindow || window);
- }
- } // Fire handlers on the event path
- i = 0;
- while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {
- lastElement = cur;
- event.type = i > 1 ? bubbleType : special.bindType || type; // jQuery handler
- handle = (dataPriv.get(cur, "events") || {})[event.type] && dataPriv.get(cur, "handle");
- if (handle) {
- handle.apply(cur, data);
- } // Native handler
- handle = ontype && cur[ontype];
- if (handle && handle.apply && acceptData(cur)) {
- event.result = handle.apply(cur, data);
- if (event.result === false) {
- event.preventDefault();
- }
- }
- }
- event.type = type; // If nobody prevented the default action, do it now
- if (!onlyHandlers && !event.isDefaultPrevented()) {
- if ((!special._default || special._default.apply(eventPath.pop(), data) === false) && acceptData(elem)) {
- // Call a native DOM method on the target with the same name as the event.
- // Don't do default actions on window, that's where global variables be (#6170)
- if (ontype && isFunction(elem[type]) && !isWindow(elem)) {
- // Don't re-trigger an onFOO event when we call its FOO() method
- tmp = elem[ontype];
- if (tmp) {
- elem[ontype] = null;
- } // Prevent re-triggering of the same event, since we already bubbled it above
- jQuery.event.triggered = type;
- if (event.isPropagationStopped()) {
- lastElement.addEventListener(type, stopPropagationCallback);
- }
- elem[type]();
- if (event.isPropagationStopped()) {
- lastElement.removeEventListener(type, stopPropagationCallback);
- }
- jQuery.event.triggered = undefined;
- if (tmp) {
- elem[ontype] = tmp;
- }
- }
- }
- }
- return event.result;
- },
- // Piggyback on a donor event to simulate a different one
- // Used only for `focus(in | out)` events
- simulate: function (type, elem, event) {
- var e = jQuery.extend(new jQuery.Event(), event, {
- type: type,
- isSimulated: true
- });
- jQuery.event.trigger(e, null, elem);
- }
- });
- jQuery.fn.extend({
- trigger: function (type, data) {
- return this.each(function () {
- jQuery.event.trigger(type, data, this);
- });
- },
- triggerHandler: function (type, data) {
- var elem = this[0];
- if (elem) {
- return jQuery.event.trigger(type, data, elem, true);
- }
- }
- }); // Support: Firefox <=44
- // Firefox doesn't have focus(in | out) events
- // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
- //
- // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
- // focus(in | out) events fire after focus & blur events,
- // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
- // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
- if (!support.focusin) {
- jQuery.each({
- focus: "focusin",
- blur: "focusout"
- }, function (orig, fix) {
- // Attach a single capturing handler on the document while someone wants focusin/focusout
- var handler = function (event) {
- jQuery.event.simulate(fix, event.target, jQuery.event.fix(event));
- };
- jQuery.event.special[fix] = {
- setup: function () {
- var doc = this.ownerDocument || this,
- attaches = dataPriv.access(doc, fix);
- if (!attaches) {
- doc.addEventListener(orig, handler, true);
- }
- dataPriv.access(doc, fix, (attaches || 0) + 1);
- },
- teardown: function () {
- var doc = this.ownerDocument || this,
- attaches = dataPriv.access(doc, fix) - 1;
- if (!attaches) {
- doc.removeEventListener(orig, handler, true);
- dataPriv.remove(doc, fix);
- } else {
- dataPriv.access(doc, fix, attaches);
- }
- }
- };
- });
- }
- var location = window.location;
- var nonce = Date.now();
- var rquery = /\?/; // Cross-browser xml parsing
- jQuery.parseXML = function (data) {
- var xml;
- if (!data || typeof data !== "string") {
- return null;
- } // Support: IE 9 - 11 only
- // IE throws on parseFromString with invalid input.
- try {
- xml = new window.DOMParser().parseFromString(data, "text/xml");
- } catch (e) {
- xml = undefined;
- }
- if (!xml || xml.getElementsByTagName("parsererror").length) {
- jQuery.error("Invalid XML: " + data);
- }
- return xml;
- };
- var rbracket = /\[\]$/,
- rCRLF = /\r?\n/g,
- rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
- rsubmittable = /^(?:input|select|textarea|keygen)/i;
- function buildParams(prefix, obj, traditional, add) {
- var name;
- if (Array.isArray(obj)) {
- // Serialize array item.
- jQuery.each(obj, function (i, v) {
- if (traditional || rbracket.test(prefix)) {
- // Treat each array item as a scalar.
- add(prefix, v);
- } else {
- // Item is non-scalar (array or object), encode its numeric index.
- buildParams(prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]", v, traditional, add);
- }
- });
- } else if (!traditional && toType(obj) === "object") {
- // Serialize object item.
- for (name in obj) {
- buildParams(prefix + "[" + name + "]", obj[name], traditional, add);
- }
- } else {
- // Serialize scalar item.
- add(prefix, obj);
- }
- } // Serialize an array of form elements or a set of
- // key/values into a query string
- jQuery.param = function (a, traditional) {
- var prefix,
- s = [],
- add = function (key, valueOrFunction) {
- // If value is a function, invoke it and use its return value
- var value = isFunction(valueOrFunction) ? valueOrFunction() : valueOrFunction;
- s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value == null ? "" : value);
- }; // If an array was passed in, assume that it is an array of form elements.
- if (Array.isArray(a) || a.jquery && !jQuery.isPlainObject(a)) {
- // Serialize the form elements
- jQuery.each(a, function () {
- add(this.name, this.value);
- });
- } else {
- // If traditional, encode the "old" way (the way 1.3.2 or older
- // did it), otherwise encode params recursively.
- for (prefix in a) {
- buildParams(prefix, a[prefix], traditional, add);
- }
- } // Return the resulting serialization
- return s.join("&");
- };
- jQuery.fn.extend({
- serialize: function () {
- return jQuery.param(this.serializeArray());
- },
- serializeArray: function () {
- return this.map(function () {
- // Can add propHook for "elements" to filter or add form elements
- var elements = jQuery.prop(this, "elements");
- return elements ? jQuery.makeArray(elements) : this;
- }).filter(function () {
- var type = this.type; // Use .is( ":disabled" ) so that fieldset[disabled] works
- return this.name && !jQuery(this).is(":disabled") && rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && (this.checked || !rcheckableType.test(type));
- }).map(function (i, elem) {
- var val = jQuery(this).val();
- if (val == null) {
- return null;
- }
- if (Array.isArray(val)) {
- return jQuery.map(val, function (val) {
- return {
- name: elem.name,
- value: val.replace(rCRLF, "\r\n")
- };
- });
- }
- return {
- name: elem.name,
- value: val.replace(rCRLF, "\r\n")
- };
- }).get();
- }
- });
- var r20 = /%20/g,
- rhash = /#.*$/,
- rantiCache = /([?&])_=[^&]*/,
- rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
- // #7653, #8125, #8152: local protocol detection
- rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
- rnoContent = /^(?:GET|HEAD)$/,
- rprotocol = /^\/\//,
- /* Prefilters
- * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
- * 2) These are called:
- * - BEFORE asking for a transport
- * - AFTER param serialization (s.data is a string if s.processData is true)
- * 3) key is the dataType
- * 4) the catchall symbol "*" can be used
- * 5) execution will start with transport dataType and THEN continue down to "*" if needed
- */
- prefilters = {},
- /* Transports bindings
- * 1) key is the dataType
- * 2) the catchall symbol "*" can be used
- * 3) selection will start with transport dataType and THEN go to "*" if needed
- */
- transports = {},
- // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
- allTypes = "*/".concat("*"),
- // Anchor tag for parsing the document origin
- originAnchor = document.createElement("a");
- originAnchor.href = location.href; // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
- function addToPrefiltersOrTransports(structure) {
- // dataTypeExpression is optional and defaults to "*"
- return function (dataTypeExpression, func) {
- if (typeof dataTypeExpression !== "string") {
- func = dataTypeExpression;
- dataTypeExpression = "*";
- }
- var dataType,
- i = 0,
- dataTypes = dataTypeExpression.toLowerCase().match(rnothtmlwhite) || [];
- if (isFunction(func)) {
- // For each dataType in the dataTypeExpression
- while (dataType = dataTypes[i++]) {
- // Prepend if requested
- if (dataType[0] === "+") {
- dataType = dataType.slice(1) || "*";
- (structure[dataType] = structure[dataType] || []).unshift(func); // Otherwise append
- } else {
- (structure[dataType] = structure[dataType] || []).push(func);
- }
- }
- }
- };
- } // Base inspection function for prefilters and transports
- function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) {
- var inspected = {},
- seekingTransport = structure === transports;
- function inspect(dataType) {
- var selected;
- inspected[dataType] = true;
- jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) {
- var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR);
- if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) {
- options.dataTypes.unshift(dataTypeOrTransport);
- inspect(dataTypeOrTransport);
- return false;
- } else if (seekingTransport) {
- return !(selected = dataTypeOrTransport);
- }
- });
- return selected;
- }
- return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*");
- } // A special extend for ajax options
- // that takes "flat" options (not to be deep extended)
- // Fixes #9887
- function ajaxExtend(target, src) {
- var key,
- deep,
- flatOptions = jQuery.ajaxSettings.flatOptions || {};
- for (key in src) {
- if (src[key] !== undefined) {
- (flatOptions[key] ? target : deep || (deep = {}))[key] = src[key];
- }
- }
- if (deep) {
- jQuery.extend(true, target, deep);
- }
- return target;
- }
- /* Handles responses to an ajax request:
- * - finds the right dataType (mediates between content-type and expected dataType)
- * - returns the corresponding response
- */
- function ajaxHandleResponses(s, jqXHR, responses) {
- var ct,
- type,
- finalDataType,
- firstDataType,
- contents = s.contents,
- dataTypes = s.dataTypes; // Remove auto dataType and get content-type in the process
- while (dataTypes[0] === "*") {
- dataTypes.shift();
- if (ct === undefined) {
- ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
- }
- } // Check if we're dealing with a known content-type
- if (ct) {
- for (type in contents) {
- if (contents[type] && contents[type].test(ct)) {
- dataTypes.unshift(type);
- break;
- }
- }
- } // Check to see if we have a response for the expected dataType
- if (dataTypes[0] in responses) {
- finalDataType = dataTypes[0];
- } else {
- // Try convertible dataTypes
- for (type in responses) {
- if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) {
- finalDataType = type;
- break;
- }
- if (!firstDataType) {
- firstDataType = type;
- }
- } // Or just use first one
- finalDataType = finalDataType || firstDataType;
- } // If we found a dataType
- // We add the dataType to the list if needed
- // and return the corresponding response
- if (finalDataType) {
- if (finalDataType !== dataTypes[0]) {
- dataTypes.unshift(finalDataType);
- }
- return responses[finalDataType];
- }
- }
- /* Chain conversions given the request and the original response
- * Also sets the responseXXX fields on the jqXHR instance
- */
- function ajaxConvert(s, response, jqXHR, isSuccess) {
- var conv2,
- current,
- conv,
- tmp,
- prev,
- converters = {},
- // Work with a copy of dataTypes in case we need to modify it for conversion
- dataTypes = s.dataTypes.slice(); // Create converters map with lowercased keys
- if (dataTypes[1]) {
- for (conv in s.converters) {
- converters[conv.toLowerCase()] = s.converters[conv];
- }
- }
- current = dataTypes.shift(); // Convert to each sequential dataType
- while (current) {
- if (s.responseFields[current]) {
- jqXHR[s.responseFields[current]] = response;
- } // Apply the dataFilter if provided
- if (!prev && isSuccess && s.dataFilter) {
- response = s.dataFilter(response, s.dataType);
- }
- prev = current;
- current = dataTypes.shift();
- if (current) {
- // There's only work to do if current dataType is non-auto
- if (current === "*") {
- current = prev; // Convert response if prev dataType is non-auto and differs from current
- } else if (prev !== "*" && prev !== current) {
- // Seek a direct converter
- conv = converters[prev + " " + current] || converters["* " + current]; // If none found, seek a pair
- if (!conv) {
- for (conv2 in converters) {
- // If conv2 outputs current
- tmp = conv2.split(" ");
- if (tmp[1] === current) {
- // If prev can be converted to accepted input
- conv = converters[prev + " " + tmp[0]] || converters["* " + tmp[0]];
- if (conv) {
- // Condense equivalence converters
- if (conv === true) {
- conv = converters[conv2]; // Otherwise, insert the intermediate dataType
- } else if (converters[conv2] !== true) {
- current = tmp[0];
- dataTypes.unshift(tmp[1]);
- }
- break;
- }
- }
- }
- } // Apply converter (if not an equivalence)
- if (conv !== true) {
- // Unless errors are allowed to bubble, catch and return them
- if (conv && s.throws) {
- response = conv(response);
- } else {
- try {
- response = conv(response);
- } catch (e) {
- return {
- state: "parsererror",
- error: conv ? e : "No conversion from " + prev + " to " + current
- };
- }
- }
- }
- }
- }
- }
- return {
- state: "success",
- data: response
- };
- }
- jQuery.extend({
- // Counter for holding the number of active queries
- active: 0,
- // Last-Modified header cache for next request
- lastModified: {},
- etag: {},
- ajaxSettings: {
- url: location.href,
- type: "GET",
- isLocal: rlocalProtocol.test(location.protocol),
- global: true,
- processData: true,
- async: true,
- contentType: "application/x-www-form-urlencoded; charset=UTF-8",
- /*
- timeout: 0,
- data: null,
- dataType: null,
- username: null,
- password: null,
- cache: null,
- throws: false,
- traditional: false,
- headers: {},
- */
- accepts: {
- "*": allTypes,
- text: "text/plain",
- html: "text/html",
- xml: "application/xml, text/xml",
- json: "application/json, text/javascript"
- },
- contents: {
- xml: /\bxml\b/,
- html: /\bhtml/,
- json: /\bjson\b/
- },
- responseFields: {
- xml: "responseXML",
- text: "responseText",
- json: "responseJSON"
- },
- // Data converters
- // Keys separate source (or catchall "*") and destination types with a single space
- converters: {
- // Convert anything to text
- "* text": String,
- // Text to html (true = no transformation)
- "text html": true,
- // Evaluate text as a json expression
- "text json": JSON.parse,
- // Parse text as xml
- "text xml": jQuery.parseXML
- },
- // For options that shouldn't be deep extended:
- // you can add your own custom options here if
- // and when you create one that shouldn't be
- // deep extended (see ajaxExtend)
- flatOptions: {
- url: true,
- context: true
- }
- },
- // Creates a full fledged settings object into target
- // with both ajaxSettings and settings fields.
- // If target is omitted, writes into ajaxSettings.
- ajaxSetup: function (target, settings) {
- return settings ? // Building a settings object
- ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) : // Extending ajaxSettings
- ajaxExtend(jQuery.ajaxSettings, target);
- },
- ajaxPrefilter: addToPrefiltersOrTransports(prefilters),
- ajaxTransport: addToPrefiltersOrTransports(transports),
- // Main method
- ajax: function (url, options) {
- // If url is an object, simulate pre-1.5 signature
- if (typeof url === "object") {
- options = url;
- url = undefined;
- } // Force options to be an object
- options = options || {};
- var transport,
- // URL without anti-cache param
- cacheURL,
- // Response headers
- responseHeadersString,
- responseHeaders,
- // timeout handle
- timeoutTimer,
- // Url cleanup var
- urlAnchor,
- // Request state (becomes false upon send and true upon completion)
- completed,
- // To know if global events are to be dispatched
- fireGlobals,
- // Loop variable
- i,
- // uncached part of the url
- uncached,
- // Create the final options object
- s = jQuery.ajaxSetup({}, options),
- // Callbacks context
- callbackContext = s.context || s,
- // Context for global events is callbackContext if it is a DOM node or jQuery collection
- globalEventContext = s.context && (callbackContext.nodeType || callbackContext.jquery) ? jQuery(callbackContext) : jQuery.event,
- // Deferreds
- deferred = jQuery.Deferred(),
- completeDeferred = jQuery.Callbacks("once memory"),
- // Status-dependent callbacks
- statusCode = s.statusCode || {},
- // Headers (they are sent all at once)
- requestHeaders = {},
- requestHeadersNames = {},
- // Default abort message
- strAbort = "canceled",
- // Fake xhr
- jqXHR = {
- readyState: 0,
- // Builds headers hashtable if needed
- getResponseHeader: function (key) {
- var match;
- if (completed) {
- if (!responseHeaders) {
- responseHeaders = {};
- while (match = rheaders.exec(responseHeadersString)) {
- responseHeaders[match[1].toLowerCase()] = match[2];
- }
- }
- match = responseHeaders[key.toLowerCase()];
- }
- return match == null ? null : match;
- },
- // Raw string
- getAllResponseHeaders: function () {
- return completed ? responseHeadersString : null;
- },
- // Caches the header
- setRequestHeader: function (name, value) {
- if (completed == null) {
- name = requestHeadersNames[name.toLowerCase()] = requestHeadersNames[name.toLowerCase()] || name;
- requestHeaders[name] = value;
- }
- return this;
- },
- // Overrides response content-type header
- overrideMimeType: function (type) {
- if (completed == null) {
- s.mimeType = type;
- }
- return this;
- },
- // Status-dependent callbacks
- statusCode: function (map) {
- var code;
- if (map) {
- if (completed) {
- // Execute the appropriate callbacks
- jqXHR.always(map[jqXHR.status]);
- } else {
- // Lazy-add the new callbacks in a way that preserves old ones
- for (code in map) {
- statusCode[code] = [statusCode[code], map[code]];
- }
- }
- }
- return this;
- },
- // Cancel the request
- abort: function (statusText) {
- var finalText = statusText || strAbort;
- if (transport) {
- transport.abort(finalText);
- }
- done(0, finalText);
- return this;
- }
- }; // Attach deferreds
- deferred.promise(jqXHR); // Add protocol if not provided (prefilters might expect it)
- // Handle falsy url in the settings object (#10093: consistency with old signature)
- // We also use the url parameter if available
- s.url = ((url || s.url || location.href) + "").replace(rprotocol, location.protocol + "//"); // Alias method option to type as per ticket #12004
- s.type = options.method || options.type || s.method || s.type; // Extract dataTypes list
- s.dataTypes = (s.dataType || "*").toLowerCase().match(rnothtmlwhite) || [""]; // A cross-domain request is in order when the origin doesn't match the current origin.
- if (s.crossDomain == null) {
- urlAnchor = document.createElement("a"); // Support: IE <=8 - 11, Edge 12 - 15
- // IE throws exception on accessing the href property if url is malformed,
- // e.g. http://example.com:80x/
- try {
- urlAnchor.href = s.url; // Support: IE <=8 - 11 only
- // Anchor's host property isn't correctly set when s.url is relative
- urlAnchor.href = urlAnchor.href;
- s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== urlAnchor.protocol + "//" + urlAnchor.host;
- } catch (e) {
- // If there is an error parsing the URL, assume it is crossDomain,
- // it can be rejected by the transport if it is invalid
- s.crossDomain = true;
- }
- } // Convert data if not already a string
- if (s.data && s.processData && typeof s.data !== "string") {
- s.data = jQuery.param(s.data, s.traditional);
- } // Apply prefilters
- inspectPrefiltersOrTransports(prefilters, s, options, jqXHR); // If request was aborted inside a prefilter, stop there
- if (completed) {
- return jqXHR;
- } // We can fire global events as of now if asked to
- // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
- fireGlobals = jQuery.event && s.global; // Watch for a new set of requests
- if (fireGlobals && jQuery.active++ === 0) {
- jQuery.event.trigger("ajaxStart");
- } // Uppercase the type
- s.type = s.type.toUpperCase(); // Determine if request has content
- s.hasContent = !rnoContent.test(s.type); // Save the URL in case we're toying with the If-Modified-Since
- // and/or If-None-Match header later on
- // Remove hash to simplify url manipulation
- cacheURL = s.url.replace(rhash, ""); // More options handling for requests with no content
- if (!s.hasContent) {
- // Remember the hash so we can put it back
- uncached = s.url.slice(cacheURL.length); // If data is available and should be processed, append data to url
- if (s.data && (s.processData || typeof s.data === "string")) {
- cacheURL += (rquery.test(cacheURL) ? "&" : "?") + s.data; // #9682: remove data so that it's not used in an eventual retry
- delete s.data;
- } // Add or update anti-cache param if needed
- if (s.cache === false) {
- cacheURL = cacheURL.replace(rantiCache, "$1");
- uncached = (rquery.test(cacheURL) ? "&" : "?") + "_=" + nonce++ + uncached;
- } // Put hash and anti-cache on the URL that will be requested (gh-1732)
- s.url = cacheURL + uncached; // Change '%20' to '+' if this is encoded form body content (gh-2658)
- } else if (s.data && s.processData && (s.contentType || "").indexOf("application/x-www-form-urlencoded") === 0) {
- s.data = s.data.replace(r20, "+");
- } // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
- if (s.ifModified) {
- if (jQuery.lastModified[cacheURL]) {
- jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL]);
- }
- if (jQuery.etag[cacheURL]) {
- jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL]);
- }
- } // Set the correct header, if data is being sent
- if (s.data && s.hasContent && s.contentType !== false || options.contentType) {
- jqXHR.setRequestHeader("Content-Type", s.contentType);
- } // Set the Accepts header for the server, depending on the dataType
- jqXHR.setRequestHeader("Accept", s.dataTypes[0] && s.accepts[s.dataTypes[0]] ? s.accepts[s.dataTypes[0]] + (s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01" : "") : s.accepts["*"]); // Check for headers option
- for (i in s.headers) {
- jqXHR.setRequestHeader(i, s.headers[i]);
- } // Allow custom headers/mimetypes and early abort
- if (s.beforeSend && (s.beforeSend.call(callbackContext, jqXHR, s) === false || completed)) {
- // Abort if not done already and return
- return jqXHR.abort();
- } // Aborting is no longer a cancellation
- strAbort = "abort"; // Install callbacks on deferreds
- completeDeferred.add(s.complete);
- jqXHR.done(s.success);
- jqXHR.fail(s.error); // Get transport
- transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR); // If no transport, we auto-abort
- if (!transport) {
- done(-1, "No Transport");
- } else {
- jqXHR.readyState = 1; // Send global event
- if (fireGlobals) {
- globalEventContext.trigger("ajaxSend", [jqXHR, s]);
- } // If request was aborted inside ajaxSend, stop there
- if (completed) {
- return jqXHR;
- } // Timeout
- if (s.async && s.timeout > 0) {
- timeoutTimer = window.setTimeout(function () {
- jqXHR.abort("timeout");
- }, s.timeout);
- }
- try {
- completed = false;
- transport.send(requestHeaders, done);
- } catch (e) {
- // Rethrow post-completion exceptions
- if (completed) {
- throw e;
- } // Propagate others as results
- done(-1, e);
- }
- } // Callback for when everything is done
- function done(status, nativeStatusText, responses, headers) {
- var isSuccess,
- success,
- error,
- response,
- modified,
- statusText = nativeStatusText; // Ignore repeat invocations
- if (completed) {
- return;
- }
- completed = true; // Clear timeout if it exists
- if (timeoutTimer) {
- window.clearTimeout(timeoutTimer);
- } // Dereference transport for early garbage collection
- // (no matter how long the jqXHR object will be used)
- transport = undefined; // Cache response headers
- responseHeadersString = headers || ""; // Set readyState
- jqXHR.readyState = status > 0 ? 4 : 0; // Determine if successful
- isSuccess = status >= 200 && status < 300 || status === 304; // Get response data
- if (responses) {
- response = ajaxHandleResponses(s, jqXHR, responses);
- } // Convert no matter what (that way responseXXX fields are always set)
- response = ajaxConvert(s, response, jqXHR, isSuccess); // If successful, handle type chaining
- if (isSuccess) {
- // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
- if (s.ifModified) {
- modified = jqXHR.getResponseHeader("Last-Modified");
- if (modified) {
- jQuery.lastModified[cacheURL] = modified;
- }
- modified = jqXHR.getResponseHeader("etag");
- if (modified) {
- jQuery.etag[cacheURL] = modified;
- }
- } // if no content
- if (status === 204 || s.type === "HEAD") {
- statusText = "nocontent"; // if not modified
- } else if (status === 304) {
- statusText = "notmodified"; // If we have data, let's convert it
- } else {
- statusText = response.state;
- success = response.data;
- error = response.error;
- isSuccess = !error;
- }
- } else {
- // Extract error from statusText and normalize for non-aborts
- error = statusText;
- if (status || !statusText) {
- statusText = "error";
- if (status < 0) {
- status = 0;
- }
- }
- } // Set data for the fake xhr object
- jqXHR.status = status;
- jqXHR.statusText = (nativeStatusText || statusText) + ""; // Success/Error
- if (isSuccess) {
- deferred.resolveWith(callbackContext, [success, statusText, jqXHR]);
- } else {
- deferred.rejectWith(callbackContext, [jqXHR, statusText, error]);
- } // Status-dependent callbacks
- jqXHR.statusCode(statusCode);
- statusCode = undefined;
- if (fireGlobals) {
- globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError", [jqXHR, s, isSuccess ? success : error]);
- } // Complete
- completeDeferred.fireWith(callbackContext, [jqXHR, statusText]);
- if (fireGlobals) {
- globalEventContext.trigger("ajaxComplete", [jqXHR, s]); // Handle the global AJAX counter
- if (! --jQuery.active) {
- jQuery.event.trigger("ajaxStop");
- }
- }
- }
- return jqXHR;
- },
- getJSON: function (url, data, callback) {
- return jQuery.get(url, data, callback, "json");
- },
- getScript: function (url, callback) {
- return jQuery.get(url, undefined, callback, "script");
- }
- });
- jQuery.each(["get", "post"], function (i, method) {
- jQuery[method] = function (url, data, callback, type) {
- // Shift arguments if data argument was omitted
- if (isFunction(data)) {
- type = type || callback;
- callback = data;
- data = undefined;
- } // The url can be an options object (which then must have .url)
- return jQuery.ajax(jQuery.extend({
- url: url,
- type: method,
- dataType: type,
- data: data,
- success: callback
- }, jQuery.isPlainObject(url) && url));
- };
- });
- jQuery._evalUrl = function (url) {
- return jQuery.ajax({
- url: url,
- // Make this explicit, since user can override this through ajaxSetup (#11264)
- type: "GET",
- dataType: "script",
- cache: true,
- async: false,
- global: false,
- "throws": true
- });
- };
- jQuery.fn.extend({
- wrapAll: function (html) {
- var wrap;
- if (this[0]) {
- if (isFunction(html)) {
- html = html.call(this[0]);
- } // The elements to wrap the target around
- wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true);
- if (this[0].parentNode) {
- wrap.insertBefore(this[0]);
- }
- wrap.map(function () {
- var elem = this;
- while (elem.firstElementChild) {
- elem = elem.firstElementChild;
- }
- return elem;
- }).append(this);
- }
- return this;
- },
- wrapInner: function (html) {
- if (isFunction(html)) {
- return this.each(function (i) {
- jQuery(this).wrapInner(html.call(this, i));
- });
- }
- return this.each(function () {
- var self = jQuery(this),
- contents = self.contents();
- if (contents.length) {
- contents.wrapAll(html);
- } else {
- self.append(html);
- }
- });
- },
- wrap: function (html) {
- var htmlIsFunction = isFunction(html);
- return this.each(function (i) {
- jQuery(this).wrapAll(htmlIsFunction ? html.call(this, i) : html);
- });
- },
- unwrap: function (selector) {
- this.parent(selector).not("body").each(function () {
- jQuery(this).replaceWith(this.childNodes);
- });
- return this;
- }
- });
- jQuery.expr.pseudos.hidden = function (elem) {
- return !jQuery.expr.pseudos.visible(elem);
- };
- jQuery.expr.pseudos.visible = function (elem) {
- return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
- };
- jQuery.ajaxSettings.xhr = function () {
- try {
- return new window.XMLHttpRequest();
- } catch (e) {}
- };
- var xhrSuccessStatus = {
- // File protocol always yields status code 0, assume 200
- 0: 200,
- // Support: IE <=9 only
- // #1450: sometimes IE returns 1223 when it should be 204
- 1223: 204
- },
- xhrSupported = jQuery.ajaxSettings.xhr();
- support.cors = !!xhrSupported && "withCredentials" in xhrSupported;
- support.ajax = xhrSupported = !!xhrSupported;
- jQuery.ajaxTransport(function (options) {
- var callback, errorCallback; // Cross domain only allowed if supported through XMLHttpRequest
- if (support.cors || xhrSupported && !options.crossDomain) {
- return {
- send: function (headers, complete) {
- var i,
- xhr = options.xhr();
- xhr.open(options.type, options.url, options.async, options.username, options.password); // Apply custom fields if provided
- if (options.xhrFields) {
- for (i in options.xhrFields) {
- xhr[i] = options.xhrFields[i];
- }
- } // Override mime type if needed
- if (options.mimeType && xhr.overrideMimeType) {
- xhr.overrideMimeType(options.mimeType);
- } // X-Requested-With header
- // For cross-domain requests, seeing as conditions for a preflight are
- // akin to a jigsaw puzzle, we simply never set it to be sure.
- // (it can always be set on a per-request basis or even using ajaxSetup)
- // For same-domain requests, won't change header if already provided.
- if (!options.crossDomain && !headers["X-Requested-With"]) {
- headers["X-Requested-With"] = "XMLHttpRequest";
- } // Set headers
- for (i in headers) {
- xhr.setRequestHeader(i, headers[i]);
- } // Callback
- callback = function (type) {
- return function () {
- if (callback) {
- callback = errorCallback = xhr.onload = xhr.onerror = xhr.onabort = xhr.ontimeout = xhr.onreadystatechange = null;
- if (type === "abort") {
- xhr.abort();
- } else if (type === "error") {
- // Support: IE <=9 only
- // On a manual native abort, IE9 throws
- // errors on any property access that is not readyState
- if (typeof xhr.status !== "number") {
- complete(0, "error");
- } else {
- complete( // File: protocol always yields status 0; see #8605, #14207
- xhr.status, xhr.statusText);
- }
- } else {
- complete(xhrSuccessStatus[xhr.status] || xhr.status, xhr.statusText, // Support: IE <=9 only
- // IE9 has no XHR2 but throws on binary (trac-11426)
- // For XHR2 non-text, let the caller handle it (gh-2498)
- (xhr.responseType || "text") !== "text" || typeof xhr.responseText !== "string" ? {
- binary: xhr.response
- } : {
- text: xhr.responseText
- }, xhr.getAllResponseHeaders());
- }
- }
- };
- }; // Listen to events
- xhr.onload = callback();
- errorCallback = xhr.onerror = xhr.ontimeout = callback("error"); // Support: IE 9 only
- // Use onreadystatechange to replace onabort
- // to handle uncaught aborts
- if (xhr.onabort !== undefined) {
- xhr.onabort = errorCallback;
- } else {
- xhr.onreadystatechange = function () {
- // Check readyState before timeout as it changes
- if (xhr.readyState === 4) {
- // Allow onerror to be called first,
- // but that will not handle a native abort
- // Also, save errorCallback to a variable
- // as xhr.onerror cannot be accessed
- window.setTimeout(function () {
- if (callback) {
- errorCallback();
- }
- });
- }
- };
- } // Create the abort callback
- callback = callback("abort");
- try {
- // Do send the request (this may raise an exception)
- xhr.send(options.hasContent && options.data || null);
- } catch (e) {
- // #14683: Only rethrow if this hasn't been notified as an error yet
- if (callback) {
- throw e;
- }
- }
- },
- abort: function () {
- if (callback) {
- callback();
- }
- }
- };
- }
- }); // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
- jQuery.ajaxPrefilter(function (s) {
- if (s.crossDomain) {
- s.contents.script = false;
- }
- }); // Install script dataType
- jQuery.ajaxSetup({
- accepts: {
- script: "text/javascript, application/javascript, " + "application/ecmascript, application/x-ecmascript"
- },
- contents: {
- script: /\b(?:java|ecma)script\b/
- },
- converters: {
- "text script": function (text) {
- jQuery.globalEval(text);
- return text;
- }
- }
- }); // Handle cache's special case and crossDomain
- jQuery.ajaxPrefilter("script", function (s) {
- if (s.cache === undefined) {
- s.cache = false;
- }
- if (s.crossDomain) {
- s.type = "GET";
- }
- }); // Bind script tag hack transport
- jQuery.ajaxTransport("script", function (s) {
- // This transport only deals with cross domain requests
- if (s.crossDomain) {
- var script, callback;
- return {
- send: function (_, complete) {
- script = jQuery("<script>").prop({
- charset: s.scriptCharset,
- src: s.url
- }).on("load error", callback = function (evt) {
- script.remove();
- callback = null;
- if (evt) {
- complete(evt.type === "error" ? 404 : 200, evt.type);
- }
- }); // Use native DOM manipulation to avoid our domManip AJAX trickery
- document.head.appendChild(script[0]);
- },
- abort: function () {
- if (callback) {
- callback();
- }
- }
- };
- }
- });
- var oldCallbacks = [],
- rjsonp = /(=)\?(?=&|$)|\?\?/; // Default jsonp settings
- jQuery.ajaxSetup({
- jsonp: "callback",
- jsonpCallback: function () {
- var callback = oldCallbacks.pop() || jQuery.expando + "_" + nonce++;
- this[callback] = true;
- return callback;
- }
- }); // Detect, normalize options and install callbacks for jsonp requests
- jQuery.ajaxPrefilter("json jsonp", function (s, originalSettings, jqXHR) {
- var callbackName,
- overwritten,
- responseContainer,
- jsonProp = s.jsonp !== false && (rjsonp.test(s.url) ? "url" : typeof s.data === "string" && (s.contentType || "").indexOf("application/x-www-form-urlencoded") === 0 && rjsonp.test(s.data) && "data"); // Handle iff the expected data type is "jsonp" or we have a parameter to set
- if (jsonProp || s.dataTypes[0] === "jsonp") {
- // Get callback name, remembering preexisting value associated with it
- callbackName = s.jsonpCallback = isFunction(s.jsonpCallback) ? s.jsonpCallback() : s.jsonpCallback; // Insert callback into url or form data
- if (jsonProp) {
- s[jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName);
- } else if (s.jsonp !== false) {
- s.url += (rquery.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName;
- } // Use data converter to retrieve json after script execution
- s.converters["script json"] = function () {
- if (!responseContainer) {
- jQuery.error(callbackName + " was not called");
- }
- return responseContainer[0];
- }; // Force json dataType
- s.dataTypes[0] = "json"; // Install callback
- overwritten = window[callbackName];
- window[callbackName] = function () {
- responseContainer = arguments;
- }; // Clean-up function (fires after converters)
- jqXHR.always(function () {
- // If previous value didn't exist - remove it
- if (overwritten === undefined) {
- jQuery(window).removeProp(callbackName); // Otherwise restore preexisting value
- } else {
- window[callbackName] = overwritten;
- } // Save back as free
- if (s[callbackName]) {
- // Make sure that re-using the options doesn't screw things around
- s.jsonpCallback = originalSettings.jsonpCallback; // Save the callback name for future use
- oldCallbacks.push(callbackName);
- } // Call if it was a function and we have a response
- if (responseContainer && isFunction(overwritten)) {
- overwritten(responseContainer[0]);
- }
- responseContainer = overwritten = undefined;
- }); // Delegate to script
- return "script";
- }
- }); // Support: Safari 8 only
- // In Safari 8 documents created via document.implementation.createHTMLDocument
- // collapse sibling forms: the second one becomes a child of the first one.
- // Because of that, this security measure has to be disabled in Safari 8.
- // https://bugs.webkit.org/show_bug.cgi?id=137337
- support.createHTMLDocument = function () {
- var body = document.implementation.createHTMLDocument("").body;
- body.innerHTML = "<form></form><form></form>";
- return body.childNodes.length === 2;
- }(); // Argument "data" should be string of html
- // context (optional): If specified, the fragment will be created in this context,
- // defaults to document
- // keepScripts (optional): If true, will include scripts passed in the html string
- jQuery.parseHTML = function (data, context, keepScripts) {
- if (typeof data !== "string") {
- return [];
- }
- if (typeof context === "boolean") {
- keepScripts = context;
- context = false;
- }
- var base, parsed, scripts;
- if (!context) {
- // Stop scripts or inline event handlers from being executed immediately
- // by using document.implementation
- if (support.createHTMLDocument) {
- context = document.implementation.createHTMLDocument(""); // Set the base href for the created document
- // so any parsed elements with URLs
- // are based on the document's URL (gh-2965)
- base = context.createElement("base");
- base.href = document.location.href;
- context.head.appendChild(base);
- } else {
- context = document;
- }
- }
- parsed = rsingleTag.exec(data);
- scripts = !keepScripts && []; // Single tag
- if (parsed) {
- return [context.createElement(parsed[1])];
- }
- parsed = buildFragment([data], context, scripts);
- if (scripts && scripts.length) {
- jQuery(scripts).remove();
- }
- return jQuery.merge([], parsed.childNodes);
- };
- /**
- * Load a url into a page
- */
- jQuery.fn.load = function (url, params, callback) {
- var selector,
- type,
- response,
- self = this,
- off = url.indexOf(" ");
- if (off > -1) {
- selector = stripAndCollapse(url.slice(off));
- url = url.slice(0, off);
- } // If it's a function
- if (isFunction(params)) {
- // We assume that it's the callback
- callback = params;
- params = undefined; // Otherwise, build a param string
- } else if (params && typeof params === "object") {
- type = "POST";
- } // If we have elements to modify, make the request
- if (self.length > 0) {
- jQuery.ajax({
- url: url,
- // If "type" variable is undefined, then "GET" method will be used.
- // Make value of this field explicit since
- // user can override it through ajaxSetup method
- type: type || "GET",
- dataType: "html",
- data: params
- }).done(function (responseText) {
- // Save response for use in complete callback
- response = arguments;
- self.html(selector ? // If a selector was specified, locate the right elements in a dummy div
- // Exclude scripts to avoid IE 'Permission Denied' errors
- jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) : // Otherwise use the full result
- responseText); // If the request succeeds, this function gets "data", "status", "jqXHR"
- // but they are ignored because response was set above.
- // If it fails, this function gets "jqXHR", "status", "error"
- }).always(callback && function (jqXHR, status) {
- self.each(function () {
- callback.apply(this, response || [jqXHR.responseText, status, jqXHR]);
- });
- });
- }
- return this;
- }; // Attach a bunch of functions for handling common AJAX events
- jQuery.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function (i, type) {
- jQuery.fn[type] = function (fn) {
- return this.on(type, fn);
- };
- });
- jQuery.expr.pseudos.animated = function (elem) {
- return jQuery.grep(jQuery.timers, function (fn) {
- return elem === fn.elem;
- }).length;
- };
- jQuery.offset = {
- setOffset: function (elem, options, i) {
- var curPosition,
- curLeft,
- curCSSTop,
- curTop,
- curOffset,
- curCSSLeft,
- calculatePosition,
- position = jQuery.css(elem, "position"),
- curElem = jQuery(elem),
- props = {}; // Set position first, in-case top/left are set even on static elem
- if (position === "static") {
- elem.style.position = "relative";
- }
- curOffset = curElem.offset();
- curCSSTop = jQuery.css(elem, "top");
- curCSSLeft = jQuery.css(elem, "left");
- calculatePosition = (position === "absolute" || position === "fixed") && (curCSSTop + curCSSLeft).indexOf("auto") > -1; // Need to be able to calculate position if either
- // top or left is auto and position is either absolute or fixed
- if (calculatePosition) {
- curPosition = curElem.position();
- curTop = curPosition.top;
- curLeft = curPosition.left;
- } else {
- curTop = parseFloat(curCSSTop) || 0;
- curLeft = parseFloat(curCSSLeft) || 0;
- }
- if (isFunction(options)) {
- // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
- options = options.call(elem, i, jQuery.extend({}, curOffset));
- }
- if (options.top != null) {
- props.top = options.top - curOffset.top + curTop;
- }
- if (options.left != null) {
- props.left = options.left - curOffset.left + curLeft;
- }
- if ("using" in options) {
- options.using.call(elem, props);
- } else {
- curElem.css(props);
- }
- }
- };
- jQuery.fn.extend({
- // offset() relates an element's border box to the document origin
- offset: function (options) {
- // Preserve chaining for setter
- if (arguments.length) {
- return options === undefined ? this : this.each(function (i) {
- jQuery.offset.setOffset(this, options, i);
- });
- }
- var rect,
- win,
- elem = this[0];
- if (!elem) {
- return;
- } // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
- // Support: IE <=11 only
- // Running getBoundingClientRect on a
- // disconnected node in IE throws an error
- if (!elem.getClientRects().length) {
- return {
- top: 0,
- left: 0
- };
- } // Get document-relative position by adding viewport scroll to viewport-relative gBCR
- rect = elem.getBoundingClientRect();
- win = elem.ownerDocument.defaultView;
- return {
- top: rect.top + win.pageYOffset,
- left: rect.left + win.pageXOffset
- };
- },
- // position() relates an element's margin box to its offset parent's padding box
- // This corresponds to the behavior of CSS absolute positioning
- position: function () {
- if (!this[0]) {
- return;
- }
- var offsetParent,
- offset,
- doc,
- elem = this[0],
- parentOffset = {
- top: 0,
- left: 0
- }; // position:fixed elements are offset from the viewport, which itself always has zero offset
- if (jQuery.css(elem, "position") === "fixed") {
- // Assume position:fixed implies availability of getBoundingClientRect
- offset = elem.getBoundingClientRect();
- } else {
- offset = this.offset(); // Account for the *real* offset parent, which can be the document or its root element
- // when a statically positioned element is identified
- doc = elem.ownerDocument;
- offsetParent = elem.offsetParent || doc.documentElement;
- while (offsetParent && (offsetParent === doc.body || offsetParent === doc.documentElement) && jQuery.css(offsetParent, "position") === "static") {
- offsetParent = offsetParent.parentNode;
- }
- if (offsetParent && offsetParent !== elem && offsetParent.nodeType === 1) {
- // Incorporate borders into its offset, since they are outside its content origin
- parentOffset = jQuery(offsetParent).offset();
- parentOffset.top += jQuery.css(offsetParent, "borderTopWidth", true);
- parentOffset.left += jQuery.css(offsetParent, "borderLeftWidth", true);
- }
- } // Subtract parent offsets and element margins
- return {
- top: offset.top - parentOffset.top - jQuery.css(elem, "marginTop", true),
- left: offset.left - parentOffset.left - jQuery.css(elem, "marginLeft", true)
- };
- },
- // This method will return documentElement in the following cases:
- // 1) For the element inside the iframe without offsetParent, this method will return
- // documentElement of the parent window
- // 2) For the hidden or detached element
- // 3) For body or html element, i.e. in case of the html node - it will return itself
- //
- // but those exceptions were never presented as a real life use-cases
- // and might be considered as more preferable results.
- //
- // This logic, however, is not guaranteed and can change at any point in the future
- offsetParent: function () {
- return this.map(function () {
- var offsetParent = this.offsetParent;
- while (offsetParent && jQuery.css(offsetParent, "position") === "static") {
- offsetParent = offsetParent.offsetParent;
- }
- return offsetParent || documentElement;
- });
- }
- }); // Create scrollLeft and scrollTop methods
- jQuery.each({
- scrollLeft: "pageXOffset",
- scrollTop: "pageYOffset"
- }, function (method, prop) {
- var top = "pageYOffset" === prop;
- jQuery.fn[method] = function (val) {
- return access(this, function (elem, method, val) {
- // Coalesce documents and windows
- var win;
- if (isWindow(elem)) {
- win = elem;
- } else if (elem.nodeType === 9) {
- win = elem.defaultView;
- }
- if (val === undefined) {
- return win ? win[prop] : elem[method];
- }
- if (win) {
- win.scrollTo(!top ? val : win.pageXOffset, top ? val : win.pageYOffset);
- } else {
- elem[method] = val;
- }
- }, method, val, arguments.length);
- };
- }); // Support: Safari <=7 - 9.1, Chrome <=37 - 49
- // Add the top/left cssHooks using jQuery.fn.position
- // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
- // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
- // getComputedStyle returns percent when specified for top/left/bottom/right;
- // rather than make the css module depend on the offset module, just check for it here
- jQuery.each(["top", "left"], function (i, prop) {
- jQuery.cssHooks[prop] = addGetHookIf(support.pixelPosition, function (elem, computed) {
- if (computed) {
- computed = curCSS(elem, prop); // If curCSS returns percentage, fallback to offset
- return rnumnonpx.test(computed) ? jQuery(elem).position()[prop] + "px" : computed;
- }
- });
- }); // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
- jQuery.each({
- Height: "height",
- Width: "width"
- }, function (name, type) {
- jQuery.each({
- padding: "inner" + name,
- content: type,
- "": "outer" + name
- }, function (defaultExtra, funcName) {
- // Margin is only for outerHeight, outerWidth
- jQuery.fn[funcName] = function (margin, value) {
- var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"),
- extra = defaultExtra || (margin === true || value === true ? "margin" : "border");
- return access(this, function (elem, type, value) {
- var doc;
- if (isWindow(elem)) {
- // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
- return funcName.indexOf("outer") === 0 ? elem["inner" + name] : elem.document.documentElement["client" + name];
- } // Get document width or height
- if (elem.nodeType === 9) {
- doc = elem.documentElement; // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
- // whichever is greatest
- return Math.max(elem.body["scroll" + name], doc["scroll" + name], elem.body["offset" + name], doc["offset" + name], doc["client" + name]);
- }
- return value === undefined ? // Get width or height on the element, requesting but not forcing parseFloat
- jQuery.css(elem, type, extra) : // Set width or height on the element
- jQuery.style(elem, type, value, extra);
- }, type, chainable ? margin : undefined, chainable);
- };
- });
- });
- jQuery.each(("blur focus focusin focusout resize scroll click dblclick " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "change select submit keydown keypress keyup contextmenu").split(" "), function (i, name) {
- // Handle event binding
- jQuery.fn[name] = function (data, fn) {
- return arguments.length > 0 ? this.on(name, null, data, fn) : this.trigger(name);
- };
- });
- jQuery.fn.extend({
- hover: function (fnOver, fnOut) {
- return this.mouseenter(fnOver).mouseleave(fnOut || fnOver);
- }
- });
- jQuery.fn.extend({
- bind: function (types, data, fn) {
- return this.on(types, null, data, fn);
- },
- unbind: function (types, fn) {
- return this.off(types, null, fn);
- },
- delegate: function (selector, types, data, fn) {
- return this.on(types, selector, data, fn);
- },
- undelegate: function (selector, types, fn) {
- // ( namespace ) or ( selector, types [, fn] )
- return arguments.length === 1 ? this.off(selector, "**") : this.off(types, selector || "**", fn);
- }
- }); // Bind a function to a context, optionally partially applying any
- // arguments.
- // jQuery.proxy is deprecated to promote standards (specifically Function#bind)
- // However, it is not slated for removal any time soon
- jQuery.proxy = function (fn, context) {
- var tmp, args, proxy;
- if (typeof context === "string") {
- tmp = fn[context];
- context = fn;
- fn = tmp;
- } // Quick check to determine if target is callable, in the spec
- // this throws a TypeError, but we will just return undefined.
- if (!isFunction(fn)) {
- return undefined;
- } // Simulated bind
- args = slice.call(arguments, 2);
- proxy = function () {
- return fn.apply(context || this, args.concat(slice.call(arguments)));
- }; // Set the guid of unique handler to the same of original handler, so it can be removed
- proxy.guid = fn.guid = fn.guid || jQuery.guid++;
- return proxy;
- };
- jQuery.holdReady = function (hold) {
- if (hold) {
- jQuery.readyWait++;
- } else {
- jQuery.ready(true);
- }
- };
- jQuery.isArray = Array.isArray;
- jQuery.parseJSON = JSON.parse;
- jQuery.nodeName = nodeName;
- jQuery.isFunction = isFunction;
- jQuery.isWindow = isWindow;
- jQuery.camelCase = camelCase;
- jQuery.type = toType;
- jQuery.now = Date.now;
- jQuery.isNumeric = function (obj) {
- // As of jQuery 3.0, isNumeric is limited to
- // strings and numbers (primitives or objects)
- // that can be coerced to finite numbers (gh-2662)
- var type = jQuery.type(obj);
- return (type === "number" || type === "string") && // parseFloat NaNs numeric-cast false positives ("")
- // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
- // subtraction forces infinities to NaN
- !isNaN(obj - parseFloat(obj));
- }; // Register as a named AMD module, since jQuery can be concatenated with other
- // files that may use define, but not via a proper concatenation script that
- // understands anonymous AMD modules. A named AMD is safest and most robust
- // way to register. Lowercase jquery is used because AMD module names are
- // derived from file names, and jQuery is normally delivered in a lowercase
- // file name. Do this after creating the global so that if an AMD module wants
- // to call noConflict to hide this version of jQuery, it will work.
- // Note that for maximum portability, libraries that are not jQuery should
- // declare themselves as anonymous modules, and avoid setting a global if an
- // AMD loader is present. jQuery is a special case. For more information, see
- // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () {
- return jQuery;
- }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
- __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- }
- var // Map over jQuery in case of overwrite
- _jQuery = window.jQuery,
- // Map over the $ in case of overwrite
- _$ = window.$;
- jQuery.noConflict = function (deep) {
- if (window.$ === jQuery) {
- window.$ = _$;
- }
- if (deep && window.jQuery === jQuery) {
- window.jQuery = _jQuery;
- }
- return jQuery;
- };
- if (!noGlobal) {
- window.jQuery = window.$ = jQuery;
- }
- return jQuery;
- });
- }),
- /* 23 */
- (function(module, exports, __webpack_require__) {
- //import JsSIP from 'jssip';
- var _JsSIP = __webpack_require__(24);
- var adapter = __webpack_require__(44);
- var _DetectRTC = __webpack_require__(20);
- var _PhoneLogger = __webpack_require__(59);
- var _PhoneNetwork = __webpack_require__(61);
- var PhoneJs = _JsSIP;
- var DetectRTC = _DetectRTC;
- var PhoneLogger = _PhoneLogger;
- var PhoneNetwork = _PhoneNetwork;
- var _default = {
- WS_IP: '13.228.213.46',
- WS_PORT: '10080',
- SIP_IP: '125.91.33.50',
- SIP_PORT: '8052'
- };
- function reloadDetectRTC(callback1, callback2) {
- DetectRTC.load(function () {
- // onDetectRTCLoaded();
- if (callback2 && typeof callback2 == 'function') {
- callback2();
- }
- if (callback1 && typeof callback1 == 'function') {
- callback1();
- }
- });
- }
- PhoneJs._def = _default;
- PhoneJs.DetectRTC = DetectRTC;
- PhoneJs.PhoneLogger = PhoneLogger;
- PhoneJs.PhoneNetwork = PhoneNetwork;
- module.exports = PhoneJs;
- module.exports.loadDetectRTC = function (callback) {
- DetectRTC.load(function () {
- reloadDetectRTC(null, callback);
- try {
- if (DetectRTC.MediaDevices[0] && DetectRTC.MediaDevices[0].isCustomLabel) {
- navigator.mediaDevices.getUserMedia({
- audio: true,
- video: true
- }).then(function (stream) {
- var video;
- try {
- video = document.createElement('video');
- video.muted = true;
- video.volume = 0;
- video.src = URL.createObjectURL(stream);
- video.style.display = 'none';
- video.style.opacity = 0;
- (document.body || document.documentElement).appendChild(vide);
- } catch (e) {}
- reloadDetectRTC(function () {
- // release camera
- stream.getTracks().forEach(function (track) {
- track.stop();
- });
- if (video && video.parentNode) {
- video.parentNode.removeChild(video);
- }
- }, callback);
- }).catch(reloadDetectRTC);
- return;
- }
- } catch (e) {}
- if (callback && typeof callback == 'function') {
- callback();
- }
- });
- }; //module.exports.JsSIP = _JsSIP;
- }),
- /* 24 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- var pkg = __webpack_require__(12);
- var C = __webpack_require__(1);
- var Exceptions = __webpack_require__(6);
- var Utils = __webpack_require__(2);
- var UA = __webpack_require__(25);
- var URI = __webpack_require__(8);
- var NameAddrHeader = __webpack_require__(11);
- var Grammar = __webpack_require__(3);
- var WebSocketInterface = __webpack_require__(43);
- var debug = __webpack_require__(0)('JsSIP');
- debug('version %s', pkg.version);
- /**
- * Expose the JsSIP module.
- */
- module.exports = {
- C: C,
- Exceptions: Exceptions,
- Utils: Utils,
- UA: UA,
- URI: URI,
- NameAddrHeader: NameAddrHeader,
- WebSocketInterface: WebSocketInterface,
- Grammar: Grammar,
- // Expose the debug module.
- debug: __webpack_require__(0),
- get name() {
- return pkg.title;
- },
- get version() {
- return pkg.version;
- }
- };
- }),
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _typeof(obj) {
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
- _typeof = function _typeof(obj) {
- return typeof obj;
- };
- } else {
- _typeof = function _typeof(obj) {
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
- };
- }
- return _typeof(obj);
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _possibleConstructorReturn(self, call) {
- if (call && (_typeof(call) === "object" || typeof call === "function")) {
- return call;
- }
- return _assertThisInitialized(self);
- }
- function _getPrototypeOf(o) {
- _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
- return o.__proto__ || Object.getPrototypeOf(o);
- };
- return _getPrototypeOf(o);
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- function _inherits(subClass, superClass) {
- if (typeof superClass !== "function" && superClass !== null) {
- throw new TypeError("Super expression must either be null or a function");
- }
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- writable: true,
- configurable: true
- }
- });
- if (superClass) _setPrototypeOf(subClass, superClass);
- }
- function _setPrototypeOf(o, p) {
- _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
- o.__proto__ = p;
- return o;
- };
- return _setPrototypeOf(o, p);
- }
- function _assertThisInitialized(self) {
- if (self === void 0) {
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- }
- return self;
- }
- var EventEmitter = __webpack_require__(7).EventEmitter;
- var JsSIP_C = __webpack_require__(1);
- var Registrator = __webpack_require__(26);
- var RTCSession = __webpack_require__(17);
- var Message = __webpack_require__(38);
- var Transactions = __webpack_require__(9);
- var Transport = __webpack_require__(39);
- var Utils = __webpack_require__(2);
- var Exceptions = __webpack_require__(6);
- var URI = __webpack_require__(8);
- var Grammar = __webpack_require__(3);
- var Parser = __webpack_require__(40);
- var SIPMessage = __webpack_require__(5);
- var sanityCheck = __webpack_require__(41);
- var config = __webpack_require__(42);
- var debug = __webpack_require__(0)('JsSIP:UA');
- var debugerror = __webpack_require__(0)('JsSIP:ERROR:UA');
- var PhoneLogger = __webpack_require__(59);
- debugerror.log = console.warn.bind(console);
- var C = {
- // UA status codes.
- STATUS_INIT: 0,
- STATUS_READY: 1,
- STATUS_USER_CLOSED: 2,
- STATUS_NOT_READY: 3,
- // UA error codes.
- CONFIGURATION_ERROR: 1,
- NETWORK_ERROR: 2
- };
- /**
- * The User-Agent class.
- * @class JsSIP.UA
- * @param {Object} configuration Configuration parameters.
- * @throws {JsSIP.Exceptions.ConfigurationError} If a configuration parameter is invalid.
- * @throws {TypeError} If no configuration is given.
- */
- module.exports =
- /*#__PURE__*/
- function (_EventEmitter) {
- _inherits(UA, _EventEmitter);
- _createClass(UA, null, [{
- key: "C",
- // Expose C object.
- get: function get() {
- return C;
- }
- }]);
- function setBandwidth(sdp, audio, video) {
- // remove existing bandwidth lines
- sdp = sdp.replace(/b=AS([^\r\n]+\r\n)/g, '');
- sdp = sdp.replace(/b=TIAS([^\r\n]+\r\n)/g, '');
- // audio bandwidth kilobits per second
- if(audio) {
- sdp = sdp.replace(/a=mid:audio\r\n/g, 'a=mid:audio\r\nb=AS:'+audio+'\r\n'+'b=TIAS:'+audio+'\r\n');
- }
-
- // video bandwidth kilobits per second
- if(video) {
- sdp = sdp.replace(/a=mid:video\r\n/g, 'a=mid:video\r\nb=AS:'+video+'\r\n'+'b=TIAS:'+video+'\r\n');
- }
-
- return sdp;
- }
- function UA(configuration) {
- var _this;
- _classCallCheck(this, UA);
- debug('new() [configuration:%o]', configuration);
- _this = _possibleConstructorReturn(this, _getPrototypeOf(UA).call(this));
- _this._cache = {
- credentials: {}
- };
- _this._configuration = Object.assign({}, config.settings);
- _this._dynConfiguration = {};
- _this._dialogs = {}; // User actions outside any session/dialog (MESSAGE).
- _this._applicants = {};
- _this._sessions = {};
- _this._transport = null;
- _this._contact = null;
- _this._status = C.STATUS_INIT;
- _this._error = null;
- _this._transactions = {
- nist: {},
- nict: {},
- ist: {},
- ict: {}
- }; // Custom UA empty object for high level use.
- _this._data = {};
- _this._closeTimer = null; // Check configuration argument.
- if (configuration === undefined) {
- throw new TypeError('Not enough arguments');
- } // Load configuration.
- try {
- _this._loadConfig(configuration);
- } catch (e) {
- _this._status = C.STATUS_NOT_READY;
- _this._error = C.CONFIGURATION_ERROR;
- throw e;
- } // Initialize registrator.
- _this._registrator = new Registrator(_assertThisInitialized(_assertThisInitialized(_this)));
- return _this;
- }
- _createClass(UA, [{
- key: "start",
- // =================
- // High Level API
- // =================
- /**
- * Connect to the server if status = STATUS_INIT.
- * Resume UA after being closed.
- */
- value: function start() {
- debug('start()');
- if (this._status === C.STATUS_INIT) {
- this._transport.connect();
- } else if (this._status === C.STATUS_USER_CLOSED) {
- debug('restarting UA'); // Disconnect.
- if (this._closeTimer !== null) {
- clearTimeout(this._closeTimer);
- this._closeTimer = null;
- this._transport.disconnect();
- } // Reconnect.
- this._status = C.STATUS_INIT;
- this._transport.connect();
- } else if (this._status === C.STATUS_READY) {
- debug('UA is in READY status, not restarted');
- } else {
- debug('ERROR: connection is down, Auto-Recovery system is trying to reconnect');
- } // Set dynamic configuration.
- this._dynConfiguration.register = this._configuration.register;
- }
- /**
- * Register.
- */
- }, {
- key: "register",
- value: function register() {
- debug('register()');
- this._dynConfiguration.register = true;
- this._registrator.register();
- }
- /**
- * Unregister.
- */
- }, {
- key: "unregister",
- value: function unregister(options) {
- debug('unregister()');
- this._dynConfiguration.register = false;
- this._registrator.unregister(options);
- }
- /**
- * Get the Registrator instance.
- */
- }, {
- key: "registrator",
- value: function registrator() {
- return this._registrator;
- }
- /**
- * Registration state.
- */
- }, {
- key: "isRegistered",
- value: function isRegistered() {
- return this._registrator.registered;
- }
- /**
- * Connection state.
- */
- }, {
- key: "isConnected",
- value: function isConnected() {
- return this._transport.isConnected();
- }
- /**
- * Make an outgoing call.
- *
- * -param {String} target
- * -param {Object} [options]
- *
- * -throws {TypeError}
- *
- */
- }, {
- key: "call",
- value: function call(target, options) {
- debug('call()');
- var session = new RTCSession(this);
- session.connect(target, options);
- return session;
- }
- /**
- * Send a message.
- *
- * -param {String} target
- * -param {String} body
- * -param {Object} [options]
- *
- * -throws {TypeError}
- *
- */
- },{
- key: 'setVideoBandwidth',
- value: function setVideoBandwidth(val) {
- debug('setVideoBandwidth()');
- this._videoBandwidth = val;
- }
- },{
- key: 'setAudioBandwidth',
- value: function setAudioBandwidth(val) {
- debug('setAudioBandwidth()');
- this._audioBandwidth = val;
- }
- }, {
- key: "sendMessage",
- value: function sendMessage(target, body, options) {
- debug('sendMessage()');
- var message = new Message(this);
- message.send(target, body, options);
- return message;
- }
- /**
- * Terminate ongoing sessions.
- */
- }, {
- key: "terminateSessions",
- value: function terminateSessions(options) {
- debug('terminateSessions()');
- for (var idx in this._sessions) {
- if (!this._sessions[idx].isEnded()) {
- this._sessions[idx].terminate(options);
- }
- }
- }
- /**
- * Gracefully close.
- *
- */
- }, {
- key: "stop",
- value: function stop() {
- var _this2 = this;
- debug('stop()'); // Remove dynamic settings.
- this._dynConfiguration = {};
- if (this._status === C.STATUS_USER_CLOSED) {
- debug('UA already closed');
- return;
- } // Close registrator.
- this._registrator.close(); // If there are session wait a bit so CANCEL/BYE can be sent and their responses received.
- var num_sessions = Object.keys(this._sessions).length; // Run _terminate_ on every Session.
- for (var session in this._sessions) {
- if (Object.prototype.hasOwnProperty.call(this._sessions, session)) {
- debug("closing session ".concat(session));
- try {
- this._sessions[session].terminate();
- } catch (error) {}
- }
- } // Run _close_ on every applicant.
- for (var applicant in this._applicants) {
- if (Object.prototype.hasOwnProperty.call(this._applicants, applicant)) try {
- this._applicants[applicant].close();
- } catch (error) {}
- }
- this._status = C.STATUS_USER_CLOSED;
- var num_transactions = Object.keys(this._transactions.nict).length + Object.keys(this._transactions.nist).length + Object.keys(this._transactions.ict).length + Object.keys(this._transactions.ist).length;
- if (num_transactions === 0 && num_sessions === 0) {
- this._transport.disconnect();
- } else {
- this._closeTimer = setTimeout(function () {
- _this2._closeTimer = null;
- _this2._transport.disconnect();
- }, 2000);
- }
- }
- /**
- * Normalice a string into a valid SIP request URI
- * -param {String} target
- * -returns {JsSIP.URI|undefined}
- */
- }, {
- key: "normalizeTarget",
- value: function normalizeTarget(target) {
- return Utils.normalizeTarget(target, this._configuration.hostport_params);
- }
- /**
- * Allow retrieving configuration and autogenerated fields in runtime.
- */
- }, {
- key: "get",
- value: function get(parameter) {
- switch (parameter) {
- case 'realm':
- return this._configuration.realm;
- case 'ha1':
- return this._configuration.ha1;
- default:
- debugerror('get() | cannot get "%s" parameter in runtime', parameter);
- return undefined;
- }
- }
- /**
- * Allow configuration changes in runtime.
- * Returns true if the parameter could be set.
- */
- }, {
- key: "set",
- value: function set(parameter, value) {
- switch (parameter) {
- case 'password':
- {
- this._configuration.password = String(value);
- break;
- }
- case 'realm':
- {
- this._configuration.realm = String(value);
- break;
- }
- case 'ha1':
- {
- this._configuration.ha1 = String(value); // Delete the plain SIP password.
- this._configuration.password = null;
- break;
- }
- case 'display_name':
- {
- if (Grammar.parse("\"".concat(value, "\""), 'display_name') === -1) {
- debugerror('set() | wrong "display_name"');
- return false;
- }
- this._configuration.display_name = value;
- break;
- }
- default:
- debugerror('set() | cannot set "%s" parameter in runtime', parameter);
- return false;
- }
- return true;
- } // ==========================
- // Event Handlers.
- // ==========================
- /**
- * new Transaction
- */
- }, {
- key: "newTransaction",
- value: function newTransaction(transaction) {
- this._transactions[transaction.type][transaction.id] = transaction;
- this.emit('newTransaction', {
- transaction: transaction
- });
- }
- /**
- * Transaction destroyed.
- */
- }, {
- key: "destroyTransaction",
- value: function destroyTransaction(transaction) {
- delete this._transactions[transaction.type][transaction.id];
- this.emit('transactionDestroyed', {
- transaction: transaction
- });
- }
- /**
- * new Dialog
- */
- }, {
- key: "newDialog",
- value: function newDialog(dialog) {
- this._dialogs[dialog.id] = dialog;
- }
- /**
- * Dialog destroyed.
- */
- }, {
- key: "destroyDialog",
- value: function destroyDialog(dialog) {
- delete this._dialogs[dialog.id];
- }
- /**
- * new Message
- */
- }, {
- key: "newMessage",
- value: function newMessage(message, data) {
- this._applicants[message] = message;
- this.emit('newMessage', data);
- }
- /**
- * Message destroyed.
- */
- }, {
- key: "destroyMessage",
- value: function destroyMessage(message) {
- delete this._applicants[message];
- }
- /**
- * new RTCSession
- */
- }, {
- key: "newRTCSession",
- value: function newRTCSession(session, data) {
- var videoBandwidth = this._videoBandwidth;
- var audioBandwidth = this._audioBandwidth;
- session.on('sdp', function (e) {
- var sdp = e.sdp;
-
- e.sdp = setBandwidth(sdp, audioBandwidth, videoBandwidth);
- });
- this._sessions[session.id] = session;
- this.emit('newRTCSession', data);
- }
- /**
- * RTCSession destroyed.
- */
- }, {
- key: "destroyRTCSession",
- value: function destroyRTCSession(session) {
- delete this._sessions[session.id];
- }
- /**
- * Registered
- */
- }, {
- key: "registered",
- value: function registered(data) {
- var user;
- if (data.response.headers.From[0]) {
- var _from = data.response.headers.From[0].raw;
- // const from = _from.match(new RegExp(' ' + "(.*)" + ';'));
- // user = from[1] ? from[1] : '';
- user = _from;
- }
- PhoneLogger.user = user;
- // console.log(PhoneLogger.user);
- PhoneLogger.info({
- event: "registered",
- data: data
- });
- this.emit('registered', data);
- }
- /**
- * Unregistered
- */
- }, {
- key: "unregistered",
- value: function unregistered(data) {
- PhoneLogger.info({
- event: "unregistered",
- data: data
- });
- this.emit('unregistered', data);
- }
- /**
- * Registration Failed
- */
- }, {
- key: "registrationFailed",
- value: function registrationFailed(data) {
- PhoneLogger.error({
- event: "registrationFailed",
- data: data
- });
- this.emit('registrationFailed', data);
- } // =========================
- // ReceiveRequest.
- // =========================
- /**
- * Request reception
- */
- }, {
- key: "receiveRequest",
- value: function receiveRequest(request) {
- var method = request.method; // Check that request URI points to us.
- if (request.ruri.user !== this._configuration.uri.user && request.ruri.user !== this._contact.uri.user) {
- debug('Request-URI does not point to us');
- if (request.method !== JsSIP_C.ACK) {
- request.reply_sl(404);
- }
- return;
- } // Check request URI scheme.
- if (request.ruri.scheme === JsSIP_C.SIPS) {
- request.reply_sl(416);
- return;
- } // Check transaction.
- if (Transactions.checkTransaction(this, request)) {
- return;
- } // Create the server transaction.
- if (method === JsSIP_C.INVITE) {
- /* eslint-disable no-new */
- new Transactions.InviteServerTransaction(this, this._transport, request);
- /* eslint-enable no-new */
- } else if (method !== JsSIP_C.ACK && method !== JsSIP_C.CANCEL) {
- /* eslint-disable no-new */
- new Transactions.NonInviteServerTransaction(this, this._transport, request);
- /* eslint-enable no-new */
- }
- /* RFC3261 12.2.2
- * Requests that do not change in any way the state of a dialog may be
- * received within a dialog (for example, an OPTIONS request).
- * They are processed as if they had been received outside the dialog.
- */
- if (method === JsSIP_C.OPTIONS) {
- request.reply(200);
- } else if (method === JsSIP_C.MESSAGE) {
- if (this.listeners('newMessage').length === 0) {
- request.reply(405);
- return;
- }
- var message = new Message(this);
- message.init_incoming(request);
- } else if (method === JsSIP_C.INVITE) {
- // Initial INVITE.
- if (!request.to_tag && this.listeners('newRTCSession').length === 0) {
- request.reply(405);
- return;
- }
- }
- var dialog;
- var session; // Initial Request.
- if (!request.to_tag) {
- switch (method) {
- case JsSIP_C.INVITE:
- if (window.RTCPeerConnection) {
- // TODO
- if (request.hasHeader('replaces')) {
- var replaces = request.replaces;
- dialog = this._findDialog(replaces.call_id, replaces.from_tag, replaces.to_tag);
- if (dialog) {
- session = dialog.owner;
- if (!session.isEnded()) {
- session.receiveRequest(request);
- } else {
- request.reply(603);
- }
- } else {
- request.reply(481);
- }
- } else {
- session = new RTCSession(this);
- session.init_incoming(request);
- }
- } else {
- debugerror('INVITE received but WebRTC is not supported');
- request.reply(488);
- }
- break;
- case JsSIP_C.BYE:
- // Out of dialog BYE received.
- request.reply(481);
- break;
- case JsSIP_C.CANCEL:
- session = this._findSession(request);
- if (session) {
- session.receiveRequest(request);
- } else {
- debug('received CANCEL request for a non existent session');
- }
- break;
- case JsSIP_C.ACK:
- /* Absorb it.
- * ACK request without a corresponding Invite Transaction
- * and without To tag.
- */
- break;
- case JsSIP_C.NOTIFY:
- // Receive new sip event.
- this.emit('sipEvent', {
- event: request.event,
- request: request
- });
- request.reply(200);
- break;
- default:
- request.reply(405);
- break;
- }
- } // In-dialog request.
- else {
- dialog = this._findDialog(request.call_id, request.from_tag, request.to_tag);
- if (dialog) {
- dialog.receiveRequest(request);
- } else if (method === JsSIP_C.NOTIFY) {
- session = this._findSession(request);
- if (session) {
- session.receiveRequest(request);
- } else {
- debug('received NOTIFY request for a non existent subscription');
- request.reply(481, 'Subscription does not exist');
- }
- }
- /* RFC3261 12.2.2
- * Request with to tag, but no matching dialog found.
- * Exception: ACK for an Invite request for which a dialog has not
- * been created.
- */
- else if (method !== JsSIP_C.ACK) {
- request.reply(481);
- }
- }
- } // =================
- // Utils.
- // =================
- /**
- * Get the session to which the request belongs to, if any.
- */
- }, {
- key: "_findSession",
- value: function _findSession(_ref) {
- var call_id = _ref.call_id,
- from_tag = _ref.from_tag,
- to_tag = _ref.to_tag;
- var sessionIDa = call_id + from_tag;
- var sessionA = this._sessions[sessionIDa];
- var sessionIDb = call_id + to_tag;
- var sessionB = this._sessions[sessionIDb];
- if (sessionA) {
- return sessionA;
- } else if (sessionB) {
- return sessionB;
- } else {
- return null;
- }
- }
- /**
- * Get the dialog to which the request belongs to, if any.
- */
- }, {
- key: "_findDialog",
- value: function _findDialog(call_id, from_tag, to_tag) {
- var id = call_id + from_tag + to_tag;
- var dialog = this._dialogs[id];
- if (dialog) {
- return dialog;
- } else {
- id = call_id + to_tag + from_tag;
- dialog = this._dialogs[id];
- if (dialog) {
- return dialog;
- } else {
- return null;
- }
- }
- }
- }, {
- key: "_loadConfig",
- value: function _loadConfig(configuration) {
- // Check and load the given configuration.
- try {
- config.load(this._configuration, configuration);
- } catch (e) {
- throw e;
- } // Post Configuration Process.
- // Allow passing 0 number as display_name.
- if (this._configuration.display_name === 0) {
- this._configuration.display_name = '0';
- } // Instance-id for GRUU.
- if (!this._configuration.instance_id) {
- this._configuration.instance_id = Utils.newUUID();
- } // Jssip_id instance parameter. Static random tag of length 5.
- this._configuration.jssip_id = Utils.createRandomToken(5); // String containing this._configuration.uri without scheme and user.
- var hostport_params = this._configuration.uri.clone();
- hostport_params.user = null;
- this._configuration.hostport_params = hostport_params.toString().replace(/^sip:/i, ''); // Transport.
- try {
- this._transport = new Transport(this._configuration.sockets, {
- // Recovery options.
- max_interval: this._configuration.connection_recovery_max_interval,
- min_interval: this._configuration.connection_recovery_min_interval
- }); // Transport event callbacks.
- this._transport.onconnecting = onTransportConnecting.bind(this);
- this._transport.onconnect = onTransportConnect.bind(this);
- this._transport.ondisconnect = onTransportDisconnect.bind(this);
- this._transport.ondata = onTransportData.bind(this);
- } catch (e) {
- debugerror(e);
- throw new Exceptions.ConfigurationError('sockets', this._configuration.sockets);
- } // Remove sockets instance from configuration object.
- delete this._configuration.sockets; // Check whether authorization_user is explicitly defined.
- // Take 'this._configuration.uri.user' value if not.
- if (!this._configuration.authorization_user) {
- this._configuration.authorization_user = this._configuration.uri.user;
- } // If no 'registrar_server' is set use the 'uri' value without user portion and
- // without URI params/headers.
- if (!this._configuration.registrar_server) {
- var registrar_server = this._configuration.uri.clone();
- registrar_server.user = null;
- registrar_server.clearParams();
- registrar_server.clearHeaders();
- this._configuration.registrar_server = registrar_server;
- } // User no_answer_timeout.
- this._configuration.no_answer_timeout *= 1000; // Via Host.
- if (this._configuration.contact_uri) {
- this._configuration.via_host = this._configuration.contact_uri.host;
- } // Contact URI.
- else {
- this._configuration.contact_uri = new URI('sip', Utils.createRandomToken(8), this._configuration.via_host, null, {
- transport: 'ws'
- });
- }
- this._contact = {
- pub_gruu: null,
- temp_gruu: null,
- uri: this._configuration.contact_uri,
- toString: function toString() {
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- var anonymous = options.anonymous || null;
- var outbound = options.outbound || null;
- var contact = '<';
- if (anonymous) {
- contact += this.temp_gruu || 'sip:anonymous@anonymous.invalid;transport=ws';
- } else {
- contact += this.pub_gruu || this.uri.toString();
- }
-
- contact += '>';
- return contact;
- }
- }; // Seal the configuration.
- var writable_parameters = ['password', 'realm', 'ha1', 'display_name', 'register'];
- for (var parameter in this._configuration) {
- if (Object.prototype.hasOwnProperty.call(this._configuration, parameter)) {
- if (writable_parameters.indexOf(parameter) !== -1) {
- Object.defineProperty(this._configuration, parameter, {
- writable: true,
- configurable: false
- });
- } else {
- Object.defineProperty(this._configuration, parameter, {
- writable: false,
- configurable: false
- });
- }
- }
- }
- debug('configuration parameters after validation:');
- for (var _parameter in this._configuration) {
- // Only show the user user configurable parameters.
- if (Object.prototype.hasOwnProperty.call(config.settings, _parameter)) {
- switch (_parameter) {
- case 'uri':
- case 'registrar_server':
- debug("- ".concat(_parameter, ": ").concat(this._configuration[_parameter]));
- break;
- case 'password':
- case 'ha1':
- debug("- ".concat(_parameter, ": NOT SHOWN"));
- break;
- default:
- debug("- ".concat(_parameter, ": ").concat(JSON.stringify(this._configuration[_parameter])));
- }
- }
- }
- return;
- }
- }, {
- key: "C",
- get: function get() {
- return C;
- }
- }, {
- key: "status",
- get: function get() {
- return this._status;
- }
- }, {
- key: "contact",
- get: function get() {
- return this._contact;
- }
- }, {
- key: "configuration",
- get: function get() {
- return this._configuration;
- }
- }, {
- key: "transport",
- get: function get() {
- return this._transport;
- }
- }]);
- return UA;
- }(EventEmitter);
- /**
- * Transport event handlers
- */
- // Transport connecting event.
- function onTransportConnecting(data) {
- this.emit('connecting', data);
- } // Transport connected event.
- function onTransportConnect(data) {
- if (this._status === C.STATUS_USER_CLOSED) {
- return;
- }
- this._status = C.STATUS_READY;
- this._error = null;
- this.emit('connected', data);
- if (this._dynConfiguration.register) {
- this._registrator.register();
- }
- } // Transport disconnected event.
- function onTransportDisconnect(data) {
- // Run _onTransportError_ callback on every client transaction using _transport_.
- var client_transactions = ['nict', 'ict', 'nist', 'ist'];
- for (var _i = 0; _i < client_transactions.length; _i++) {
- var type = client_transactions[_i];
- for (var id in this._transactions[type]) {
- if (Object.prototype.hasOwnProperty.call(this._transactions[type], id)) {
- this._transactions[type][id].onTransportError();
- }
- }
- }
- this.emit('disconnected', data); // Call registrator _onTransportClosed_.
- this._registrator.onTransportClosed();
- if (this._status !== C.STATUS_USER_CLOSED) {
- this._status = C.STATUS_NOT_READY;
- this._error = C.NETWORK_ERROR;
- }
- } // Transport data event.
- function onTransportData(data) {
- var transport = data.transport;
- var message = data.message;
- message = Parser.parseMessage(message, this);
- if (!message) {
- return;
- }
- if (this._status === C.STATUS_USER_CLOSED && message instanceof SIPMessage.IncomingRequest) {
- return;
- } // Do some sanity check.
- if (!sanityCheck(message, this, transport)) {
- return;
- }
- if (message instanceof SIPMessage.IncomingRequest) {
- message.transport = transport;
- this.receiveRequest(message);
- } else if (message instanceof SIPMessage.IncomingResponse) {
- /* Unike stated in 18.1.2, if a response does not match
- * any transaction, it is discarded here and no passed to the core
- * in order to be discarded there.
- */
- var transaction;
- switch (message.method) {
- case JsSIP_C.INVITE:
- transaction = this._transactions.ict[message.via_branch];
- if (transaction) {
- transaction.receiveResponse(message);
- }
- break;
- case JsSIP_C.ACK:
- // Just in case ;-).
- break;
- default:
- transaction = this._transactions.nict[message.via_branch];
- if (transaction) {
- transaction.receiveResponse(message);
- }
- break;
- }
- }
- }
- }),
- /* 26 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- var Utils = __webpack_require__(2);
- var JsSIP_C = __webpack_require__(1);
- var SIPMessage = __webpack_require__(5);
- var RequestSender = __webpack_require__(10);
- var debug = __webpack_require__(0)('JsSIP:Registrator');
- var MIN_REGISTER_EXPIRES = 10; // In seconds.
- module.exports =
- /*#__PURE__*/
- function () {
- function Registrator(ua, transport) {
- _classCallCheck(this, Registrator);
- var reg_id = 1; // Force reg_id to 1.
- this._ua = ua;
- this._transport = transport;
- this._registrar = ua.configuration.registrar_server;
- this._expires = ua.configuration.register_expires; // Call-ID and CSeq values RFC3261 10.2.
- this._call_id = Utils.createRandomToken(22);
- this._cseq = 0;
- this._to_uri = ua.configuration.uri;
- this._registrationTimer = null; // Ongoing Register request.
- this._registering = false; // Set status.
- this._registered = false; // Contact header.
- this._contact = this._ua.contact.toString(); // Sip.ice media feature tag (RFC 5768).
- this._contact += ';+sip.ice'; // Custom headers for REGISTER and un-REGISTER.
- this._extraHeaders = []; // Custom Contact header params for REGISTER and un-REGISTER.
- this._extraContactParams = '';
- if (reg_id) {
- this._contact += ";reg-id=".concat(reg_id);
- this._contact += ";+sip.instance=\"<urn:uuid:".concat(this._ua.configuration.instance_id, ">\"");
- }
-
- }
- _createClass(Registrator, [{
- key: "setExtraHeaders",
- value: function setExtraHeaders(extraHeaders) {
- if (!Array.isArray(extraHeaders)) {
- extraHeaders = [];
- }
- this._extraHeaders = extraHeaders.slice();
- }
- }, {
- key: "setExtraContactParams",
- value: function setExtraContactParams(extraContactParams) {
- if (!(extraContactParams instanceof Object)) {
- extraContactParams = {};
- } // Reset it.
- this._extraContactParams = '';
- for (var param_key in extraContactParams) {
- if (Object.prototype.hasOwnProperty.call(extraContactParams, param_key)) {
- var param_value = extraContactParams[param_key];
- this._extraContactParams += ";".concat(param_key);
- if (param_value) {
- this._extraContactParams += "=".concat(param_value);
- }
- }
- }
- }
- }, {
- key: "register",
- value: function register() {
- var _this = this;
- if (this._registering) {
- debug('Register request in progress...');
- return;
- }
- var extraHeaders = this._extraHeaders.slice();
- extraHeaders.push("Contact: ".concat(this._contact, ";expires=").concat(this._expires).concat(this._extraContactParams));
- extraHeaders.push("Expires: ".concat(this._expires));
- var request = new SIPMessage.OutgoingRequest(JsSIP_C.REGISTER, this._registrar, this._ua, {
- 'to_uri': this._to_uri,
- 'call_id': this._call_id,
- 'cseq': this._cseq += 1
- }, extraHeaders);
- var request_sender = new RequestSender(this._ua, request, {
- onRequestTimeout: function onRequestTimeout() {
- _this._registrationFailure(null, JsSIP_C.causes.REQUEST_TIMEOUT);
- },
- onTransportError: function onTransportError() {
- _this._registrationFailure(null, JsSIP_C.causes.CONNECTION_ERROR);
- },
- // Increase the CSeq on authentication.
- onAuthenticated: function onAuthenticated() {
- _this._cseq += 1;
- },
- onReceiveResponse: function onReceiveResponse(response) {
- // Discard responses to older REGISTER/un-REGISTER requests.
- if (response.cseq !== _this._cseq) {
- return;
- } // Clear registration timer.
- if (_this._registrationTimer !== null) {
- clearTimeout(_this._registrationTimer);
- _this._registrationTimer = null;
- }
- switch (true) {
- case /^1[0-9]{2}$/.test(response.status_code):
- {
- // Ignore provisional responses.
- break;
- }
- case /^2[0-9]{2}$/.test(response.status_code):
- {
- _this._registering = false;
- if (!response.hasHeader('Contact')) {
- debug('no Contact header in response to REGISTER, response ignored');
- break;
- }
- var contacts = response.headers['Contact'].reduce(function (a, b) {
- return a.concat(b.parsed);
- }, []); // Get the Contact pointing to us and update the expires value accordingly.
- var contact = contacts.find(function (element) {
- return element.uri.user === _this._ua.contact.uri.user;
- });
- if (!contact) {
- debug('no Contact header pointing to us, response ignored');
- break;
- }
- var expires = contact.getParam('expires');
- if (!expires && response.hasHeader('expires')) {
- expires = response.getHeader('expires');
- }
- if (!expires) {
- expires = _this._expires;
- }
- expires = Number(expires);
- if (expires < MIN_REGISTER_EXPIRES) expires = MIN_REGISTER_EXPIRES; // Re-Register or emit an event before the expiration interval has elapsed.
- // For that, decrease the expires value. ie: 3 seconds.
- _this._registrationTimer = setTimeout(function () {
- _this._registrationTimer = null; // If there are no listeners for registrationExpiring, renew registration.
- // If there are listeners, let the function listening do the register call.
- if (_this._ua.listeners('registrationExpiring').length === 0) {
- _this.register();
- } else {
- _this._ua.emit('registrationExpiring');
- }
- }, expires * 1000 - 5000); // Save gruu values.
- if (contact.hasParam('temp-gruu')) {
- _this._ua.contact.temp_gruu = contact.getParam('temp-gruu').replace(/"/g, '');
- }
- if (contact.hasParam('pub-gruu')) {
- _this._ua.contact.pub_gruu = contact.getParam('pub-gruu').replace(/"/g, '');
- }
- if (!_this._registered) {
- _this._registered = true;
- _this._ua.registered({
- response: response
- });
- }
- break;
- }
- // Interval too brief RFC3261 10.2.8.
- case /^423$/.test(response.status_code):
- {
- if (response.hasHeader('min-expires')) {
- // Increase our registration interval to the suggested minimum.
- _this._expires = Number(response.getHeader('min-expires'));
- if (_this._expires < MIN_REGISTER_EXPIRES) _this._expires = MIN_REGISTER_EXPIRES; // Attempt the registration again immediately.
- _this.register();
- } else {
- // This response MUST contain a Min-Expires header field.
- debug('423 response received for REGISTER without Min-Expires');
- _this._registrationFailure(response, JsSIP_C.causes.SIP_FAILURE_CODE);
- }
- break;
- }
- default:
- {
- var cause = Utils.sipErrorCause(response.status_code);
- _this._registrationFailure(response, cause);
- }
- }
- }
- });
- this._registering = true;
- request_sender.send();
- }
- }, {
- key: "unregister",
- value: function unregister() {
- var _this2 = this;
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- if (!this._registered) {
- debug('already unregistered');
- return;
- }
- this._registered = false; // Clear the registration timer.
- if (this._registrationTimer !== null) {
- clearTimeout(this._registrationTimer);
- this._registrationTimer = null;
- }
- var extraHeaders = this._extraHeaders.slice();
- if (options.all) {
- extraHeaders.push("Contact: *".concat(this._extraContactParams));
- } else {
- extraHeaders.push("Contact: ".concat(this._contact, ";expires=0").concat(this._extraContactParams));
- }
- extraHeaders.push('Expires: 0');
- var request = new SIPMessage.OutgoingRequest(JsSIP_C.REGISTER, this._registrar, this._ua, {
- 'to_uri': this._to_uri,
- 'call_id': this._call_id,
- 'cseq': this._cseq += 1
- }, extraHeaders);
- var request_sender = new RequestSender(this._ua, request, {
- onRequestTimeout: function onRequestTimeout() {
- _this2._unregistered(null, JsSIP_C.causes.REQUEST_TIMEOUT);
- },
- onTransportError: function onTransportError() {
- _this2._unregistered(null, JsSIP_C.causes.CONNECTION_ERROR);
- },
- // Increase the CSeq on authentication.
- onAuthenticated: function onAuthenticated() {
- _this2._cseq += 1;
- },
- onReceiveResponse: function onReceiveResponse(response) {
- switch (true) {
- case /^1[0-9]{2}$/.test(response.status_code):
- // Ignore provisional responses.
- break;
- case /^2[0-9]{2}$/.test(response.status_code):
- _this2._unregistered(response);
- break;
- default:
- {
- var cause = Utils.sipErrorCause(response.status_code);
- _this2._unregistered(response, cause);
- }
- }
- }
- });
- request_sender.send();
- }
- }, {
- key: "close",
- value: function close() {
- if (this._registered) {
- this.unregister();
- }
- }
- }, {
- key: "onTransportClosed",
- value: function onTransportClosed() {
- this._registering = false;
- if (this._registrationTimer !== null) {
- clearTimeout(this._registrationTimer);
- this._registrationTimer = null;
- }
- if (this._registered) {
- this._registered = false;
- this._ua.unregistered({});
- }
- }
- }, {
- key: "_registrationFailure",
- value: function _registrationFailure(response, cause) {
- this._registering = false;
- this._ua.registrationFailed({
- response: response || null,
- cause: cause
- });
- if (this._registered) {
- this._registered = false;
- this._ua.unregistered({
- response: response || null,
- cause: cause
- });
- }
- }
- }, {
- key: "_unregistered",
- value: function _unregistered(response, cause) {
- this._registering = false;
- this._registered = false;
- this._ua.unregistered({
- response: response || null,
- cause: cause || null
- });
- }
- }, {
- key: "registered",
- get: function get() {
- return this._registered;
- }
- }]);
- return Registrator;
- }();
- }),
- /* 27 */
- (function(module, exports, __webpack_require__) {
- var toIntIfInt = function (v) {
- return String(Number(v)) === v ? Number(v) : v;
- };
- var attachProperties = function (match, location, names, rawName) {
- if (rawName && !names) {
- location[rawName] = toIntIfInt(match[1]);
- } else {
- for (var i = 0; i < names.length; i += 1) {
- if (match[i + 1] != null) {
- location[names[i]] = toIntIfInt(match[i + 1]);
- }
- }
- }
- };
- var parseReg = function (obj, location, content) {
- var needsBlank = obj.name && obj.names;
- if (obj.push && !location[obj.push]) {
- location[obj.push] = [];
- } else if (needsBlank && !location[obj.name]) {
- location[obj.name] = {};
- }
- var keyLocation = obj.push ? {} : // blank object that will be pushed
- needsBlank ? location[obj.name] : location; // otherwise, named location or root
- attachProperties(content.match(obj.reg), keyLocation, obj.names, obj.name);
- if (obj.push) {
- location[obj.push].push(keyLocation);
- }
- };
- var grammar = __webpack_require__(14);
- var validLine = RegExp.prototype.test.bind(/^([a-z])=(.*)/);
- exports.parse = function (sdp) {
- var session = {},
- media = [],
- location = session; // points at where properties go under (one of the above)
- // parse lines we understand
- sdp.split(/(\r\n|\r|\n)/).filter(validLine).forEach(function (l) {
- var type = l[0];
- var content = l.slice(2);
- if (type === 'm') {
- media.push({
- rtp: [],
- fmtp: []
- });
- location = media[media.length - 1]; // point at latest media line
- }
- for (var j = 0; j < (grammar[type] || []).length; j += 1) {
- var obj = grammar[type][j];
- if (obj.reg.test(content)) {
- return parseReg(obj, location, content);
- }
- }
- });
- session.media = media; // link it up
- return session;
- };
- var paramReducer = function (acc, expr) {
- var s = expr.split(/=(.+)/, 2);
- if (s.length === 2) {
- acc[s[0]] = toIntIfInt(s[1]);
- } else if (s.length === 1 && expr.length > 1) {
- acc[s[0]] = undefined;
- }
- return acc;
- };
- exports.parseParams = function (str) {
- return str.split(/\;\s?/).reduce(paramReducer, {});
- }; // For backward compatibility - alias will be removed in 3.0.0
- exports.parseFmtpConfig = exports.parseParams;
- exports.parsePayloads = function (str) {
- return str.split(' ').map(Number);
- };
- exports.parseRemoteCandidates = function (str) {
- var candidates = [];
- var parts = str.split(' ').map(toIntIfInt);
- for (var i = 0; i < parts.length; i += 3) {
- candidates.push({
- component: parts[i],
- ip: parts[i + 1],
- port: parts[i + 2]
- });
- }
- return candidates;
- };
- exports.parseImageAttributes = function (str) {
- return str.split(' ').map(function (item) {
- return item.substring(1, item.length - 1).split(',').reduce(paramReducer, {});
- });
- };
- exports.parseSimulcastStreamList = function (str) {
- return str.split(';').map(function (stream) {
- return stream.split(',').map(function (format) {
- var scid,
- paused = false;
- if (format[0] !== '~') {
- scid = toIntIfInt(format);
- } else {
- scid = toIntIfInt(format.substring(1, format.length));
- paused = true;
- }
- return {
- scid: scid,
- paused: paused
- };
- });
- });
- };
- }),
- /* 28 */
- (function(module, exports, __webpack_require__) {
- var grammar = __webpack_require__(14); // customized janus.format - discards excess arguments and can void middle ones
- var formatRegExp = /%[sdv%]/g;
- var format = function (formatStr) {
- var i = 1;
- var args = arguments;
- var len = args.length;
- return formatStr.replace(formatRegExp, function (x) {
- if (i >= len) {
- return x; // missing argument
- }
- var arg = args[i];
- i += 1;
- switch (x) {
- case '%%':
- return '%';
- case '%s':
- return String(arg);
- case '%d':
- return Number(arg);
- case '%v':
- return '';
- }
- }); // NB: we discard excess arguments - they are typically undefined from makeLine
- };
- var makeLine = function (type, obj, location) {
- var str = obj.format instanceof Function ? obj.format(obj.push ? location : location[obj.name]) : obj.format;
- var args = [type + '=' + str];
- if (obj.names) {
- for (var i = 0; i < obj.names.length; i += 1) {
- var n = obj.names[i];
- if (obj.name) {
- args.push(location[obj.name][n]);
- } else {
- // for mLine and push attributes
- args.push(location[obj.names[i]]);
- }
- }
- } else {
- args.push(location[obj.name]);
- }
- return format.apply(null, args);
- }; // RFC specified order
- // TODO: extend this with all the rest
- var defaultOuterOrder = ['v', 'o', 's', 'i', 'u', 'e', 'p', 'c', 'b', 't', 'r', 'z', 'a'];
- var defaultInnerOrder = ['i', 'c', 'b', 'a'];
- module.exports = function (session, opts) {
- opts = opts || {}; // ensure certain properties exist
- if (session.version == null) {
- session.version = 0; // 'v=0' must be there (only defined version atm)
- }
- if (session.name == null) {
- session.name = ' '; // 's= ' must be there if no meaningful name set
- }
- session.media.forEach(function (mLine) {
- if (mLine.payloads == null) {
- mLine.payloads = '';
- }
- });
- var outerOrder = opts.outerOrder || defaultOuterOrder;
- var innerOrder = opts.innerOrder || defaultInnerOrder;
- var sdp = []; // loop through outerOrder for matching properties on session
- outerOrder.forEach(function (type) {
- grammar[type].forEach(function (obj) {
- if (obj.name in session && session[obj.name] != null) {
- sdp.push(makeLine(type, obj, session));
- } else if (obj.push in session && session[obj.push] != null) {
- session[obj.push].forEach(function (el) {
- sdp.push(makeLine(type, obj, el));
- });
- }
- });
- }); // then for each media line, follow the innerOrder
- session.media.forEach(function (mLine) {
- sdp.push(makeLine('m', grammar.m[0], mLine));
- innerOrder.forEach(function (type) {
- grammar[type].forEach(function (obj) {
- if (obj.name in mLine && mLine[obj.name] != null) {
- sdp.push(makeLine(type, obj, mLine));
- } else if (obj.push in mLine && mLine[obj.push] != null) {
- mLine[obj.push].forEach(function (el) {
- sdp.push(makeLine(type, obj, el));
- });
- }
- });
- });
- });
- return sdp.join('\r\n') + '\r\n';
- };
- }),
- /* 29 */
- (function(module, exports, __webpack_require__) {
- /**
- * This is the common logic for both the Node.js and web browser
- * implementations of `debug()`.
- */
- function setup(env) {
- createDebug.debug = createDebug;
- createDebug.default = createDebug;
- createDebug.coerce = coerce;
- createDebug.disable = disable;
- createDebug.enable = enable;
- createDebug.enabled = enabled;
- createDebug.humanize = __webpack_require__(30);
- Object.keys(env).forEach(key => {
- createDebug[key] = env[key];
- });
- /**
- * Active `debug` instances.
- */
- createDebug.instances = [];
- /**
- * The currently active debug mode names, and names to skip.
- */
- createDebug.names = [];
- createDebug.skips = [];
- /**
- * Map of special "%n" handling functions, for the debug "format" argument.
- *
- * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
- */
- createDebug.formatters = {};
- /**
- * Selects a color for a debug namespace
- * @param {String} namespace The namespace string for the for the debug instance to be colored
- * @return {Number|String} An ANSI color code for the given namespace
- * @api private
- */
- function selectColor(namespace) {
- let hash = 0;
- for (let i = 0; i < namespace.length; i++) {
- hash = (hash << 5) - hash + namespace.charCodeAt(i);
- hash |= 0; // Convert to 32bit integer
- }
- return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
- }
- createDebug.selectColor = selectColor;
- /**
- * Create a debugger with the given `namespace`.
- *
- * @param {String} namespace
- * @return {Function}
- * @api public
- */
- function createDebug(namespace) {
- let prevTime;
- function debug(...args) {
- // TODO: Disabled?
- /*if (!debug.enabled) {
- return;
- }*/
- const self = debug; // Set `diff` timestamp
- const curr = Number(new Date());
- const ms = curr - (prevTime || curr);
- self.diff = ms;
- self.prev = prevTime;
- self.curr = curr;
- prevTime = curr;
- args[0] = createDebug.coerce(args[0]);
- if (typeof args[0] !== 'string') {
- // Anything else let's inspect with %O
- args.unshift('%O');
- } // Apply any `formatters` transformations
- let index = 0;
- args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
- // If we encounter an escaped % then don't increase the array index
- if (match === '%%') {
- return match;
- }
- index++;
- const formatter = createDebug.formatters[format];
- if (typeof formatter === 'function') {
- const val = args[index];
- match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format`
- args.splice(index, 1);
- index--;
- }
- return match;
- }); // Apply env-specific formatting (colors, etc.)
- createDebug.formatArgs.call(self, args);
- const logFn = self.log || createDebug.log;
- logFn.apply(self, args);
- }
- debug.namespace = namespace;
- debug.enabled = createDebug.enabled(namespace);
- debug.useColors = createDebug.useColors();
- debug.color = selectColor(namespace);
- debug.destroy = destroy;
- debug.extend = extend; // Debug.formatArgs = formatArgs;
- // debug.rawLog = rawLog;
- // env-specific initialization logic for debug instances
- if (typeof createDebug.init === 'function') {
- createDebug.init(debug);
- }
- createDebug.instances.push(debug);
- return debug;
- }
- function destroy() {
- const index = createDebug.instances.indexOf(this);
- if (index !== -1) {
- createDebug.instances.splice(index, 1);
- return true;
- }
- return false;
- }
- function extend(namespace, delimiter) {
- const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
- newDebug.log = this.log;
- return newDebug;
- }
- /**
- * Enables a debug mode by namespaces. This can include modes
- * separated by a colon and wildcards.
- *
- * @param {String} namespaces
- * @api public
- */
- function enable(namespaces) {
- createDebug.save(namespaces);
- createDebug.names = [];
- createDebug.skips = [];
- let i;
- const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
- const len = split.length;
- for (i = 0; i < len; i++) {
- if (!split[i]) {
- // ignore empty strings
- continue;
- }
- namespaces = split[i].replace(/\*/g, '.*?');
- if (namespaces[0] === '-') {
- createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
- } else {
- createDebug.names.push(new RegExp('^' + namespaces + '$'));
- }
- }
- for (i = 0; i < createDebug.instances.length; i++) {
- const instance = createDebug.instances[i];
- instance.enabled = createDebug.enabled(instance.namespace);
- }
- }
- /**
- * Disable debug output.
- *
- * @return {String} namespaces
- * @api public
- */
- function disable() {
- const namespaces = [...createDebug.names.map(toNamespace), ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)].join(',');
- createDebug.enable('');
- return namespaces;
- }
- /**
- * Returns true if the given mode name is enabled, false otherwise.
- *
- * @param {String} name
- * @return {Boolean}
- * @api public
- */
- function enabled(name) {
- if (name[name.length - 1] === '*') {
- return true;
- }
- let i;
- let len;
- for (i = 0, len = createDebug.skips.length; i < len; i++) {
- if (createDebug.skips[i].test(name)) {
- return false;
- }
- }
- for (i = 0, len = createDebug.names.length; i < len; i++) {
- if (createDebug.names[i].test(name)) {
- return true;
- }
- }
- return false;
- }
- /**
- * Convert regexp to namespace
- *
- * @param {RegExp} regxep
- * @return {String} namespace
- * @api private
- */
- function toNamespace(regexp) {
- return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\.\*\?$/, '*');
- }
- /**
- * Coerce `val`.
- *
- * @param {Mixed} val
- * @return {Mixed}
- * @api private
- */
- function coerce(val) {
- if (val instanceof Error) {
- return val.stack || val.message;
- }
- return val;
- }
- createDebug.enable(createDebug.load());
- return createDebug;
- }
- module.exports = setup;
- }),
- /* 30 */
- (function(module, exports) {
- /**
- * Helpers.
- */
- var s = 1000;
- var m = s * 60;
- var h = m * 60;
- var d = h * 24;
- var w = d * 7;
- var y = d * 365.25;
- /**
- * Parse or format the given `val`.
- *
- * Options:
- *
- * - `long` verbose formatting [false]
- *
- * @param {String|Number} val
- * @param {Object} [options]
- * @throws {Error} throw an error if val is not a non-empty string or a number
- * @return {String|Number}
- * @api public
- */
- module.exports = function (val, options) {
- options = options || {};
- var type = typeof val;
- if (type === 'string' && val.length > 0) {
- return parse(val);
- } else if (type === 'number' && isNaN(val) === false) {
- return options.long ? fmtLong(val) : fmtShort(val);
- }
- throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val));
- };
- /**
- * Parse the given `str` and return milliseconds.
- *
- * @param {String} str
- * @return {Number}
- * @api private
- */
- function parse(str) {
- str = String(str);
- if (str.length > 100) {
- return;
- }
- var match = /^((?:\d+)?\-?\d?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str);
- if (!match) {
- return;
- }
- var n = parseFloat(match[1]);
- var type = (match[2] || 'ms').toLowerCase();
- switch (type) {
- case 'years':
- case 'year':
- case 'yrs':
- case 'yr':
- case 'y':
- return n * y;
- case 'weeks':
- case 'week':
- case 'w':
- return n * w;
- case 'days':
- case 'day':
- case 'd':
- return n * d;
- case 'hours':
- case 'hour':
- case 'hrs':
- case 'hr':
- case 'h':
- return n * h;
- case 'minutes':
- case 'minute':
- case 'mins':
- case 'min':
- case 'm':
- return n * m;
- case 'seconds':
- case 'second':
- case 'secs':
- case 'sec':
- case 's':
- return n * s;
- case 'milliseconds':
- case 'millisecond':
- case 'msecs':
- case 'msec':
- case 'ms':
- return n;
- default:
- return undefined;
- }
- }
- /**
- * Short format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
- function fmtShort(ms) {
- var msAbs = Math.abs(ms);
- if (msAbs >= d) {
- return Math.round(ms / d) + 'd';
- }
- if (msAbs >= h) {
- return Math.round(ms / h) + 'h';
- }
- if (msAbs >= m) {
- return Math.round(ms / m) + 'm';
- }
- if (msAbs >= s) {
- return Math.round(ms / s) + 's';
- }
- return ms + 'ms';
- }
- /**
- * Long format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
- function fmtLong(ms) {
- var msAbs = Math.abs(ms);
- if (msAbs >= d) {
- return plural(ms, msAbs, d, 'day');
- }
- if (msAbs >= h) {
- return plural(ms, msAbs, h, 'hour');
- }
- if (msAbs >= m) {
- return plural(ms, msAbs, m, 'minute');
- }
- if (msAbs >= s) {
- return plural(ms, msAbs, s, 'second');
- }
- return ms + ' ms';
- }
- /**
- * Pluralization helper.
- */
- function plural(ms, msAbs, n, name) {
- var isPlural = msAbs >= n * 1.5;
- return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
- }
- }),
- /* 31 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- var Utils = __webpack_require__(2);
- var debug = __webpack_require__(0)('JsSIP:DigestAuthentication');
- var debugerror = __webpack_require__(0)('JsSIP:ERROR:DigestAuthentication');
- debugerror.log = console.warn.bind(console);
- module.exports =
- /*#__PURE__*/
- function () {
- function DigestAuthentication(credentials) {
- _classCallCheck(this, DigestAuthentication);
- this._credentials = credentials;
- this._cnonce = null;
- this._nc = 0;
- this._ncHex = '00000000';
- this._algorithm = null;
- this._realm = null;
- this._nonce = null;
- this._opaque = null;
- this._stale = null;
- this._qop = null;
- this._method = null;
- this._uri = null;
- this._ha1 = null;
- this._response = null;
- }
- _createClass(DigestAuthentication, [{
- key: "get",
- value: function get(parameter) {
- switch (parameter) {
- case 'realm':
- return this._realm;
- case 'ha1':
- return this._ha1;
- default:
- debugerror('get() | cannot get "%s" parameter', parameter);
- return undefined;
- }
- }
- /**
- * Performs Digest authentication given a SIP request and the challenge
- * received in a response to that request.
- * Returns true if auth was successfully generated, false otherwise.
- */
- }, {
- key: "authenticate",
- value: function authenticate(_ref, challenge)
- /* test interface */
- {
- var method = _ref.method,
- ruri = _ref.ruri,
- body = _ref.body;
- var cnonce = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
- this._algorithm = challenge.algorithm;
- this._realm = challenge.realm;
- this._nonce = challenge.nonce;
- this._opaque = challenge.opaque;
- this._stale = challenge.stale;
- if (this._algorithm) {
- if (this._algorithm !== 'MD5') {
- debugerror('authenticate() | challenge with Digest algorithm different than "MD5", authentication aborted');
- return false;
- }
- } else {
- this._algorithm = 'MD5';
- }
- if (!this._nonce) {
- debugerror('authenticate() | challenge without Digest nonce, authentication aborted');
- return false;
- }
- if (!this._realm) {
- debugerror('authenticate() | challenge without Digest realm, authentication aborted');
- return false;
- } // If no plain SIP password is provided.
- if (!this._credentials.password) {
- // If ha1 is not provided we cannot authenticate.
- if (!this._credentials.ha1) {
- debugerror('authenticate() | no plain SIP password nor ha1 provided, authentication aborted');
- return false;
- } // If the realm does not match the stored realm we cannot authenticate.
- if (this._credentials.realm !== this._realm) {
- debugerror('authenticate() | no plain SIP password, and stored `realm` does not match the given `realm`, cannot authenticate [stored:"%s", given:"%s"]', this._credentials.realm, this._realm);
- return false;
- }
- } // 'qop' can contain a list of values (Array). Let's choose just one.
- if (challenge.qop) {
- if (challenge.qop.indexOf('auth-int') > -1) {
- this._qop = 'auth-int';
- } else if (challenge.qop.indexOf('auth') > -1) {
- this._qop = 'auth';
- } else {
- // Otherwise 'qop' is present but does not contain 'auth' or 'auth-int', so abort here.
- debugerror('authenticate() | challenge without Digest qop different than "auth" or "auth-int", authentication aborted');
- return false;
- }
- } else {
- this._qop = null;
- } // Fill other attributes.
- this._method = method;
- this._uri = ruri;
- this._cnonce = cnonce || Utils.createRandomToken(12);
- this._nc += 1;
- var hex = Number(this._nc).toString(16);
- this._ncHex = '00000000'.substr(0, 8 - hex.length) + hex; // Nc-value = 8LHEX. Max value = 'FFFFFFFF'.
- if (this._nc === 4294967296) {
- this._nc = 1;
- this._ncHex = '00000001';
- } // Calculate the Digest "response" value.
- // If we have plain SIP password then regenerate ha1.
- if (this._credentials.password) {
- // HA1 = MD5(A1) = MD5(username:realm:password).
- this._ha1 = Utils.calculateMD5("".concat(this._credentials.username, ":").concat(this._realm, ":").concat(this._credentials.password));
- } // Otherwise reuse the stored ha1.
- else {
- this._ha1 = this._credentials.ha1;
- }
- var ha2;
- if (this._qop === 'auth') {
- // HA2 = MD5(A2) = MD5(method:digestURI).
- ha2 = Utils.calculateMD5("".concat(this._method, ":").concat(this._uri)); // Response = MD5(HA1:nonce:nonceCount:credentialsNonce:qop:HA2).
- this._response = Utils.calculateMD5("".concat(this._ha1, ":").concat(this._nonce, ":").concat(this._ncHex, ":").concat(this._cnonce, ":auth:").concat(ha2));
- } else if (this._qop === 'auth-int') {
- // HA2 = MD5(A2) = MD5(method:digestURI:MD5(entityBody)).
- ha2 = Utils.calculateMD5("".concat(this._method, ":").concat(this._uri, ":").concat(Utils.calculateMD5(body ? body : ''))); // Response = MD5(HA1:nonce:nonceCount:credentialsNonce:qop:HA2).
- this._response = Utils.calculateMD5("".concat(this._ha1, ":").concat(this._nonce, ":").concat(this._ncHex, ":").concat(this._cnonce, ":auth-int:").concat(ha2));
- } else if (this._qop === null) {
- // HA2 = MD5(A2) = MD5(method:digestURI).
- ha2 = Utils.calculateMD5("".concat(this._method, ":").concat(this._uri)); // Response = MD5(HA1:nonce:HA2).
- this._response = Utils.calculateMD5("".concat(this._ha1, ":").concat(this._nonce, ":").concat(ha2));
- }
- debug('authenticate() | response generated');
- return true;
- }
- /**
- * Return the Proxy-Authorization or WWW-Authorization header value.
- */
- }, {
- key: "toString",
- value: function toString() {
- var auth_params = [];
- if (!this._response) {
- throw new Error('response field does not exist, cannot generate Authorization header');
- }
- auth_params.push("algorithm=".concat(this._algorithm));
- auth_params.push("username=\"".concat(this._credentials.username, "\""));
- auth_params.push("realm=\"".concat(this._realm, "\""));
- auth_params.push("nonce=\"".concat(this._nonce, "\""));
- auth_params.push("uri=\"".concat(this._uri, "\""));
- auth_params.push("response=\"".concat(this._response, "\""));
- if (this._opaque) {
- auth_params.push("opaque=\"".concat(this._opaque, "\""));
- }
- if (this._qop) {
- auth_params.push("qop=".concat(this._qop));
- auth_params.push("cnonce=\"".concat(this._cnonce, "\""));
- auth_params.push("nc=".concat(this._ncHex));
- }
- return "Digest ".concat(auth_params.join(', '));
- }
- }]);
- return DigestAuthentication;
- }();
- }),
- /* 32 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- var SIPMessage = __webpack_require__(5);
- var JsSIP_C = __webpack_require__(1);
- var Transactions = __webpack_require__(9);
- var Dialog_RequestSender = __webpack_require__(33);
- var Utils = __webpack_require__(2);
- var debug = __webpack_require__(0)('JsSIP:Dialog');
- var C = {
- // Dialog states.
- STATUS_EARLY: 1,
- STATUS_CONFIRMED: 2
- }; // RFC 3261 12.1.
- module.exports =
- /*#__PURE__*/
- function () {
- _createClass(Dialog, null, [{
- key: "C",
- // Expose C object.
- get: function get() {
- return C;
- }
- }]);
- function Dialog(owner, message, type) {
- var state = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : C.STATUS_CONFIRMED;
- _classCallCheck(this, Dialog);
- this._owner = owner;
- this._ua = owner._ua;
- this._uac_pending_reply = false;
- this._uas_pending_reply = false;
- if (!message.hasHeader('contact')) {
- return {
- error: 'unable to create a Dialog without Contact header field'
- };
- }
- if (message instanceof SIPMessage.IncomingResponse) {
- state = message.status_code < 200 ? C.STATUS_EARLY : C.STATUS_CONFIRMED;
- }
- var contact = message.parseHeader('contact'); // RFC 3261 12.1.1.
- if (type === 'UAS') {
- this._id = {
- call_id: message.call_id,
- local_tag: message.to_tag,
- remote_tag: message.from_tag,
- toString: function toString() {
- return this.call_id + this.local_tag + this.remote_tag;
- }
- };
- this._state = state;
- this._remote_seqnum = message.cseq;
- this._local_uri = message.parseHeader('to').uri;
- this._remote_uri = message.parseHeader('from').uri;
- this._remote_target = contact.uri;
- this._route_set = message.getHeaders('record-route');
- this._ack_seqnum = this._remote_seqnum;
- } // RFC 3261 12.1.2.
- else if (type === 'UAC') {
- this._id = {
- call_id: message.call_id,
- local_tag: message.from_tag,
- remote_tag: message.to_tag,
- toString: function toString() {
- return this.call_id + this.local_tag + this.remote_tag;
- }
- };
- this._state = state;
- this._local_seqnum = message.cseq;
- this._local_uri = message.parseHeader('from').uri;
- this._remote_uri = message.parseHeader('to').uri;
- this._remote_target = contact.uri;
- this._route_set = message.getHeaders('record-route').reverse();
- this._ack_seqnum = null;
- }
- this._ua.newDialog(this);
- debug("new ".concat(type, " dialog created with status ").concat(this._state === C.STATUS_EARLY ? 'EARLY' : 'CONFIRMED'));
- }
- _createClass(Dialog, [{
- key: "update",
- value: function update(message, type) {
- this._state = C.STATUS_CONFIRMED;
- debug("dialog ".concat(this._id.toString(), " changed to CONFIRMED state"));
- if (type === 'UAC') {
- // RFC 3261 13.2.2.4.
- this._route_set = message.getHeaders('record-route').reverse();
- }
- }
- }, {
- key: "terminate",
- value: function terminate() {
- debug("dialog ".concat(this._id.toString(), " deleted"));
- this._ua.destroyDialog(this);
- }
- }, {
- key: "sendRequest",
- value: function sendRequest(method) {
- var _this = this;
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- var extraHeaders = Utils.cloneArray(options.extraHeaders);
- var eventHandlers = options.eventHandlers || {};
- var body = options.body || null;
- var request = this._createRequest(method, extraHeaders, body); // Increase the local CSeq on authentication.
- eventHandlers.onAuthenticated = function () {
- _this._local_seqnum += 1;
- };
- var request_sender = new Dialog_RequestSender(this, request, eventHandlers);
- request_sender.send(); // Return the instance of OutgoingRequest.
- return request;
- }
- }, {
- key: "receiveRequest",
- value: function receiveRequest(request) {
- // Check in-dialog request.
- if (!this._checkInDialogRequest(request)) {
- return;
- } // ACK received. Cleanup this._ack_seqnum.
- if (request.method === JsSIP_C.ACK && this._ack_seqnum !== null) {
- this._ack_seqnum = null;
- } // INVITE received. Set this._ack_seqnum.
- else if (request.method === JsSIP_C.INVITE) {
- this._ack_seqnum = request.cseq;
- }
- this._owner.receiveRequest(request);
- } // RFC 3261 12.2.1.1.
- }, {
- key: "_createRequest",
- value: function _createRequest(method, extraHeaders, body) {
- extraHeaders = Utils.cloneArray(extraHeaders);
- if (!this._local_seqnum) {
- this._local_seqnum = Math.floor(Math.random() * 10000);
- }
- var cseq = method === JsSIP_C.CANCEL || method === JsSIP_C.ACK ? this._local_seqnum : this._local_seqnum += 1;
- var request = new SIPMessage.OutgoingRequest(method, this._remote_target, this._ua, {
- 'cseq': cseq,
- 'call_id': this._id.call_id,
- 'from_uri': this._local_uri,
- 'from_tag': this._id.local_tag,
- 'to_uri': this._remote_uri,
- 'to_tag': this._id.remote_tag,
- 'route_set': this._route_set
- }, extraHeaders, body);
- return request;
- } // RFC 3261 12.2.2.
- }, {
- key: "_checkInDialogRequest",
- value: function _checkInDialogRequest(request) {
- var _this2 = this;
- if (!this._remote_seqnum) {
- this._remote_seqnum = request.cseq;
- } else if (request.cseq < this._remote_seqnum) {
- if (request.method === JsSIP_C.ACK) {
- // We are not expecting any ACK with lower seqnum than the current one.
- // Or this is not the ACK we are waiting for.
- if (this._ack_seqnum === null || request.cseq !== this._ack_seqnum) {
- return false;
- }
- } else {
- request.reply(500);
- return false;
- }
- } else if (request.cseq > this._remote_seqnum) {
- this._remote_seqnum = request.cseq;
- } // RFC3261 14.2 Modifying an Existing Session -UAS BEHAVIOR-.
- if (request.method === JsSIP_C.INVITE || request.method === JsSIP_C.UPDATE && request.body) {
- if (this._uac_pending_reply === true) {
- request.reply(491);
- } else if (this._uas_pending_reply === true) {
- var retryAfter = (Math.random() * 10 | 0) + 1;
- request.reply(500, null, ["Retry-After:".concat(retryAfter)]);
- return false;
- } else {
- this._uas_pending_reply = true;
- var stateChanged = function stateChanged() {
- if (request.server_transaction.state === Transactions.C.STATUS_ACCEPTED || request.server_transaction.state === Transactions.C.STATUS_COMPLETED || request.server_transaction.state === Transactions.C.STATUS_TERMINATED) {
- request.server_transaction.removeListener('stateChanged', stateChanged);
- _this2._uas_pending_reply = false;
- }
- };
- request.server_transaction.on('stateChanged', stateChanged);
- } // RFC3261 12.2.2 Replace the dialog`s remote target URI if the request is accepted.
- if (request.hasHeader('contact')) {
- request.server_transaction.on('stateChanged', function () {
- if (request.server_transaction.state === Transactions.C.STATUS_ACCEPTED) {
- _this2._remote_target = request.parseHeader('contact').uri;
- }
- });
- }
- } else if (request.method === JsSIP_C.NOTIFY) {
- // RFC6665 3.2 Replace the dialog`s remote target URI if the request is accepted.
- if (request.hasHeader('contact')) {
- request.server_transaction.on('stateChanged', function () {
- if (request.server_transaction.state === Transactions.C.STATUS_COMPLETED) {
- _this2._remote_target = request.parseHeader('contact').uri;
- }
- });
- }
- }
- return true;
- }
- }, {
- key: "id",
- get: function get() {
- return this._id;
- }
- }, {
- key: "local_seqnum",
- get: function get() {
- return this._local_seqnum;
- },
- set: function set(num) {
- this._local_seqnum = num;
- }
- }, {
- key: "owner",
- get: function get() {
- return this._owner;
- }
- }, {
- key: "uac_pending_reply",
- get: function get() {
- return this._uac_pending_reply;
- },
- set: function set(pending) {
- this._uac_pending_reply = pending;
- }
- }, {
- key: "uas_pending_reply",
- get: function get() {
- return this._uas_pending_reply;
- }
- }]);
- return Dialog;
- }();
- }),
- /* 33 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- var JsSIP_C = __webpack_require__(1);
- var Transactions = __webpack_require__(9);
- var RTCSession = __webpack_require__(17);
- var RequestSender = __webpack_require__(10); // Default event handlers.
- var EventHandlers = {
- onRequestTimeout: function onRequestTimeout() {},
- onTransportError: function onTransportError() {},
- onSuccessResponse: function onSuccessResponse() {},
- onErrorResponse: function onErrorResponse() {},
- onAuthenticated: function onAuthenticated() {},
- onDialogError: function onDialogError() {}
- };
- module.exports =
- /*#__PURE__*/
- function () {
- function DialogRequestSender(dialog, request, eventHandlers) {
- _classCallCheck(this, DialogRequestSender);
- this._dialog = dialog;
- this._ua = dialog._ua;
- this._request = request;
- this._eventHandlers = eventHandlers; // RFC3261 14.1 Modifying an Existing Session. UAC Behavior.
- this._reattempt = false;
- this._reattemptTimer = null; // Define the undefined handlers.
- for (var handler in EventHandlers) {
- if (Object.prototype.hasOwnProperty.call(EventHandlers, handler)) {
- if (!this._eventHandlers[handler]) {
- this._eventHandlers[handler] = EventHandlers[handler];
- }
- }
- }
- }
- _createClass(DialogRequestSender, [{
- key: "send",
- value: function send() {
- var _this = this;
- var request_sender = new RequestSender(this._ua, this._request, {
- onRequestTimeout: function onRequestTimeout() {
- _this._eventHandlers.onRequestTimeout();
- },
- onTransportError: function onTransportError() {
- _this._eventHandlers.onTransportError();
- },
- onAuthenticated: function onAuthenticated(request) {
- _this._eventHandlers.onAuthenticated(request);
- },
- onReceiveResponse: function onReceiveResponse(response) {
- _this._receiveResponse(response);
- }
- });
- request_sender.send(); // RFC3261 14.2 Modifying an Existing Session -UAC BEHAVIOR-.
- if ((this._request.method === JsSIP_C.INVITE || this._request.method === JsSIP_C.UPDATE && this._request.body) && request_sender.clientTransaction.state !== Transactions.C.STATUS_TERMINATED) {
- this._dialog.uac_pending_reply = true;
- var stateChanged = function stateChanged() {
- if (request_sender.clientTransaction.state === Transactions.C.STATUS_ACCEPTED || request_sender.clientTransaction.state === Transactions.C.STATUS_COMPLETED || request_sender.clientTransaction.state === Transactions.C.STATUS_TERMINATED) {
- request_sender.clientTransaction.removeListener('stateChanged', stateChanged);
- _this._dialog.uac_pending_reply = false;
- }
- };
- request_sender.clientTransaction.on('stateChanged', stateChanged);
- }
- }
- }, {
- key: "_receiveResponse",
- value: function _receiveResponse(response) {
- var _this2 = this; // RFC3261 12.2.1.2 408 or 481 is received for a request within a dialog.
- if (response.status_code === 408 || response.status_code === 481) {
- this._eventHandlers.onDialogError(response);
- } else if (response.method === JsSIP_C.INVITE && response.status_code === 491) {
- if (this._reattempt) {
- if (response.status_code >= 200 && response.status_code < 300) {
- this._eventHandlers.onSuccessResponse(response);
- } else if (response.status_code >= 300) {
- this._eventHandlers.onErrorResponse(response);
- }
- } else {
- this._request.cseq.value = this._dialog.local_seqnum += 1;
- this._reattemptTimer = setTimeout(function () {
- // TODO: look at dialog state instead.
- if (_this2._dialog.owner.status !== RTCSession.C.STATUS_TERMINATED) {
- _this2._reattempt = true;
- _this2._request_sender.send();
- }
- }, 1000);
- }
- } else if (response.status_code >= 200 && response.status_code < 300) {
- this._eventHandlers.onSuccessResponse(response);
- } else if (response.status_code >= 300) {
- this._eventHandlers.onErrorResponse(response);
- }
- }
- }, {
- key: "request",
- get: function get() {
- return this._request;
- }
- }]);
- return DialogRequestSender;
- }();
- }),
- /* 34 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _typeof(obj) {
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
- _typeof = function _typeof(obj) {
- return typeof obj;
- };
- } else {
- _typeof = function _typeof(obj) {
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
- };
- }
- return _typeof(obj);
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- function _possibleConstructorReturn(self, call) {
- if (call && (_typeof(call) === "object" || typeof call === "function")) {
- return call;
- }
- return _assertThisInitialized(self);
- }
- function _assertThisInitialized(self) {
- if (self === void 0) {
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- }
- return self;
- }
- function _getPrototypeOf(o) {
- _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
- return o.__proto__ || Object.getPrototypeOf(o);
- };
- return _getPrototypeOf(o);
- }
- function _inherits(subClass, superClass) {
- if (typeof superClass !== "function" && superClass !== null) {
- throw new TypeError("Super expression must either be null or a function");
- }
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- writable: true,
- configurable: true
- }
- });
- if (superClass) _setPrototypeOf(subClass, superClass);
- }
- function _setPrototypeOf(o, p) {
- _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
- o.__proto__ = p;
- return o;
- };
- return _setPrototypeOf(o, p);
- }
- var EventEmitter = __webpack_require__(7).EventEmitter;
- var JsSIP_C = __webpack_require__(1);
- var Exceptions = __webpack_require__(6);
- var Utils = __webpack_require__(2);
- var debug = __webpack_require__(0)('JsSIP:RTCSession:DTMF');
- var debugerror = __webpack_require__(0)('JsSIP:ERROR:RTCSession:DTMF');
- debugerror.log = console.warn.bind(console);
- var C = {
- MIN_DURATION: 70,
- MAX_DURATION: 6000,
- DEFAULT_DURATION: 100,
- MIN_INTER_TONE_GAP: 50,
- DEFAULT_INTER_TONE_GAP: 500
- };
- module.exports =
- /*#__PURE__*/
- function (_EventEmitter) {
- _inherits(DTMF, _EventEmitter);
- function DTMF(session) {
- var _this;
- _classCallCheck(this, DTMF);
- _this = _possibleConstructorReturn(this, _getPrototypeOf(DTMF).call(this));
- _this._session = session;
- _this._direction = null;
- _this._tone = null;
- _this._duration = null;
- _this._request = null;
- return _this;
- }
- _createClass(DTMF, [{
- key: "send",
- value: function send(tone) {
- var _this2 = this;
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- if (tone === undefined) {
- throw new TypeError('Not enough arguments');
- }
- this._direction = 'outgoing'; // Check RTCSession Status.
- if (this._session.status !== this._session.C.STATUS_CONFIRMED && this._session.status !== this._session.C.STATUS_WAITING_FOR_ACK) {
- throw new Exceptions.InvalidStateError(this._session.status);
- }
- var extraHeaders = Utils.cloneArray(options.extraHeaders);
- this.eventHandlers = options.eventHandlers || {}; // Check tone type.
- if (typeof tone === 'string') {
- tone = tone.toUpperCase();
- } else if (typeof tone === 'number') {
- tone = tone.toString();
- } else {
- throw new TypeError("Invalid tone: ".concat(tone));
- } // Check tone value.
- if (!tone.match(/^[0-9A-DR#*]$/)) {
- throw new TypeError("Invalid tone: ".concat(tone));
- } else {
- this._tone = tone;
- } // Duration is checked/corrected in RTCSession.
- this._duration = options.duration;
- extraHeaders.push('Content-Type: application/dtmf-relay');
- var body = "Signal=".concat(this._tone, "\r\n");
- body += "Duration=".concat(this._duration);
- this._session.newDTMF({
- originator: 'local',
- dtmf: this,
- request: this._request
- });
- this._session.sendRequest(JsSIP_C.INFO, {
- extraHeaders: extraHeaders,
- eventHandlers: {
- onSuccessResponse: function onSuccessResponse(response) {
- _this2.emit('succeeded', {
- originator: 'remote',
- response: response
- });
- },
- onErrorResponse: function onErrorResponse(response) {
- if (_this2.eventHandlers.onFailed) {
- _this2.eventHandlers.onFailed();
- }
- _this2.emit('failed', {
- originator: 'remote',
- response: response
- });
- },
- onRequestTimeout: function onRequestTimeout() {
- _this2._session.onRequestTimeout();
- },
- onTransportError: function onTransportError() {
- _this2._session.onTransportError();
- },
- onDialogError: function onDialogError() {
- _this2._session.onDialogError();
- }
- },
- body: body
- });
- }
- }, {
- key: "init_incoming",
- value: function init_incoming(request) {
- var reg_tone = /^(Signal\s*?=\s*?)([0-9A-D#*]{1})(\s)?.*/;
- var reg_duration = /^(Duration\s?=\s?)([0-9]{1,4})(\s)?.*/;
- this._direction = 'incoming';
- this._request = request;
- request.reply(200);
- if (request.body) {
- var body = request.body.split('\n');
- if (body.length >= 1) {
- if (reg_tone.test(body[0])) {
- this._tone = body[0].replace(reg_tone, '$2');
- }
- }
- if (body.length >= 2) {
- if (reg_duration.test(body[1])) {
- this._duration = parseInt(body[1].replace(reg_duration, '$2'), 10);
- }
- }
- }
- if (!this._duration) {
- this._duration = C.DEFAULT_DURATION;
- }
- if (!this._tone) {
- debug('invalid INFO DTMF received, discarded');
- } else {
- this._session.newDTMF({
- originator: 'remote',
- dtmf: this,
- request: request
- });
- }
- }
- }, {
- key: "tone",
- get: function get() {
- return this._tone;
- }
- }, {
- key: "duration",
- get: function get() {
- return this._duration;
- }
- }]);
- return DTMF;
- }(EventEmitter);
- /**
- * Expose C object.
- */
- module.exports.C = C;
- }),
- /* 35 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _typeof(obj) {
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
- _typeof = function _typeof(obj) {
- return typeof obj;
- };
- } else {
- _typeof = function _typeof(obj) {
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
- };
- }
- return _typeof(obj);
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- function _possibleConstructorReturn(self, call) {
- if (call && (_typeof(call) === "object" || typeof call === "function")) {
- return call;
- }
- return _assertThisInitialized(self);
- }
- function _assertThisInitialized(self) {
- if (self === void 0) {
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- }
- return self;
- }
- function _getPrototypeOf(o) {
- _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
- return o.__proto__ || Object.getPrototypeOf(o);
- };
- return _getPrototypeOf(o);
- }
- function _inherits(subClass, superClass) {
- if (typeof superClass !== "function" && superClass !== null) {
- throw new TypeError("Super expression must either be null or a function");
- }
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- writable: true,
- configurable: true
- }
- });
- if (superClass) _setPrototypeOf(subClass, superClass);
- }
- function _setPrototypeOf(o, p) {
- _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
- o.__proto__ = p;
- return o;
- };
- return _setPrototypeOf(o, p);
- }
- var EventEmitter = __webpack_require__(7).EventEmitter;
- var debugerror = __webpack_require__(0)('JsSIP:ERROR:RTCSession:Info');
- debugerror.log = console.warn.bind(console);
- var JsSIP_C = __webpack_require__(1);
- var Exceptions = __webpack_require__(6);
- var Utils = __webpack_require__(2);
- module.exports =
- /*#__PURE__*/
- function (_EventEmitter) {
- _inherits(Info, _EventEmitter);
- function Info(session) {
- var _this;
- _classCallCheck(this, Info);
- _this = _possibleConstructorReturn(this, _getPrototypeOf(Info).call(this));
- _this._session = session;
- _this._direction = null;
- _this._contentType = null;
- _this._body = null;
- return _this;
- }
- _createClass(Info, [{
- key: "send",
- value: function send(contentType, body) {
- var _this2 = this;
- var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
- this._direction = 'outgoing';
- if (contentType === undefined) {
- throw new TypeError('Not enough arguments');
- } // Check RTCSession Status.
- if (this._session.status !== this._session.C.STATUS_CONFIRMED && this._session.status !== this._session.C.STATUS_WAITING_FOR_ACK) {
- throw new Exceptions.InvalidStateError(this._session.status);
- }
- this._contentType = contentType;
- this._body = body;
- var extraHeaders = Utils.cloneArray(options.extraHeaders);
- extraHeaders.push("Content-Type: ".concat(contentType));
- this._session.newInfo({
- originator: 'local',
- info: this,
- request: this.request
- });
- this._session.sendRequest(JsSIP_C.INFO, {
- extraHeaders: extraHeaders,
- eventHandlers: {
- onSuccessResponse: function onSuccessResponse(response) {
- _this2.emit('succeeded', {
- originator: 'remote',
- response: response
- });
- },
- onErrorResponse: function onErrorResponse(response) {
- _this2.emit('failed', {
- originator: 'remote',
- response: response
- });
- },
- onTransportError: function onTransportError() {
- _this2._session.onTransportError();
- },
- onRequestTimeout: function onRequestTimeout() {
- _this2._session.onRequestTimeout();
- },
- onDialogError: function onDialogError() {
- _this2._session.onDialogError();
- }
- },
- body: body
- });
- }
- }, {
- key: "init_incoming",
- value: function init_incoming(request) {
- this._direction = 'incoming';
- this.request = request;
- request.reply(200);
- this._contentType = request.getHeader('content-type');
- this._body = request.body;
- this._session.newInfo({
- originator: 'remote',
- info: this,
- request: request
- });
- }
- }, {
- key: "contentType",
- get: function get() {
- return this._contentType;
- }
- }, {
- key: "body",
- get: function get() {
- return this._body;
- }
- }]);
- return Info;
- }(EventEmitter);
- }),
- /* 36 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- var JsSIP_C = __webpack_require__(1);
- var debug = __webpack_require__(0)('JsSIP:RTCSession:ReferNotifier');
- var C = {
- event_type: 'refer',
- body_type: 'message/sipfrag;version=2.0',
- expires: 300
- };
- module.exports =
- /*#__PURE__*/
- function () {
- function ReferNotifier(session, id, expires) {
- _classCallCheck(this, ReferNotifier);
- this._session = session;
- this._id = id;
- this._expires = expires || C.expires;
- this._active = true; // The creation of a Notifier results in an immediate NOTIFY.
- this.notify(100);
- }
- _createClass(ReferNotifier, [{
- key: "notify",
- value: function notify(code, reason) {
- debug('notify()');
- if (this._active === false) {
- return;
- }
- reason = reason || JsSIP_C.REASON_PHRASE[code] || '';
- var state;
- if (code >= 200) {
- state = 'terminated;reason=noresource';
- } else {
- state = "active;expires=".concat(this._expires);
- } // Put this in a try/catch block.
- this._session.sendRequest(JsSIP_C.NOTIFY, {
- extraHeaders: ["Event: ".concat(C.event_type, ";id=").concat(this._id), "Subscription-State: ".concat(state), "Content-Type: ".concat(C.body_type)],
- body: "SIP/2.0 ".concat(code, " ").concat(reason),
- eventHandlers: {
- // If a negative response is received, subscription is canceled.
- onErrorResponse: function onErrorResponse() {
- this._active = false;
- }
- }
- });
- }
- }]);
- return ReferNotifier;
- }();
- }),
- /* 37 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _typeof(obj) {
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
- _typeof = function _typeof(obj) {
- return typeof obj;
- };
- } else {
- _typeof = function _typeof(obj) {
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
- };
- }
- return _typeof(obj);
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- function _possibleConstructorReturn(self, call) {
- if (call && (_typeof(call) === "object" || typeof call === "function")) {
- return call;
- }
- return _assertThisInitialized(self);
- }
- function _assertThisInitialized(self) {
- if (self === void 0) {
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- }
- return self;
- }
- function _getPrototypeOf(o) {
- _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
- return o.__proto__ || Object.getPrototypeOf(o);
- };
- return _getPrototypeOf(o);
- }
- function _inherits(subClass, superClass) {
- if (typeof superClass !== "function" && superClass !== null) {
- throw new TypeError("Super expression must either be null or a function");
- }
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- writable: true,
- configurable: true
- }
- });
- if (superClass) _setPrototypeOf(subClass, superClass);
- }
- function _setPrototypeOf(o, p) {
- _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
- o.__proto__ = p;
- return o;
- };
- return _setPrototypeOf(o, p);
- }
- var EventEmitter = __webpack_require__(7).EventEmitter;
- var JsSIP_C = __webpack_require__(1);
- var Grammar = __webpack_require__(3);
- var Utils = __webpack_require__(2);
- var debug = __webpack_require__(0)('JsSIP:RTCSession:ReferSubscriber');
- module.exports =
- /*#__PURE__*/
- function (_EventEmitter) {
- _inherits(ReferSubscriber, _EventEmitter);
- function ReferSubscriber(session) {
- var _this;
- _classCallCheck(this, ReferSubscriber);
- _this = _possibleConstructorReturn(this, _getPrototypeOf(ReferSubscriber).call(this));
- _this._id = null;
- _this._session = session;
- return _this;
- }
- _createClass(ReferSubscriber, [{
- key: "sendRefer",
- value: function sendRefer(target) {
- var _this2 = this;
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
- debug('sendRefer()');
- var extraHeaders = Utils.cloneArray(options.extraHeaders);
- var eventHandlers = options.eventHandlers || {}; // Set event handlers.
- for (var event in eventHandlers) {
- if (Object.prototype.hasOwnProperty.call(eventHandlers, event)) {
- this.on(event, eventHandlers[event]);
- }
- } // Replaces URI header field.
- var replaces = null;
- if (options.replaces) {
- replaces = options.replaces._request.call_id;
- replaces += ";to-tag=".concat(options.replaces._to_tag);
- replaces += ";from-tag=".concat(options.replaces._from_tag);
- replaces = encodeURIComponent(replaces);
- } // Refer-To header field.
- var referTo = "Refer-To: <".concat(target).concat(replaces ? "?Replaces=".concat(replaces) : '', ">");
- extraHeaders.push(referTo);
- extraHeaders.push("Contact: ".concat(this._session.contact));
- var request = this._session.sendRequest(JsSIP_C.REFER, {
- extraHeaders: extraHeaders,
- eventHandlers: {
- onSuccessResponse: function onSuccessResponse(response) {
- _this2._requestSucceeded(response);
- },
- onErrorResponse: function onErrorResponse(response) {
- _this2._requestFailed(response, JsSIP_C.causes.REJECTED);
- },
- onTransportError: function onTransportError() {
- _this2._requestFailed(null, JsSIP_C.causes.CONNECTION_ERROR);
- },
- onRequestTimeout: function onRequestTimeout() {
- _this2._requestFailed(null, JsSIP_C.causes.REQUEST_TIMEOUT);
- },
- onDialogError: function onDialogError() {
- _this2._requestFailed(null, JsSIP_C.causes.DIALOG_ERROR);
- }
- }
- });
- this._id = request.cseq;
- }
- }, {
- key: "receiveNotify",
- value: function receiveNotify(request) {
- debug('receiveNotify()');
- if (!request.body) {
- return;
- }
- var status_line = Grammar.parse(request.body.trim(), 'Status_Line');
- if (status_line === -1) {
- debug("receiveNotify() | error parsing NOTIFY body: \"".concat(request.body, "\""));
- return;
- }
- switch (true) {
- case /^100$/.test(status_line.status_code):
- this.emit('trying', {
- request: request,
- status_line: status_line
- });
- break;
- case /^1[0-9]{2}$/.test(status_line.status_code):
- this.emit('progress', {
- request: request,
- status_line: status_line
- });
- break;
- case /^2[0-9]{2}$/.test(status_line.status_code):
- this.emit('accepted', {
- request: request,
- status_line: status_line
- });
- break;
- default:
- this.emit('failed', {
- request: request,
- status_line: status_line
- });
- break;
- }
- }
- }, {
- key: "_requestSucceeded",
- value: function _requestSucceeded(response) {
- debug('REFER succeeded');
- debug('emit "requestSucceeded"');
- this.emit('requestSucceeded', {
- response: response
- });
- }
- }, {
- key: "_requestFailed",
- value: function _requestFailed(response, cause) {
- debug('REFER failed');
- debug('emit "requestFailed"');
- this.emit('requestFailed', {
- response: response || null,
- cause: cause
- });
- }
- }, {
- key: "id",
- get: function get() {
- return this._id;
- }
- }]);
- return ReferSubscriber;
- }(EventEmitter);
- }),
- /* 38 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _typeof(obj) {
- if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
- _typeof = function _typeof(obj) {
- return typeof obj;
- };
- } else {
- _typeof = function _typeof(obj) {
- return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
- };
- }
- return _typeof(obj);
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- function _possibleConstructorReturn(self, call) {
- if (call && (_typeof(call) === "object" || typeof call === "function")) {
- return call;
- }
- return _assertThisInitialized(self);
- }
- function _assertThisInitialized(self) {
- if (self === void 0) {
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- }
- return self;
- }
- function _getPrototypeOf(o) {
- _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
- return o.__proto__ || Object.getPrototypeOf(o);
- };
- return _getPrototypeOf(o);
- }
- function _inherits(subClass, superClass) {
- if (typeof superClass !== "function" && superClass !== null) {
- throw new TypeError("Super expression must either be null or a function");
- }
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- writable: true,
- configurable: true
- }
- });
- if (superClass) _setPrototypeOf(subClass, superClass);
- }
- function _setPrototypeOf(o, p) {
- _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
- o.__proto__ = p;
- return o;
- };
- return _setPrototypeOf(o, p);
- }
- var EventEmitter = __webpack_require__(7).EventEmitter;
- var JsSIP_C = __webpack_require__(1);
- var SIPMessage = __webpack_require__(5);
- var Utils = __webpack_require__(2);
- var RequestSender = __webpack_require__(10);
- var Exceptions = __webpack_require__(6);
- var debug = __webpack_require__(0)('JsSIP:Message');
- module.exports =
- /*#__PURE__*/
- function (_EventEmitter) {
- _inherits(Message, _EventEmitter);
- function Message(ua) {
- var _this;
- _classCallCheck(this, Message);
- _this = _possibleConstructorReturn(this, _getPrototypeOf(Message).call(this));
- _this._ua = ua;
- _this._request = null;
- _this._closed = false;
- _this._direction = null;
- _this._local_identity = null;
- _this._remote_identity = null; // Whether an incoming message has been replied.
- _this._is_replied = false; // Custom message empty object for high level use.
- _this._data = {};
- return _this;
- }
- _createClass(Message, [{
- key: "send",
- value: function send(target, body) {
- var _this2 = this;
- var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
- var originalTarget = target;
- if (target === undefined || body === undefined) {
- throw new TypeError('Not enough arguments');
- } // Check target validity.
- target = this._ua.normalizeTarget(target);
- if (!target) {
- throw new TypeError("Invalid target: ".concat(originalTarget));
- } // Get call options.
- var extraHeaders = Utils.cloneArray(options.extraHeaders);
- var eventHandlers = options.eventHandlers || {};
- var contentType = options.contentType || 'text/plain'; // Set event handlers.
- for (var event in eventHandlers) {
- if (Object.prototype.hasOwnProperty.call(eventHandlers, event)) {
- this.on(event, eventHandlers[event]);
- }
- }
- extraHeaders.push("Content-Type: ".concat(contentType));
- this._request = new SIPMessage.OutgoingRequest(JsSIP_C.MESSAGE, target, this._ua, null, extraHeaders);
- if (body) {
- this._request.body = body;
- }
- var request_sender = new RequestSender(this._ua, this._request, {
- onRequestTimeout: function onRequestTimeout() {
- _this2._onRequestTimeout();
- },
- onTransportError: function onTransportError() {
- _this2._onTransportError();
- },
- onReceiveResponse: function onReceiveResponse(response) {
- _this2._receiveResponse(response);
- }
- });
- this._newMessage('local', this._request);
- request_sender.send();
- }
- }, {
- key: "init_incoming",
- value: function init_incoming(request) {
- this._request = request;
- this._newMessage('remote', request); // Reply with a 200 OK if the user didn't reply.
- if (!this._is_replied) {
- this._is_replied = true;
- request.reply(200);
- }
- this._close();
- }
- /**
- * Accept the incoming Message
- * Only valid for incoming Messages
- */
- }, {
- key: "accept",
- value: function accept() {
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- var extraHeaders = Utils.cloneArray(options.extraHeaders);
- var body = options.body;
- if (this._direction !== 'incoming') {
- throw new Exceptions.NotSupportedError('"accept" not supported for outgoing Message');
- }
- if (this._is_replied) {
- throw new Error('incoming Message already replied');
- }
- this._is_replied = true;
- this._request.reply(200, null, extraHeaders, body);
- }
- /**
- * Reject the incoming Message
- * Only valid for incoming Messages
- */
- }, {
- key: "reject",
- value: function reject() {
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- var status_code = options.status_code || 480;
- var reason_phrase = options.reason_phrase;
- var extraHeaders = Utils.cloneArray(options.extraHeaders);
- var body = options.body;
- if (this._direction !== 'incoming') {
- throw new Exceptions.NotSupportedError('"reject" not supported for outgoing Message');
- }
- if (this._is_replied) {
- throw new Error('incoming Message already replied');
- }
- if (status_code < 300 || status_code >= 700) {
- throw new TypeError("Invalid status_code: ".concat(status_code));
- }
- this._is_replied = true;
- this._request.reply(status_code, reason_phrase, extraHeaders, body);
- }
- }, {
- key: "_receiveResponse",
- value: function _receiveResponse(response) {
- if (this._closed) {
- return;
- }
- switch (true) {
- case /^1[0-9]{2}$/.test(response.status_code):
- // Ignore provisional responses.
- break;
- case /^2[0-9]{2}$/.test(response.status_code):
- this._succeeded('remote', response);
- break;
- default:
- {
- var cause = Utils.sipErrorCause(response.status_code);
- this._failed('remote', response, cause);
- break;
- }
- }
- }
- }, {
- key: "_onRequestTimeout",
- value: function _onRequestTimeout() {
- if (this._closed) {
- return;
- }
- this._failed('system', null, JsSIP_C.causes.REQUEST_TIMEOUT);
- }
- }, {
- key: "_onTransportError",
- value: function _onTransportError() {
- if (this._closed) {
- return;
- }
- this._failed('system', null, JsSIP_C.causes.CONNECTION_ERROR);
- }
- }, {
- key: "_close",
- value: function _close() {
- this._closed = true;
- this._ua.destroyMessage(this);
- }
- /**
- * Internal Callbacks
- */
- }, {
- key: "_newMessage",
- value: function _newMessage(originator, request) {
- if (originator === 'remote') {
- this._direction = 'incoming';
- this._local_identity = request.to;
- this._remote_identity = request.from;
- } else if (originator === 'local') {
- this._direction = 'outgoing';
- this._local_identity = request.from;
- this._remote_identity = request.to;
- }
- this._ua.newMessage(this, {
- originator: originator,
- message: this,
- request: request
- });
- }
- }, {
- key: "_failed",
- value: function _failed(originator, response, cause) {
- debug('MESSAGE failed');
- this._close();
- debug('emit "failed"');
- this.emit('failed', {
- originator: originator,
- response: response || null,
- cause: cause
- });
- }
- }, {
- key: "_succeeded",
- value: function _succeeded(originator, response) {
- debug('MESSAGE succeeded');
- this._close();
- debug('emit "succeeded"');
- this.emit('succeeded', {
- originator: originator,
- response: response
- });
- }
- }, {
- key: "direction",
- get: function get() {
- return this._direction;
- }
- }, {
- key: "local_identity",
- get: function get() {
- return this._local_identity;
- }
- }, {
- key: "remote_identity",
- get: function get() {
- return this._remote_identity;
- }
- }]);
- return Message;
- }(EventEmitter);
- }),
- /* 39 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- var Socket = __webpack_require__(18);
- var debug = __webpack_require__(0)('JsSIP:Transport');
- var debugerror = __webpack_require__(0)('JsSIP:ERROR:Transport');
- var PhoneLogger = __webpack_require__(59);
- var user;
- debugerror.log = console.warn.bind(console);
- /**
- * Constants
- */
- var C = {
- // Transport status.
- STATUS_CONNECTED: 0,
- STATUS_CONNECTING: 1,
- STATUS_DISCONNECTED: 2,
- // Socket status.
- SOCKET_STATUS_READY: 0,
- SOCKET_STATUS_ERROR: 1,
- // Recovery options.
- recovery_options: {
- min_interval: 2,
- // minimum interval in seconds between recover attempts
- max_interval: 30 // maximum interval in seconds between recover attempts
- }
- };
- /*
- * Manages one or multiple JsSIP.Socket instances.
- * Is reponsible for transport recovery logic among all socket instances.
- *
- * @socket JsSIP::Socket instance
- */
- module.exports =
- /*#__PURE__*/
- function () {
- function Transport(sockets) {
- var recovery_options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : C.recovery_options;
- _classCallCheck(this, Transport);
- debug('new()');
- this.status = C.STATUS_DISCONNECTED; // Current socket.
- this.socket = null; // Socket collection.
- this.sockets = [];
- this.recovery_options = recovery_options;
- this.recover_attempts = 0;
- this.recovery_timer = null;
- this.close_requested = false;
- if (typeof sockets === 'undefined') {
- throw new TypeError('Invalid argument.' + ' undefined \'sockets\' argument');
- }
- if (!(sockets instanceof Array)) {
- sockets = [sockets];
- }
- sockets.forEach(function (socket) {
- if (!Socket.isSocket(socket.socket)) {
- throw new TypeError('Invalid argument.' + ' invalid \'JsSIP.Socket\' instance');
- }
- if (socket.weight && !Number(socket.weight)) {
- throw new TypeError('Invalid argument.' + ' \'weight\' attribute is not a number');
- }
- this.sockets.push({
- socket: socket.socket,
- weight: socket.weight || 0,
- status: C.SOCKET_STATUS_READY
- });
- }, this); // Get the socket with higher weight.
- this._getSocket();
- }
- /**
- * Instance Methods
- */
- _createClass(Transport, [{
- key: "connect",
- value: function connect() {
- debug('connect()');
- if (this.isConnected()) {
- debug('Transport is already connected');
- return;
- } else if (this.isConnecting()) {
- debug('Transport is connecting');
- return;
- }
- this.close_requested = false;
- this.status = C.STATUS_CONNECTING;
- this.onconnecting({
- socket: this.socket,
- attempts: this.recover_attempts
- });
- if (!this.close_requested) {
- // Bind socket event callbacks.
- this.socket.onconnect = this._onConnect.bind(this);
- this.socket.ondisconnect = this._onDisconnect.bind(this);
- this.socket.ondata = this._onData.bind(this);
- this.socket.connect();
- }
- return;
- }
- }, {
- key: "disconnect",
- value: function disconnect() {
- debug('close()');
- this.close_requested = true;
- this.recover_attempts = 0;
- this.status = C.STATUS_DISCONNECTED; // Clear recovery_timer.
- if (this.recovery_timer !== null) {
- clearTimeout(this.recovery_timer);
- this.recovery_timer = null;
- } // Unbind socket event callbacks.
- this.socket.onconnect = function () {};
- this.socket.ondisconnect = function () {};
- this.socket.ondata = function () {};
- this.socket.disconnect();
- this.ondisconnect({
- socket: this.socket,
- error: false
- });
- }
- }, {
- key: "send",
- value: function send(data) {
- debug('send()');
- if (!this.isConnected()) {
- debugerror('unable to send message, transport is not connected');
- return false;
- }
- // var uri = JSON.parse(JSON.stringify(data.ua._configuration.uri));
- // const user = '<' + uri._scheme + ':' + uri._user + '@' + uri._host + ':' + uri._port + '>';
- var message = data.toString();
- PhoneLogger.debug({
- direction: 'SEND',
- // user: user,
- data: data
- });
- console.log('%c SEND Message! ', 'background: #D11D05; color: #BABACA');
- console.log(message);
- debug("sending message:\n\n".concat(message, "\n"));
- return this.socket.send(message);
- }
- }, {
- key: "isConnected",
- value: function isConnected() {
- return this.status === C.STATUS_CONNECTED;
- }
- }, {
- key: "isConnecting",
- value: function isConnecting() {
- return this.status === C.STATUS_CONNECTING;
- }
- /**
- * Private API.
- */
- }, {
- key: "_reconnect",
- value: function _reconnect() {
- var _this = this;
- this.recover_attempts += 1;
- var k = Math.floor(Math.random() * Math.pow(2, this.recover_attempts) + 1);
- if (k < this.recovery_options.min_interval) {
- k = this.recovery_options.min_interval;
- } else if (k > this.recovery_options.max_interval) {
- k = this.recovery_options.max_interval;
- }
- debug("reconnection attempt: ".concat(this.recover_attempts, ". next connection attempt in ").concat(k, " seconds"));
- this.recovery_timer = setTimeout(function () {
- if (!_this.close_requested && !(_this.isConnected() || _this.isConnecting())) {
- // Get the next available socket with higher weight.
- _this._getSocket(); // Connect the socket.
- _this.connect();
- }
- }, k * 1000);
- }
- /**
- * get the next available socket with higher weight
- */
- }, {
- key: "_getSocket",
- value: function _getSocket() {
- var candidates = [];
- this.sockets.forEach(function (socket) {
- if (socket.status === C.SOCKET_STATUS_ERROR) {
- return; // continue the array iteration
- } else if (candidates.length === 0) {
- candidates.push(socket);
- } else if (socket.weight > candidates[0].weight) {
- candidates = [socket];
- } else if (socket.weight === candidates[0].weight) {
- candidates.push(socket);
- }
- });
- if (candidates.length === 0) {
- // All sockets have failed. reset sockets status.
- this.sockets.forEach(function (socket) {
- socket.status = C.SOCKET_STATUS_READY;
- }); // Get next available socket.
- this._getSocket();
- return;
- }
- var idx = Math.floor(Math.random() * candidates.length);
- this.socket = candidates[idx].socket;
- }
- /**
- * Socket Event Handlers
- */
- }, {
- key: "_onConnect",
- value: function _onConnect() {
- this.recover_attempts = 0;
- this.status = C.STATUS_CONNECTED; // Clear recovery_timer.
- if (this.recovery_timer !== null) {
- clearTimeout(this.recovery_timer);
- this.recovery_timer = null;
- }
- this.onconnect({
- socket: this
- });
- }
- }, {
- key: "_onDisconnect",
- value: function _onDisconnect(error, code, reason) {
- this.status = C.STATUS_DISCONNECTED;
- this.ondisconnect({
- socket: this.socket,
- error: error,
- code: code,
- reason: reason
- });
- if (this.close_requested) {
- return;
- } // Update socket status.
- else {
- this.sockets.forEach(function (socket) {
- if (this.socket === socket.socket) {
- socket.status = C.SOCKET_STATUS_ERROR;
- }
- }, this);
- }
- this._reconnect(error);
- }
- }, {
- key: "_onData",
- value: function _onData(data) {
- // CRLF Keep Alive response from server. Ignore it.
- if (data === '\r\n') {
- debug('received message with CRLF Keep Alive response');
- return;
- } // Binary message.
- else if (typeof data !== 'string') {
- try {
- data = String.fromCharCode.apply(null, new Uint8Array(data));
- } catch (evt) {
- debug('received binary message failed to be converted into string,' + ' message discarded');
- return;
- }
- debug("received binary message:\n\n".concat(data, "\n"));
- } // Text message.
- else {
- // console.log(data)
- // const uri = data.ua._configuration.uri;
- // const user = '<' + uri._scheme + ':' + uri._user + '@' + uri._host + ':' + uri._port + '>'
- PhoneLogger.debug({
- direction: 'RECV',
- // user: user,
- data: data
- });
-
- debug("received text message:\n\n".concat(data, "\n"));
- }
- // console.log("received text message:");
- console.log('%c RECEIVED Message! ', 'background: #02AC1E; color: #BABACA');
- console.log(data);
- this.ondata({
- transport: this,
- message: data
- });
- }
- }, {
- key: "via_transport",
- get: function get() {
- return this.socket.via_transport;
- }
- }, {
- key: "url",
- get: function get() {
- return this.socket.url;
- }
- }, {
- key: "sip_uri",
- get: function get() {
- return this.socket.sip_uri;
- }
- }]);
- return Transport;
- }();
- }),
- /* 40 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- var Grammar = __webpack_require__(3);
- var SIPMessage = __webpack_require__(5);
- var debugerror = __webpack_require__(0)('JsSIP:ERROR:Parser');
- debugerror.log = console.warn.bind(console);
- /**
- * Parse SIP Message
- */
- exports.parseMessage = function (data, ua) {
- var message;
- var bodyStart;
- var headerEnd = data.indexOf('\r\n');
- if (headerEnd === -1) {
- debugerror('parseMessage() | no CRLF found, not a SIP message');
- return;
- } // Parse first line. Check if it is a Request or a Reply.
- var firstLine = data.substring(0, headerEnd);
- var parsed = Grammar.parse(firstLine, 'Request_Response');
- if (parsed === -1) {
- debugerror("parseMessage() | error parsing first line of SIP message: \"".concat(firstLine, "\""));
- return;
- } else if (!parsed.status_code) {
- message = new SIPMessage.IncomingRequest(ua);
- message.method = parsed.method;
- message.ruri = parsed.uri;
- } else {
- message = new SIPMessage.IncomingResponse();
- message.status_code = parsed.status_code;
- message.reason_phrase = parsed.reason_phrase;
- }
- message.data = data;
- var headerStart = headerEnd + 2;
- /* Loop over every line in data. Detect the end of each header and parse
- * it or simply add to the headers collection.
- */
- while (true) {
- headerEnd = getHeader(data, headerStart); // The SIP message has normally finished.
- if (headerEnd === -2) {
- bodyStart = headerStart + 2;
- break;
- } // Data.indexOf returned -1 due to a malformed message.
- else if (headerEnd === -1) {
- debugerror('parseMessage() | malformed message');
- return;
- }
- parsed = parseHeader(message, data, headerStart, headerEnd);
- if (parsed !== true) {
- debugerror('parseMessage() |', parsed.error);
- return;
- }
- headerStart = headerEnd + 2;
- }
- /* RFC3261 18.3.
- * If there are additional bytes in the transport packet
- * beyond the end of the body, they MUST be discarded.
- */
- if (message.hasHeader('content-length')) {
- var contentLength = message.getHeader('content-length');
- message.body = data.substr(bodyStart, contentLength);
- } else {
- message.body = data.substring(bodyStart);
- }
- return message;
- };
- /**
- * Extract and parse every header of a SIP message.
- */
- function getHeader(data, headerStart) {
- // 'start' position of the header.
- var start = headerStart; // 'end' position of the header.
- var end = 0; // 'partial end' position of the header.
- var partialEnd = 0; // End of message.
- if (data.substring(start, start + 2).match(/(^\r\n)/)) {
- return -2;
- }
- while (end === 0) {
- // Partial End of Header.
- partialEnd = data.indexOf('\r\n', start); // 'indexOf' returns -1 if the value to be found never occurs.
- if (partialEnd === -1) {
- return partialEnd;
- }
- if (!data.substring(partialEnd + 2, partialEnd + 4).match(/(^\r\n)/) && data.charAt(partialEnd + 2).match(/(^\s+)/)) {
- // Not the end of the message. Continue from the next position.
- start = partialEnd + 2;
- } else {
- end = partialEnd;
- }
- }
- return end;
- }
- function parseHeader(message, data, headerStart, headerEnd) {
- var parsed;
- var hcolonIndex = data.indexOf(':', headerStart);
- var headerName = data.substring(headerStart, hcolonIndex).trim();
- var headerValue = data.substring(hcolonIndex + 1, headerEnd).trim(); // If header-field is well-known, parse it.
- switch (headerName.toLowerCase()) {
- case 'via':
- case 'v':
- message.addHeader('via', headerValue);
- if (message.getHeaders('via').length === 1) {
- parsed = message.parseHeader('Via');
- if (parsed) {
- message.via = parsed;
- message.via_branch = parsed.branch;
- }
- } else {
- parsed = 0;
- }
- break;
- case 'from':
- case 'f':
- message.setHeader('from', headerValue);
- parsed = message.parseHeader('from');
- if (parsed) {
- message.from = parsed;
- message.from_tag = parsed.getParam('tag');
- }
- break;
- case 'to':
- case 't':
- message.setHeader('to', headerValue);
- parsed = message.parseHeader('to');
- if (parsed) {
- message.to = parsed;
- message.to_tag = parsed.getParam('tag');
- }
- break;
- case 'record-route':
- parsed = Grammar.parse(headerValue, 'Record_Route');
- if (parsed === -1) {
- parsed = undefined;
- } else {
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
- try {
- for (var _iterator = parsed[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var header = _step.value;
- message.addHeader('record-route', headerValue.substring(header.possition, header.offset));
- message.headers['Record-Route'][message.getHeaders('record-route').length - 1].parsed = header.parsed;
- }
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator.return != null) {
- _iterator.return();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
- }
- }
- break;
- case 'call-id':
- case 'i':
- message.setHeader('call-id', headerValue);
- parsed = message.parseHeader('call-id');
- if (parsed) {
- message.call_id = headerValue;
- }
- break;
- case 'contact':
- case 'm':
- parsed = Grammar.parse(headerValue, 'Contact');
- if (parsed === -1) {
- parsed = undefined;
- } else {
- var _iteratorNormalCompletion2 = true;
- var _didIteratorError2 = false;
- var _iteratorError2 = undefined;
- try {
- for (var _iterator2 = parsed[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
- var _header = _step2.value;
- message.addHeader('contact', headerValue.substring(_header.possition, _header.offset));
- message.headers.Contact[message.getHeaders('contact').length - 1].parsed = _header.parsed;
- }
- } catch (err) {
- _didIteratorError2 = true;
- _iteratorError2 = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
- _iterator2.return();
- }
- } finally {
- if (_didIteratorError2) {
- throw _iteratorError2;
- }
- }
- }
- }
- break;
- case 'content-length':
- case 'l':
- message.setHeader('content-length', headerValue);
- parsed = message.parseHeader('content-length');
- break;
- case 'content-type':
- case 'c':
- message.setHeader('content-type', headerValue);
- parsed = message.parseHeader('content-type');
- break;
- case 'cseq':
- message.setHeader('cseq', headerValue);
- parsed = message.parseHeader('cseq');
- if (parsed) {
- message.cseq = parsed.value;
- }
- if (message instanceof SIPMessage.IncomingResponse) {
- message.method = parsed.method;
- }
- break;
- case 'max-forwards':
- message.setHeader('max-forwards', headerValue);
- parsed = message.parseHeader('max-forwards');
- break;
- case 'www-authenticate':
- message.setHeader('www-authenticate', headerValue);
- parsed = message.parseHeader('www-authenticate');
- break;
- case 'proxy-authenticate':
- message.setHeader('proxy-authenticate', headerValue);
- parsed = message.parseHeader('proxy-authenticate');
- break;
- case 'session-expires':
- case 'x':
- message.setHeader('session-expires', headerValue);
- parsed = message.parseHeader('session-expires');
- if (parsed) {
- message.session_expires = parsed.expires;
- message.session_expires_refresher = parsed.refresher;
- }
- break;
- case 'refer-to':
- case 'r':
- message.setHeader('refer-to', headerValue);
- parsed = message.parseHeader('refer-to');
- if (parsed) {
- message.refer_to = parsed;
- }
- break;
- case 'replaces':
- message.setHeader('replaces', headerValue);
- parsed = message.parseHeader('replaces');
- if (parsed) {
- message.replaces = parsed;
- }
- break;
- case 'event':
- case 'o':
- message.setHeader('event', headerValue);
- parsed = message.parseHeader('event');
- if (parsed) {
- message.event = parsed;
- }
- break;
- default:
- // Do not parse this header.
- message.addHeader(headerName, headerValue);
- parsed = 0;
- }
- if (parsed === undefined) {
- return {
- error: "error parsing header \"".concat(headerName, "\"")
- };
- } else {
- return true;
- }
- }
- }),
- /* 41 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- var JsSIP_C = __webpack_require__(1);
- var SIPMessage = __webpack_require__(5);
- var Utils = __webpack_require__(2);
- var debug = __webpack_require__(0)('JsSIP:sanityCheck'); // Checks for requests and responses.
- var all = [minimumHeaders]; // Checks for requests.
- var requests = [rfc3261_8_2_2_1, rfc3261_16_3_4, rfc3261_18_3_request, rfc3261_8_2_2_2]; // Checks for responses.
- var responses = [rfc3261_8_1_3_3, rfc3261_18_3_response]; // local variables.
- var message;
- var ua;
- var transport;
- module.exports = function (m, u, t) {
- message = m;
- ua = u;
- transport = t;
- for (var _i = 0; _i < all.length; _i++) {
- var _check2 = all[_i];
- if (_check2() === false) {
- return false;
- }
- }
- if (message instanceof SIPMessage.IncomingRequest) {
- for (var _i2 = 0; _i2 < requests.length; _i2++) {
- var check = requests[_i2];
- if (check() === false) {
- return false;
- }
- }
- } else if (message instanceof SIPMessage.IncomingResponse) {
- for (var _i3 = 0; _i3 < responses.length; _i3++) {
- var _check = responses[_i3];
- if (_check() === false) {
- return false;
- }
- }
- } // Everything is OK.
- return true;
- };
- /*
- * Sanity Check for incoming Messages
- *
- * Requests:
- * - _rfc3261_8_2_2_1_ Receive a Request with a non supported URI scheme
- * - _rfc3261_16_3_4_ Receive a Request already sent by us
- * Does not look at via sent-by but at jssip_id, which is inserted as
- * a prefix in all initial requests generated by the ua
- * - _rfc3261_18_3_request_ Body Content-Length
- * - _rfc3261_8_2_2_2_ Merged Requests
- *
- * Responses:
- * - _rfc3261_8_1_3_3_ Multiple Via headers
- * - _rfc3261_18_3_response_ Body Content-Length
- *
- * All:
- * - Minimum headers in a SIP message
- */
- // Sanity Check functions for requests.
- function rfc3261_8_2_2_1() {
- if (message.s('to').uri.scheme !== 'sip') {
- reply(416);
- return false;
- }
- }
- function rfc3261_16_3_4() {
- if (!message.to_tag) {
- if (message.call_id.substr(0, 5) === ua.configuration.jssip_id) {
- reply(482);
- return false;
- }
- }
- }
- function rfc3261_18_3_request() {
- var len = Utils.str_utf8_length(message.body);
- var contentLength = message.getHeader('content-length');
- if (len < contentLength) {
- reply(400);
- return false;
- }
- }
- function rfc3261_8_2_2_2() {
- var fromTag = message.from_tag;
- var call_id = message.call_id;
- var cseq = message.cseq;
- var tr; // Accept any in-dialog request.
- if (message.to_tag) {
- return;
- } // INVITE request.
- if (message.method === JsSIP_C.INVITE) {
- // If the branch matches the key of any IST then assume it is a retransmission
- // and ignore the INVITE.
- // TODO: we should reply the last response.
- if (ua._transactions.ist[message.via_branch]) {
- return false;
- } // Otherwise check whether it is a merged request.
- else {
- for (var transaction in ua._transactions.ist) {
- if (Object.prototype.hasOwnProperty.call(ua._transactions.ist, transaction)) {
- tr = ua._transactions.ist[transaction];
- if (tr.request.from_tag === fromTag && tr.request.call_id === call_id && tr.request.cseq === cseq) {
- reply(482);
- return false;
- }
- }
- }
- }
- } // Non INVITE request.
- // If the branch matches the key of any NIST then assume it is a retransmission
- // and ignore the request.
- // TODO: we should reply the last response.
- else if (ua._transactions.nist[message.via_branch]) {
- return false;
- } // Otherwise check whether it is a merged request.
- else {
- for (var _transaction in ua._transactions.nist) {
- if (Object.prototype.hasOwnProperty.call(ua._transactions.nist, _transaction)) {
- tr = ua._transactions.nist[_transaction];
- if (tr.request.from_tag === fromTag && tr.request.call_id === call_id && tr.request.cseq === cseq) {
- reply(482);
- return false;
- }
- }
- }
- }
- } // Sanity Check functions for responses.
- function rfc3261_8_1_3_3() {
- if (message.getHeaders('via').length > 1) {
- debug('more than one Via header field present in the response, dropping the response');
- return false;
- }
- }
- function rfc3261_18_3_response() {
- var len = Utils.str_utf8_length(message.body),
- contentLength = message.getHeader('content-length');
- if (len < contentLength) {
- debug('message body length is lower than the value in Content-Length header field, dropping the response');
- return false;
- }
- } // Sanity Check functions for requests and responses.
- function minimumHeaders() {
- var mandatoryHeaders = ['from', 'to', 'call_id', 'cseq', 'via'];
- for (var _i4 = 0; _i4 < mandatoryHeaders.length; _i4++) {
- var header = mandatoryHeaders[_i4];
- if (!message.hasHeader(header)) {
- debug("missing mandatory header field : ".concat(header, ", dropping the response"));
- return false;
- }
- }
- } // Reply.
- function reply(status_code) {
- var vias = message.getHeaders('via');
- var to;
- var response = "SIP/2.0 ".concat(status_code, " ").concat(JsSIP_C.REASON_PHRASE[status_code], "\r\n");
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
- try {
- for (var _iterator = vias[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var via = _step.value;
- response += "Via: ".concat(via, "\r\n");
- }
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator.return != null) {
- _iterator.return();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
- }
- to = message.getHeader('To');
- if (!message.to_tag) {
- to += ";tag=".concat(Utils.newTag());
- }
- response += "To: ".concat(to, "\r\n");
- response += "From: ".concat(message.getHeader('From'), "\r\n");
- response += "Call-ID: ".concat(message.call_id, "\r\n");
- response += "CSeq: ".concat(message.cseq, " ").concat(message.method, "\r\n");
- response += '\r\n';
- transport.send(response);
- }
- }),
- /* 42 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- var Utils = __webpack_require__(2);
- var JsSIP_C = __webpack_require__(1);
- var Grammar = __webpack_require__(3);
- var URI = __webpack_require__(8);
- var Socket = __webpack_require__(18);
- var Exceptions = __webpack_require__(6); // Default settings.
- exports.settings = {
- // SIP authentication.
- authorization_user: null,
- password: null,
- realm: null,
- ha1: null,
- // SIP account.
- display_name: null,
- uri: null,
- contact_uri: null,
- // SIP instance id (GRUU).
- instance_id: null,
- // Preloaded SIP Route header field.
- use_preloaded_route: false,
- // Session parameters.
- session_timers: true,
- session_timers_refresh_method: JsSIP_C.UPDATE,
- no_answer_timeout: 60,
- // Registration parameters.
- register: true,
- register_expires: 600,
- registrar_server: null,
- // Connection options.
- sockets: null,
- connection_recovery_max_interval: null,
- connection_recovery_min_interval: null,
- /*
- * Host address.
- * Value to be set in Via sent_by and host part of Contact FQDN.
- */
- via_host: "".concat(Utils.createRandomToken(12), ".invalid")
- }; // Configuration checks.
- var checks = {
- mandatory: {
- sockets: function sockets(_sockets2) {
- /* Allow defining sockets parameter as:
- * Socket: socket
- * Array of Socket: [socket1, socket2]
- * Array of Objects: [{socket: socket1, weight:1}, {socket: Socket2, weight:0}]
- * Array of Objects and Socket: [{socket: socket1}, socket2]
- */
- var _sockets = [];
- if (Socket.isSocket(_sockets2)) {
- _sockets.push({
- socket: _sockets2
- });
- } else if (Array.isArray(_sockets2) && _sockets2.length) {
- var _iteratorNormalCompletion = true;
- var _didIteratorError = false;
- var _iteratorError = undefined;
- try {
- for (var _iterator = _sockets2[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
- var socket = _step.value;
- if (Object.prototype.hasOwnProperty.call(socket, 'socket') && Socket.isSocket(socket.socket)) {
- _sockets.push(socket);
- } else if (Socket.isSocket(socket)) {
- _sockets.push({
- socket: socket
- });
- }
- }
- } catch (err) {
- _didIteratorError = true;
- _iteratorError = err;
- } finally {
- try {
- if (!_iteratorNormalCompletion && _iterator.return != null) {
- _iterator.return();
- }
- } finally {
- if (_didIteratorError) {
- throw _iteratorError;
- }
- }
- }
- } else {
- return;
- }
- return _sockets;
- },
- uri: function uri(_uri) {
- if (!/^sip:/i.test(_uri)) {
- _uri = "".concat(JsSIP_C.SIP, ":").concat(_uri);
- }
- var parsed = URI.parse(_uri);
- if (!parsed) {
- return;
- } else if (!parsed.user) {
- return;
- } else {
- return parsed;
- }
- }
- },
- optional: {
- authorization_user: function authorization_user(_authorization_user) {
- if (Grammar.parse("\"".concat(_authorization_user, "\""), 'quoted_string') === -1) {
- return;
- } else {
- return _authorization_user;
- }
- },
- user_agent: function user_agent(_user_agent) {
- if (typeof _user_agent === 'string') {
- return _user_agent;
- }
- },
- connection_recovery_max_interval: function connection_recovery_max_interval(_connection_recovery_max_interval) {
- if (Utils.isDecimal(_connection_recovery_max_interval)) {
- var value = Number(_connection_recovery_max_interval);
- if (value > 0) {
- return value;
- }
- }
- },
- connection_recovery_min_interval: function connection_recovery_min_interval(_connection_recovery_min_interval) {
- if (Utils.isDecimal(_connection_recovery_min_interval)) {
- var value = Number(_connection_recovery_min_interval);
- if (value > 0) {
- return value;
- }
- }
- },
- contact_uri: function contact_uri(_contact_uri) {
- if (typeof _contact_uri === 'string') {
- var uri = Grammar.parse(_contact_uri, 'SIP_URI');
- if (uri !== -1) {
- return uri;
- }
- }
- },
- display_name: function display_name(_display_name) {
- if (Grammar.parse("\"".concat(_display_name, "\""), 'display_name') === -1) {
- return;
- } else {
- return _display_name;
- }
- },
- instance_id: function instance_id(_instance_id) {
- if (/^uuid:/i.test(_instance_id)) {
- _instance_id = _instance_id.substr(5);
- }
- if (Grammar.parse(_instance_id, 'uuid') === -1) {
- return;
- } else {
- return _instance_id;
- }
- },
- no_answer_timeout: function no_answer_timeout(_no_answer_timeout) {
- if (Utils.isDecimal(_no_answer_timeout)) {
- var value = Number(_no_answer_timeout);
- if (value > 0) {
- return value;
- }
- }
- },
- session_timers: function session_timers(_session_timers) {
- if (typeof _session_timers === 'boolean') {
- return _session_timers;
- }
- },
- session_timers_refresh_method: function session_timers_refresh_method(method) {
- if (typeof method === 'string') {
- method = method.toUpperCase();
- if (method === JsSIP_C.INVITE || method === JsSIP_C.UPDATE) {
- return method;
- }
- }
- },
- password: function password(_password) {
- return String(_password);
- },
- realm: function realm(_realm) {
- return String(_realm);
- },
- ha1: function ha1(_ha) {
- return String(_ha);
- },
- register: function register(_register) {
- if (typeof _register === 'boolean') {
- return _register;
- }
- },
- register_expires: function register_expires(_register_expires) {
- if (Utils.isDecimal(_register_expires)) {
- var value = Number(_register_expires);
- if (value > 0) {
- return value;
- }
- }
- },
- registrar_server: function registrar_server(_registrar_server) {
- if (!/^sip:/i.test(_registrar_server)) {
- _registrar_server = "".concat(JsSIP_C.SIP, ":").concat(_registrar_server);
- }
- var parsed = URI.parse(_registrar_server);
- if (!parsed) {
- return;
- } else if (parsed.user) {
- return;
- } else {
- return parsed;
- }
- },
- use_preloaded_route: function use_preloaded_route(_use_preloaded_route) {
- if (typeof _use_preloaded_route === 'boolean') {
- return _use_preloaded_route;
- }
- }
- }
- };
- exports.load = function (dst, src) {
- // Check Mandatory parameters.
- for (var parameter in checks.mandatory) {
- if (!src.hasOwnProperty(parameter)) {
- throw new Exceptions.ConfigurationError(parameter);
- } else {
- var value = src[parameter];
- var checked_value = checks.mandatory[parameter](value);
- if (checked_value !== undefined) {
- dst[parameter] = checked_value;
- } else {
- throw new Exceptions.ConfigurationError(parameter, value);
- }
- }
- } // Check Optional parameters.
- for (var _parameter in checks.optional) {
- if (src.hasOwnProperty(_parameter)) {
- var _value = src[_parameter];
- /* If the parameter value is null, empty string, undefined, empty array
- * or it's a number with NaN value, then apply its default value.
- */
- if (Utils.isEmpty(_value)) {
- continue;
- }
- var _checked_value = checks.optional[_parameter](_value);
- if (_checked_value !== undefined) {
- dst[_parameter] = _checked_value;
- } else {
- throw new Exceptions.ConfigurationError(_parameter, _value);
- }
- }
- }
- };
- }),
- /* 43 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- }
- function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- return Constructor;
- }
- var Grammar = __webpack_require__(3);
- var debug = __webpack_require__(0)('JsSIP:WebSocketInterface');
- var debugerror = __webpack_require__(0)('JsSIP:ERROR:WebSocketInterface');
- var PhoneNetwork = __webpack_require__(61);
- debugerror.log = console.warn.bind(console);
- module.exports =
- /*#__PURE__*/
- function () {
- function WebSocketInterface(url) {
- _classCallCheck(this, WebSocketInterface);
- debug('new() [url:"%s"]', url);
- this._url = url;
- this._sip_uri = null;
- this._via_transport = null;
- this._ws = null;
- var parsed_url = Grammar.parse(url, 'absoluteURI');
- if (parsed_url === -1) {
- debugerror("invalid WebSocket URI: ".concat(url));
- throw new TypeError("Invalid argument: ".concat(url));
- } else if (parsed_url.scheme !== 'wss' && parsed_url.scheme !== 'ws') {
- debugerror("invalid WebSocket URI scheme: ".concat(parsed_url.scheme));
- throw new TypeError("Invalid argument: ".concat(url));
- } else {
- this._sip_uri = "sip:".concat(parsed_url.host).concat(parsed_url.port ? ":".concat(parsed_url.port) : '', ";transport=udp");
- this._via_transport = parsed_url.scheme.toUpperCase();
- }
- }
- _createClass(WebSocketInterface, [{
- key: "connect",
- value: function connect() {
- debug('connect()');
- if (this.isConnected()) {
- debug("WebSocket ".concat(this._url, " is already connected"));
- return;
- } else if (this.isConnecting()) {
- debug("WebSocket ".concat(this._url, " is connecting"));
- return;
- }
- if (this._ws) {
- this.disconnect();
- }
- debug("connecting to WebSocket ".concat(this._url));
- PhoneNetwork.test();
- try {
- this._ws = new WebSocket(this._url, 'sip');
- this._ws.binaryType = 'arraybuffer';
- this._ws.onopen = this._onOpen.bind(this);
- this._ws.onclose = this._onClose.bind(this);
- this._ws.onmessage = this._onMessage.bind(this);
- this._ws.onerror = this._onError.bind(this);
- } catch (e) {
- this._onError(e);
- }
- }
- }, {
- key: "disconnect",
- value: function disconnect() {
- debug('disconnect()');
- if (this._ws) {
- // Unbind websocket event callbacks.
- this._ws.onopen = function () {};
- this._ws.onclose = function () {};
- this._ws.onmessage = function () {};
- this._ws.onerror = function () {};
- this._ws.close();
- this._ws = null;
- }
- }
- }, {
- key: "send",
- value: function send(message) {
- debug('send()');
- if (this.isConnected()) {
- this._ws.send(message);
- return true;
- } else {
- debugerror('unable to send message, WebSocket is not open');
- return false;
- }
- }
- }, {
- key: "isConnected",
- value: function isConnected() {
- return this._ws && this._ws.readyState === this._ws.OPEN;
- }
- }, {
- key: "isConnecting",
- value: function isConnecting() {
- return this._ws && this._ws.readyState === this._ws.CONNECTING;
- }
- /**
- * WebSocket Event Handlers
- */
- }, {
- key: "_onOpen",
- value: function _onOpen() {
- debug("WebSocket ".concat(this._url, " connected"));
- this.onconnect();
- }
- }, {
- key: "_onClose",
- value: function _onClose(_ref) {
- var wasClean = _ref.wasClean,
- code = _ref.code,
- reason = _ref.reason;
- debug("WebSocket ".concat(this._url, " closed"));
- if (wasClean === false) {
- debug('WebSocket abrupt disconnection');
- }
- var data = {
- socket: this,
- error: !wasClean,
- code: code,
- reason: reason
- };
- this.ondisconnect(data);
- }
- }, {
- key: "_onMessage",
- value: function _onMessage(_ref2) {
- var data = _ref2.data;
- debug('received WebSocket message');
- this.ondata(data);
- }
- }, {
- key: "_onError",
- value: function _onError(e) {
- debugerror("WebSocket ".concat(this._url, " error: ").concat(e));
- }
- }, {
- key: "via_transport",
- get: function get() {
- return this._via_transport;
- },
- set: function set(value) {
- this._via_transport = value.toUpperCase();
- }
- }, {
- key: "sip_uri",
- get: function get() {
- return this._sip_uri;
- }
- }, {
- key: "url",
- get: function get() {
- return this._url;
- }
- }]);
- return WebSocketInterface;
- }();
- }),
- /* 44 */
- (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__adapter_factory_js__ = __webpack_require__(45);
- /*
- * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- /* eslint-env node */
- const adapter = Object(__WEBPACK_IMPORTED_MODULE_0__adapter_factory_js__["a" /* adapterFactory */])({
- window
- });
- /* harmony default export */ __webpack_exports__["default"] = (adapter);
- }),
- /* 45 */
- (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- /* harmony export (immutable) */ __webpack_exports__["a"] = adapterFactory;
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils__ = __webpack_require__(4);
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__chrome_chrome_shim__ = __webpack_require__(46);
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__edge_edge_shim__ = __webpack_require__(49);
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__firefox_firefox_shim__ = __webpack_require__(54);
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__safari_safari_shim__ = __webpack_require__(57);
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__common_shim__ = __webpack_require__(58);
- /*
- * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- // Browser shims.
- // Shimming starts here.
- function adapterFactory({
- window
- } = {}, options = {
- shimChrome: true,
- shimFirefox: true,
- shimEdge: true,
- shimSafari: true
- }) {
- // Utils.
- const logging = __WEBPACK_IMPORTED_MODULE_0__utils__["f" /* log */];
- const browserDetails = __WEBPACK_IMPORTED_MODULE_0__utils__["b" /* detectBrowser */](window);
- const adapter = {
- browserDetails,
- commonShim: __WEBPACK_IMPORTED_MODULE_5__common_shim__,
- extractVersion: __WEBPACK_IMPORTED_MODULE_0__utils__["e" /* extractVersion */],
- disableLog: __WEBPACK_IMPORTED_MODULE_0__utils__["c" /* disableLog */],
- disableWarnings: __WEBPACK_IMPORTED_MODULE_0__utils__["d" /* disableWarnings */]
- }; // Shim browser if found.
- switch (browserDetails.browser) {
- case 'chrome':
- if (!__WEBPACK_IMPORTED_MODULE_1__chrome_chrome_shim__ || !__WEBPACK_IMPORTED_MODULE_1__chrome_chrome_shim__["shimPeerConnection"] || !options.shimChrome) {
- logging('Chrome shim is not included in this adapter release.');
- return adapter;
- }
- logging('adapter.js shimming chrome.'); // Export to the adapter global object visible in the browser.
- adapter.browserShim = __WEBPACK_IMPORTED_MODULE_1__chrome_chrome_shim__;
- __WEBPACK_IMPORTED_MODULE_1__chrome_chrome_shim__["shimGetUserMedia"](window);
- __WEBPACK_IMPORTED_MODULE_1__chrome_chrome_shim__["shimMediaStream"](window);
- __WEBPACK_IMPORTED_MODULE_1__chrome_chrome_shim__["shimPeerConnection"](window);
- __WEBPACK_IMPORTED_MODULE_1__chrome_chrome_shim__["shimOnTrack"](window);
- __WEBPACK_IMPORTED_MODULE_1__chrome_chrome_shim__["shimAddTrackRemoveTrack"](window);
- __WEBPACK_IMPORTED_MODULE_1__chrome_chrome_shim__["shimGetSendersWithDtmf"](window);
- __WEBPACK_IMPORTED_MODULE_1__chrome_chrome_shim__["shimSenderReceiverGetStats"](window);
- __WEBPACK_IMPORTED_MODULE_1__chrome_chrome_shim__["fixNegotiationNeeded"](window);
- __WEBPACK_IMPORTED_MODULE_5__common_shim__["shimRTCIceCandidate"](window);
- __WEBPACK_IMPORTED_MODULE_5__common_shim__["shimConnectionState"](window);
- __WEBPACK_IMPORTED_MODULE_5__common_shim__["shimMaxMessageSize"](window);
- __WEBPACK_IMPORTED_MODULE_5__common_shim__["shimSendThrowTypeError"](window);
- break;
- case 'firefox':
- if (!__WEBPACK_IMPORTED_MODULE_3__firefox_firefox_shim__ || !__WEBPACK_IMPORTED_MODULE_3__firefox_firefox_shim__["shimPeerConnection"] || !options.shimFirefox) {
- logging('Firefox shim is not included in this adapter release.');
- return adapter;
- }
- logging('adapter.js shimming firefox.'); // Export to the adapter global object visible in the browser.
- adapter.browserShim = __WEBPACK_IMPORTED_MODULE_3__firefox_firefox_shim__;
- __WEBPACK_IMPORTED_MODULE_3__firefox_firefox_shim__["shimGetUserMedia"](window);
- __WEBPACK_IMPORTED_MODULE_3__firefox_firefox_shim__["shimPeerConnection"](window);
- __WEBPACK_IMPORTED_MODULE_3__firefox_firefox_shim__["shimOnTrack"](window);
- __WEBPACK_IMPORTED_MODULE_3__firefox_firefox_shim__["shimRemoveStream"](window);
- __WEBPACK_IMPORTED_MODULE_3__firefox_firefox_shim__["shimSenderGetStats"](window);
- __WEBPACK_IMPORTED_MODULE_3__firefox_firefox_shim__["shimReceiverGetStats"](window);
- __WEBPACK_IMPORTED_MODULE_3__firefox_firefox_shim__["shimRTCDataChannel"](window);
- __WEBPACK_IMPORTED_MODULE_5__common_shim__["shimRTCIceCandidate"](window);
- __WEBPACK_IMPORTED_MODULE_5__common_shim__["shimConnectionState"](window);
- __WEBPACK_IMPORTED_MODULE_5__common_shim__["shimMaxMessageSize"](window);
- __WEBPACK_IMPORTED_MODULE_5__common_shim__["shimSendThrowTypeError"](window);
- break;
- case 'edge':
- if (!__WEBPACK_IMPORTED_MODULE_2__edge_edge_shim__ || !__WEBPACK_IMPORTED_MODULE_2__edge_edge_shim__["shimPeerConnection"] || !options.shimEdge) {
- logging('MS edge shim is not included in this adapter release.');
- return adapter;
- }
- logging('adapter.js shimming edge.'); // Export to the adapter global object visible in the browser.
- adapter.browserShim = __WEBPACK_IMPORTED_MODULE_2__edge_edge_shim__;
- __WEBPACK_IMPORTED_MODULE_2__edge_edge_shim__["shimGetUserMedia"](window);
- __WEBPACK_IMPORTED_MODULE_2__edge_edge_shim__["shimGetDisplayMedia"](window);
- __WEBPACK_IMPORTED_MODULE_2__edge_edge_shim__["shimPeerConnection"](window);
- __WEBPACK_IMPORTED_MODULE_2__edge_edge_shim__["shimReplaceTrack"](window); // the edge shim implements the full RTCIceCandidate object.
- __WEBPACK_IMPORTED_MODULE_5__common_shim__["shimMaxMessageSize"](window);
- __WEBPACK_IMPORTED_MODULE_5__common_shim__["shimSendThrowTypeError"](window);
- break;
- case 'safari':
- if (!__WEBPACK_IMPORTED_MODULE_4__safari_safari_shim__ || !options.shimSafari) {
- logging('Safari shim is not included in this adapter release.');
- return adapter;
- }
- logging('adapter.js shimming safari.'); // Export to the adapter global object visible in the browser.
- adapter.browserShim = __WEBPACK_IMPORTED_MODULE_4__safari_safari_shim__;
- __WEBPACK_IMPORTED_MODULE_4__safari_safari_shim__["shimRTCIceServerUrls"](window);
- __WEBPACK_IMPORTED_MODULE_4__safari_safari_shim__["shimCreateOfferLegacy"](window);
- __WEBPACK_IMPORTED_MODULE_4__safari_safari_shim__["shimCallbacksAPI"](window);
- __WEBPACK_IMPORTED_MODULE_4__safari_safari_shim__["shimLocalStreamsAPI"](window);
- __WEBPACK_IMPORTED_MODULE_4__safari_safari_shim__["shimRemoteStreamsAPI"](window);
- __WEBPACK_IMPORTED_MODULE_4__safari_safari_shim__["shimTrackEventTransceiver"](window);
- __WEBPACK_IMPORTED_MODULE_4__safari_safari_shim__["shimGetUserMedia"](window);
- __WEBPACK_IMPORTED_MODULE_5__common_shim__["shimRTCIceCandidate"](window);
- __WEBPACK_IMPORTED_MODULE_5__common_shim__["shimMaxMessageSize"](window);
- __WEBPACK_IMPORTED_MODULE_5__common_shim__["shimSendThrowTypeError"](window);
- break;
- default:
- logging('Unsupported browser!');
- break;
- }
- return adapter;
- }
- }),
- /* 46 */
- (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
- /* harmony export (immutable) */ __webpack_exports__["shimMediaStream"] = shimMediaStream;
- /* harmony export (immutable) */ __webpack_exports__["shimOnTrack"] = shimOnTrack;
- /* harmony export (immutable) */ __webpack_exports__["shimGetSendersWithDtmf"] = shimGetSendersWithDtmf;
- /* harmony export (immutable) */ __webpack_exports__["shimSenderReceiverGetStats"] = shimSenderReceiverGetStats;
- /* harmony export (immutable) */ __webpack_exports__["shimAddTrackRemoveTrackWithNative"] = shimAddTrackRemoveTrackWithNative;
- /* harmony export (immutable) */ __webpack_exports__["shimAddTrackRemoveTrack"] = shimAddTrackRemoveTrack;
- /* harmony export (immutable) */ __webpack_exports__["shimPeerConnection"] = shimPeerConnection;
- /* harmony export (immutable) */ __webpack_exports__["fixNegotiationNeeded"] = fixNegotiationNeeded;
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_js__ = __webpack_require__(4);
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__getusermedia__ = __webpack_require__(47);
- /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "shimGetUserMedia", function() { return __WEBPACK_IMPORTED_MODULE_1__getusermedia__["a"]; });
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__getdisplaymedia__ = __webpack_require__(48);
- /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "shimGetDisplayMedia", function() { return __WEBPACK_IMPORTED_MODULE_2__getdisplaymedia__["a"]; });
- /*
- * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- /* eslint-env node */
- /* iterates the stats graph recursively. */
- function walkStats(stats, base, resultSet) {
- if (!base || resultSet.has(base.id)) {
- return;
- }
- resultSet.set(base.id, base);
- Object.keys(base).forEach(name => {
- if (name.endsWith('Id')) {
- walkStats(stats, stats.get(base[name]), resultSet);
- } else if (name.endsWith('Ids')) {
- base[name].forEach(id => {
- walkStats(stats, stats.get(id), resultSet);
- });
- }
- });
- }
- /* filter getStats for a sender/receiver track. */
- function filterStats(result, track, outbound) {
- const streamStatsType = outbound ? 'outbound-rtp' : 'inbound-rtp';
- const filteredResult = new Map();
- if (track === null) {
- return filteredResult;
- }
- const trackStats = [];
- result.forEach(value => {
- if (value.type === 'track' && value.trackIdentifier === track.id) {
- trackStats.push(value);
- }
- });
- trackStats.forEach(trackStat => {
- result.forEach(stats => {
- if (stats.type === streamStatsType && stats.trackId === trackStat.id) {
- walkStats(result, stats, filteredResult);
- }
- });
- });
- return filteredResult;
- }
- function shimMediaStream(window) {
- window.MediaStream = window.MediaStream || window.webkitMediaStream;
- }
- function shimOnTrack(window) {
- if (typeof window === 'object' && window.RTCPeerConnection && !('ontrack' in window.RTCPeerConnection.prototype)) {
- Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', {
- get() {
- return this._ontrack;
- },
- set(f) {
- if (this._ontrack) {
- this.removeEventListener('track', this._ontrack);
- }
- this.addEventListener('track', this._ontrack = f);
- },
- enumerable: true,
- configurable: true
- });
- const origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription;
- window.RTCPeerConnection.prototype.setRemoteDescription = function () {
- if (!this._ontrackpoly) {
- this._ontrackpoly = e => {
- // onaddstream does not fire when a track is added to an existing
- // stream. But stream.onaddtrack is implemented so we use that.
- e.stream.addEventListener('addtrack', te => {
- let receiver;
- if (window.RTCPeerConnection.prototype.getReceivers) {
- receiver = this.getReceivers().find(r => r.track && r.track.id === te.track.id);
- } else {
- receiver = {
- track: te.track
- };
- }
- const event = new Event('track');
- event.track = te.track;
- event.receiver = receiver;
- event.transceiver = {
- receiver
- };
- event.streams = [e.stream];
- this.dispatchEvent(event);
- });
- e.stream.getTracks().forEach(track => {
- let receiver;
- if (window.RTCPeerConnection.prototype.getReceivers) {
- receiver = this.getReceivers().find(r => r.track && r.track.id === track.id);
- } else {
- receiver = {
- track
- };
- }
- const event = new Event('track');
- event.track = track;
- event.receiver = receiver;
- event.transceiver = {
- receiver
- };
- event.streams = [e.stream];
- this.dispatchEvent(event);
- });
- };
- this.addEventListener('addstream', this._ontrackpoly);
- }
- return origSetRemoteDescription.apply(this, arguments);
- };
- } else {
- // even if RTCRtpTransceiver is in window, it is only used and
- // emitted in unified-plan. Unfortunately this means we need
- // to unconditionally wrap the event.
- __WEBPACK_IMPORTED_MODULE_0__utils_js__["g" /* wrapPeerConnectionEvent */](window, 'track', e => {
- if (!e.transceiver) {
- Object.defineProperty(e, 'transceiver', {
- value: {
- receiver: e.receiver
- }
- });
- }
- return e;
- });
- }
- }
- function shimGetSendersWithDtmf(window) {
- // Overrides addTrack/removeTrack, depends on shimAddTrackRemoveTrack.
- if (typeof window === 'object' && window.RTCPeerConnection && !('getSenders' in window.RTCPeerConnection.prototype) && 'createDTMFSender' in window.RTCPeerConnection.prototype) {
- const shimSenderWithDtmf = function (pc, track) {
- return {
- track,
- get dtmf() {
- if (this._dtmf === undefined) {
- if (track.kind === 'audio') {
- this._dtmf = pc.createDTMFSender(track);
- } else {
- this._dtmf = null;
- }
- }
- return this._dtmf;
- },
- _pc: pc
- };
- }; // augment addTrack when getSenders is not available.
- if (!window.RTCPeerConnection.prototype.getSenders) {
- window.RTCPeerConnection.prototype.getSenders = function () {
- this._senders = this._senders || [];
- return this._senders.slice(); // return a copy of the internal state.
- };
- const origAddTrack = window.RTCPeerConnection.prototype.addTrack;
- window.RTCPeerConnection.prototype.addTrack = function (track, stream) {
- let sender = origAddTrack.apply(this, arguments);
- if (!sender) {
- sender = shimSenderWithDtmf(this, track);
- this._senders.push(sender);
- }
- return sender;
- };
- const origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;
- window.RTCPeerConnection.prototype.removeTrack = function (sender) {
- origRemoveTrack.apply(this, arguments);
- const idx = this._senders.indexOf(sender);
- if (idx !== -1) {
- this._senders.splice(idx, 1);
- }
- };
- }
- const origAddStream = window.RTCPeerConnection.prototype.addStream;
- window.RTCPeerConnection.prototype.addStream = function (stream) {
- this._senders = this._senders || [];
- origAddStream.apply(this, [stream]);
- stream.getTracks().forEach(track => {
- this._senders.push(shimSenderWithDtmf(this, track));
- });
- };
- const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
- window.RTCPeerConnection.prototype.removeStream = function (stream) {
- this._senders = this._senders || [];
- origRemoveStream.apply(this, [stream]);
- stream.getTracks().forEach(track => {
- const sender = this._senders.find(s => s.track === track);
- if (sender) {
- // remove sender
- this._senders.splice(this._senders.indexOf(sender), 1);
- }
- });
- };
- } else if (typeof window === 'object' && window.RTCPeerConnection && 'getSenders' in window.RTCPeerConnection.prototype && 'createDTMFSender' in window.RTCPeerConnection.prototype && window.RTCRtpSender && !('dtmf' in window.RTCRtpSender.prototype)) {
- const origGetSenders = window.RTCPeerConnection.prototype.getSenders;
- window.RTCPeerConnection.prototype.getSenders = function () {
- const senders = origGetSenders.apply(this, []);
- senders.forEach(sender => sender._pc = this);
- return senders;
- };
- Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', {
- get() {
- if (this._dtmf === undefined) {
- if (this.track.kind === 'audio') {
- this._dtmf = this._pc.createDTMFSender(this.track);
- } else {
- this._dtmf = null;
- }
- }
- return this._dtmf;
- }
- });
- }
- }
- function shimSenderReceiverGetStats(window) {
- if (!(typeof window === 'object' && window.RTCPeerConnection && window.RTCRtpSender && window.RTCRtpReceiver)) {
- return;
- } // shim sender stats.
- if (!('getStats' in window.RTCRtpSender.prototype)) {
- const origGetSenders = window.RTCPeerConnection.prototype.getSenders;
- if (origGetSenders) {
- window.RTCPeerConnection.prototype.getSenders = function () {
- const senders = origGetSenders.apply(this, []);
- senders.forEach(sender => sender._pc = this);
- return senders;
- };
- }
- const origAddTrack = window.RTCPeerConnection.prototype.addTrack;
- if (origAddTrack) {
- window.RTCPeerConnection.prototype.addTrack = function () {
- const sender = origAddTrack.apply(this, arguments);
- sender._pc = this;
- return sender;
- };
- }
- window.RTCRtpSender.prototype.getStats = function () {
- const sender = this;
- return this._pc.getStats().then(result =>
- /* Note: this will include stats of all senders that
- * send a track with the same id as sender.track as
- * it is not possible to identify the RTCRtpSender.
- */
- filterStats(result, sender.track, true));
- };
- } // shim receiver stats.
- if (!('getStats' in window.RTCRtpReceiver.prototype)) {
- const origGetReceivers = window.RTCPeerConnection.prototype.getReceivers;
- if (origGetReceivers) {
- window.RTCPeerConnection.prototype.getReceivers = function () {
- const receivers = origGetReceivers.apply(this, []);
- receivers.forEach(receiver => receiver._pc = this);
- return receivers;
- };
- }
- __WEBPACK_IMPORTED_MODULE_0__utils_js__["g" /* wrapPeerConnectionEvent */](window, 'track', e => {
- e.receiver._pc = e.srcElement;
- return e;
- });
- window.RTCRtpReceiver.prototype.getStats = function () {
- const receiver = this;
- return this._pc.getStats().then(result => filterStats(result, receiver.track, false));
- };
- }
- if (!('getStats' in window.RTCRtpSender.prototype && 'getStats' in window.RTCRtpReceiver.prototype)) {
- return;
- } // shim RTCPeerConnection.getStats(track).
- const origGetStats = window.RTCPeerConnection.prototype.getStats;
- window.RTCPeerConnection.prototype.getStats = function () {
- if (arguments.length > 0 && arguments[0] instanceof window.MediaStreamTrack) {
- const track = arguments[0];
- let sender;
- let receiver;
- let err;
- this.getSenders().forEach(s => {
- if (s.track === track) {
- if (sender) {
- err = true;
- } else {
- sender = s;
- }
- }
- });
- this.getReceivers().forEach(r => {
- if (r.track === track) {
- if (receiver) {
- err = true;
- } else {
- receiver = r;
- }
- }
- return r.track === track;
- });
- if (err || sender && receiver) {
- return Promise.reject(new DOMException('There are more than one sender or receiver for the track.', 'InvalidAccessError'));
- } else if (sender) {
- return sender.getStats();
- } else if (receiver) {
- return receiver.getStats();
- }
- return Promise.reject(new DOMException('There is no sender or receiver for the track.', 'InvalidAccessError'));
- }
- return origGetStats.apply(this, arguments);
- };
- }
- function shimAddTrackRemoveTrackWithNative(window) {
- // shim addTrack/removeTrack with native variants in order to make
- // the interactions with legacy getLocalStreams behave as in other browsers.
- // Keeps a mapping stream.id => [stream, rtpsenders...]
- window.RTCPeerConnection.prototype.getLocalStreams = function () {
- this._shimmedLocalStreams = this._shimmedLocalStreams || {};
- return Object.keys(this._shimmedLocalStreams).map(streamId => this._shimmedLocalStreams[streamId][0]);
- };
- const origAddTrack = window.RTCPeerConnection.prototype.addTrack;
- window.RTCPeerConnection.prototype.addTrack = function (track, stream) {
- if (!stream) {
- return origAddTrack.apply(this, arguments);
- }
- this._shimmedLocalStreams = this._shimmedLocalStreams || {};
- const sender = origAddTrack.apply(this, arguments);
- if (!this._shimmedLocalStreams[stream.id]) {
- this._shimmedLocalStreams[stream.id] = [stream, sender];
- } else if (this._shimmedLocalStreams[stream.id].indexOf(sender) === -1) {
- this._shimmedLocalStreams[stream.id].push(sender);
- }
- return sender;
- };
- const origAddStream = window.RTCPeerConnection.prototype.addStream;
- window.RTCPeerConnection.prototype.addStream = function (stream) {
- this._shimmedLocalStreams = this._shimmedLocalStreams || {};
- stream.getTracks().forEach(track => {
- const alreadyExists = this.getSenders().find(s => s.track === track);
- if (alreadyExists) {
- throw new DOMException('Track already exists.', 'InvalidAccessError');
- }
- });
- const existingSenders = this.getSenders();
- origAddStream.apply(this, arguments);
- const newSenders = this.getSenders().filter(newSender => existingSenders.indexOf(newSender) === -1);
- this._shimmedLocalStreams[stream.id] = [stream].concat(newSenders);
- };
- const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
- window.RTCPeerConnection.prototype.removeStream = function (stream) {
- this._shimmedLocalStreams = this._shimmedLocalStreams || {};
- delete this._shimmedLocalStreams[stream.id];
- return origRemoveStream.apply(this, arguments);
- };
- const origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;
- window.RTCPeerConnection.prototype.removeTrack = function (sender) {
- this._shimmedLocalStreams = this._shimmedLocalStreams || {};
- if (sender) {
- Object.keys(this._shimmedLocalStreams).forEach(streamId => {
- const idx = this._shimmedLocalStreams[streamId].indexOf(sender);
- if (idx !== -1) {
- this._shimmedLocalStreams[streamId].splice(idx, 1);
- }
- if (this._shimmedLocalStreams[streamId].length === 1) {
- delete this._shimmedLocalStreams[streamId];
- }
- });
- }
- return origRemoveTrack.apply(this, arguments);
- };
- }
- function shimAddTrackRemoveTrack(window) {
- if (!window.RTCPeerConnection) {
- return;
- }
- const browserDetails = __WEBPACK_IMPORTED_MODULE_0__utils_js__["b" /* detectBrowser */](window); // shim addTrack and removeTrack.
- if (window.RTCPeerConnection.prototype.addTrack && browserDetails.version >= 65) {
- return shimAddTrackRemoveTrackWithNative(window);
- } // also shim pc.getLocalStreams when addTrack is shimmed
- // to return the original streams.
- const origGetLocalStreams = window.RTCPeerConnection.prototype.getLocalStreams;
- window.RTCPeerConnection.prototype.getLocalStreams = function () {
- const nativeStreams = origGetLocalStreams.apply(this);
- this._reverseStreams = this._reverseStreams || {};
- return nativeStreams.map(stream => this._reverseStreams[stream.id]);
- };
- const origAddStream = window.RTCPeerConnection.prototype.addStream;
- window.RTCPeerConnection.prototype.addStream = function (stream) {
- this._streams = this._streams || {};
- this._reverseStreams = this._reverseStreams || {};
- stream.getTracks().forEach(track => {
- const alreadyExists = this.getSenders().find(s => s.track === track);
- if (alreadyExists) {
- throw new DOMException('Track already exists.', 'InvalidAccessError');
- }
- }); // Add identity mapping for consistency with addTrack.
- // Unless this is being used with a stream from addTrack.
- if (!this._reverseStreams[stream.id]) {
- const newStream = new window.MediaStream(stream.getTracks());
- this._streams[stream.id] = newStream;
- this._reverseStreams[newStream.id] = stream;
- stream = newStream;
- }
- origAddStream.apply(this, [stream]);
- };
- const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
- window.RTCPeerConnection.prototype.removeStream = function (stream) {
- this._streams = this._streams || {};
- this._reverseStreams = this._reverseStreams || {};
- origRemoveStream.apply(this, [this._streams[stream.id] || stream]);
- delete this._reverseStreams[this._streams[stream.id] ? this._streams[stream.id].id : stream.id];
- delete this._streams[stream.id];
- };
- window.RTCPeerConnection.prototype.addTrack = function (track, stream) {
- if (this.signalingState === 'closed') {
- throw new DOMException('The RTCPeerConnection\'s signalingState is \'closed\'.', 'InvalidStateError');
- }
- const streams = [].slice.call(arguments, 1);
- if (streams.length !== 1 || !streams[0].getTracks().find(t => t === track)) {
- // this is not fully correct but all we can manage without
- // [[associated MediaStreams]] internal slot.
- throw new DOMException('The adapter.js addTrack polyfill only supports a single ' + ' stream which is associated with the specified track.', 'NotSupportedError');
- }
- const alreadyExists = this.getSenders().find(s => s.track === track);
- if (alreadyExists) {
- throw new DOMException('Track already exists.', 'InvalidAccessError');
- }
- this._streams = this._streams || {};
- this._reverseStreams = this._reverseStreams || {};
- const oldStream = this._streams[stream.id];
- if (oldStream) {
- // this is using odd Chrome behaviour, use with caution:
- // https://bugs.chromium.org/p/webrtc/issues/detail?id=7815
- // Note: we rely on the high-level addTrack/dtmf shim to
- // create the sender with a dtmf sender.
- oldStream.addTrack(track); // Trigger ONN async.
- Promise.resolve().then(() => {
- this.dispatchEvent(new Event('negotiationneeded'));
- });
- } else {
- const newStream = new window.MediaStream([track]);
- this._streams[stream.id] = newStream;
- this._reverseStreams[newStream.id] = stream;
- this.addStream(newStream);
- }
- return this.getSenders().find(s => s.track === track);
- }; // replace the internal stream id with the external one and
- // vice versa.
- function replaceInternalStreamId(pc, description) {
- let sdp = description.sdp;
- Object.keys(pc._reverseStreams || []).forEach(internalId => {
- const externalStream = pc._reverseStreams[internalId];
- const internalStream = pc._streams[externalStream.id];
- sdp = sdp.replace(new RegExp(internalStream.id, 'g'), externalStream.id);
- });
- return new RTCSessionDescription({
- type: description.type,
- sdp
- });
- }
- function replaceExternalStreamId(pc, description) {
- let sdp = description.sdp;
- Object.keys(pc._reverseStreams || []).forEach(internalId => {
- const externalStream = pc._reverseStreams[internalId];
- const internalStream = pc._streams[externalStream.id];
- sdp = sdp.replace(new RegExp(externalStream.id, 'g'), internalStream.id);
- });
- return new RTCSessionDescription({
- type: description.type,
- sdp
- });
- }
- ['createOffer', 'createAnswer'].forEach(function (method) {
- const nativeMethod = window.RTCPeerConnection.prototype[method];
- window.RTCPeerConnection.prototype[method] = function () {
- const args = arguments;
- const isLegacyCall = arguments.length && typeof arguments[0] === 'function';
- if (isLegacyCall) {
- return nativeMethod.apply(this, [description => {
- const desc = replaceInternalStreamId(this, description);
- args[0].apply(null, [desc]);
- }, err => {
- if (args[1]) {
- args[1].apply(null, err);
- }
- }, arguments[2]]);
- }
- return nativeMethod.apply(this, arguments).then(description => replaceInternalStreamId(this, description));
- };
- });
- const origSetLocalDescription = window.RTCPeerConnection.prototype.setLocalDescription;
- window.RTCPeerConnection.prototype.setLocalDescription = function () {
- if (!arguments.length || !arguments[0].type) {
- return origSetLocalDescription.apply(this, arguments);
- }
- arguments[0] = replaceExternalStreamId(this, arguments[0]);
- return origSetLocalDescription.apply(this, arguments);
- }; // TODO: mangle getStats: https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamstats-streamidentifier
- const origLocalDescription = Object.getOwnPropertyDescriptor(window.RTCPeerConnection.prototype, 'localDescription');
- Object.defineProperty(window.RTCPeerConnection.prototype, 'localDescription', {
- get() {
- const description = origLocalDescription.get.apply(this);
- if (description.type === '') {
- return description;
- }
- return replaceInternalStreamId(this, description);
- }
- });
- window.RTCPeerConnection.prototype.removeTrack = function (sender) {
- if (this.signalingState === 'closed') {
- throw new DOMException('The RTCPeerConnection\'s signalingState is \'closed\'.', 'InvalidStateError');
- } // We can not yet check for sender instanceof RTCRtpSender
- // since we shim RTPSender. So we check if sender._pc is set.
- if (!sender._pc) {
- throw new DOMException('Argument 1 of RTCPeerConnection.removeTrack ' + 'does not implement interface RTCRtpSender.', 'TypeError');
- }
- const isLocal = sender._pc === this;
- if (!isLocal) {
- throw new DOMException('Sender was not created by this connection.', 'InvalidAccessError');
- } // Search for the native stream the senders track belongs to.
- this._streams = this._streams || {};
- let stream;
- Object.keys(this._streams).forEach(streamid => {
- const hasTrack = this._streams[streamid].getTracks().find(track => sender.track === track);
- if (hasTrack) {
- stream = this._streams[streamid];
- }
- });
- if (stream) {
- if (stream.getTracks().length === 1) {
- // if this is the last track of the stream, remove the stream. This
- // takes care of any shimmed _senders.
- this.removeStream(this._reverseStreams[stream.id]);
- } else {
- // relying on the same odd chrome behaviour as above.
- stream.removeTrack(sender.track);
- }
- this.dispatchEvent(new Event('negotiationneeded'));
- }
- };
- }
- function shimPeerConnection(window) {
- if (!window.RTCPeerConnection && window.webkitRTCPeerConnection) {
- // very basic support for old versions.
- window.RTCPeerConnection = window.webkitRTCPeerConnection;
- }
- if (!window.RTCPeerConnection) {
- return;
- }
- const origGetStats = window.RTCPeerConnection.prototype.getStats;
- window.RTCPeerConnection.prototype.getStats = function (selector, successCallback, errorCallback) {
- const args = arguments; // If selector is a function then we are in the old style stats so just
- // pass back the original getStats format to avoid breaking old users.
- if (arguments.length > 0 && typeof selector === 'function') {
- return origGetStats.apply(this, arguments);
- } // When spec-style getStats is supported, return those when called with
- // either no arguments or the selector argument is null.
- if (origGetStats.length === 0 && (arguments.length === 0 || typeof arguments[0] !== 'function')) {
- return origGetStats.apply(this, []);
- }
- const fixChromeStats_ = function (response) {
- const standardReport = {};
- const reports = response.result();
- reports.forEach(report => {
- const standardStats = {
- id: report.id,
- timestamp: report.timestamp,
- type: {
- localcandidate: 'local-candidate',
- remotecandidate: 'remote-candidate'
- }[report.type] || report.type
- };
- report.names().forEach(name => {
- standardStats[name] = report.stat(name);
- });
- standardReport[standardStats.id] = standardStats;
- });
- return standardReport;
- }; // shim getStats with maplike support
- const makeMapStats = function (stats) {
- return new Map(Object.keys(stats).map(key => [key, stats[key]]));
- };
- if (arguments.length >= 2) {
- const successCallbackWrapper_ = function (response) {
- args[1](makeMapStats(fixChromeStats_(response)));
- };
- return origGetStats.apply(this, [successCallbackWrapper_, arguments[0]]);
- } // promise-support
- return new Promise((resolve, reject) => {
- origGetStats.apply(this, [function (response) {
- resolve(makeMapStats(fixChromeStats_(response)));
- }, reject]);
- }).then(successCallback, errorCallback);
- }; // shim implicit creation of RTCSessionDescription/RTCIceCandidate
- ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'].forEach(function (method) {
- const nativeMethod = window.RTCPeerConnection.prototype[method];
- window.RTCPeerConnection.prototype[method] = function () {
- arguments[0] = new (method === 'addIceCandidate' ? window.RTCIceCandidate : window.RTCSessionDescription)(arguments[0]);
- return nativeMethod.apply(this, arguments);
- };
- }); // support for addIceCandidate(null or undefined)
- const nativeAddIceCandidate = window.RTCPeerConnection.prototype.addIceCandidate;
- window.RTCPeerConnection.prototype.addIceCandidate = function () {
- if (!arguments[0]) {
- if (arguments[1]) {
- arguments[1].apply(null);
- }
- return Promise.resolve();
- }
- return nativeAddIceCandidate.apply(this, arguments);
- };
- }
- function fixNegotiationNeeded(window) {
- __WEBPACK_IMPORTED_MODULE_0__utils_js__["g" /* wrapPeerConnectionEvent */](window, 'negotiationneeded', e => {
- const pc = e.target;
- if (pc.signalingState !== 'stable') {
- return;
- }
- return e;
- });
- }
- }),
- /* 47 */
- (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- /* harmony export (immutable) */ __webpack_exports__["a"] = shimGetUserMedia;
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_js__ = __webpack_require__(4);
- /*
- * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- /* eslint-env node */
- const logging = __WEBPACK_IMPORTED_MODULE_0__utils_js__["f" /* log */];
- function shimGetUserMedia(window) {
- const navigator = window && window.navigator;
- if (!navigator.mediaDevices) {
- return;
- }
- const browserDetails = __WEBPACK_IMPORTED_MODULE_0__utils_js__["b" /* detectBrowser */](window);
- const constraintsToChrome_ = function (c) {
- if (typeof c !== 'object' || c.mandatory || c.optional) {
- return c;
- }
- const cc = {};
- Object.keys(c).forEach(key => {
- if (key === 'require' || key === 'advanced' || key === 'mediaSource') {
- return;
- }
- const r = typeof c[key] === 'object' ? c[key] : {
- ideal: c[key]
- };
- if (r.exact !== undefined && typeof r.exact === 'number') {
- r.min = r.max = r.exact;
- }
- const oldname_ = function (prefix, name) {
- if (prefix) {
- return prefix + name.charAt(0).toUpperCase() + name.slice(1);
- }
- return name === 'deviceId' ? 'sourceId' : name;
- };
- if (r.ideal !== undefined) {
- cc.optional = cc.optional || [];
- let oc = {};
- if (typeof r.ideal === 'number') {
- oc[oldname_('min', key)] = r.ideal;
- cc.optional.push(oc);
- oc = {};
- oc[oldname_('max', key)] = r.ideal;
- cc.optional.push(oc);
- } else {
- oc[oldname_('', key)] = r.ideal;
- cc.optional.push(oc);
- }
- }
- if (r.exact !== undefined && typeof r.exact !== 'number') {
- cc.mandatory = cc.mandatory || {};
- cc.mandatory[oldname_('', key)] = r.exact;
- } else {
- ['min', 'max'].forEach(mix => {
- if (r[mix] !== undefined) {
- cc.mandatory = cc.mandatory || {};
- cc.mandatory[oldname_(mix, key)] = r[mix];
- }
- });
- }
- });
- if (c.advanced) {
- cc.optional = (cc.optional || []).concat(c.advanced);
- }
- return cc;
- };
- const shimConstraints_ = function (constraints, func) {
- if (browserDetails.version >= 61) {
- return func(constraints);
- }
- constraints = JSON.parse(JSON.stringify(constraints));
- if (constraints && typeof constraints.audio === 'object') {
- const remap = function (obj, a, b) {
- if (a in obj && !(b in obj)) {
- obj[b] = obj[a];
- delete obj[a];
- }
- };
- constraints = JSON.parse(JSON.stringify(constraints));
- remap(constraints.audio, 'autoGainControl', 'googAutoGainControl');
- remap(constraints.audio, 'noiseSuppression', 'googNoiseSuppression');
- constraints.audio = constraintsToChrome_(constraints.audio);
- }
- if (constraints && typeof constraints.video === 'object') {
- // Shim facingMode for mobile & surface pro.
- let face = constraints.video.facingMode;
- face = face && (typeof face === 'object' ? face : {
- ideal: face
- });
- const getSupportedFacingModeLies = browserDetails.version < 66;
- if (face && (face.exact === 'user' || face.exact === 'environment' || face.ideal === 'user' || face.ideal === 'environment') && !(navigator.mediaDevices.getSupportedConstraints && navigator.mediaDevices.getSupportedConstraints().facingMode && !getSupportedFacingModeLies)) {
- delete constraints.video.facingMode;
- let matches;
- if (face.exact === 'environment' || face.ideal === 'environment') {
- matches = ['back', 'rear'];
- } else if (face.exact === 'user' || face.ideal === 'user') {
- matches = ['front'];
- }
- if (matches) {
- // Look for matches in label, or use last cam for back (typical).
- return navigator.mediaDevices.enumerateDevices().then(devices => {
- devices = devices.filter(d => d.kind === 'videoinput');
- let dev = devices.find(d => matches.some(match => d.label.toLowerCase().includes(match)));
- if (!dev && devices.length && matches.includes('back')) {
- dev = devices[devices.length - 1]; // more likely the back cam
- }
- if (dev) {
- constraints.video.deviceId = face.exact ? {
- exact: dev.deviceId
- } : {
- ideal: dev.deviceId
- };
- }
- constraints.video = constraintsToChrome_(constraints.video);
- logging('chrome: ' + JSON.stringify(constraints));
- return func(constraints);
- });
- }
- }
- constraints.video = constraintsToChrome_(constraints.video);
- }
- logging('chrome: ' + JSON.stringify(constraints));
- return func(constraints);
- };
- const shimError_ = function (e) {
- if (browserDetails.version >= 64) {
- return e;
- }
- return {
- name: {
- PermissionDeniedError: 'NotAllowedError',
- PermissionDismissedError: 'NotAllowedError',
- InvalidStateError: 'NotAllowedError',
- DevicesNotFoundError: 'NotFoundError',
- ConstraintNotSatisfiedError: 'OverconstrainedError',
- TrackStartError: 'NotReadableError',
- MediaDeviceFailedDueToShutdown: 'NotAllowedError',
- MediaDeviceKillSwitchOn: 'NotAllowedError',
- TabCaptureError: 'AbortError',
- ScreenCaptureError: 'AbortError',
- DeviceCaptureError: 'AbortError'
- }[e.name] || e.name,
- message: e.message,
- constraint: e.constraint || e.constraintName,
- toString() {
- return this.name + (this.message && ': ') + this.message;
- }
- };
- };
- const getUserMedia_ = function (constraints, onSuccess, onError) {
- shimConstraints_(constraints, c => {
- navigator.webkitGetUserMedia(c, onSuccess, e => {
- if (onError) {
- onError(shimError_(e));
- }
- });
- });
- };
- navigator.getUserMedia = getUserMedia_.bind(navigator); // Even though Chrome 45 has navigator.mediaDevices and a getUserMedia
- // function which returns a Promise, it does not accept spec-style
- // constraints.
- const origGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);
- navigator.mediaDevices.getUserMedia = function (cs) {
- return shimConstraints_(cs, c => origGetUserMedia(c).then(stream => {
- if (c.audio && !stream.getAudioTracks().length || c.video && !stream.getVideoTracks().length) {
- stream.getTracks().forEach(track => {
- track.stop();
- });
- throw new DOMException('', 'NotFoundError');
- }
- return stream;
- }, e => Promise.reject(shimError_(e))));
- };
- }
- }),
- /* 48 */
- (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- /* harmony export (immutable) */ __webpack_exports__["a"] = shimGetDisplayMedia;
- /*
- * Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- /* eslint-env node */
- function shimGetDisplayMedia(window, getSourceId) {
- if (window.navigator.mediaDevices && 'getDisplayMedia' in window.navigator.mediaDevices) {
- return;
- }
- if (!window.navigator.mediaDevices) {
- return;
- } // getSourceId is a function that returns a promise resolving with
- // the sourceId of the screen/window/tab to be shared.
- if (typeof getSourceId !== 'function') {
- console.error('shimGetDisplayMedia: getSourceId argument is not ' + 'a function');
- return;
- }
- window.navigator.mediaDevices.getDisplayMedia = function (constraints) {
- return getSourceId(constraints).then(sourceId => {
- const widthSpecified = constraints.video && constraints.video.width;
- const heightSpecified = constraints.video && constraints.video.height;
- const frameRateSpecified = constraints.video && constraints.video.frameRate;
- constraints.video = {
- mandatory: {
- chromeMediaSource: 'desktop',
- chromeMediaSourceId: sourceId,
- maxFrameRate: frameRateSpecified || 3
- }
- };
- if (widthSpecified) {
- constraints.video.mandatory.maxWidth = widthSpecified;
- }
- if (heightSpecified) {
- constraints.video.mandatory.maxHeight = heightSpecified;
- }
- return window.navigator.mediaDevices.getUserMedia(constraints);
- });
- };
- }
- }),
- /* 49 */
- (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
- /* harmony export (immutable) */ __webpack_exports__["shimPeerConnection"] = shimPeerConnection;
- /* harmony export (immutable) */ __webpack_exports__["shimReplaceTrack"] = shimReplaceTrack;
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils__ = __webpack_require__(4);
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__filtericeservers__ = __webpack_require__(50);
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_rtcpeerconnection_shim__ = __webpack_require__(51);
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_rtcpeerconnection_shim___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_rtcpeerconnection_shim__);
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__getusermedia__ = __webpack_require__(52);
- /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "shimGetUserMedia", function() { return __WEBPACK_IMPORTED_MODULE_3__getusermedia__["a"]; });
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__getdisplaymedia__ = __webpack_require__(53);
- /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "shimGetDisplayMedia", function() { return __WEBPACK_IMPORTED_MODULE_4__getdisplaymedia__["a"]; });
- /*
- * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- /* eslint-env node */
- function shimPeerConnection(window) {
- const browserDetails = __WEBPACK_IMPORTED_MODULE_0__utils__["b" /* detectBrowser */](window);
- if (window.RTCIceGatherer) {
- if (!window.RTCIceCandidate) {
- window.RTCIceCandidate = function (args) {
- return args;
- };
- }
- if (!window.RTCSessionDescription) {
- window.RTCSessionDescription = function (args) {
- return args;
- };
- } // this adds an additional event listener to MediaStrackTrack that signals
- // when a tracks enabled property was changed. Workaround for a bug in
- // addStream, see below. No longer required in 15025+
- if (browserDetails.version < 15025) {
- const origMSTEnabled = Object.getOwnPropertyDescriptor(window.MediaStreamTrack.prototype, 'enabled');
- Object.defineProperty(window.MediaStreamTrack.prototype, 'enabled', {
- set(value) {
- origMSTEnabled.set.call(this, value);
- const ev = new Event('enabled');
- ev.enabled = value;
- this.dispatchEvent(ev);
- }
- });
- }
- } // ORTC defines the DTMF sender a bit different.
- // https://github.com/w3c/ortc/issues/714
- if (window.RTCRtpSender && !('dtmf' in window.RTCRtpSender.prototype)) {
- Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', {
- get() {
- if (this._dtmf === undefined) {
- if (this.track.kind === 'audio') {
- this._dtmf = new window.RTCDtmfSender(this);
- } else if (this.track.kind === 'video') {
- this._dtmf = null;
- }
- }
- return this._dtmf;
- }
- });
- } // Edge currently only implements the RTCDtmfSender, not the
- // RTCDTMFSender alias. See http://draft.ortc.org/#rtcdtmfsender2*
- if (window.RTCDtmfSender && !window.RTCDTMFSender) {
- window.RTCDTMFSender = window.RTCDtmfSender;
- }
- const RTCPeerConnectionShim = __WEBPACK_IMPORTED_MODULE_2_rtcpeerconnection_shim___default()(window, browserDetails.version);
- window.RTCPeerConnection = function (config) {
- if (config && config.iceServers) {
- config.iceServers = Object(__WEBPACK_IMPORTED_MODULE_1__filtericeservers__["a" /* filterIceServers */])(config.iceServers, browserDetails.version);
- __WEBPACK_IMPORTED_MODULE_0__utils__["f" /* log */]('ICE servers after filtering:', config.iceServers);
- }
- return new RTCPeerConnectionShim(config);
- };
- window.RTCPeerConnection.prototype = RTCPeerConnectionShim.prototype;
- }
- function shimReplaceTrack(window) {
- // ORTC has replaceTrack -- https://github.com/w3c/ortc/issues/614
- if (window.RTCRtpSender && !('replaceTrack' in window.RTCRtpSender.prototype)) {
- window.RTCRtpSender.prototype.replaceTrack = window.RTCRtpSender.prototype.setTrack;
- }
- }
- }),
- /* 50 */
- (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- /* harmony export (immutable) */ __webpack_exports__["a"] = filterIceServers;
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils__ = __webpack_require__(4);
- /*
- * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- /* eslint-env node */
- // Edge does not like
- // 1) stun: filtered after 14393 unless ?transport=udp is present
- // 2) turn: that does not have all of turn:host:port?transport=udp
- // 3) turn: with ipv6 addresses
- // 4) turn: occurring muliple times
- function filterIceServers(iceServers, edgeVersion) {
- let hasTurn = false;
- iceServers = JSON.parse(JSON.stringify(iceServers));
- return iceServers.filter(server => {
- if (server && (server.urls || server.url)) {
- var urls = server.urls || server.url;
- if (server.url && !server.urls) {
- __WEBPACK_IMPORTED_MODULE_0__utils__["a" /* deprecated */]('RTCIceServer.url', 'RTCIceServer.urls');
- }
- const isString = typeof urls === 'string';
- if (isString) {
- urls = [urls];
- }
- urls = urls.filter(url => {
- // filter STUN unconditionally.
- if (url.indexOf('stun:') === 0) {
- return false;
- }
- const validTurn = url.startsWith('turn') && !url.startsWith('turn:[') && url.includes('transport=udp');
- if (validTurn && !hasTurn) {
- hasTurn = true;
- return true;
- }
- return validTurn && !hasTurn;
- });
- delete server.url;
- server.urls = isString ? urls[0] : urls;
- return !!urls.length;
- }
- });
- }
- }),
- /* 51 */
- (function(module, exports, __webpack_require__) {
- "use strict";
- /*
- * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- /* eslint-env node */
- var SDPUtils = __webpack_require__(19);
- function fixStatsType(stat) {
- return {
- inboundrtp: 'inbound-rtp',
- outboundrtp: 'outbound-rtp',
- candidatepair: 'candidate-pair',
- localcandidate: 'local-candidate',
- remotecandidate: 'remote-candidate'
- }[stat.type] || stat.type;
- }
- function writeMediaSection(transceiver, caps, type, stream, dtlsRole) {
- var sdp = SDPUtils.writeRtpDescription(transceiver.kind, caps); // Map ICE parameters (ufrag, pwd) to SDP.
- sdp += SDPUtils.writeIceParameters(transceiver.iceGatherer.getLocalParameters()); // Map DTLS parameters to SDP.
- sdp += SDPUtils.writeDtlsParameters(transceiver.dtlsTransport.getLocalParameters(), type === 'offer' ? 'actpass' : dtlsRole || 'active');
- sdp += 'a=mid:' + transceiver.mid + '\r\n';
- if (transceiver.rtpSender && transceiver.rtpReceiver) {
- sdp += 'a=sendrecv\r\n';
- } else if (transceiver.rtpSender) {
- sdp += 'a=sendonly\r\n';
- } else if (transceiver.rtpReceiver) {
- sdp += 'a=recvonly\r\n';
- } else {
- sdp += 'a=inactive\r\n';
- }
- if (transceiver.rtpSender) {
- var trackId = transceiver.rtpSender._initialTrackId || transceiver.rtpSender.track.id;
- transceiver.rtpSender._initialTrackId = trackId; // spec.
- var msid = 'msid:' + (stream ? stream.id : '-') + ' ' + trackId + '\r\n';
- sdp += 'a=' + msid; // for Chrome. Legacy should no longer be required.
- sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc + ' ' + msid; // RTX
- if (transceiver.sendEncodingParameters[0].rtx) {
- sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc + ' ' + msid;
- sdp += 'a=ssrc-group:FID ' + transceiver.sendEncodingParameters[0].ssrc + ' ' + transceiver.sendEncodingParameters[0].rtx.ssrc + '\r\n';
- }
- } // FIXME: this should be written by writeRtpDescription.
- sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc + ' cname:' + SDPUtils.localCName + '\r\n';
- if (transceiver.rtpSender && transceiver.sendEncodingParameters[0].rtx) {
- sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc + ' cname:' + SDPUtils.localCName + '\r\n';
- }
- return sdp;
- } // Edge does not like
- // 1) stun: filtered after 14393 unless ?transport=udp is present
- // 2) turn: that does not have all of turn:host:port?transport=udp
- // 3) turn: with ipv6 addresses
- // 4) turn: occurring muliple times
- function filterIceServers(iceServers, edgeVersion) {
- var hasTurn = false;
- iceServers = JSON.parse(JSON.stringify(iceServers));
- return iceServers.filter(function (server) {
- if (server && (server.urls || server.url)) {
- var urls = server.urls || server.url;
- if (server.url && !server.urls) {
- console.warn('RTCIceServer.url is deprecated! Use urls instead.');
- }
- var isString = typeof urls === 'string';
- if (isString) {
- urls = [urls];
- }
- urls = urls.filter(function (url) {
- var validTurn = url.indexOf('turn:') === 0 && url.indexOf('transport=udp') !== -1 && url.indexOf('turn:[') === -1 && !hasTurn;
- if (validTurn) {
- hasTurn = true;
- return true;
- }
- return url.indexOf('stun:') === 0 && edgeVersion >= 14393 && url.indexOf('?transport=udp') === -1;
- });
- delete server.url;
- server.urls = isString ? urls[0] : urls;
- return !!urls.length;
- }
- });
- } // Determines the intersection of local and remote capabilities.
- function getCommonCapabilities(localCapabilities, remoteCapabilities) {
- var commonCapabilities = {
- codecs: [],
- headerExtensions: [],
- fecMechanisms: []
- };
- var findCodecByPayloadType = function (pt, codecs) {
- pt = parseInt(pt, 10);
- for (var i = 0; i < codecs.length; i++) {
- if (codecs[i].payloadType === pt || codecs[i].preferredPayloadType === pt) {
- return codecs[i];
- }
- }
- };
- var rtxCapabilityMatches = function (lRtx, rRtx, lCodecs, rCodecs) {
- var lCodec = findCodecByPayloadType(lRtx.parameters.apt, lCodecs);
- var rCodec = findCodecByPayloadType(rRtx.parameters.apt, rCodecs);
- return lCodec && rCodec && lCodec.name.toLowerCase() === rCodec.name.toLowerCase();
- };
- localCapabilities.codecs.forEach(function (lCodec) {
- for (var i = 0; i < remoteCapabilities.codecs.length; i++) {
- var rCodec = remoteCapabilities.codecs[i];
- if (lCodec.name.toLowerCase() === rCodec.name.toLowerCase() && lCodec.clockRate === rCodec.clockRate) {
- if (lCodec.name.toLowerCase() === 'rtx' && lCodec.parameters && rCodec.parameters.apt) {
- // for RTX we need to find the local rtx that has a apt
- // which points to the same local codec as the remote one.
- if (!rtxCapabilityMatches(lCodec, rCodec, localCapabilities.codecs, remoteCapabilities.codecs)) {
- continue;
- }
- }
- rCodec = JSON.parse(JSON.stringify(rCodec)); // deepcopy
- // number of channels is the highest common number of channels
- rCodec.numChannels = Math.min(lCodec.numChannels, rCodec.numChannels); // push rCodec so we reply with offerer payload type
- commonCapabilities.codecs.push(rCodec); // determine common feedback mechanisms
- rCodec.rtcpFeedback = rCodec.rtcpFeedback.filter(function (fb) {
- for (var j = 0; j < lCodec.rtcpFeedback.length; j++) {
- if (lCodec.rtcpFeedback[j].type === fb.type && lCodec.rtcpFeedback[j].parameter === fb.parameter) {
- return true;
- }
- }
- return false;
- }); // FIXME: also need to determine .parameters
- // see https://github.com/openpeer/ortc/issues/569
- break;
- }
- }
- });
- localCapabilities.headerExtensions.forEach(function (lHeaderExtension) {
- for (var i = 0; i < remoteCapabilities.headerExtensions.length; i++) {
- var rHeaderExtension = remoteCapabilities.headerExtensions[i];
- if (lHeaderExtension.uri === rHeaderExtension.uri) {
- commonCapabilities.headerExtensions.push(rHeaderExtension);
- break;
- }
- }
- }); // FIXME: fecMechanisms
- return commonCapabilities;
- } // is action=setLocalDescription with type allowed in signalingState
- function isActionAllowedInSignalingState(action, type, signalingState) {
- return {
- offer: {
- setLocalDescription: ['stable', 'have-local-offer'],
- setRemoteDescription: ['stable', 'have-remote-offer']
- },
- answer: {
- setLocalDescription: ['have-remote-offer', 'have-local-pranswer'],
- setRemoteDescription: ['have-local-offer', 'have-remote-pranswer']
- }
- }[type][action].indexOf(signalingState) !== -1;
- }
- function maybeAddCandidate(iceTransport, candidate) {
- // Edge's internal representation adds some fields therefore
- // not all fieldѕ are taken into account.
- var alreadyAdded = iceTransport.getRemoteCandidates().find(function (remoteCandidate) {
- return candidate.foundation === remoteCandidate.foundation && candidate.ip === remoteCandidate.ip && candidate.port === remoteCandidate.port && candidate.priority === remoteCandidate.priority && candidate.protocol === remoteCandidate.protocol && candidate.type === remoteCandidate.type;
- });
- if (!alreadyAdded) {
- iceTransport.addRemoteCandidate(candidate);
- }
- return !alreadyAdded;
- }
- function makeError(name, description) {
- var e = new Error(description);
- e.name = name; // legacy error codes from https://heycam.github.io/webidl/#idl-DOMException-error-names
- e.code = {
- NotSupportedError: 9,
- InvalidStateError: 11,
- InvalidAccessError: 15,
- TypeError: undefined,
- OperationError: undefined
- }[name];
- return e;
- }
- module.exports = function (window, edgeVersion) {
- // https://w3c.github.io/mediacapture-main/#mediastream
- // Helper function to add the track to the stream and
- // dispatch the event ourselves.
- function addTrackToStreamAndFireEvent(track, stream) {
- stream.addTrack(track);
- stream.dispatchEvent(new window.MediaStreamTrackEvent('addtrack', {
- track: track
- }));
- }
- function removeTrackFromStreamAndFireEvent(track, stream) {
- stream.removeTrack(track);
- stream.dispatchEvent(new window.MediaStreamTrackEvent('removetrack', {
- track: track
- }));
- }
- function fireAddTrack(pc, track, receiver, streams) {
- var trackEvent = new Event('track');
- trackEvent.track = track;
- trackEvent.receiver = receiver;
- trackEvent.transceiver = {
- receiver: receiver
- };
- trackEvent.streams = streams;
- window.setTimeout(function () {
- pc._dispatchEvent('track', trackEvent);
- });
- }
- var RTCPeerConnection = function (config) {
- var pc = this;
- var _eventTarget = document.createDocumentFragment();
- ['addEventListener', 'removeEventListener', 'dispatchEvent'].forEach(function (method) {
- pc[method] = _eventTarget[method].bind(_eventTarget);
- });
- this.canTrickleIceCandidates = null;
- this.needNegotiation = false;
- this.localStreams = [];
- this.remoteStreams = [];
- this._localDescription = null;
- this._remoteDescription = null;
- this.signalingState = 'stable';
- this.iceConnectionState = 'new';
- this.connectionState = 'new';
- this.iceGatheringState = 'new';
- config = JSON.parse(JSON.stringify(config || {}));
- this.usingBundle = config.bundlePolicy === 'max-bundle';
- if (config.rtcpMuxPolicy === 'negotiate') {
- throw makeError('NotSupportedError', 'rtcpMuxPolicy \'negotiate\' is not supported');
- } else if (!config.rtcpMuxPolicy) {
- config.rtcpMuxPolicy = 'require';
- }
- switch (config.iceTransportPolicy) {
- case 'all':
- case 'relay':
- break;
- default:
- config.iceTransportPolicy = 'all';
- break;
- }
- switch (config.bundlePolicy) {
- case 'balanced':
- case 'max-compat':
- case 'max-bundle':
- break;
- default:
- config.bundlePolicy = 'balanced';
- break;
- }
- config.iceServers = filterIceServers(config.iceServers || [], edgeVersion);
- this._iceGatherers = [];
- if (config.iceCandidatePoolSize) {
- for (var i = config.iceCandidatePoolSize; i > 0; i--) {
- this._iceGatherers.push(new window.RTCIceGatherer({
- iceServers: config.iceServers,
- gatherPolicy: config.iceTransportPolicy
- }));
- }
- } else {
- config.iceCandidatePoolSize = 0;
- }
- this._config = config; // per-track iceGathers, iceTransports, dtlsTransports, rtpSenders, ...
- // everything that is needed to describe a SDP m-line.
- this.transceivers = [];
- this._sdpSessionId = SDPUtils.generateSessionId();
- this._sdpSessionVersion = 0;
- this._dtlsRole = undefined; // role for a=setup to use in answers.
- this._isClosed = false;
- };
- Object.defineProperty(RTCPeerConnection.prototype, 'localDescription', {
- configurable: true,
- get: function () {
- return this._localDescription;
- }
- });
- Object.defineProperty(RTCPeerConnection.prototype, 'remoteDescription', {
- configurable: true,
- get: function () {
- return this._remoteDescription;
- }
- }); // set up event handlers on prototype
- RTCPeerConnection.prototype.onicecandidate = null;
- RTCPeerConnection.prototype.onaddstream = null;
- RTCPeerConnection.prototype.ontrack = null;
- RTCPeerConnection.prototype.onremovestream = null;
- RTCPeerConnection.prototype.onsignalingstatechange = null;
- RTCPeerConnection.prototype.oniceconnectionstatechange = null;
- RTCPeerConnection.prototype.onconnectionstatechange = null;
- RTCPeerConnection.prototype.onicegatheringstatechange = null;
- RTCPeerConnection.prototype.onnegotiationneeded = null;
- RTCPeerConnection.prototype.ondatachannel = null;
- RTCPeerConnection.prototype._dispatchEvent = function (name, event) {
- if (this._isClosed) {
- return;
- }
- this.dispatchEvent(event);
- if (typeof this['on' + name] === 'function') {
- this['on' + name](event);
- }
- };
- RTCPeerConnection.prototype._emitGatheringStateChange = function () {
- var event = new Event('icegatheringstatechange');
- this._dispatchEvent('icegatheringstatechange', event);
- };
- RTCPeerConnection.prototype.getConfiguration = function () {
- return this._config;
- };
- RTCPeerConnection.prototype.getLocalStreams = function () {
- return this.localStreams;
- };
- RTCPeerConnection.prototype.getRemoteStreams = function () {
- return this.remoteStreams;
- }; // internal helper to create a transceiver object.
- // (which is not yet the same as the WebRTC 1.0 transceiver)
- RTCPeerConnection.prototype._createTransceiver = function (kind, doNotAdd) {
- var hasBundleTransport = this.transceivers.length > 0;
- var transceiver = {
- track: null,
- iceGatherer: null,
- iceTransport: null,
- dtlsTransport: null,
- localCapabilities: null,
- remoteCapabilities: null,
- rtpSender: null,
- rtpReceiver: null,
- kind: kind,
- mid: null,
- sendEncodingParameters: null,
- recvEncodingParameters: null,
- stream: null,
- associatedRemoteMediaStreams: [],
- wantReceive: true
- };
- if (this.usingBundle && hasBundleTransport) {
- transceiver.iceTransport = this.transceivers[0].iceTransport;
- transceiver.dtlsTransport = this.transceivers[0].dtlsTransport;
- } else {
- var transports = this._createIceAndDtlsTransports();
- transceiver.iceTransport = transports.iceTransport;
- transceiver.dtlsTransport = transports.dtlsTransport;
- }
- if (!doNotAdd) {
- this.transceivers.push(transceiver);
- }
- return transceiver;
- };
- RTCPeerConnection.prototype.addTrack = function (track, stream) {
- if (this._isClosed) {
- throw makeError('InvalidStateError', 'Attempted to call addTrack on a closed peerconnection.');
- }
- var alreadyExists = this.transceivers.find(function (s) {
- return s.track === track;
- });
- if (alreadyExists) {
- throw makeError('InvalidAccessError', 'Track already exists.');
- }
- var transceiver;
- for (var i = 0; i < this.transceivers.length; i++) {
- if (!this.transceivers[i].track && this.transceivers[i].kind === track.kind) {
- transceiver = this.transceivers[i];
- }
- }
- if (!transceiver) {
- transceiver = this._createTransceiver(track.kind);
- }
- this._maybeFireNegotiationNeeded();
- if (this.localStreams.indexOf(stream) === -1) {
- this.localStreams.push(stream);
- }
- transceiver.track = track;
- transceiver.stream = stream;
- transceiver.rtpSender = new window.RTCRtpSender(track, transceiver.dtlsTransport);
- return transceiver.rtpSender;
- };
- RTCPeerConnection.prototype.addStream = function (stream) {
- var pc = this;
- if (edgeVersion >= 15025) {
- stream.getTracks().forEach(function (track) {
- pc.addTrack(track, stream);
- });
- } else {
- // Clone is necessary for local demos mostly, attaching directly
- // to two different senders does not work (build 10547).
- // Fixed in 15025 (or earlier)
- var clonedStream = stream.clone();
- stream.getTracks().forEach(function (track, idx) {
- var clonedTrack = clonedStream.getTracks()[idx];
- track.addEventListener('enabled', function (event) {
- clonedTrack.enabled = event.enabled;
- });
- });
- clonedStream.getTracks().forEach(function (track) {
- pc.addTrack(track, clonedStream);
- });
- }
- };
- RTCPeerConnection.prototype.removeTrack = function (sender) {
- if (this._isClosed) {
- throw makeError('InvalidStateError', 'Attempted to call removeTrack on a closed peerconnection.');
- }
- if (!(sender instanceof window.RTCRtpSender)) {
- throw new TypeError('Argument 1 of RTCPeerConnection.removeTrack ' + 'does not implement interface RTCRtpSender.');
- }
- var transceiver = this.transceivers.find(function (t) {
- return t.rtpSender === sender;
- });
- if (!transceiver) {
- throw makeError('InvalidAccessError', 'Sender was not created by this connection.');
- }
- var stream = transceiver.stream;
- transceiver.rtpSender.stop();
- transceiver.rtpSender = null;
- transceiver.track = null;
- transceiver.stream = null; // remove the stream from the set of local streams
- var localStreams = this.transceivers.map(function (t) {
- return t.stream;
- });
- if (localStreams.indexOf(stream) === -1 && this.localStreams.indexOf(stream) > -1) {
- this.localStreams.splice(this.localStreams.indexOf(stream), 1);
- }
- this._maybeFireNegotiationNeeded();
- };
- RTCPeerConnection.prototype.removeStream = function (stream) {
- var pc = this;
- stream.getTracks().forEach(function (track) {
- var sender = pc.getSenders().find(function (s) {
- return s.track === track;
- });
- if (sender) {
- pc.removeTrack(sender);
- }
- });
- };
- RTCPeerConnection.prototype.getSenders = function () {
- return this.transceivers.filter(function (transceiver) {
- return !!transceiver.rtpSender;
- }).map(function (transceiver) {
- return transceiver.rtpSender;
- });
- };
- RTCPeerConnection.prototype.getReceivers = function () {
- return this.transceivers.filter(function (transceiver) {
- return !!transceiver.rtpReceiver;
- }).map(function (transceiver) {
- return transceiver.rtpReceiver;
- });
- };
- RTCPeerConnection.prototype._createIceGatherer = function (sdpMLineIndex, usingBundle) {
- var pc = this;
- if (usingBundle && sdpMLineIndex > 0) {
- return this.transceivers[0].iceGatherer;
- } else if (this._iceGatherers.length) {
- return this._iceGatherers.shift();
- }
- var iceGatherer = new window.RTCIceGatherer({
- iceServers: this._config.iceServers,
- gatherPolicy: this._config.iceTransportPolicy
- });
- Object.defineProperty(iceGatherer, 'state', {
- value: 'new',
- writable: true
- });
- this.transceivers[sdpMLineIndex].bufferedCandidateEvents = [];
- this.transceivers[sdpMLineIndex].bufferCandidates = function (event) {
- var end = !event.candidate || Object.keys(event.candidate).length === 0; // polyfill since RTCIceGatherer.state is not implemented in
- // Edge 10547 yet.
- iceGatherer.state = end ? 'completed' : 'gathering';
- if (pc.transceivers[sdpMLineIndex].bufferedCandidateEvents !== null) {
- pc.transceivers[sdpMLineIndex].bufferedCandidateEvents.push(event);
- }
- };
- iceGatherer.addEventListener('localcandidate', this.transceivers[sdpMLineIndex].bufferCandidates);
- return iceGatherer;
- }; // start gathering from an RTCIceGatherer.
- RTCPeerConnection.prototype._gather = function (mid, sdpMLineIndex) {
- var pc = this;
- var iceGatherer = this.transceivers[sdpMLineIndex].iceGatherer;
- if (iceGatherer.onlocalcandidate) {
- return;
- }
- var bufferedCandidateEvents = this.transceivers[sdpMLineIndex].bufferedCandidateEvents;
- this.transceivers[sdpMLineIndex].bufferedCandidateEvents = null;
- iceGatherer.removeEventListener('localcandidate', this.transceivers[sdpMLineIndex].bufferCandidates);
- iceGatherer.onlocalcandidate = function (evt) {
- if (pc.usingBundle && sdpMLineIndex > 0) {
- // if we know that we use bundle we can drop candidates with
- // ѕdpMLineIndex > 0. If we don't do this then our state gets
- // confused since we dispose the extra ice gatherer.
- return;
- }
- var event = new Event('icecandidate');
- event.candidate = {
- sdpMid: mid,
- sdpMLineIndex: sdpMLineIndex
- };
- var cand = evt.candidate; // Edge emits an empty object for RTCIceCandidateComplete‥
- var end = !cand || Object.keys(cand).length === 0;
- if (end) {
- // polyfill since RTCIceGatherer.state is not implemented in
- // Edge 10547 yet.
- if (iceGatherer.state === 'new' || iceGatherer.state === 'gathering') {
- iceGatherer.state = 'completed';
- }
- } else {
- if (iceGatherer.state === 'new') {
- iceGatherer.state = 'gathering';
- } // RTCIceCandidate doesn't have a component, needs to be added
- cand.component = 1; // also the usernameFragment. TODO: update SDP to take both variants.
- cand.ufrag = iceGatherer.getLocalParameters().usernameFragment;
- var serializedCandidate = SDPUtils.writeCandidate(cand);
- event.candidate = Object.assign(event.candidate, SDPUtils.parseCandidate(serializedCandidate));
- event.candidate.candidate = serializedCandidate;
- event.candidate.toJSON = function () {
- return {
- candidate: event.candidate.candidate,
- sdpMid: event.candidate.sdpMid,
- sdpMLineIndex: event.candidate.sdpMLineIndex,
- usernameFragment: event.candidate.usernameFragment
- };
- };
- } // update local description.
- var sections = SDPUtils.getMediaSections(pc._localDescription.sdp);
- if (!end) {
- sections[event.candidate.sdpMLineIndex] += 'a=' + event.candidate.candidate + '\r\n';
- } else {
- sections[event.candidate.sdpMLineIndex] += 'a=end-of-candidates\r\n';
- }
- pc._localDescription.sdp = SDPUtils.getDescription(pc._localDescription.sdp) + sections.join('');
- var complete = pc.transceivers.every(function (transceiver) {
- return transceiver.iceGatherer && transceiver.iceGatherer.state === 'completed';
- });
- if (pc.iceGatheringState !== 'gathering') {
- pc.iceGatheringState = 'gathering';
- pc._emitGatheringStateChange();
- } // Emit candidate. Also emit null candidate when all gatherers are
- // complete.
- if (!end) {
- pc._dispatchEvent('icecandidate', event);
- }
- if (complete) {
- pc._dispatchEvent('icecandidate', new Event('icecandidate'));
- pc.iceGatheringState = 'complete';
- pc._emitGatheringStateChange();
- }
- }; // emit already gathered candidates.
- window.setTimeout(function () {
- bufferedCandidateEvents.forEach(function (e) {
- iceGatherer.onlocalcandidate(e);
- });
- }, 0);
- }; // Create ICE transport and DTLS transport.
- RTCPeerConnection.prototype._createIceAndDtlsTransports = function () {
- var pc = this;
- var iceTransport = new window.RTCIceTransport(null);
- iceTransport.onicestatechange = function () {
- pc._updateIceConnectionState();
- pc._updateConnectionState();
- };
- var dtlsTransport = new window.RTCDtlsTransport(iceTransport);
- dtlsTransport.ondtlsstatechange = function () {
- pc._updateConnectionState();
- };
- dtlsTransport.onerror = function () {
- // onerror does not set state to failed by itself.
- Object.defineProperty(dtlsTransport, 'state', {
- value: 'failed',
- writable: true
- });
- pc._updateConnectionState();
- };
- return {
- iceTransport: iceTransport,
- dtlsTransport: dtlsTransport
- };
- }; // Destroy ICE gatherer, ICE transport and DTLS transport.
- // Without triggering the callbacks.
- RTCPeerConnection.prototype._disposeIceAndDtlsTransports = function (sdpMLineIndex) {
- var iceGatherer = this.transceivers[sdpMLineIndex].iceGatherer;
- if (iceGatherer) {
- delete iceGatherer.onlocalcandidate;
- delete this.transceivers[sdpMLineIndex].iceGatherer;
- }
- var iceTransport = this.transceivers[sdpMLineIndex].iceTransport;
- if (iceTransport) {
- delete iceTransport.onicestatechange;
- delete this.transceivers[sdpMLineIndex].iceTransport;
- }
- var dtlsTransport = this.transceivers[sdpMLineIndex].dtlsTransport;
- if (dtlsTransport) {
- delete dtlsTransport.ondtlsstatechange;
- delete dtlsTransport.onerror;
- delete this.transceivers[sdpMLineIndex].dtlsTransport;
- }
- }; // Start the RTP Sender and Receiver for a transceiver.
- RTCPeerConnection.prototype._transceive = function (transceiver, send, recv) {
- var params = getCommonCapabilities(transceiver.localCapabilities, transceiver.remoteCapabilities);
- if (send && transceiver.rtpSender) {
- params.encodings = transceiver.sendEncodingParameters;
- params.rtcp = {
- cname: SDPUtils.localCName,
- compound: transceiver.rtcpParameters.compound
- };
- if (transceiver.recvEncodingParameters.length) {
- params.rtcp.ssrc = transceiver.recvEncodingParameters[0].ssrc;
- }
- transceiver.rtpSender.send(params);
- }
- if (recv && transceiver.rtpReceiver && params.codecs.length > 0) {
- // remove RTX field in Edge 14942
- if (transceiver.kind === 'video' && transceiver.recvEncodingParameters && edgeVersion < 15019) {
- transceiver.recvEncodingParameters.forEach(function (p) {
- delete p.rtx;
- });
- }
- if (transceiver.recvEncodingParameters.length) {
- params.encodings = transceiver.recvEncodingParameters;
- } else {
- params.encodings = [{}];
- }
- params.rtcp = {
- compound: transceiver.rtcpParameters.compound
- };
- if (transceiver.rtcpParameters.cname) {
- params.rtcp.cname = transceiver.rtcpParameters.cname;
- }
- if (transceiver.sendEncodingParameters.length) {
- params.rtcp.ssrc = transceiver.sendEncodingParameters[0].ssrc;
- }
- transceiver.rtpReceiver.receive(params);
- }
- };
- RTCPeerConnection.prototype.setLocalDescription = function (description) {
- var pc = this; // Note: pranswer is not supported.
- if (['offer', 'answer'].indexOf(description.type) === -1) {
- return Promise.reject(makeError('TypeError', 'Unsupported type "' + description.type + '"'));
- }
- if (!isActionAllowedInSignalingState('setLocalDescription', description.type, pc.signalingState) || pc._isClosed) {
- return Promise.reject(makeError('InvalidStateError', 'Can not set local ' + description.type + ' in state ' + pc.signalingState));
- }
- var sections;
- var sessionpart;
- if (description.type === 'offer') {
- // VERY limited support for SDP munging. Limited to:
- // * changing the order of codecs
- sections = SDPUtils.splitSections(description.sdp);
- sessionpart = sections.shift();
- sections.forEach(function (mediaSection, sdpMLineIndex) {
- var caps = SDPUtils.parseRtpParameters(mediaSection);
- pc.transceivers[sdpMLineIndex].localCapabilities = caps;
- });
- pc.transceivers.forEach(function (transceiver, sdpMLineIndex) {
- pc._gather(transceiver.mid, sdpMLineIndex);
- });
- } else if (description.type === 'answer') {
- sections = SDPUtils.splitSections(pc._remoteDescription.sdp);
- sessionpart = sections.shift();
- var isIceLite = SDPUtils.matchPrefix(sessionpart, 'a=ice-lite').length > 0;
- sections.forEach(function (mediaSection, sdpMLineIndex) {
- var transceiver = pc.transceivers[sdpMLineIndex];
- var iceGatherer = transceiver.iceGatherer;
- var iceTransport = transceiver.iceTransport;
- var dtlsTransport = transceiver.dtlsTransport;
- var localCapabilities = transceiver.localCapabilities;
- var remoteCapabilities = transceiver.remoteCapabilities; // treat bundle-only as not-rejected.
- var rejected = SDPUtils.isRejected(mediaSection) && SDPUtils.matchPrefix(mediaSection, 'a=bundle-only').length === 0;
- if (!rejected && !transceiver.rejected) {
- var remoteIceParameters = SDPUtils.getIceParameters(mediaSection, sessionpart);
- var remoteDtlsParameters = SDPUtils.getDtlsParameters(mediaSection, sessionpart);
- if (isIceLite) {
- remoteDtlsParameters.role = 'server';
- }
- if (!pc.usingBundle || sdpMLineIndex === 0) {
- pc._gather(transceiver.mid, sdpMLineIndex);
- if (iceTransport.state === 'new') {
- iceTransport.start(iceGatherer, remoteIceParameters, isIceLite ? 'controlling' : 'controlled');
- }
- if (dtlsTransport.state === 'new') {
- dtlsTransport.start(remoteDtlsParameters);
- }
- } // Calculate intersection of capabilities.
- var params = getCommonCapabilities(localCapabilities, remoteCapabilities); // Start the RTCRtpSender. The RTCRtpReceiver for this
- // transceiver has already been started in setRemoteDescription.
- pc._transceive(transceiver, params.codecs.length > 0, false);
- }
- });
- }
- pc._localDescription = {
- type: description.type,
- sdp: description.sdp
- };
- if (description.type === 'offer') {
- pc._updateSignalingState('have-local-offer');
- } else {
- pc._updateSignalingState('stable');
- }
- return Promise.resolve();
- };
- RTCPeerConnection.prototype.setRemoteDescription = function (description) {
- var pc = this; // Note: pranswer is not supported.
- if (['offer', 'answer'].indexOf(description.type) === -1) {
- return Promise.reject(makeError('TypeError', 'Unsupported type "' + description.type + '"'));
- }
- if (!isActionAllowedInSignalingState('setRemoteDescription', description.type, pc.signalingState) || pc._isClosed) {
- return Promise.reject(makeError('InvalidStateError', 'Can not set remote ' + description.type + ' in state ' + pc.signalingState));
- }
- var streams = {};
- pc.remoteStreams.forEach(function (stream) {
- streams[stream.id] = stream;
- });
- var receiverList = [];
- var sections = SDPUtils.splitSections(description.sdp);
- var sessionpart = sections.shift();
- var isIceLite = SDPUtils.matchPrefix(sessionpart, 'a=ice-lite').length > 0;
- var usingBundle = SDPUtils.matchPrefix(sessionpart, 'a=group:BUNDLE ').length > 0;
- pc.usingBundle = usingBundle;
- var iceOptions = SDPUtils.matchPrefix(sessionpart, 'a=ice-options:')[0];
- if (iceOptions) {
- pc.canTrickleIceCandidates = iceOptions.substr(14).split(' ').indexOf('trickle') >= 0;
- } else {
- pc.canTrickleIceCandidates = false;
- }
- sections.forEach(function (mediaSection, sdpMLineIndex) {
- var lines = SDPUtils.splitLines(mediaSection);
- var kind = SDPUtils.getKind(mediaSection); // treat bundle-only as not-rejected.
- var rejected = SDPUtils.isRejected(mediaSection) && SDPUtils.matchPrefix(mediaSection, 'a=bundle-only').length === 0;
- var protocol = lines[0].substr(2).split(' ')[2];
- var direction = SDPUtils.getDirection(mediaSection, sessionpart);
- var remoteMsid = SDPUtils.parseMsid(mediaSection);
- var mid = SDPUtils.getMid(mediaSection) || SDPUtils.generateIdentifier(); // Reject datachannels which are not implemented yet.
- if (rejected || kind === 'application' && (protocol === 'DTLS/SCTP' || protocol === 'UDP/DTLS/SCTP')) {
- // TODO: this is dangerous in the case where a non-rejected m-line
- // becomes rejected.
- pc.transceivers[sdpMLineIndex] = {
- mid: mid,
- kind: kind,
- protocol: protocol,
- rejected: true
- };
- return;
- }
- if (!rejected && pc.transceivers[sdpMLineIndex] && pc.transceivers[sdpMLineIndex].rejected) {
- // recycle a rejected transceiver.
- pc.transceivers[sdpMLineIndex] = pc._createTransceiver(kind, true);
- }
- var transceiver;
- var iceGatherer;
- var iceTransport;
- var dtlsTransport;
- var rtpReceiver;
- var sendEncodingParameters;
- var recvEncodingParameters;
- var localCapabilities;
- var track; // FIXME: ensure the mediaSection has rtcp-mux set.
- var remoteCapabilities = SDPUtils.parseRtpParameters(mediaSection);
- var remoteIceParameters;
- var remoteDtlsParameters;
- if (!rejected) {
- remoteIceParameters = SDPUtils.getIceParameters(mediaSection, sessionpart);
- remoteDtlsParameters = SDPUtils.getDtlsParameters(mediaSection, sessionpart);
- remoteDtlsParameters.role = 'client';
- }
- recvEncodingParameters = SDPUtils.parseRtpEncodingParameters(mediaSection);
- var rtcpParameters = SDPUtils.parseRtcpParameters(mediaSection);
- var isComplete = SDPUtils.matchPrefix(mediaSection, 'a=end-of-candidates', sessionpart).length > 0;
- var cands = SDPUtils.matchPrefix(mediaSection, 'a=candidate:').map(function (cand) {
- return SDPUtils.parseCandidate(cand);
- }).filter(function (cand) {
- return cand.component === 1;
- }); // Check if we can use BUNDLE and dispose transports.
- if ((description.type === 'offer' || description.type === 'answer') && !rejected && usingBundle && sdpMLineIndex > 0 && pc.transceivers[sdpMLineIndex]) {
- pc._disposeIceAndDtlsTransports(sdpMLineIndex);
- pc.transceivers[sdpMLineIndex].iceGatherer = pc.transceivers[0].iceGatherer;
- pc.transceivers[sdpMLineIndex].iceTransport = pc.transceivers[0].iceTransport;
- pc.transceivers[sdpMLineIndex].dtlsTransport = pc.transceivers[0].dtlsTransport;
- if (pc.transceivers[sdpMLineIndex].rtpSender) {
- pc.transceivers[sdpMLineIndex].rtpSender.setTransport(pc.transceivers[0].dtlsTransport);
- }
- if (pc.transceivers[sdpMLineIndex].rtpReceiver) {
- pc.transceivers[sdpMLineIndex].rtpReceiver.setTransport(pc.transceivers[0].dtlsTransport);
- }
- }
- if (description.type === 'offer' && !rejected) {
- transceiver = pc.transceivers[sdpMLineIndex] || pc._createTransceiver(kind);
- transceiver.mid = mid;
- if (!transceiver.iceGatherer) {
- transceiver.iceGatherer = pc._createIceGatherer(sdpMLineIndex, usingBundle);
- }
- if (cands.length && transceiver.iceTransport.state === 'new') {
- if (isComplete && (!usingBundle || sdpMLineIndex === 0)) {
- transceiver.iceTransport.setRemoteCandidates(cands);
- } else {
- cands.forEach(function (candidate) {
- maybeAddCandidate(transceiver.iceTransport, candidate);
- });
- }
- }
- localCapabilities = window.RTCRtpReceiver.getCapabilities(kind); // filter RTX until additional stuff needed for RTX is implemented
- // in adapter.js
- if (edgeVersion < 15019) {
- localCapabilities.codecs = localCapabilities.codecs.filter(function (codec) {
- return codec.name !== 'rtx';
- });
- }
- sendEncodingParameters = transceiver.sendEncodingParameters || [{
- ssrc: (2 * sdpMLineIndex + 2) * 1001
- }]; // TODO: rewrite to use http://w3c.github.io/webrtc-pc/#set-associated-remote-streams
- var isNewTrack = false;
- if (direction === 'sendrecv' || direction === 'sendonly') {
- isNewTrack = !transceiver.rtpReceiver;
- rtpReceiver = transceiver.rtpReceiver || new window.RTCRtpReceiver(transceiver.dtlsTransport, kind);
- if (isNewTrack) {
- var stream;
- track = rtpReceiver.track; // FIXME: does not work with Plan B.
- if (remoteMsid && remoteMsid.stream === '-') {// no-op. a stream id of '-' means: no associated stream.
- } else if (remoteMsid) {
- if (!streams[remoteMsid.stream]) {
- streams[remoteMsid.stream] = new window.MediaStream();
- Object.defineProperty(streams[remoteMsid.stream], 'id', {
- get: function () {
- return remoteMsid.stream;
- }
- });
- }
- Object.defineProperty(track, 'id', {
- get: function () {
- return remoteMsid.track;
- }
- });
- stream = streams[remoteMsid.stream];
- } else {
- if (!streams.default) {
- streams.default = new window.MediaStream();
- }
- stream = streams.default;
- }
- if (stream) {
- addTrackToStreamAndFireEvent(track, stream);
- transceiver.associatedRemoteMediaStreams.push(stream);
- }
- receiverList.push([track, rtpReceiver, stream]);
- }
- } else if (transceiver.rtpReceiver && transceiver.rtpReceiver.track) {
- transceiver.associatedRemoteMediaStreams.forEach(function (s) {
- var nativeTrack = s.getTracks().find(function (t) {
- return t.id === transceiver.rtpReceiver.track.id;
- });
- if (nativeTrack) {
- removeTrackFromStreamAndFireEvent(nativeTrack, s);
- }
- });
- transceiver.associatedRemoteMediaStreams = [];
- }
- transceiver.localCapabilities = localCapabilities;
- transceiver.remoteCapabilities = remoteCapabilities;
- transceiver.rtpReceiver = rtpReceiver;
- transceiver.rtcpParameters = rtcpParameters;
- transceiver.sendEncodingParameters = sendEncodingParameters;
- transceiver.recvEncodingParameters = recvEncodingParameters; // Start the RTCRtpReceiver now. The RTPSender is started in
- // setLocalDescription.
- pc._transceive(pc.transceivers[sdpMLineIndex], false, isNewTrack);
- } else if (description.type === 'answer' && !rejected) {
- transceiver = pc.transceivers[sdpMLineIndex];
- iceGatherer = transceiver.iceGatherer;
- iceTransport = transceiver.iceTransport;
- dtlsTransport = transceiver.dtlsTransport;
- rtpReceiver = transceiver.rtpReceiver;
- sendEncodingParameters = transceiver.sendEncodingParameters;
- localCapabilities = transceiver.localCapabilities;
- pc.transceivers[sdpMLineIndex].recvEncodingParameters = recvEncodingParameters;
- pc.transceivers[sdpMLineIndex].remoteCapabilities = remoteCapabilities;
- pc.transceivers[sdpMLineIndex].rtcpParameters = rtcpParameters;
- if (cands.length && iceTransport.state === 'new') {
- if ((isIceLite || isComplete) && (!usingBundle || sdpMLineIndex === 0)) {
- iceTransport.setRemoteCandidates(cands);
- } else {
- cands.forEach(function (candidate) {
- maybeAddCandidate(transceiver.iceTransport, candidate);
- });
- }
- }
- if (!usingBundle || sdpMLineIndex === 0) {
- if (iceTransport.state === 'new') {
- iceTransport.start(iceGatherer, remoteIceParameters, 'controlling');
- }
- if (dtlsTransport.state === 'new') {
- dtlsTransport.start(remoteDtlsParameters);
- }
- } // If the offer contained RTX but the answer did not,
- // remove RTX from sendEncodingParameters.
- var commonCapabilities = getCommonCapabilities(transceiver.localCapabilities, transceiver.remoteCapabilities);
- var hasRtx = commonCapabilities.codecs.filter(function (c) {
- return c.name.toLowerCase() === 'rtx';
- }).length;
- if (!hasRtx && transceiver.sendEncodingParameters[0].rtx) {
- delete transceiver.sendEncodingParameters[0].rtx;
- }
- pc._transceive(transceiver, direction === 'sendrecv' || direction === 'recvonly', direction === 'sendrecv' || direction === 'sendonly'); // TODO: rewrite to use http://w3c.github.io/webrtc-pc/#set-associated-remote-streams
- if (rtpReceiver && (direction === 'sendrecv' || direction === 'sendonly')) {
- track = rtpReceiver.track;
- if (remoteMsid) {
- if (!streams[remoteMsid.stream]) {
- streams[remoteMsid.stream] = new window.MediaStream();
- }
- addTrackToStreamAndFireEvent(track, streams[remoteMsid.stream]);
- receiverList.push([track, rtpReceiver, streams[remoteMsid.stream]]);
- } else {
- if (!streams.default) {
- streams.default = new window.MediaStream();
- }
- addTrackToStreamAndFireEvent(track, streams.default);
- receiverList.push([track, rtpReceiver, streams.default]);
- }
- } else {
- // FIXME: actually the receiver should be created later.
- delete transceiver.rtpReceiver;
- }
- }
- });
- if (pc._dtlsRole === undefined) {
- pc._dtlsRole = description.type === 'offer' ? 'active' : 'passive';
- }
- pc._remoteDescription = {
- type: description.type,
- sdp: description.sdp
- };
- if (description.type === 'offer') {
- pc._updateSignalingState('have-remote-offer');
- } else {
- pc._updateSignalingState('stable');
- }
- Object.keys(streams).forEach(function (sid) {
- var stream = streams[sid];
- if (stream.getTracks().length) {
- if (pc.remoteStreams.indexOf(stream) === -1) {
- pc.remoteStreams.push(stream);
- var event = new Event('addstream');
- event.stream = stream;
- window.setTimeout(function () {
- pc._dispatchEvent('addstream', event);
- });
- }
- receiverList.forEach(function (item) {
- var track = item[0];
- var receiver = item[1];
- if (stream.id !== item[2].id) {
- return;
- }
- fireAddTrack(pc, track, receiver, [stream]);
- });
- }
- });
- receiverList.forEach(function (item) {
- if (item[2]) {
- return;
- }
- fireAddTrack(pc, item[0], item[1], []);
- }); // check whether addIceCandidate({}) was called within four seconds after
- // setRemoteDescription.
- window.setTimeout(function () {
- if (!(pc && pc.transceivers)) {
- return;
- }
- pc.transceivers.forEach(function (transceiver) {
- if (transceiver.iceTransport && transceiver.iceTransport.state === 'new' && transceiver.iceTransport.getRemoteCandidates().length > 0) {
- console.warn('Timeout for addRemoteCandidate. Consider sending ' + 'an end-of-candidates notification');
- transceiver.iceTransport.addRemoteCandidate({});
- }
- });
- }, 4000);
- return Promise.resolve();
- };
- RTCPeerConnection.prototype.close = function () {
- this.transceivers.forEach(function (transceiver) {
- /* not yet
- if (transceiver.iceGatherer) {
- transceiver.iceGatherer.close();
- }
- */
- if (transceiver.iceTransport) {
- transceiver.iceTransport.stop();
- }
- if (transceiver.dtlsTransport) {
- transceiver.dtlsTransport.stop();
- }
- if (transceiver.rtpSender) {
- transceiver.rtpSender.stop();
- }
- if (transceiver.rtpReceiver) {
- transceiver.rtpReceiver.stop();
- }
- }); // FIXME: clean up tracks, local streams, remote streams, etc
- this._isClosed = true;
- this._updateSignalingState('closed');
- }; // Update the signaling state.
- RTCPeerConnection.prototype._updateSignalingState = function (newState) {
- this.signalingState = newState;
- var event = new Event('signalingstatechange');
- this._dispatchEvent('signalingstatechange', event);
- }; // Determine whether to fire the negotiationneeded event.
- RTCPeerConnection.prototype._maybeFireNegotiationNeeded = function () {
- var pc = this;
- if (this.signalingState !== 'stable' || this.needNegotiation === true) {
- return;
- }
- this.needNegotiation = true;
- window.setTimeout(function () {
- if (pc.needNegotiation) {
- pc.needNegotiation = false;
- var event = new Event('negotiationneeded');
- pc._dispatchEvent('negotiationneeded', event);
- }
- }, 0);
- }; // Update the ice connection state.
- RTCPeerConnection.prototype._updateIceConnectionState = function () {
- var newState;
- var states = {
- 'new': 0,
- closed: 0,
- checking: 0,
- connected: 0,
- completed: 0,
- disconnected: 0,
- failed: 0
- };
- this.transceivers.forEach(function (transceiver) {
- if (transceiver.iceTransport && !transceiver.rejected) {
- states[transceiver.iceTransport.state]++;
- }
- });
- newState = 'new';
- if (states.failed > 0) {
- newState = 'failed';
- } else if (states.checking > 0) {
- newState = 'checking';
- } else if (states.disconnected > 0) {
- newState = 'disconnected';
- } else if (states.new > 0) {
- newState = 'new';
- } else if (states.connected > 0) {
- newState = 'connected';
- } else if (states.completed > 0) {
- newState = 'completed';
- }
- if (newState !== this.iceConnectionState) {
- this.iceConnectionState = newState;
- var event = new Event('iceconnectionstatechange');
- this._dispatchEvent('iceconnectionstatechange', event);
- }
- }; // Update the connection state.
- RTCPeerConnection.prototype._updateConnectionState = function () {
- var newState;
- var states = {
- 'new': 0,
- closed: 0,
- connecting: 0,
- connected: 0,
- completed: 0,
- disconnected: 0,
- failed: 0
- };
- this.transceivers.forEach(function (transceiver) {
- if (transceiver.iceTransport && transceiver.dtlsTransport && !transceiver.rejected) {
- states[transceiver.iceTransport.state]++;
- states[transceiver.dtlsTransport.state]++;
- }
- }); // ICETransport.completed and connected are the same for this purpose.
- states.connected += states.completed;
- newState = 'new';
- if (states.failed > 0) {
- newState = 'failed';
- } else if (states.connecting > 0) {
- newState = 'connecting';
- } else if (states.disconnected > 0) {
- newState = 'disconnected';
- } else if (states.new > 0) {
- newState = 'new';
- } else if (states.connected > 0) {
- newState = 'connected';
- }
- if (newState !== this.connectionState) {
- this.connectionState = newState;
- var event = new Event('connectionstatechange');
- this._dispatchEvent('connectionstatechange', event);
- }
- };
- RTCPeerConnection.prototype.createOffer = function () {
- var pc = this;
- if (pc._isClosed) {
- return Promise.reject(makeError('InvalidStateError', 'Can not call createOffer after close'));
- }
- var numAudioTracks = pc.transceivers.filter(function (t) {
- return t.kind === 'audio';
- }).length;
- var numVideoTracks = pc.transceivers.filter(function (t) {
- return t.kind === 'video';
- }).length; // Determine number of audio and video tracks we need to send/recv.
- var offerOptions = arguments[0];
- if (offerOptions) {
- // Reject Chrome legacy constraints.
- if (offerOptions.mandatory || offerOptions.optional) {
- throw new TypeError('Legacy mandatory/optional constraints not supported.');
- }
- if (offerOptions.offerToReceiveAudio !== undefined) {
- if (offerOptions.offerToReceiveAudio === true) {
- numAudioTracks = 1;
- } else if (offerOptions.offerToReceiveAudio === false) {
- numAudioTracks = 0;
- } else {
- numAudioTracks = offerOptions.offerToReceiveAudio;
- }
- }
- if (offerOptions.offerToReceiveVideo !== undefined) {
- if (offerOptions.offerToReceiveVideo === true) {
- numVideoTracks = 1;
- } else if (offerOptions.offerToReceiveVideo === false) {
- numVideoTracks = 0;
- } else {
- numVideoTracks = offerOptions.offerToReceiveVideo;
- }
- }
- }
- pc.transceivers.forEach(function (transceiver) {
- if (transceiver.kind === 'audio') {
- numAudioTracks--;
- if (numAudioTracks < 0) {
- transceiver.wantReceive = false;
- }
- } else if (transceiver.kind === 'video') {
- numVideoTracks--;
- if (numVideoTracks < 0) {
- transceiver.wantReceive = false;
- }
- }
- }); // Create M-lines for recvonly streams.
- while (numAudioTracks > 0 || numVideoTracks > 0) {
- if (numAudioTracks > 0) {
- pc._createTransceiver('audio');
- numAudioTracks--;
- }
- if (numVideoTracks > 0) {
- pc._createTransceiver('video');
- numVideoTracks--;
- }
- }
- var sdp = SDPUtils.writeSessionBoilerplate(pc._sdpSessionId, pc._sdpSessionVersion++);
- pc.transceivers.forEach(function (transceiver, sdpMLineIndex) {
- // For each track, create an ice gatherer, ice transport,
- // dtls transport, potentially rtpsender and rtpreceiver.
- var track = transceiver.track;
- var kind = transceiver.kind;
- var mid = transceiver.mid || SDPUtils.generateIdentifier();
- transceiver.mid = mid;
- if (!transceiver.iceGatherer) {
- transceiver.iceGatherer = pc._createIceGatherer(sdpMLineIndex, pc.usingBundle);
- }
- var localCapabilities = window.RTCRtpSender.getCapabilities(kind); // filter RTX until additional stuff needed for RTX is implemented
- // in adapter.js
- if (edgeVersion < 15019) {
- localCapabilities.codecs = localCapabilities.codecs.filter(function (codec) {
- return codec.name !== 'rtx';
- });
- }
- localCapabilities.codecs.forEach(function (codec) {
- // work around https://bugs.chromium.org/p/webrtc/issues/detail?id=6552
- // by adding level-asymmetry-allowed=1
- if (codec.name === 'H264' && codec.parameters['level-asymmetry-allowed'] === undefined) {
- codec.parameters['level-asymmetry-allowed'] = '1';
- } // for subsequent offers, we might have to re-use the payload
- // type of the last offer.
- if (transceiver.remoteCapabilities && transceiver.remoteCapabilities.codecs) {
- transceiver.remoteCapabilities.codecs.forEach(function (remoteCodec) {
- if (codec.name.toLowerCase() === remoteCodec.name.toLowerCase() && codec.clockRate === remoteCodec.clockRate) {
- codec.preferredPayloadType = remoteCodec.payloadType;
- }
- });
- }
- });
- localCapabilities.headerExtensions.forEach(function (hdrExt) {
- var remoteExtensions = transceiver.remoteCapabilities && transceiver.remoteCapabilities.headerExtensions || [];
- remoteExtensions.forEach(function (rHdrExt) {
- if (hdrExt.uri === rHdrExt.uri) {
- hdrExt.id = rHdrExt.id;
- }
- });
- }); // generate an ssrc now, to be used later in rtpSender.send
- var sendEncodingParameters = transceiver.sendEncodingParameters || [{
- ssrc: (2 * sdpMLineIndex + 1) * 1001
- }];
- if (track) {
- // add RTX
- if (edgeVersion >= 15019 && kind === 'video' && !sendEncodingParameters[0].rtx) {
- sendEncodingParameters[0].rtx = {
- ssrc: sendEncodingParameters[0].ssrc + 1
- };
- }
- }
- if (transceiver.wantReceive) {
- transceiver.rtpReceiver = new window.RTCRtpReceiver(transceiver.dtlsTransport, kind);
- }
- transceiver.localCapabilities = localCapabilities;
- transceiver.sendEncodingParameters = sendEncodingParameters;
- }); // always offer BUNDLE and dispose on return if not supported.
- if (pc._config.bundlePolicy !== 'max-compat') {
- sdp += 'a=group:BUNDLE ' + pc.transceivers.map(function (t) {
- return t.mid;
- }).join(' ') + '\r\n';
- }
- sdp += 'a=ice-options:trickle\r\n';
- pc.transceivers.forEach(function (transceiver, sdpMLineIndex) {
- sdp += writeMediaSection(transceiver, transceiver.localCapabilities, 'offer', transceiver.stream, pc._dtlsRole);
- sdp += 'a=rtcp-rsize\r\n';
- if (transceiver.iceGatherer && pc.iceGatheringState !== 'new' && (sdpMLineIndex === 0 || !pc.usingBundle)) {
- transceiver.iceGatherer.getLocalCandidates().forEach(function (cand) {
- cand.component = 1;
- sdp += 'a=' + SDPUtils.writeCandidate(cand) + '\r\n';
- });
- if (transceiver.iceGatherer.state === 'completed') {
- sdp += 'a=end-of-candidates\r\n';
- }
- }
- });
- var desc = new window.RTCSessionDescription({
- type: 'offer',
- sdp: sdp
- });
- return Promise.resolve(desc);
- };
- RTCPeerConnection.prototype.createAnswer = function () {
- var pc = this;
- if (pc._isClosed) {
- return Promise.reject(makeError('InvalidStateError', 'Can not call createAnswer after close'));
- }
- if (!(pc.signalingState === 'have-remote-offer' || pc.signalingState === 'have-local-pranswer')) {
- return Promise.reject(makeError('InvalidStateError', 'Can not call createAnswer in signalingState ' + pc.signalingState));
- }
- var sdp = SDPUtils.writeSessionBoilerplate(pc._sdpSessionId, pc._sdpSessionVersion++);
- if (pc.usingBundle) {
- sdp += 'a=group:BUNDLE ' + pc.transceivers.map(function (t) {
- return t.mid;
- }).join(' ') + '\r\n';
- }
- sdp += 'a=ice-options:trickle\r\n';
- var mediaSectionsInOffer = SDPUtils.getMediaSections(pc._remoteDescription.sdp).length;
- pc.transceivers.forEach(function (transceiver, sdpMLineIndex) {
- if (sdpMLineIndex + 1 > mediaSectionsInOffer) {
- return;
- }
- if (transceiver.rejected) {
- if (transceiver.kind === 'application') {
- if (transceiver.protocol === 'DTLS/SCTP') {
- // legacy fmt
- sdp += 'm=application 0 DTLS/SCTP 5000\r\n';
- } else {
- sdp += 'm=application 0 ' + transceiver.protocol + ' webrtc-datachannel\r\n';
- }
- } else if (transceiver.kind === 'audio') {
- sdp += 'm=audio 0 UDP/TLS/RTP/SAVPF 0\r\n' + 'a=rtpmap:0 PCMU/8000\r\n';
- } else if (transceiver.kind === 'video') {
- sdp += 'm=video 0 UDP/TLS/RTP/SAVPF 120\r\n' + 'a=rtpmap:120 VP8/90000\r\n';
- }
- sdp += 'c=IN IP4 0.0.0.0\r\n' + 'a=inactive\r\n' + 'a=mid:' + transceiver.mid + '\r\n';
- return;
- } // FIXME: look at direction.
- if (transceiver.stream) {
- var localTrack;
- if (transceiver.kind === 'audio') {
- localTrack = transceiver.stream.getAudioTracks()[0];
- } else if (transceiver.kind === 'video') {
- localTrack = transceiver.stream.getVideoTracks()[0];
- }
- if (localTrack) {
- // add RTX
- if (edgeVersion >= 15019 && transceiver.kind === 'video' && !transceiver.sendEncodingParameters[0].rtx) {
- transceiver.sendEncodingParameters[0].rtx = {
- ssrc: transceiver.sendEncodingParameters[0].ssrc + 1
- };
- }
- }
- } // Calculate intersection of capabilities.
- var commonCapabilities = getCommonCapabilities(transceiver.localCapabilities, transceiver.remoteCapabilities);
- var hasRtx = commonCapabilities.codecs.filter(function (c) {
- return c.name.toLowerCase() === 'rtx';
- }).length;
- if (!hasRtx && transceiver.sendEncodingParameters[0].rtx) {
- delete transceiver.sendEncodingParameters[0].rtx;
- }
- sdp += writeMediaSection(transceiver, commonCapabilities, 'answer', transceiver.stream, pc._dtlsRole);
- if (transceiver.rtcpParameters && transceiver.rtcpParameters.reducedSize) {
- sdp += 'a=rtcp-rsize\r\n';
- }
- });
- var desc = new window.RTCSessionDescription({
- type: 'answer',
- sdp: sdp
- });
- return Promise.resolve(desc);
- };
- RTCPeerConnection.prototype.addIceCandidate = function (candidate) {
- var pc = this;
- var sections;
- if (candidate && !(candidate.sdpMLineIndex !== undefined || candidate.sdpMid)) {
- return Promise.reject(new TypeError('sdpMLineIndex or sdpMid required'));
- } // TODO: needs to go into ops queue.
- return new Promise(function (resolve, reject) {
- if (!pc._remoteDescription) {
- return reject(makeError('InvalidStateError', 'Can not add ICE candidate without a remote description'));
- } else if (!candidate || candidate.candidate === '') {
- for (var j = 0; j < pc.transceivers.length; j++) {
- if (pc.transceivers[j].rejected) {
- continue;
- }
- pc.transceivers[j].iceTransport.addRemoteCandidate({});
- sections = SDPUtils.getMediaSections(pc._remoteDescription.sdp);
- sections[j] += 'a=end-of-candidates\r\n';
- pc._remoteDescription.sdp = SDPUtils.getDescription(pc._remoteDescription.sdp) + sections.join('');
- if (pc.usingBundle) {
- break;
- }
- }
- } else {
- var sdpMLineIndex = candidate.sdpMLineIndex;
- if (candidate.sdpMid) {
- for (var i = 0; i < pc.transceivers.length; i++) {
- if (pc.transceivers[i].mid === candidate.sdpMid) {
- sdpMLineIndex = i;
- break;
- }
- }
- }
- var transceiver = pc.transceivers[sdpMLineIndex];
- if (transceiver) {
- if (transceiver.rejected) {
- return resolve();
- }
- var cand = Object.keys(candidate.candidate).length > 0 ? SDPUtils.parseCandidate(candidate.candidate) : {}; // Ignore Chrome's invalid candidates since Edge does not like them.
- if (cand.protocol === 'tcp' && (cand.port === 0 || cand.port === 9)) {
- return resolve();
- } // Ignore RTCP candidates, we assume RTCP-MUX.
- if (cand.component && cand.component !== 1) {
- return resolve();
- } // when using bundle, avoid adding candidates to the wrong
- // ice transport. And avoid adding candidates added in the SDP.
- if (sdpMLineIndex === 0 || sdpMLineIndex > 0 && transceiver.iceTransport !== pc.transceivers[0].iceTransport) {
- if (!maybeAddCandidate(transceiver.iceTransport, cand)) {
- return reject(makeError('OperationError', 'Can not add ICE candidate'));
- }
- } // update the remoteDescription.
- var candidateString = candidate.candidate.trim();
- if (candidateString.indexOf('a=') === 0) {
- candidateString = candidateString.substr(2);
- }
- sections = SDPUtils.getMediaSections(pc._remoteDescription.sdp);
- sections[sdpMLineIndex] += 'a=' + (cand.type ? candidateString : 'end-of-candidates') + '\r\n';
- pc._remoteDescription.sdp = SDPUtils.getDescription(pc._remoteDescription.sdp) + sections.join('');
- } else {
- return reject(makeError('OperationError', 'Can not add ICE candidate'));
- }
- }
- resolve();
- });
- };
- RTCPeerConnection.prototype.getStats = function (selector) {
- if (selector && selector instanceof window.MediaStreamTrack) {
- var senderOrReceiver = null;
- this.transceivers.forEach(function (transceiver) {
- if (transceiver.rtpSender && transceiver.rtpSender.track === selector) {
- senderOrReceiver = transceiver.rtpSender;
- } else if (transceiver.rtpReceiver && transceiver.rtpReceiver.track === selector) {
- senderOrReceiver = transceiver.rtpReceiver;
- }
- });
- if (!senderOrReceiver) {
- throw makeError('InvalidAccessError', 'Invalid selector.');
- }
- return senderOrReceiver.getStats();
- }
- var promises = [];
- this.transceivers.forEach(function (transceiver) {
- ['rtpSender', 'rtpReceiver', 'iceGatherer', 'iceTransport', 'dtlsTransport'].forEach(function (method) {
- if (transceiver[method]) {
- promises.push(transceiver[method].getStats());
- }
- });
- });
- return Promise.all(promises).then(function (allStats) {
- var results = new Map();
- allStats.forEach(function (stats) {
- stats.forEach(function (stat) {
- results.set(stat.id, stat);
- });
- });
- return results;
- });
- }; // fix low-level stat names and return Map instead of object.
- var ortcObjects = ['RTCRtpSender', 'RTCRtpReceiver', 'RTCIceGatherer', 'RTCIceTransport', 'RTCDtlsTransport'];
- ortcObjects.forEach(function (ortcObjectName) {
- var obj = window[ortcObjectName];
- if (obj && obj.prototype && obj.prototype.getStats) {
- var nativeGetstats = obj.prototype.getStats;
- obj.prototype.getStats = function () {
- return nativeGetstats.apply(this).then(function (nativeStats) {
- var mapStats = new Map();
- Object.keys(nativeStats).forEach(function (id) {
- nativeStats[id].type = fixStatsType(nativeStats[id]);
- mapStats.set(id, nativeStats[id]);
- });
- return mapStats;
- });
- };
- }
- }); // legacy callback shims. Should be moved to adapter.js some days.
- var methods = ['createOffer', 'createAnswer'];
- methods.forEach(function (method) {
- var nativeMethod = RTCPeerConnection.prototype[method];
- RTCPeerConnection.prototype[method] = function () {
- var args = arguments;
- if (typeof args[0] === 'function' || typeof args[1] === 'function') {
- // legacy
- return nativeMethod.apply(this, [arguments[2]]).then(function (description) {
- if (typeof args[0] === 'function') {
- args[0].apply(null, [description]);
- }
- }, function (error) {
- if (typeof args[1] === 'function') {
- args[1].apply(null, [error]);
- }
- });
- }
- return nativeMethod.apply(this, arguments);
- };
- });
- methods = ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'];
- methods.forEach(function (method) {
- var nativeMethod = RTCPeerConnection.prototype[method];
- RTCPeerConnection.prototype[method] = function () {
- var args = arguments;
- if (typeof args[1] === 'function' || typeof args[2] === 'function') {
- // legacy
- return nativeMethod.apply(this, arguments).then(function () {
- if (typeof args[1] === 'function') {
- args[1].apply(null);
- }
- }, function (error) {
- if (typeof args[2] === 'function') {
- args[2].apply(null, [error]);
- }
- });
- }
- return nativeMethod.apply(this, arguments);
- };
- }); // getStats is special. It doesn't have a spec legacy method yet we support
- // getStats(something, cb) without error callbacks.
- ['getStats'].forEach(function (method) {
- var nativeMethod = RTCPeerConnection.prototype[method];
- RTCPeerConnection.prototype[method] = function () {
- var args = arguments;
- if (typeof args[1] === 'function') {
- return nativeMethod.apply(this, arguments).then(function () {
- if (typeof args[1] === 'function') {
- args[1].apply(null);
- }
- });
- }
- return nativeMethod.apply(this, arguments);
- };
- });
- return RTCPeerConnection;
- };
- }),
- /* 52 */
- (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- /* harmony export (immutable) */ __webpack_exports__["a"] = shimGetUserMedia;
- /*
- * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- /* eslint-env node */
- function shimGetUserMedia(window) {
- const navigator = window && window.navigator;
- const shimError_ = function (e) {
- return {
- name: {
- PermissionDeniedError: 'NotAllowedError'
- }[e.name] || e.name,
- message: e.message,
- constraint: e.constraint,
- toString() {
- return this.name;
- }
- };
- }; // getUserMedia error shim.
- const origGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);
- navigator.mediaDevices.getUserMedia = function (c) {
- return origGetUserMedia(c).catch(e => Promise.reject(shimError_(e)));
- };
- }
- }),
- /* 53 */
- (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- /* harmony export (immutable) */ __webpack_exports__["a"] = shimGetDisplayMedia;
- /*
- * Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- /* eslint-env node */
- function shimGetDisplayMedia(window) {
- if (!('getDisplayMedia' in window.navigator)) {
- return;
- }
- if (!window.navigator.mediaDevices) {
- return;
- }
- if (window.navigator.mediaDevices && 'getDisplayMedia' in window.navigator.mediaDevices) {
- return;
- }
- window.navigator.mediaDevices.getDisplayMedia = window.navigator.getDisplayMedia.bind(window.navigator.mediaDevices);
- }
- }),
- /* 54 */
- (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
- /* harmony export (immutable) */ __webpack_exports__["shimOnTrack"] = shimOnTrack;
- /* harmony export (immutable) */ __webpack_exports__["shimPeerConnection"] = shimPeerConnection;
- /* harmony export (immutable) */ __webpack_exports__["shimSenderGetStats"] = shimSenderGetStats;
- /* harmony export (immutable) */ __webpack_exports__["shimReceiverGetStats"] = shimReceiverGetStats;
- /* harmony export (immutable) */ __webpack_exports__["shimRemoveStream"] = shimRemoveStream;
- /* harmony export (immutable) */ __webpack_exports__["shimRTCDataChannel"] = shimRTCDataChannel;
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils__ = __webpack_require__(4);
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__getusermedia__ = __webpack_require__(55);
- /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "shimGetUserMedia", function() { return __WEBPACK_IMPORTED_MODULE_1__getusermedia__["a"]; });
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__getdisplaymedia__ = __webpack_require__(56);
- /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "shimGetDisplayMedia", function() { return __WEBPACK_IMPORTED_MODULE_2__getdisplaymedia__["a"]; });
- /*
- * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- /* eslint-env node */
- function shimOnTrack(window) {
- if (typeof window === 'object' && window.RTCTrackEvent && 'receiver' in window.RTCTrackEvent.prototype && !('transceiver' in window.RTCTrackEvent.prototype)) {
- Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', {
- get() {
- return {
- receiver: this.receiver
- };
- }
- });
- }
- }
- function shimPeerConnection(window) {
- const browserDetails = __WEBPACK_IMPORTED_MODULE_0__utils__["b" /* detectBrowser */](window);
- if (typeof window !== 'object' || !(window.RTCPeerConnection || window.mozRTCPeerConnection)) {
- return; // probably media.peerconnection.enabled=false in about:config
- }
- if (!window.RTCPeerConnection && window.mozRTCPeerConnection) {
- // very basic support for old versions.
- window.RTCPeerConnection = window.mozRTCPeerConnection;
- } // shim away need for obsolete RTCIceCandidate/RTCSessionDescription.
- ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'].forEach(function (method) {
- const nativeMethod = window.RTCPeerConnection.prototype[method];
- window.RTCPeerConnection.prototype[method] = function () {
- arguments[0] = new (method === 'addIceCandidate' ? window.RTCIceCandidate : window.RTCSessionDescription)(arguments[0]);
- return nativeMethod.apply(this, arguments);
- };
- }); // support for addIceCandidate(null or undefined)
- const nativeAddIceCandidate = window.RTCPeerConnection.prototype.addIceCandidate;
- window.RTCPeerConnection.prototype.addIceCandidate = function () {
- if (!arguments[0]) {
- if (arguments[1]) {
- arguments[1].apply(null);
- }
- return Promise.resolve();
- }
- return nativeAddIceCandidate.apply(this, arguments);
- };
- const modernStatsTypes = {
- inboundrtp: 'inbound-rtp',
- outboundrtp: 'outbound-rtp',
- candidatepair: 'candidate-pair',
- localcandidate: 'local-candidate',
- remotecandidate: 'remote-candidate'
- };
- const nativeGetStats = window.RTCPeerConnection.prototype.getStats;
- window.RTCPeerConnection.prototype.getStats = function (selector, onSucc, onErr) {
- return nativeGetStats.apply(this, [selector || null]).then(stats => {
- if (browserDetails.version < 53 && !onSucc) {
- // Shim only promise getStats with spec-hyphens in type names
- // Leave callback version alone; misc old uses of forEach before Map
- try {
- stats.forEach(stat => {
- stat.type = modernStatsTypes[stat.type] || stat.type;
- });
- } catch (e) {
- if (e.name !== 'TypeError') {
- throw e;
- } // Avoid TypeError: "type" is read-only, in old versions. 34-43ish
- stats.forEach((stat, i) => {
- stats.set(i, Object.assign({}, stat, {
- type: modernStatsTypes[stat.type] || stat.type
- }));
- });
- }
- }
- return stats;
- }).then(onSucc, onErr);
- };
- }
- function shimSenderGetStats(window) {
- if (!(typeof window === 'object' && window.RTCPeerConnection && window.RTCRtpSender)) {
- return;
- }
- if (window.RTCRtpSender && 'getStats' in window.RTCRtpSender.prototype) {
- return;
- }
- const origGetSenders = window.RTCPeerConnection.prototype.getSenders;
- if (origGetSenders) {
- window.RTCPeerConnection.prototype.getSenders = function () {
- const senders = origGetSenders.apply(this, []);
- senders.forEach(sender => sender._pc = this);
- return senders;
- };
- }
- const origAddTrack = window.RTCPeerConnection.prototype.addTrack;
- if (origAddTrack) {
- window.RTCPeerConnection.prototype.addTrack = function () {
- const sender = origAddTrack.apply(this, arguments);
- sender._pc = this;
- return sender;
- };
- }
- window.RTCRtpSender.prototype.getStats = function () {
- return this.track ? this._pc.getStats(this.track) : Promise.resolve(new Map());
- };
- }
- function shimReceiverGetStats(window) {
- if (!(typeof window === 'object' && window.RTCPeerConnection && window.RTCRtpSender)) {
- return;
- }
- if (window.RTCRtpSender && 'getStats' in window.RTCRtpReceiver.prototype) {
- return;
- }
- const origGetReceivers = window.RTCPeerConnection.prototype.getReceivers;
- if (origGetReceivers) {
- window.RTCPeerConnection.prototype.getReceivers = function () {
- const receivers = origGetReceivers.apply(this, []);
- receivers.forEach(receiver => receiver._pc = this);
- return receivers;
- };
- }
- __WEBPACK_IMPORTED_MODULE_0__utils__["g" /* wrapPeerConnectionEvent */](window, 'track', e => {
- e.receiver._pc = e.srcElement;
- return e;
- });
- window.RTCRtpReceiver.prototype.getStats = function () {
- return this._pc.getStats(this.track);
- };
- }
- function shimRemoveStream(window) {
- if (!window.RTCPeerConnection || 'removeStream' in window.RTCPeerConnection.prototype) {
- return;
- }
- window.RTCPeerConnection.prototype.removeStream = function (stream) {
- __WEBPACK_IMPORTED_MODULE_0__utils__["a" /* deprecated */]('removeStream', 'removeTrack');
- this.getSenders().forEach(sender => {
- if (sender.track && stream.getTracks().includes(sender.track)) {
- this.removeTrack(sender);
- }
- });
- };
- }
- function shimRTCDataChannel(window) {
- // rename DataChannel to RTCDataChannel (native fix in FF60):
- // https://bugzilla.mozilla.org/show_bug.cgi?id=1173851
- if (window.DataChannel && !window.RTCDataChannel) {
- window.RTCDataChannel = window.DataChannel;
- }
- }
- }),
- /* 55 */
- (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- /* harmony export (immutable) */ __webpack_exports__["a"] = shimGetUserMedia;
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils__ = __webpack_require__(4);
- /*
- * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- /* eslint-env node */
- function shimGetUserMedia(window) {
- const browserDetails = __WEBPACK_IMPORTED_MODULE_0__utils__["b" /* detectBrowser */](window);
- const navigator = window && window.navigator;
- const MediaStreamTrack = window && window.MediaStreamTrack;
- navigator.getUserMedia = function (constraints, onSuccess, onError) {
- // Replace Firefox 44+'s deprecation warning with unprefixed version.
- __WEBPACK_IMPORTED_MODULE_0__utils__["a" /* deprecated */]('navigator.getUserMedia', 'navigator.mediaDevices.getUserMedia');
- navigator.mediaDevices.getUserMedia(constraints).then(onSuccess, onError);
- };
- if (!(browserDetails.version > 55 && 'autoGainControl' in navigator.mediaDevices.getSupportedConstraints())) {
- const remap = function (obj, a, b) {
- if (a in obj && !(b in obj)) {
- obj[b] = obj[a];
- delete obj[a];
- }
- };
- const nativeGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);
- navigator.mediaDevices.getUserMedia = function (c) {
- if (typeof c === 'object' && typeof c.audio === 'object') {
- c = JSON.parse(JSON.stringify(c));
- remap(c.audio, 'autoGainControl', 'mozAutoGainControl');
- remap(c.audio, 'noiseSuppression', 'mozNoiseSuppression');
- }
- return nativeGetUserMedia(c);
- };
- if (MediaStreamTrack && MediaStreamTrack.prototype.getSettings) {
- const nativeGetSettings = MediaStreamTrack.prototype.getSettings;
- MediaStreamTrack.prototype.getSettings = function () {
- const obj = nativeGetSettings.apply(this, arguments);
- remap(obj, 'mozAutoGainControl', 'autoGainControl');
- remap(obj, 'mozNoiseSuppression', 'noiseSuppression');
- return obj;
- };
- }
- if (MediaStreamTrack && MediaStreamTrack.prototype.applyConstraints) {
- const nativeApplyConstraints = MediaStreamTrack.prototype.applyConstraints;
- MediaStreamTrack.prototype.applyConstraints = function (c) {
- if (this.kind === 'audio' && typeof c === 'object') {
- c = JSON.parse(JSON.stringify(c));
- remap(c, 'autoGainControl', 'mozAutoGainControl');
- remap(c, 'noiseSuppression', 'mozNoiseSuppression');
- }
- return nativeApplyConstraints.apply(this, [c]);
- };
- }
- }
- }
- }),
- /* 56 */
- (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- /* harmony export (immutable) */ __webpack_exports__["a"] = shimGetDisplayMedia;
- /*
- * Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- /* eslint-env node */
- function shimGetDisplayMedia(window, preferredMediaSource) {
- if (window.navigator.mediaDevices && 'getDisplayMedia' in window.navigator.mediaDevices) {
- return;
- }
- if (!window.navigator.mediaDevices) {
- return;
- }
- window.navigator.mediaDevices.getDisplayMedia = function (constraints) {
- if (!(constraints && constraints.video)) {
- const err = new DOMException('getDisplayMedia without video ' + 'constraints is undefined');
- err.name = 'NotFoundError'; // from https://heycam.github.io/webidl/#idl-DOMException-error-names
- err.code = 8;
- return Promise.reject(err);
- }
- if (constraints.video === true) {
- constraints.video = {
- mediaSource: preferredMediaSource
- };
- } else {
- constraints.video.mediaSource = preferredMediaSource;
- }
- return window.navigator.mediaDevices.getUserMedia(constraints);
- };
- }
- }),
- /* 57 */
- (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
- /* harmony export (immutable) */ __webpack_exports__["shimLocalStreamsAPI"] = shimLocalStreamsAPI;
- /* harmony export (immutable) */ __webpack_exports__["shimRemoteStreamsAPI"] = shimRemoteStreamsAPI;
- /* harmony export (immutable) */ __webpack_exports__["shimCallbacksAPI"] = shimCallbacksAPI;
- /* harmony export (immutable) */ __webpack_exports__["shimGetUserMedia"] = shimGetUserMedia;
- /* harmony export (immutable) */ __webpack_exports__["shimRTCIceServerUrls"] = shimRTCIceServerUrls;
- /* harmony export (immutable) */ __webpack_exports__["shimTrackEventTransceiver"] = shimTrackEventTransceiver;
- /* harmony export (immutable) */ __webpack_exports__["shimCreateOfferLegacy"] = shimCreateOfferLegacy;
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils__ = __webpack_require__(4);
- /*
- * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- function shimLocalStreamsAPI(window) {
- if (typeof window !== 'object' || !window.RTCPeerConnection) {
- return;
- }
- if (!('getLocalStreams' in window.RTCPeerConnection.prototype)) {
- window.RTCPeerConnection.prototype.getLocalStreams = function () {
- if (!this._localStreams) {
- this._localStreams = [];
- }
- return this._localStreams;
- };
- }
- if (!('addStream' in window.RTCPeerConnection.prototype)) {
- const _addTrack = window.RTCPeerConnection.prototype.addTrack;
- window.RTCPeerConnection.prototype.addStream = function (stream) {
- if (!this._localStreams) {
- this._localStreams = [];
- }
- if (!this._localStreams.includes(stream)) {
- this._localStreams.push(stream);
- }
- stream.getTracks().forEach(track => _addTrack.call(this, track, stream));
- };
- window.RTCPeerConnection.prototype.addTrack = function (track, stream) {
- if (stream) {
- if (!this._localStreams) {
- this._localStreams = [stream];
- } else if (!this._localStreams.includes(stream)) {
- this._localStreams.push(stream);
- }
- }
- return _addTrack.call(this, track, stream);
- };
- }
- if (!('removeStream' in window.RTCPeerConnection.prototype)) {
- window.RTCPeerConnection.prototype.removeStream = function (stream) {
- if (!this._localStreams) {
- this._localStreams = [];
- }
- const index = this._localStreams.indexOf(stream);
- if (index === -1) {
- return;
- }
- this._localStreams.splice(index, 1);
- const tracks = stream.getTracks();
- this.getSenders().forEach(sender => {
- if (tracks.includes(sender.track)) {
- this.removeTrack(sender);
- }
- });
- };
- }
- }
- function shimRemoteStreamsAPI(window) {
- if (typeof window !== 'object' || !window.RTCPeerConnection) {
- return;
- }
- if (!('getRemoteStreams' in window.RTCPeerConnection.prototype)) {
- window.RTCPeerConnection.prototype.getRemoteStreams = function () {
- return this._remoteStreams ? this._remoteStreams : [];
- };
- }
- if (!('onaddstream' in window.RTCPeerConnection.prototype)) {
- Object.defineProperty(window.RTCPeerConnection.prototype, 'onaddstream', {
- get() {
- return this._onaddstream;
- },
- set(f) {
- if (this._onaddstream) {
- this.removeEventListener('addstream', this._onaddstream);
- this.removeEventListener('track', this._onaddstreampoly);
- }
- this.addEventListener('addstream', this._onaddstream = f);
- this.addEventListener('track', this._onaddstreampoly = e => {
- e.streams.forEach(stream => {
- if (!this._remoteStreams) {
- this._remoteStreams = [];
- }
- if (this._remoteStreams.includes(stream)) {
- return;
- }
- this._remoteStreams.push(stream);
- const event = new Event('addstream');
- event.stream = stream;
- this.dispatchEvent(event);
- });
- });
- }
- });
- const origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription;
- window.RTCPeerConnection.prototype.setRemoteDescription = function () {
- const pc = this;
- if (!this._onaddstreampoly) {
- this.addEventListener('track', this._onaddstreampoly = function (e) {
- e.streams.forEach(stream => {
- if (!pc._remoteStreams) {
- pc._remoteStreams = [];
- }
- if (pc._remoteStreams.indexOf(stream) >= 0) {
- return;
- }
- pc._remoteStreams.push(stream);
- const event = new Event('addstream');
- event.stream = stream;
- pc.dispatchEvent(event);
- });
- });
- }
- return origSetRemoteDescription.apply(pc, arguments);
- };
- }
- }
- function shimCallbacksAPI(window) {
- if (typeof window !== 'object' || !window.RTCPeerConnection) {
- return;
- }
- const prototype = window.RTCPeerConnection.prototype;
- const createOffer = prototype.createOffer;
- const createAnswer = prototype.createAnswer;
- const setLocalDescription = prototype.setLocalDescription;
- const setRemoteDescription = prototype.setRemoteDescription;
- const addIceCandidate = prototype.addIceCandidate;
- prototype.createOffer = function (successCallback, failureCallback) {
- const options = arguments.length >= 2 ? arguments[2] : arguments[0];
- const promise = createOffer.apply(this, [options]);
- if (!failureCallback) {
- return promise;
- }
- promise.then(successCallback, failureCallback);
- return Promise.resolve();
- };
- prototype.createAnswer = function (successCallback, failureCallback) {
- const options = arguments.length >= 2 ? arguments[2] : arguments[0];
- const promise = createAnswer.apply(this, [options]);
- if (!failureCallback) {
- return promise;
- }
- promise.then(successCallback, failureCallback);
- return Promise.resolve();
- };
- let withCallback = function (description, successCallback, failureCallback) {
- const promise = setLocalDescription.apply(this, [description]);
- if (!failureCallback) {
- return promise;
- }
- promise.then(successCallback, failureCallback);
- return Promise.resolve();
- };
- prototype.setLocalDescription = withCallback;
- withCallback = function (description, successCallback, failureCallback) {
- const promise = setRemoteDescription.apply(this, [description]);
- if (!failureCallback) {
- return promise;
- }
- promise.then(successCallback, failureCallback);
- return Promise.resolve();
- };
- prototype.setRemoteDescription = withCallback;
- withCallback = function (candidate, successCallback, failureCallback) {
- const promise = addIceCandidate.apply(this, [candidate]);
- if (!failureCallback) {
- return promise;
- }
- promise.then(successCallback, failureCallback);
- return Promise.resolve();
- };
- prototype.addIceCandidate = withCallback;
- }
- function shimGetUserMedia(window) {
- const navigator = window && window.navigator;
- if (!navigator.getUserMedia && navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
- navigator.getUserMedia = function (constraints, cb, errcb) {
- navigator.mediaDevices.getUserMedia(constraints).then(cb, errcb);
- }.bind(navigator);
- }
- }
- function shimRTCIceServerUrls(window) {
- // migrate from non-spec RTCIceServer.url to RTCIceServer.urls
- const OrigPeerConnection = window.RTCPeerConnection;
- window.RTCPeerConnection = function (pcConfig, pcConstraints) {
- if (pcConfig && pcConfig.iceServers) {
- const newIceServers = [];
- for (let i = 0; i < pcConfig.iceServers.length; i++) {
- let server = pcConfig.iceServers[i];
- if (!server.hasOwnProperty('urls') && server.hasOwnProperty('url')) {
- __WEBPACK_IMPORTED_MODULE_0__utils__["a" /* deprecated */]('RTCIceServer.url', 'RTCIceServer.urls');
- server = JSON.parse(JSON.stringify(server));
- server.urls = server.url;
- delete server.url;
- newIceServers.push(server);
- } else {
- newIceServers.push(pcConfig.iceServers[i]);
- }
- }
- pcConfig.iceServers = newIceServers;
- }
- return new OrigPeerConnection(pcConfig, pcConstraints);
- };
- window.RTCPeerConnection.prototype = OrigPeerConnection.prototype; // wrap static methods. Currently just generateCertificate.
- if ('generateCertificate' in window.RTCPeerConnection) {
- Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', {
- get() {
- return OrigPeerConnection.generateCertificate;
- }
- });
- }
- }
- function shimTrackEventTransceiver(window) {
- // Add event.transceiver member over deprecated event.receiver
- if (typeof window === 'object' && window.RTCPeerConnection && 'receiver' in window.RTCTrackEvent.prototype && // can't check 'transceiver' in window.RTCTrackEvent.prototype, as it is
- // defined for some reason even when window.RTCTransceiver is not.
- !window.RTCTransceiver) {
- Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', {
- get() {
- return {
- receiver: this.receiver
- };
- }
- });
- }
- }
- function shimCreateOfferLegacy(window) {
- const origCreateOffer = window.RTCPeerConnection.prototype.createOffer;
- window.RTCPeerConnection.prototype.createOffer = function (offerOptions) {
- if (offerOptions) {
- if (typeof offerOptions.offerToReceiveAudio !== 'undefined') {
- // support bit values
- offerOptions.offerToReceiveAudio = !!offerOptions.offerToReceiveAudio;
- }
- const audioTransceiver = this.getTransceivers().find(transceiver => transceiver.sender.track && transceiver.sender.track.kind === 'audio');
- if (offerOptions.offerToReceiveAudio === false && audioTransceiver) {
- if (audioTransceiver.direction === 'sendrecv') {
- if (audioTransceiver.setDirection) {
- audioTransceiver.setDirection('sendonly');
- } else {
- audioTransceiver.direction = 'sendonly';
- }
- } else if (audioTransceiver.direction === 'recvonly') {
- if (audioTransceiver.setDirection) {
- audioTransceiver.setDirection('inactive');
- } else {
- audioTransceiver.direction = 'inactive';
- }
- }
- } else if (offerOptions.offerToReceiveAudio === true && !audioTransceiver) {
- this.addTransceiver('audio');
- }
- if (typeof offerOptions.offerToReceiveVideo !== 'undefined') {
- // support bit values
- offerOptions.offerToReceiveVideo = !!offerOptions.offerToReceiveVideo;
- }
- const videoTransceiver = this.getTransceivers().find(transceiver => transceiver.sender.track && transceiver.sender.track.kind === 'video');
- if (offerOptions.offerToReceiveVideo === false && videoTransceiver) {
- if (videoTransceiver.direction === 'sendrecv') {
- if (videoTransceiver.setDirection) {
- videoTransceiver.setDirection('sendonly');
- } else {
- videoTransceiver.direction = 'sendonly';
- }
- } else if (videoTransceiver.direction === 'recvonly') {
- if (videoTransceiver.setDirection) {
- videoTransceiver.setDirection('inactive');
- } else {
- videoTransceiver.direction = 'inactive';
- }
- }
- } else if (offerOptions.offerToReceiveVideo === true && !videoTransceiver) {
- this.addTransceiver('video');
- }
- }
- return origCreateOffer.apply(this, arguments);
- };
- }
- }),
- /* 58 */
- (function(module, __webpack_exports__, __webpack_require__) {
- "use strict";
- Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
- /* harmony export (immutable) */ __webpack_exports__["shimRTCIceCandidate"] = shimRTCIceCandidate;
- /* harmony export (immutable) */ __webpack_exports__["shimMaxMessageSize"] = shimMaxMessageSize;
- /* harmony export (immutable) */ __webpack_exports__["shimSendThrowTypeError"] = shimSendThrowTypeError;
- /* harmony export (immutable) */ __webpack_exports__["shimConnectionState"] = shimConnectionState;
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_sdp__ = __webpack_require__(19);
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_sdp___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_sdp__);
- /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils__ = __webpack_require__(4);
- /*
- * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree.
- */
- /* eslint-env node */
- function shimRTCIceCandidate(window) {
- // foundation is arbitrarily chosen as an indicator for full support for
- // https://w3c.github.io/webrtc-pc/#rtcicecandidate-interface
- if (!window.RTCIceCandidate || window.RTCIceCandidate && 'foundation' in window.RTCIceCandidate.prototype) {
- return;
- }
- const NativeRTCIceCandidate = window.RTCIceCandidate;
- window.RTCIceCandidate = function (args) {
- // Remove the a= which shouldn't be part of the candidate string.
- if (typeof args === 'object' && args.candidate && args.candidate.indexOf('a=') === 0) {
- args = JSON.parse(JSON.stringify(args));
- args.candidate = args.candidate.substr(2);
- }
- if (args.candidate && args.candidate.length) {
- // Augment the native candidate with the parsed fields.
- const nativeCandidate = new NativeRTCIceCandidate(args);
- const parsedCandidate = __WEBPACK_IMPORTED_MODULE_0_sdp___default.a.parseCandidate(args.candidate);
- const augmentedCandidate = Object.assign(nativeCandidate, parsedCandidate); // Add a serializer that does not serialize the extra attributes.
- augmentedCandidate.toJSON = function () {
- return {
- candidate: augmentedCandidate.candidate,
- sdpMid: augmentedCandidate.sdpMid,
- sdpMLineIndex: augmentedCandidate.sdpMLineIndex,
- usernameFragment: augmentedCandidate.usernameFragment
- };
- };
- return augmentedCandidate;
- }
- return new NativeRTCIceCandidate(args);
- };
- window.RTCIceCandidate.prototype = NativeRTCIceCandidate.prototype; // Hook up the augmented candidate in onicecandidate and
- // addEventListener('icecandidate', ...)
- __WEBPACK_IMPORTED_MODULE_1__utils__["g" /* wrapPeerConnectionEvent */](window, 'icecandidate', e => {
- if (e.candidate) {
- Object.defineProperty(e, 'candidate', {
- value: new window.RTCIceCandidate(e.candidate),
- writable: 'false'
- });
- }
- return e;
- });
- }
- function shimMaxMessageSize(window) {
- if (window.RTCSctpTransport || !window.RTCPeerConnection) {
- return;
- }
- const browserDetails = __WEBPACK_IMPORTED_MODULE_1__utils__["b" /* detectBrowser */](window);
- if (!('sctp' in window.RTCPeerConnection.prototype)) {
- Object.defineProperty(window.RTCPeerConnection.prototype, 'sctp', {
- get() {
- return typeof this._sctp === 'undefined' ? null : this._sctp;
- }
- });
- }
- const sctpInDescription = function (description) {
- const sections = __WEBPACK_IMPORTED_MODULE_0_sdp___default.a.splitSections(description.sdp);
- sections.shift();
- return sections.some(mediaSection => {
- const mLine = __WEBPACK_IMPORTED_MODULE_0_sdp___default.a.parseMLine(mediaSection);
- return mLine && mLine.kind === 'application' && mLine.protocol.indexOf('SCTP') !== -1;
- });
- };
- const getRemoteFirefoxVersion = function (description) {
- // TODO: Is there a better solution for detecting Firefox?
- const match = description.sdp.match(/mozilla...THIS_IS_SDPARTA-(\d+)/);
- if (match === null || match.length < 2) {
- return -1;
- }
- const version = parseInt(match[1], 10); // Test for NaN (yes, this is ugly)
- return version !== version ? -1 : version;
- };
- const getCanSendMaxMessageSize = function (remoteIsFirefox) {
- // Every implementation we know can send at least 64 KiB.
- // Note: Although Chrome is technically able to send up to 256 KiB, the
- // data does not reach the other peer reliably.
- // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=8419
- let canSendMaxMessageSize = 65536;
- if (browserDetails.browser === 'firefox') {
- if (browserDetails.version < 57) {
- if (remoteIsFirefox === -1) {
- // FF < 57 will send in 16 KiB chunks using the deprecated PPID
- // fragmentation.
- canSendMaxMessageSize = 16384;
- } else {
- // However, other FF (and RAWRTC) can reassemble PPID-fragmented
- // messages. Thus, supporting ~2 GiB when sending.
- canSendMaxMessageSize = 2147483637;
- }
- } else if (browserDetails.version < 60) {
- // Currently, all FF >= 57 will reset the remote maximum message size
- // to the default value when a data channel is created at a later
- // stage. :(
- // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831
- canSendMaxMessageSize = browserDetails.version === 57 ? 65535 : 65536;
- } else {
- // FF >= 60 supports sending ~2 GiB
- canSendMaxMessageSize = 2147483637;
- }
- }
- return canSendMaxMessageSize;
- };
- const getMaxMessageSize = function (description, remoteIsFirefox) {
- // Note: 65536 bytes is the default value from the SDP spec. Also,
- // every implementation we know supports receiving 65536 bytes.
- let maxMessageSize = 65536; // FF 57 has a slightly incorrect default remote max message size, so
- // we need to adjust it here to avoid a failure when sending.
- // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1425697
- if (browserDetails.browser === 'firefox' && browserDetails.version === 57) {
- maxMessageSize = 65535;
- }
- const match = __WEBPACK_IMPORTED_MODULE_0_sdp___default.a.matchPrefix(description.sdp, 'a=max-message-size:');
- if (match.length > 0) {
- maxMessageSize = parseInt(match[0].substr(19), 10);
- } else if (browserDetails.browser === 'firefox' && remoteIsFirefox !== -1) {
- // If the maximum message size is not present in the remote SDP and
- // both local and remote are Firefox, the remote peer can receive
- // ~2 GiB.
- maxMessageSize = 2147483637;
- }
- return maxMessageSize;
- };
- const origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription;
- window.RTCPeerConnection.prototype.setRemoteDescription = function () {
- this._sctp = null;
- if (sctpInDescription(arguments[0])) {
- // Check if the remote is FF.
- const isFirefox = getRemoteFirefoxVersion(arguments[0]); // Get the maximum message size the local peer is capable of sending
- const canSendMMS = getCanSendMaxMessageSize(isFirefox); // Get the maximum message size of the remote peer.
- const remoteMMS = getMaxMessageSize(arguments[0], isFirefox); // Determine final maximum message size
- let maxMessageSize;
- if (canSendMMS === 0 && remoteMMS === 0) {
- maxMessageSize = Number.POSITIVE_INFINITY;
- } else if (canSendMMS === 0 || remoteMMS === 0) {
- maxMessageSize = Math.max(canSendMMS, remoteMMS);
- } else {
- maxMessageSize = Math.min(canSendMMS, remoteMMS);
- } // Create a dummy RTCSctpTransport object and the 'maxMessageSize'
- // attribute.
- const sctp = {};
- Object.defineProperty(sctp, 'maxMessageSize', {
- get() {
- return maxMessageSize;
- }
- });
- this._sctp = sctp;
- }
- return origSetRemoteDescription.apply(this, arguments);
- };
- }
- function shimSendThrowTypeError(window) {
- if (!(window.RTCPeerConnection && 'createDataChannel' in window.RTCPeerConnection.prototype)) {
- return;
- } // Note: Although Firefox >= 57 has a native implementation, the maximum
- // message size can be reset for all data channels at a later stage.
- // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831
- function wrapDcSend(dc, pc) {
- const origDataChannelSend = dc.send;
- dc.send = function () {
- const data = arguments[0];
- const length = data.length || data.size || data.byteLength;
- if (dc.readyState === 'open' && pc.sctp && length > pc.sctp.maxMessageSize) {
- throw new TypeError('Message too large (can send a maximum of ' + pc.sctp.maxMessageSize + ' bytes)');
- }
- return origDataChannelSend.apply(dc, arguments);
- };
- }
- const origCreateDataChannel = window.RTCPeerConnection.prototype.createDataChannel;
- window.RTCPeerConnection.prototype.createDataChannel = function () {
- const dataChannel = origCreateDataChannel.apply(this, arguments);
- wrapDcSend(dataChannel, this);
- return dataChannel;
- };
- __WEBPACK_IMPORTED_MODULE_1__utils__["g" /* wrapPeerConnectionEvent */](window, 'datachannel', e => {
- wrapDcSend(e.channel, e.target);
- return e;
- });
- }
- /* shims RTCConnectionState by pretending it is the same as iceConnectionState.
- * See https://bugs.chromium.org/p/webrtc/issues/detail?id=6145#c12
- * for why this is a valid hack in Chrome. In Firefox it is slightly incorrect
- * since DTLS failures would be hidden. See
- * https://bugzilla.mozilla.org/show_bug.cgi?id=1265827
- * for the Firefox tracking bug.
- */
- function shimConnectionState(window) {
- if (!window.RTCPeerConnection || 'connectionState' in window.RTCPeerConnection.prototype) {
- return;
- }
- const proto = window.RTCPeerConnection.prototype;
- Object.defineProperty(proto, 'connectionState', {
- get() {
- return {
- completed: 'connected',
- checking: 'connecting'
- }[this.iceConnectionState] || this.iceConnectionState;
- },
- enumerable: true,
- configurable: true
- });
- Object.defineProperty(proto, 'onconnectionstatechange', {
- get() {
- return this._onconnectionstatechange || null;
- },
- set(cb) {
- if (this._onconnectionstatechange) {
- this.removeEventListener('connectionstatechange', this._onconnectionstatechange);
- delete this._onconnectionstatechange;
- }
- if (cb) {
- this.addEventListener('connectionstatechange', this._onconnectionstatechange = cb);
- }
- },
- enumerable: true,
- configurable: true
- });
- ['setLocalDescription', 'setRemoteDescription'].forEach(method => {
- const origMethod = proto[method];
- proto[method] = function () {
- if (!this._connectionstatechangepoly) {
- this._connectionstatechangepoly = e => {
- const pc = e.target;
- if (pc._lastConnectionState !== pc.connectionState) {
- pc._lastConnectionState = pc.connectionState;
- const newEvent = new Event('connectionstatechange', e);
- pc.dispatchEvent(newEvent);
- }
- return e;
- };
- this.addEventListener('iceconnectionstatechange', this._connectionstatechangepoly);
- }
- return origMethod.apply(this, arguments);
- };
- });
- }
- }),
- /* 59 */
- (function(module, exports, __webpack_require__) {
- var $ = __webpack_require__(22);
- var DetectRTC = __webpack_require__(20);
- var JSON = __webpack_require__(60);
- var PhoneNetwork = __webpack_require__(61);
- var PhoneLogger = {
- enable: false,
- Level: 'DEBUG'
- };
- PhoneLogger.url = 'https://localhost:49999';
- PhoneLogger.port = '49999'; // PhoneLogger.user = '';
- var rootAPI = '/api';
- var seq = 0;
- const authorizationToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImxvZ2dlciIsInBhc3N3b3JkIjoid1JGZCU1Lnd-cF44PDdxLSIsImlhdCI6MTU0OTI1NzU0OH0.L_rBP1IejBsWFZdT4Ih7CFJd-DrQEwY91t8i-wThb4c';
- PhoneLogger.debug = function (debug) {
- if (!PhoneLogger.enable||PhoneLogger.Level !== 'DEBUG') return;
- var _data = {
- event: 'debug',
- seq: seq,
- user: PhoneLogger.user,
- direction: debug.direction,
- network: {
- latency: PhoneNetwork.latency,
- uploadSpeed: PhoneNetwork.uploadSpeed,
- downloadSpeed: PhoneNetwork.downloadSpeed
- },
- isWebRTCSupported: DetectRTC.isWebRTCSupported,
- isGetUserMediaSupported: DetectRTC.isGetUserMediaSupported,
- isWebSocketsSupported: DetectRTC.isWebSocketsSupported,
- isAudioContextSupported : DetectRTC.isAudioContextSupported,
- os: DetectRTC.osName + ' ' + DetectRTC.osVersion,
- browser: DetectRTC.browser.name + ' ' + PhoneJs.DetectRTC.browser.fullVersion,
- isMobileDevice: DetectRTC.isMobileDevice // hasMicrophone: DetectRTC.hasMicrophone,
- // hasWebcam: DetectRTC.hasWebcam,
- // hasWebcamPermissions: DetectRTC.isWebsiteHasWebcamPermissions,
- // hasMicrophonePermissions: DetectRTC.isWebsiteHasMicrophonePermissions,
- // isGetUserMediaSupported: DetectRTC.isGetUserMediaSupported,
- // isWebRTCSupported: DetectRTC.isWebRTCSupported
- };
- if (typeof data !== 'string') {
- _data.data = debug.data.toString();
- } else {
- _data.data = debug.data;
- }
- var body = JSON.stringify(_data);
- // var url = PhoneLogger.url + rootAPI + '/debug';
- var url = PhoneLogger.url + rootAPI + '/log';
- seq++;
- $.ajax({
- url: url,
- dataType: 'json',
- headers: {
- 'Authorization':'Bearer ' + authorizationToken,
- },
- type: 'POST',
- contentType: 'application/json',
- data: body,
- success: function (data) {
-
- },
- error: function (error) {
- console.log('error: ' + JSON.stringify(error));
- }
- });
- };
- PhoneLogger.info = function (info) {
- // console.log(info);
- // console.log(info);
- if (!PhoneLogger.enable||PhoneLogger.Level === 'ERROR') return; // var _data = {};
- info.os = DetectRTC.osName + ' ' + DetectRTC.osVersion;
- info.browser = DetectRTC.browser.name + ' ' + PhoneJs.DetectRTC.browser.fullVersion;
- info.isMobileDevice = DetectRTC.isMobileDevice;
- info.isWebRTCSupported = DetectRTC.isWebRTCSupported;
- info.isGetUserMediaSupported = DetectRTC.isGetUserMediaSupported;
- info.isWebSocketsSupported = DetectRTC.isWebSocketsSupported;
- info.isAudioContextSupported = DetectRTC.isAudioContextSupported;
- info.network = {
- latency: PhoneNetwork.latency,
- uploadSpeed: PhoneNetwork.uploadSpeed,
- downloadSpeed: PhoneNetwork.downloadSpeed
- }
- var body = JSON.stringify(info);
- // var url = PhoneLogger.url + rootAPI + '/info';
- var url = PhoneLogger.url + rootAPI + '/log';
- $.ajax({
- url: url,
- dataType: 'json',
- headers: {
- 'Authorization':'Bearer ' + authorizationToken,
- },
- type: 'POST',
- contentType: 'application/json',
- data: body,
- success: function (data) {},
- error: function (error) {
- console.log('error: ' + JSON.stringify(error));
- }
- });
- };
- PhoneLogger.error = function (error) {
- if(!PhoneLogger.enable) return;
- var _data = {};
- error.os = DetectRTC.osName + ' ' + DetectRTC.osVersion;
- error.browser = DetectRTC.browser.name + ' ' + PhoneJs.DetectRTC.browser.fullVersion;
- error.isMobileDevice = DetectRTC.isMobileDevice;
- error.isWebRTCSupported = DetectRTC.isWebRTCSupported;
- error.isGetUserMediaSupported = DetectRTC.isGetUserMediaSupported;
- error.isWebSocketsSupported = DetectRTC.isWebSocketsSupported;
- error.isAudioContextSupported = DetectRTC.isAudioContextSupported;
- error.network = {
- latency: PhoneNetwork.latency,
- uploadSpeed: PhoneNetwork.uploadSpeed,
- downloadSpeed: PhoneNetwork.downloadSpeed
- }
- var body = JSON.stringify(error);
- // var url = PhoneLogger.url + rootAPI + '/error';
- var url = PhoneLogger.url + rootAPI + '/log';
- $.ajax({
- url: url,
- dataType: 'json',
- headers: {
- 'Authorization':'Bearer ' + authorizationToken,
- },
- type: 'POST',
- contentType: 'application/json',
- data: body,
- success: function (data) {// console.log('response: ' + data);
- },
- error: function (error) {
- console.log('error: ' + JSON.stringify(error));
- }
- });
- };
- module.exports = PhoneLogger;
- }),
- /* 60 */
- (function(module, exports) {
- /*!
- Copyright (C) 2013-2017 by Andrea Giammarchi - @WebReflection
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- */
- var // should be a not so common char
- // possibly one JSON does not encode
- // possibly one encodeURIComponent does not encode
- // right now this char is '~' but this might change in the future
- specialChar = '~',
- safeSpecialChar = '\\x' + ('0' + specialChar.charCodeAt(0).toString(16)).slice(-2),
- escapedSafeSpecialChar = '\\' + safeSpecialChar,
- specialCharRG = new RegExp(safeSpecialChar, 'g'),
- safeSpecialCharRG = new RegExp(escapedSafeSpecialChar, 'g'),
- safeStartWithSpecialCharRG = new RegExp('(?:^|([^\\\\]))' + escapedSafeSpecialChar),
- indexOf = [].indexOf || function (v) {
- for (var i = this.length; i-- && this[i] !== v;);
- return i;
- },
- $String = String // there's no way to drop warnings in JSHint
- // about new String ... well, I need that here!
- // faked, and happy linter!
- ;
- function generateReplacer(value, replacer, resolve) {
- var doNotIgnore = false,
- inspect = !!replacer,
- path = [],
- all = [value],
- seen = [value],
- mapp = [resolve ? specialChar : '[Circular]'],
- last = value,
- lvl = 1,
- i,
- fn;
- if (inspect) {
- fn = typeof replacer === 'object' ? function (key, value) {
- return key !== '' && replacer.indexOf(key) < 0 ? void 0 : value;
- } : replacer;
- }
- return function (key, value) {
- // the replacer has rights to decide
- // if a new object should be returned
- // or if there's some key to drop
- // let's call it here rather than "too late"
- if (inspect) value = fn.call(this, key, value); // first pass should be ignored, since it's just the initial object
- if (doNotIgnore) {
- if (last !== this) {
- i = lvl - indexOf.call(all, this) - 1;
- lvl -= i;
- all.splice(lvl, all.length);
- path.splice(lvl - 1, path.length);
- last = this;
- } // console.log(lvl, key, path);
- if (typeof value === 'object' && value) {
- // if object isn't referring to parent object, add to the
- // object path stack. Otherwise it is already there.
- if (indexOf.call(all, value) < 0) {
- all.push(last = value);
- }
- lvl = all.length;
- i = indexOf.call(seen, value);
- if (i < 0) {
- i = seen.push(value) - 1;
- if (resolve) {
- // key cannot contain specialChar but could be not a string
- path.push(('' + key).replace(specialCharRG, safeSpecialChar));
- mapp[i] = specialChar + path.join(specialChar);
- } else {
- mapp[i] = mapp[0];
- }
- } else {
- value = mapp[i];
- }
- } else {
- if (typeof value === 'string' && resolve) {
- // ensure no special char involved on deserialization
- // in this case only first char is important
- // no need to replace all value (better performance)
- value = value.replace(safeSpecialChar, escapedSafeSpecialChar).replace(specialChar, safeSpecialChar);
- }
- }
- } else {
- doNotIgnore = true;
- }
- return value;
- };
- }
- function retrieveFromPath(current, keys) {
- for (var i = 0, length = keys.length; i < length; current = current[// keys should be normalized back here
- keys[i++].replace(safeSpecialCharRG, specialChar)]);
- return current;
- }
- function generateReviver(reviver) {
- return function (key, value) {
- var isString = typeof value === 'string';
- if (isString && value.charAt(0) === specialChar) {
- return new $String(value.slice(1));
- }
- if (key === '') value = regenerate(value, value, {}); // again, only one needed, do not use the RegExp for this replacement
- // only keys need the RegExp
- if (isString) value = value.replace(safeStartWithSpecialCharRG, '$1' + specialChar).replace(escapedSafeSpecialChar, safeSpecialChar);
- return reviver ? reviver.call(this, key, value) : value;
- };
- }
- function regenerateArray(root, current, retrieve) {
- for (var i = 0, length = current.length; i < length; i++) {
- current[i] = regenerate(root, current[i], retrieve);
- }
- return current;
- }
- function regenerateObject(root, current, retrieve) {
- for (var key in current) {
- if (current.hasOwnProperty(key)) {
- current[key] = regenerate(root, current[key], retrieve);
- }
- }
- return current;
- }
- function regenerate(root, current, retrieve) {
- return current instanceof Array ? // fast Array reconstruction
- regenerateArray(root, current, retrieve) : current instanceof $String ? // root is an empty string
- current.length ? retrieve.hasOwnProperty(current) ? retrieve[current] : retrieve[current] = retrieveFromPath(root, current.split(specialChar)) : root : current instanceof Object ? // dedicated Object parser
- regenerateObject(root, current, retrieve) : // value as it is
- current;
- }
- var CircularJSON = {
- stringify: function stringify(value, replacer, space, doNotResolve) {
- return CircularJSON.parser.stringify(value, generateReplacer(value, replacer, !doNotResolve), space);
- },
- parse: function parse(text, reviver) {
- return CircularJSON.parser.parse(text, generateReviver(reviver));
- },
- // A parser should be an API 1:1 compatible with JSON
- // it should expose stringify and parse methods.
- // The default parser is the native JSON.
- parser: JSON
- };
- module.exports = CircularJSON;
- }),
- /* 61 */
- (function(module, exports, __webpack_require__) {
- var $ = __webpack_require__(22);
- var Network = __webpack_require__(62);
- var PhoneNetwork = {};
- PhoneNetwork.url = 'https://localhost:49999';
- PhoneNetwork.enable = false;
- const authorizationToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImxvZ2dlciIsInBhc3N3b3JkIjoid1JGZCU1Lnd-cF44PDdxLSIsImlhdCI6MTU0OTI1NzU0OH0.L_rBP1IejBsWFZdT4Ih7CFJd-DrQEwY91t8i-wThb4c';
- // PhoneNetwork.url = 'https://phone-log.entro-lab.com';
- var net = new Network({
- endpoint: PhoneNetwork.url + '/api/speedtest',
- // Where is located the PHP file.
- latency: {
- // Where is located your `network.php` file.
- // endpoint: PhoneNetwork.url,
- // How many measures should be returned.
- measures: 5,
- // How much attempts to get a valid value should be done for each measure.
- attempts: 3
- },
- upload: {
- // Where is located your `network.php` file.
- // endpoint: 'https://localhost:3443/api/speedtest',
- // The delay while you want to take measures.
- delay: 3000,
- data: {
- // The amount of data to initially use.
- size: 2 * 1024 * 1024,
- // 2 MB
- // If the measure period can't reach the delay defined in the settings,
- // the data amount is multiplied by the following value.
- multiplier: 2
- }
- },
- download: {
- // endpoint: 'https://localhost:3443/api/speedtest',
- delay: 3000,
- data: {
- // The amount of data to initially use.
- size: 1 * 1024 * 1024,
- // 10 MB
- // If the measure period can't reach the delay defined in the settings,
- // the data amount is multiplied by the following value.
- multiplier: 2
- }
- }
- });
- var arrTimes = [];
- var i = 0; // start
- var timesToTest = 5;
- var tThreshold = 150; //ms
- var dummyImage = new Image();
- var isConnectedFast = false;
- var downloadSize = 380685; //bytes
- var uploadSize = 380685; //bytes
- var average;
- PhoneNetwork.test = function (callback) {
- if(!PhoneNetwork.enable) return;
- testLatency(function (data) {
- i = 0;
- isConnectedFast = data.avg <= tThreshold;
- /** output */
- if (data.avg) {
- PhoneNetwork.latency = data.avg.toFixed(2);
- // console.log("Latency: " + PhoneNetwork.latency + "ms - isConnectedFast? " + isConnectedFast);
- testConnectionSpeed(function (response) {
- if (callback && typeof callback == 'function') {
- callback(response);
- }
- });
- } else {
- if (callback && typeof callback == 'function') {
- callback(data);
- }
- }
- });
- // testConnectionSpeed(callback);
- // if (callback && typeof callback == 'function') {
- // callback();
- // }
- };
- PhoneNetwork.testLatency = function (callback) {
- net.latency.on('end', function (averageLatency, allLatencies) {
- // "allLatencies" is an array containing the five calculated latencies in
- // milliseconds. They're used to determine an average latency.
- // console.log('latency', averageLatency.toFixed(2), allLatencies);
- PhoneNetwork.latency = averageLatency.toFixed(2);
- });
- net.latency.start();
- };
- PhoneNetwork.testUpload = function (callback) {
- net.upload.on('start', function (dataSize) {// console.log('start', dataSize);
- }).on('progress', function (averageSpeed, instantSpeed) {// Every bandwidth measure are in Mega BYTES per second!
- // console.log('progress', averageSpeed, instantSpeed);
- }).on('restart', function (dataSize) {// The restart event is triggered when the module didn't have time
- // (according to the `delay` option) to take all the measures. A new
- // request will start with data size increased by the multiplier value.
- // console.log('restart', dataSize);
- }).on('end', function (averageSpeed, allInstantSpeeds) {
- // console.log('upload', averageSpeed, allInstantSpeeds);
- PhoneNetwork.uploadSpeed = averageSpeed.toFixed(2);
- }).start();
- };
- PhoneNetwork.testDownload = function (callback) {
- net.upload.on('start', function (dataSize) {// console.log('start', dataSize);
- }).on('progress', function (averageSpeed, instantSpeed) {// Every bandwidth measure are in Mega BYTES per second!
- // console.log('progress', averageSpeed, instantSpeed);
- }).on('restart', function (dataSize) {// The restart event is triggered when the module didn't have time
- // (according to the `delay` option) to take all the measures. A new
- // request will start with data size increased by the multiplier value.
- // console.log('restart', dataSize);
- }).on('end', function (averageSpeed, allInstantSpeeds) {
- // console.log('download', averageSpeed, allInstantSpeeds);
- PhoneNetwork.downloadSpeed = averageSpeed.toFixed(2);
- }).start();
- };
- /** test and average time took to download image from server, called recursively timesToTest times */
- function testLatency(cb) {
- var testImage = PhoneNetwork.url + '/static/images/sample1.jpg';
- var tStart = new Date().getTime();
- if (i < timesToTest - 1) {
- // dummyImage.src = testImage + '?t=' + tStart;
- // dummyImage.onload = function () {
- // var tEnd = new Date().getTime();
- // var tTimeTook = tEnd - tStart;
- // arrTimes[i] = tTimeTook;
- // testLatency(cb);
- // i++;
- // };
- $.ajax({
- url: PhoneNetwork.url + '/api/latencytest',
- headers: {
- 'Authorization':'Bearer ' + authorizationToken,
- },
- type: 'GET',
- data: '',
- success: function (data) {
- var tEnd = new Date().getTime();
- var tTimeTook = tEnd - tStart;
- arrTimes[i] = tTimeTook;
- testLatency(cb);
- i++;
- },
- error: function (error) {
- // console.log(error);
- cb(error);
- }
- });
- } else {
- /** calculate average of array items then callback */
- var sum = arrTimes.reduce(function (a, b) {
- return a + b;
- });
- var avg = sum / arrTimes.length;
- cb({avg: avg});
- }
- }
- function getBase64Image(img) {
- var canvas = document.createElement("canvas");
- canvas.width = img.width;
- canvas.height = img.height;
- var ctx = canvas.getContext("2d");
- ctx.drawImage(img, 0, 0);
- var dataURL = canvas.toDataURL("image/png");
- return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");
- }
- function toDataUrl(url, callback) {
- var xhr = new XMLHttpRequest();
- xhr.onload = function () {
- var reader = new FileReader();
- reader.onloadend = function () {
- callback(reader.result);
- };
- reader.readAsDataURL(xhr.response);
- };
- xhr.open('GET', url);
- xhr.responseType = 'blob';
- xhr.send();
- }
- function testConnectionSpeed(callback) {
- var startDownloadTime, endDownloadTime;
- var startUploadTime, endUploadTime;
- var download = new Image();
- var imageAddr = PhoneNetwork.url + '/static/images/sample2.jpg';
- $.ajax({
- url: PhoneNetwork.url + '/api/speedtest',
- headers: {
- 'Authorization':'Bearer ' + authorizationToken,
- },
- // dataType: 'json',
- type: 'GET',
- contentType: 'text/plain',
- // processData: false,
- // data: myBase64,
- success: function (data) {
- endDownloadTime = new Date().getTime();
- startUploadTime = new Date().getTime();
- $.ajax({
- url: PhoneNetwork.url + '/api/speedtest',
- headers: {
- 'Authorization':'Bearer ' + authorizationToken,
- },
- // dataType: 'json',
- type: 'POST',
- // contentType: 'text/plain',
- // processData: false,
- data: {data : data},
- success: function (data) {
- endUploadTime = (new Date()).getTime();
- var result = getResult();
- if (callback && typeof callback == 'function') {
- callback(result);
- }
- },
- error: function (error) {
- // return error;
- if (callback && typeof callback == 'function') {
- callback(error);
- }
- // console.log('error: ' + JSON.stringify(error));
- }
- });
- },
- error: function (error) {
- // return error;
- if (callback && typeof callback == 'function') {
- callback(error);
- }
- // console.log('error: ' + JSON.stringify(error));
- }
- });
- // download.onload = function () {
- // endDownloadTime = new Date().getTime();
- // toDataUrl(imageAddr, function (myBase64) {
- // startUploadTime = new Date().getTime();
- // $.ajax({
- // url: PhoneNetwork.url + '/api/speedtest',
- // headers: {
- // 'Authorization':'Bearer ' + authorizationToken,
- // },
- // // dataType: 'json',
- // type: 'POST',
- // contentType: 'text/plain',
- // // processData: false,
- // data: myBase64,
- // success: function (data) {
- // endUploadTime = (new Date()).getTime();
- // getResult();
- // if (callback && typeof callback == 'function') {
- // callback();
- // }
- // },
- // error: function (error) {
- // console.log('error: ' + JSON.stringify(error));
- // }
- // });
- // });
- // };
- download.onerror = function (err, msg) {
- console.log("Invalid image, or error downloading");
- };
- startDownloadTime = new Date().getTime();
- var cacheBuster = "?nnn=" + startDownloadTime;
- // download.src = imageAddr + cacheBuster;
- function getResult() {
- var durationDownload = (endDownloadTime - startDownloadTime) / 1000;
- var bitsDownLoaded = downloadSize * 8;
- var speedDownloadBps = (bitsDownLoaded / durationDownload).toFixed(2);
- var speedDownloadKbps = (speedDownloadBps / 1024).toFixed(2);
- var speedDownloadMbps = (speedDownloadKbps / 1024).toFixed(2);
- var durationUpload = (endUploadTime - startUploadTime) / 1000;
- var bitsUpLoaded = uploadSize * 8;
- var speedUploadBps = (bitsUpLoaded / durationUpload).toFixed(2);
- var speedUploadKbps = (speedUploadBps / 1024).toFixed(2);
- var speedUploadMbps = (speedUploadKbps / 1024).toFixed(2); // ShowProgressMessage([
- // "Your connection speed is:",
- // speedBps + " bps",
- // speedKbps + " kbps",
- // speedMbps + " Mbps"
- // ]);
- PhoneNetwork.downloadSpeed = speedDownloadMbps;
- PhoneNetwork.uploadSpeed = speedUploadMbps;
- // console.log(["Your Download speed is:", // speedBps + " bps",
- // // speedKbps + " kbps",
- // speedDownloadMbps + " Mbps"], ["Your Upload speed is:", // speedBps + " bps",
- // // speedKbps + " kbps",
- // speedUploadMbps + " Mbps"]);
- return {
- latency: PhoneNetwork.latency,
- downloadSpeed: speedDownloadMbps,
- uploadSpeed: speedUploadMbps
- }
- }
- }
- module.exports = PhoneNetwork;
- }),
- /* 62 */
- (function(module, exports, __webpack_require__) {
- /* WEBPACK VAR INJECTION */(function(global) {var require;var require;(function (f) {
- if (true) {
- module.exports = f();
- } else if (typeof define === "function" && define.amd) {
- define([], f);
- } else {
- var g;
- if (typeof window !== "undefined") {
- g = window;
- } else if (typeof global !== "undefined") {
- g = global;
- } else if (typeof self !== "undefined") {
- g = self;
- } else {
- g = this;
- }
- g.Network = f();
- }
- })(function () {
- var define, module, exports;
- return function e(t, n, r) {
- function s(o, u) {
- if (!n[o]) {
- if (!t[o]) {
- var a = typeof require == "function" && require;
- if (!u && a) return require(o, !0);
- if (i) return i(o, !0);
- var f = new Error("Cannot find module '" + o + "'");
- throw f.code = "MODULE_NOT_FOUND", f;
- }
- var l = n[o] = {
- exports: {}
- };
- t[o][0].call(l.exports, function (e) {
- var n = t[o][1][e];
- return s(n ? n : e);
- }, l, l.exports, e, t, n, r);
- }
- return n[o].exports;
- }
- var i = typeof require == "function" && require;
- for (var o = 0; o < r.length; o++) s(r[o]);
- return s;
- }({
- 1: [function (require, module, exports) {
- 'use strict';
- Object.defineProperty(exports, '__esModule', {
- value: true
- });
- var _createDecoratedClass = function () {
- function defineProperties(target, descriptors, initializers) {
- for (var i = 0; i < descriptors.length; i++) {
- var descriptor = descriptors[i];
- var decorators = descriptor.decorators;
- var key = descriptor.key;
- delete descriptor.key;
- delete descriptor.decorators;
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ('value' in descriptor || descriptor.initializer) descriptor.writable = true;
- if (decorators) {
- for (var f = 0; f < decorators.length; f++) {
- var decorator = decorators[f];
- if (typeof decorator === 'function') {
- descriptor = decorator(target, key, descriptor) || descriptor;
- } else {
- throw new TypeError('The decorator for method ' + descriptor.key + ' is of the invalid type ' + typeof decorator);
- }
- }
- if (descriptor.initializer !== undefined) {
- initializers[key] = descriptor;
- continue;
- }
- }
- Object.defineProperty(target, key, descriptor);
- }
- }
- return function (Constructor, protoProps, staticProps, protoInitializers, staticInitializers) {
- if (protoProps) defineProperties(Constructor.prototype, protoProps, protoInitializers);
- if (staticProps) defineProperties(Constructor, staticProps, staticInitializers);
- return Constructor;
- };
- }();
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError('Cannot call a class as a function');
- }
- }
- function _defineDecoratedPropertyDescriptor(target, key, descriptors) {
- var _descriptor = descriptors[key];
- if (!_descriptor) return;
- var descriptor = {};
- for (var _key in _descriptor) descriptor[_key] = _descriptor[_key];
- descriptor.value = descriptor.initializer.call(target);
- Object.defineProperty(target, key, descriptor);
- }
- var _utilsDecorators = require('../utils/decorators');
- /**
- * A callback used as an event handler.
- * @public
- * @callback EventDispatcher~eventHandler
- * @param {...*} args The extra parameters provided to the `trigger` method.
- * @returns {?boolean} If `false` is explicitly returned, the `trigger` method will return `false`.
- */
- /**
- * @class EventDispatcher
- */
- var EventDispatcher = function () {
- var _instanceInitializers = {};
- function EventDispatcher() {
- _classCallCheck(this, EventDispatcher);
- _defineDecoratedPropertyDescriptor(this, '_eventCallbacks', _instanceInitializers);
- }
- _createDecoratedClass(EventDispatcher, [{
- key: 'on',
- /**
- * Attach a callback to one or more events.
- * @public
- * @method EventDispatcher#on
- * @param {string|string[]} events One or multiple event names.
- * @param {EventDispatcher~eventHandler} callback An event handler.
- * @returns {EventDispatcher}
- */
- value: function on(events, callback) {
- var _this = this;
- events = Array.isArray(events) ? events : [events];
- events.forEach(function (event) {
- var eventCallbacks = _this._eventCallbacks[event] = _this._eventCallbacks[event] || []; // If the callback isn't already registered, store it.
- if (!~eventCallbacks.indexOf(callback)) {
- eventCallbacks.push(callback);
- }
- });
- return this;
- }
- /**
- * Detach a callback from one or more events.
- * @public
- * @method EventDispatcher#off
- * @param {string|string[]} events One or multiple event names.
- * @param {EventDispatcher~eventHandler} [callback=null] An event handler.
- * @returns {EventDispatcher}
- */
- }, {
- key: 'off',
- value: function off(events) {
- var _this2 = this;
- var callback = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1];
- events = Array.isArray(events) ? events : [events];
- events.forEach(function (event) {
- var eventCallbacks = _this2._eventCallbacks[event]; // If there is no specified callback, simply delete all the callbacks binded to the provided event.
- if (!callback && eventCallbacks) {
- delete _this2._eventCallbacks[event];
- } else {
- var callbackIndex = eventCallbacks ? eventCallbacks.indexOf(callback) : -1; // If the callback is registered, remove it from the array.
- if (callbackIndex != -1) {
- eventCallbacks.splice(callbackIndex, 1);
- }
- }
- });
- return this;
- }
- /**
- * Trigger an event.
- * @public
- * @method EventDispatcher#trigger
- * @param {string} event An event name.
- * @param {...*} extraParameters Some extra parameters to pass to the event handlers.
- * @returns {boolean} Returns `false` if one of the event handlers explicitly returned `false`.
- */
- }, {
- key: 'trigger',
- value: function trigger(event) {
- for (var _len = arguments.length, extraParameters = Array(_len > 1 ? _len - 1 : 0), _key2 = 1; _key2 < _len; _key2++) {
- extraParameters[_key2 - 1] = arguments[_key2];
- }
- var eventCallbacks = this._eventCallbacks[event] || []; // A callback can return a boolean value which will be logically compared to the other callbacks values before
- // being returned by the trigger() method. This allows a callback to send a "signal" to the caller, like
- // cancelling an action.
- var returnValue = true;
- eventCallbacks.forEach(function (eventCallback) {
- // A callback must explicitly return false if it wants the trigger() method to return false, undefined will
- // not work. This avoids crappy callbacks to mess up with the triggering system.
- var value = eventCallback.apply(undefined, extraParameters);
- value = value !== false ? true : false;
- returnValue = returnValue && value; // Compare the result of the callback to the actual return value
- });
- return returnValue;
- }
- }, {
- key: '_eventCallbacks',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return {};
- },
- enumerable: true
- }], null, _instanceInitializers);
- return EventDispatcher;
- }();
- exports['default'] = EventDispatcher;
- module.exports = exports['default'];
- /**
- * All the registered event callbacks, organized by events.
- * @private
- * @member {Object} EventDispatcher#_eventCallbacks
- */
- }, {
- "../utils/decorators": 7
- }],
- 2: [function (require, module, exports) {
- 'use strict';
- Object.defineProperty(exports, '__esModule', {
- value: true
- });
- var _createDecoratedClass = function () {
- function defineProperties(target, descriptors, initializers) {
- for (var i = 0; i < descriptors.length; i++) {
- var descriptor = descriptors[i];
- var decorators = descriptor.decorators;
- var key = descriptor.key;
- delete descriptor.key;
- delete descriptor.decorators;
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ('value' in descriptor || descriptor.initializer) descriptor.writable = true;
- if (decorators) {
- for (var f = 0; f < decorators.length; f++) {
- var decorator = decorators[f];
- if (typeof decorator === 'function') {
- descriptor = decorator(target, key, descriptor) || descriptor;
- } else {
- throw new TypeError('The decorator for method ' + descriptor.key + ' is of the invalid type ' + typeof decorator);
- }
- }
- if (descriptor.initializer !== undefined) {
- initializers[key] = descriptor;
- continue;
- }
- }
- Object.defineProperty(target, key, descriptor);
- }
- }
- return function (Constructor, protoProps, staticProps, protoInitializers, staticInitializers) {
- if (protoProps) defineProperties(Constructor.prototype, protoProps, protoInitializers);
- if (staticProps) defineProperties(Constructor, staticProps, staticInitializers);
- return Constructor;
- };
- }();
- var _get = function get(_x2, _x3, _x4) {
- var _again = true;
- _function: while (_again) {
- var object = _x2,
- property = _x3,
- receiver = _x4;
- desc = parent = getter = undefined;
- _again = false;
- if (object === null) object = Function.prototype;
- var desc = Object.getOwnPropertyDescriptor(object, property);
- if (desc === undefined) {
- var parent = Object.getPrototypeOf(object);
- if (parent === null) {
- return undefined;
- } else {
- _x2 = parent;
- _x3 = property;
- _x4 = receiver;
- _again = true;
- continue _function;
- }
- } else if ('value' in desc) {
- return desc.value;
- } else {
- var getter = desc.get;
- if (getter === undefined) {
- return undefined;
- }
- return getter.call(receiver);
- }
- }
- };
- function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : {
- 'default': obj
- };
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError('Cannot call a class as a function');
- }
- }
- function _inherits(subClass, superClass) {
- if (typeof superClass !== 'function' && superClass !== null) {
- throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass);
- }
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
- if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
- }
- function _defineDecoratedPropertyDescriptor(target, key, descriptors) {
- var _descriptor = descriptors[key];
- if (!_descriptor) return;
- var descriptor = {};
- for (var _key in _descriptor) descriptor[_key] = _descriptor[_key];
- descriptor.value = descriptor.initializer.call(target);
- Object.defineProperty(target, key, descriptor);
- }
- var _HttpModule2 = require('./HttpModule');
- var _HttpModule3 = _interopRequireDefault(_HttpModule2);
- var _Timing = require('../Timing');
- var _Timing2 = _interopRequireDefault(_Timing);
- var _utilsHelpers = require('../../utils/helpers');
- var _utilsDecorators = require('../../utils/decorators');
- /**
- * @public
- * @typedef {Object} BandwidthModule~settingsObject
- * @extends HttpModule~settingsObject
- * @property {Object} data
- * @property {number} data.size The amount of data to initially use.
- * @property {number} [data.multiplier=2] If the measure period can't reach the delay defined in the settings, the data amount is multiplied by the following value.
- */
- /**
- * Apply a new set of custom settings.
- * @public
- * @method BandwidthModule#settings
- * @param {BandwidthModule~settingsObject} settings A set of custom settings.
- * @returns {BandwidthModule}
- */
- /**
- * Return the current set of settings.
- * @public
- * @method BandwidthModule#settings^2
- * @returns {BandwidthModule~settingsObject}
- */
- /**
- * @class BandwidthModule
- * @extends HttpModule
- * @param {string} loadingType The loading type, `upload` or `download`.
- * @param {BandwidthModule~settingsObject} [settings={}] A set of custom settings.
- */
- var BandwidthModule = function (_HttpModule) {
- var _instanceInitializers = {};
- var _instanceInitializers = {};
- _inherits(BandwidthModule, _HttpModule);
- _createDecoratedClass(BandwidthModule, [{
- key: '_loadingType',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return undefined;
- },
- /**
- *
- * @private
- * @member {boolean} BandwidthModule#_intendedEnd
- */
- enumerable: true
- }, {
- key: '_intendedEnd',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return false;
- },
- /**
- *
- * @private
- * @member {boolean} BandwidthModule#_isRestarting
- */
- enumerable: true
- }, {
- key: '_isRestarting',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return false;
- },
- /**
- * Tracks the value of the `loaded` property for each progress event.
- * @private
- * @member {?number} BandwidthModule#_lastLoadedValue
- */
- enumerable: true
- }, {
- key: '_lastLoadedValue',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return null;
- },
- /**
- * The recorded measures of speed.
- * @private
- * @member {number[]} BandwidthModule#_speedRecords
- */
- enumerable: true
- }, {
- key: '_speedRecords',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return [];
- },
- /**
- * The average speed.
- * @private
- * @member {number} BandwidthModule#_avgSpeed
- */
- enumerable: true
- }, {
- key: '_avgSpeed',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return undefined;
- },
- /**
- * The ID of the current request.
- * @private
- * @member {number} BandwidthModule#_requestID
- */
- enumerable: true
- }, {
- key: '_requestID',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return 0;
- },
- /**
- * The ID of the current progress event.
- * @private
- * @member {number} BandwidthModule#_progressID
- */
- enumerable: true
- }, {
- key: '_progressID',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return 0;
- },
- /**
- * Defines if measures have started.
- * @private
- * @member {boolean} BandwidthModule#_started
- */
- enumerable: true
- }, {
- key: '_started',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return false;
- },
- /**
- * Defines if the current progress event is the first one triggered for the current request.
- * @private
- * @member {boolean} BandwidthModule#_firstProgress
- */
- enumerable: true
- }, {
- key: '_firstProgress',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return true;
- },
- /**
- * @private
- * @member {Defer} BandwidthModule#_deferredProgress
- */
- enumerable: true
- }, {
- key: '_deferredProgress',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return undefined;
- },
- /**
- * Unique labels for each request, exclusively used to make measures.
- * @private
- * @member {Object} BandwidthModule#_timingLabels
- * @property {?string} start
- * @property {?string} progress
- * @property {?string} end
- * @property {?string} measure
- */
- enumerable: true
- }, {
- key: '_timingLabels',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return {
- start: null,
- progress: null,
- end: null,
- measure: null
- };
- },
- enumerable: true
- }], null, _instanceInitializers);
- function BandwidthModule(loadingType) {
- var _this = this;
- var settings = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
- _classCallCheck(this, BandwidthModule);
- loadingType = ~['upload', 'download'].indexOf(loadingType) ? loadingType : 'download';
- _get(Object.getPrototypeOf(BandwidthModule.prototype), 'constructor', this).call(this, loadingType);
- _defineDecoratedPropertyDescriptor(this, '_loadingType', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_intendedEnd', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_isRestarting', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_lastLoadedValue', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_speedRecords', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_avgSpeed', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_requestID', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_progressID', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_started', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_firstProgress', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_deferredProgress', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_timingLabels', _instanceInitializers);
- this._extendDefaultSettings({
- data: {
- // 2 MB for upload, 10 MB for download
- size: loadingType == 'upload' ? 2 * 1024 * 1024 : 10 * 1024 * 1024,
- multiplier: 2
- }
- }).settings(settings);
- this._loadingType = loadingType; // Bind to XHR events
- this.on('xhr-upload-loadstart', function () {
- return _Timing2['default'].mark(_this._timingLabels.start);
- });
- this.on('xhr-readystatechange', function (xhr) {
- if (!_this._started && xhr.readyState == XMLHttpRequest.LOADING) {
- _Timing2['default'].mark(_this._timingLabels.start);
- _this._started = true;
- }
- });
- var eventsPrefix = loadingType == 'upload' ? 'xhr-upload' : 'xhr';
- this.on(eventsPrefix + '-progress', function (xhr, event) {
- return _this._progress(event);
- });
- this.on(eventsPrefix + '-timeout', function () {
- return _this._timeout();
- });
- this.on(eventsPrefix + '-loadend', function () {
- return _this._end();
- });
- }
- /**
- * Start requesting the server to make measures.
- * @public
- * @method BandwidthModule#start
- * @returns {BandwidthModule}
- */
- _createDecoratedClass(BandwidthModule, [{
- key: 'start',
- value: function start() {
- var loadingType = this._loadingType,
- dataSettings = this.settings().data,
- reqID = this._requestID++;
- this._intendedEnd = false;
- this._lastLoadedValue = null;
- this._speedRecords = [];
- this._started = false;
- this._firstProgress = true;
- this._deferredProgress = (0, _utilsHelpers.defer)(); // Trigger the start event
- if (!this._isRestarting) {
- this.trigger('start', dataSettings.size);
- } // Create unique timing labels for the new request
- var labels = this._timingLabels;
- labels.start = loadingType + '-' + reqID + '-start';
- labels.progress = loadingType + '-' + reqID + '-progress';
- labels.end = loadingType + '-' + reqID + '-end';
- labels.measure = loadingType + '-' + reqID + '-measure'; // Generate some random data to upload to the server. Here we're using a Blob instead of an ArrayBuffer because
- // of a bug in Chrome (tested in v33.0.1750.146), causing a freeze of the page while trying to directly upload
- // an ArrayBuffer (through an ArrayBufferView). The freeze lasts nearly 4.5s for 10MB of data. Using a Blob
- // seems to solve the problem.
- var blob = loadingType == 'upload' ? new Blob([new ArrayBuffer(dataSettings.size)]) : null;
- var type = loadingType == 'download' ? 'GET' : 'POST'; // Initiate and send a new request
- this._newRequest(type, {
- size: dataSettings.size
- })._sendRequest(blob);
- return this;
- }
- /**
- * Abort the measures.
- * @public
- * @method BandwidthModule#abort
- * @returns {BandwidthModule}
- */
- }, {
- key: 'abort',
- value: function abort() {
- this._intendedEnd = true;
- return this._abort();
- }
- /**
- * Make bandwidth measures for the current request.
- * @private
- * @method BandwidthModule#_progress
- * @param {ProgressEvent} event The event associated with the progress event of the current request.
- * @returns {BandwidthModule}
- */
- }, {
- key: '_progress',
- value: function _progress(event) {
- var _this2 = this; // Ignore the first progress event, it generally contributes to get incoherent values.
- if (this._firstProgress) return this._firstProgress = false; // Execute the previous progress trigger
- this._deferredProgress.run();
- var labels = this._timingLabels,
- progressID = this._progressID++,
- markLabel = labels.progress + '-' + progressID,
- loaded = event.loaded;
- _Timing2['default'].mark(markLabel); // Measure the average speed (B/s) since the request started
- var avgMeasure = _Timing2['default'].measure(labels.measure + '-avg-' + progressID, labels.start, markLabel),
- avgSpeed = loaded / avgMeasure * 1000;
- var instantSpeed;
- if (this._lastLoadedValue === null) {
- // We are executing the first progress event of the current request
- instantSpeed = avgSpeed; // The instant speed of the first progress event is equal to the average one
- } else {
- // Measure the instant speed (B/s), which defines the speed between two progress events.
- var instantMeasure = _Timing2['default'].measure(labels.measure + '-instant-' + progressID, // Set the mark of the previous progress event as the starting point
- labels.progress + '-' + (progressID - 1), markLabel);
- instantSpeed = (loaded - this._lastLoadedValue) / instantMeasure * 1000;
- } // Save the `loaded` property of the event for the next progress event
- this._lastLoadedValue = loaded; // Defer measures saving and event triggering, this allows to cancel the last progress event, which can generate
- // incoherent values.
- this._deferredProgress = (0, _utilsHelpers.defer)(function () {
- _this2._avgSpeed = avgSpeed;
- _this2._speedRecords.push(instantSpeed);
- _this2.trigger('progress', avgSpeed, instantSpeed);
- });
- return this;
- }
- /**
- * Mark the current request as entirely finished (this means it ended after a time out).
- * @private
- * @method BandwidthModule#_timeout
- * @returns {BandwidthModule}
- */
- }, {
- key: '_timeout',
- value: function _timeout() {
- this._intendedEnd = true;
- return this;
- }
- /**
- * End the measures.
- * @private
- * @method BandwidthModule#_end
- * @returns {BandwidthModule}
- */
- }, {
- key: '_end',
- value: function _end() {
- // A timeout or an abort occured, bypass the further requests and trigger the "end" event.
- if (this._intendedEnd) {
- this._isRestarting = false;
- this.trigger('end', this._avgSpeed, this._speedRecords);
- } // The request ended to early, restart it with an increased data size.
- else {
- var dataSettings = this.settings().data,
- size = dataSettings.size * dataSettings.multiplier;
- this.settings({
- data: {
- size: size
- }
- });
- this.trigger('restart', size);
- this._isRestarting = true;
- this.start();
- }
- return this;
- }
- }], null, _instanceInitializers);
- return BandwidthModule;
- }(_HttpModule3['default']);
- exports['default'] = BandwidthModule;
- module.exports = exports['default'];
- /**
- *
- * @private
- * @member {string} BandwidthModule#_loadingType
- */
- }, {
- "../../utils/decorators": 7,
- "../../utils/helpers": 8,
- "../Timing": 6,
- "./HttpModule": 3
- }],
- 3: [function (require, module, exports) {
- 'use strict';
- Object.defineProperty(exports, '__esModule', {
- value: true
- });
- var _createDecoratedClass = function () {
- function defineProperties(target, descriptors, initializers) {
- for (var i = 0; i < descriptors.length; i++) {
- var descriptor = descriptors[i];
- var decorators = descriptor.decorators;
- var key = descriptor.key;
- delete descriptor.key;
- delete descriptor.decorators;
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ('value' in descriptor || descriptor.initializer) descriptor.writable = true;
- if (decorators) {
- for (var f = 0; f < decorators.length; f++) {
- var decorator = decorators[f];
- if (typeof decorator === 'function') {
- descriptor = decorator(target, key, descriptor) || descriptor;
- } else {
- throw new TypeError('The decorator for method ' + descriptor.key + ' is of the invalid type ' + typeof decorator);
- }
- }
- if (descriptor.initializer !== undefined) {
- initializers[key] = descriptor;
- continue;
- }
- }
- Object.defineProperty(target, key, descriptor);
- }
- }
- return function (Constructor, protoProps, staticProps, protoInitializers, staticInitializers) {
- if (protoProps) defineProperties(Constructor.prototype, protoProps, protoInitializers);
- if (staticProps) defineProperties(Constructor, staticProps, staticInitializers);
- return Constructor;
- };
- }();
- var _get = function get(_x4, _x5, _x6) {
- var _again = true;
- _function: while (_again) {
- var object = _x4,
- property = _x5,
- receiver = _x6;
- desc = parent = getter = undefined;
- _again = false;
- if (object === null) object = Function.prototype;
- var desc = Object.getOwnPropertyDescriptor(object, property);
- if (desc === undefined) {
- var parent = Object.getPrototypeOf(object);
- if (parent === null) {
- return undefined;
- } else {
- _x4 = parent;
- _x5 = property;
- _x6 = receiver;
- _again = true;
- continue _function;
- }
- } else if ('value' in desc) {
- return desc.value;
- } else {
- var getter = desc.get;
- if (getter === undefined) {
- return undefined;
- }
- return getter.call(receiver);
- }
- }
- };
- function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : {
- 'default': obj
- };
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError('Cannot call a class as a function');
- }
- }
- function _inherits(subClass, superClass) {
- if (typeof superClass !== 'function' && superClass !== null) {
- throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass);
- }
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
- if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
- }
- function _defineDecoratedPropertyDescriptor(target, key, descriptors) {
- var _descriptor = descriptors[key];
- if (!_descriptor) return;
- var descriptor = {};
- for (var _key in _descriptor) descriptor[_key] = _descriptor[_key];
- descriptor.value = descriptor.initializer.call(target);
- Object.defineProperty(target, key, descriptor);
- }
- var _EventDispatcher2 = require('../EventDispatcher');
- var _EventDispatcher3 = _interopRequireDefault(_EventDispatcher2);
- var _utilsHelpers = require('../../utils/helpers');
- var _utilsDecorators = require('../../utils/decorators');
- /**
- * @public
- * @typedef {Object} HttpModule~settingsObject
- * @property {string} [endpoint=./network.php] Where is located your `network.php` file.
- * @property {number} [delay=8000] The delay while you want to take measures.
- */
- /**
- * @class HttpModule
- * @extends EventDispatcher
- * @param {string} moduleName The name of the instanciated module.
- * @param {HttpModule~settingsObject} [settings={}] A set of custom settings.
- */
- var HttpModule = function (_EventDispatcher) {
- var _instanceInitializers = {};
- var _instanceInitializers = {};
- _inherits(HttpModule, _EventDispatcher);
- _createDecoratedClass(HttpModule, [{
- key: '_defaultSettings',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return null;
- },
- /**
- * The current settings.
- * @private
- * @member {?Object} HttpModule#_settings
- */
- enumerable: true
- }, {
- key: '_settings',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return null;
- },
- /**
- * The module name, will be send to the server.
- * @private
- * @member {string} HttpModule#_moduleName
- */
- enumerable: true
- }, {
- key: '_moduleName',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return undefined;
- },
- /**
- * The current XMLHttpRequest object.
- * @private
- * @member {?XMLHttpRequest} HttpModule#_xhr
- */
- enumerable: true
- }, {
- key: '_xhr',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return null;
- },
- /**
- * An URL token to avoid any caching issues. Also allows to identify the request in the Resource Timing entries.
- * @private
- * @member {?string} HttpModule#_lastURLToken
- */
- enumerable: true
- }, {
- key: '_lastURLToken',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return null;
- },
- /**
- * Defines if the module is currently running an HTTP request.
- * @private
- * @member {boolean} HttpModule#_requesting
- */
- enumerable: true
- }, {
- key: '_requesting',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return false;
- },
- /**
- * Defines if the requesting status has been overridden by the `_setRequesting` method.
- * @private
- * @member {boolean} HttpModule#_requestingOverridden
- */
- enumerable: true
- }, {
- key: '_requestingOverridden',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return false;
- },
- enumerable: true
- }], null, _instanceInitializers);
- function HttpModule(moduleName) {
- var _this = this;
- var settings = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
- _classCallCheck(this, HttpModule);
- _get(Object.getPrototypeOf(HttpModule.prototype), 'constructor', this).call(this);
- _defineDecoratedPropertyDescriptor(this, '_defaultSettings', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_settings', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_moduleName', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_xhr', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_lastURLToken', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_requesting', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_requestingOverridden', _instanceInitializers);
- this._extendDefaultSettings({
- endpoint: './network.php',
- delay: 8000
- });
- this.settings(settings);
- this._moduleName = moduleName; // Each time a request starts or ends, set the requesting value unless it has been overridden with the
- // _setRequesting() method.
- this.on(['xhr-loadstart', 'xhr-upload-loadstart'], function () {
- if (!_this._requestingOverridden) {
- _this._requesting = true;
- }
- });
- this.on(['xhr-loadend', 'xhr-upload-loadend'], function () {
- if (!_this._requestingOverridden) {
- _this._requesting = false;
- }
- });
- }
- /**
- * Apply a new set of custom settings.
- * @public
- * @method HttpModule#settings
- * @param {HttpModule~settingsObject} settings A set of custom settings.
- * @returns {HttpModule}
- */
- /**
- * Return the current set of settings.
- * @public
- * @method HttpModule#settings^2
- * @returns {HttpModule~settingsObject}
- */
- _createDecoratedClass(HttpModule, [{
- key: 'settings',
- value: function settings() {
- var _settings = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];
- if ((0, _utilsHelpers.isObject)(_settings)) {
- this._settings = (0, _utilsHelpers.assignStrict)(this._defaultSettings || {}, this._settings || {}, _settings);
- return this;
- } else {
- return (0, _utilsHelpers.copy)(this._settings || this._defaultSettings || {});
- }
- }
- /**
- * Return if the module is currently making a request.
- * @public
- * @method HttpModule#isRequesting
- * @returns {boolean} `true` if the module is requesting, otherwise `false`.
- */
- }, {
- key: 'isRequesting',
- value: function isRequesting() {
- return this._requesting;
- }
- /**
- * Extend the set of default settings.
- * @protected
- * @method HttpModule#_extendDefaultSettings
- * @param {Object} settings The new properties to add to the default settings.
- * @returns {HttpModule}
- */
- }, {
- key: '_extendDefaultSettings',
- value: function _extendDefaultSettings(settings) {
- this._defaultSettings = (0, _utilsHelpers.assign)(this._defaultSettings || {}, settings);
- return this;
- }
- /**
- * Create a new XHR request.
- * @protected
- * @method HttpModule#_newRequest
- * @param {string} httpMethod The HTTP method to use with the request, GET or POST.
- * @param {Object} queryParams The query parameters to use with the request.
- * @returns {HttpModule}
- */
- }, {
- key: '_newRequest',
- value: function _newRequest(httpMethod, queryParams) {
- var _this2 = this; // Check if a callback binded to the "_newRequest" event returns false, if it's the case, cancel the request
- // creation. If the requesting status has been overridden, there's no need to cancel the request since the user
- // should know what he's doing.
- if (!this.trigger('_newRequest') && !this._requestingOverridden) {
- console.warn('To ensure accurate measures, you can only make one request at a time.');
- return this;
- }
- var settings = this.settings(),
- xhr = new XMLHttpRequest(),
- validHttpMethods = ['GET', 'POST']; // Prepare the new request.
- if (!~validHttpMethods.indexOf(httpMethod)) {
- console.warn('The HTTP method must be GET or POST.');
- return this;
- }
- queryParams = queryParams || {};
- var tokenSuffix = new Date().getTime();
- this._lastURLToken = 'network-' + tokenSuffix; // Append the query parameters
- var url = settings.endpoint;
- url += ~url.indexOf('?') ? '&' : '?';
- url += 'module=' + this._moduleName;
- Object.keys(queryParams).forEach(function (param) {
- var value = encodeURIComponent(queryParams[param]);
- url += '&' + param + '=' + value;
- });
- url += '&' + this._lastURLToken;
- xhr.open(httpMethod, url); // Abort the previous request if it hasn't been sent
- if (this._xhr && this._xhr.readyState == XMLHttpRequest.OPENED) {
- this._xhr.abort();
- } // Replace the old request by the new one
- this._xhr = xhr; // Bind all the XHR events
- var events = ['loadstart', 'progress', 'abort', 'error', 'load', 'timeout', 'loadend', 'readystatechange'];
- events.forEach(function (eventType) {
- xhr.addEventListener(eventType, function () {
- for (var _len = arguments.length, args = Array(_len), _key2 = 0; _key2 < _len; _key2++) {
- args[_key2] = arguments[_key2];
- } // A last progress event can be triggered once a request has timed out, ignore it.
- if (eventType == 'progress' && !_this2._requesting) return;
- _this2.trigger.apply(_this2, ['xhr-' + eventType, xhr].concat(args));
- }); // The XMLHttpRequestUpload interface supports all the above event types except the "readystatechange" one
- if (eventType != 'readystatechange') {
- xhr.upload.addEventListener(eventType, function () {
- for (var _len2 = arguments.length, args = Array(_len2), _key3 = 0; _key3 < _len2; _key3++) {
- args[_key3] = arguments[_key3];
- }
- _this2.trigger.apply(_this2, ['xhr-upload-' + eventType, xhr].concat(args));
- });
- }
- }); // Define the timeout of the request. We don't use the native `timeout` property since it can distort the
- // measures.
- // See: https://github.com/nesk/network.js/issues/26
- var startTimeout = function startTimeout(xhr) {
- setTimeout(function () {
- if (xhr.readyState != XMLHttpRequest.UNSENT && xhr.readyState != XMLHttpRequest.DONE) {
- _this2.trigger('xhr-timeout');
- _this2.trigger('xhr-upload-timeout');
- xhr.abort();
- }
- }, settings.delay);
- };
- this.on('xhr-upload-loadstart', startTimeout).on('xhr-readystatechange', function (timeoutStarted) {
- return function (xhr) {
- if (!timeoutStarted && xhr.readyState == XMLHttpRequest.LOADING) {
- timeoutStarted = true;
- startTimeout(xhr);
- }
- };
- }(false));
- return this;
- }
- /**
- * Send a newly created XHR request.
- * @protected
- * @method HttpModule#_sendRequest
- * @param {?*} [data=null] The data to send with the request.
- * @returns {HttpModule}
- */
- }, {
- key: '_sendRequest',
- value: function _sendRequest() {
- var data = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];
- if (this._xhr && this._xhr.readyState == XMLHttpRequest.OPENED) {
- this._xhr.send(data);
- } else {
- console.warn('A request must have been created before sending any data.');
- }
- return this;
- }
- /**
- * Abort the current request.
- * @protected
- * @method HttpModule#_abort
- * @returns {HttpModule}
- */
- }, {
- key: '_abort',
- value: function _abort() {
- if (this._xhr) {
- this._xhr.abort();
- }
- return this;
- }
- /**
- * Get the Resource Timing entry associated to the current request.
- * @protected
- * @method HttpModule#_getTimingEntry
- * @param {HttpModule~timingCallback} callback A callback used to send back the timing entry.
- * @returns {HttpModule}
- */
- }, {
- key: '_getTimingEntry',
- value: function _getTimingEntry(callback) {
- // The Resource Timing entries aren't immediately available once the 'load' event is triggered by an
- // XMLHttpRequest, we must wait for another process tick to check for a refreshed list.
- setTimeout(function (lastURLToken) {
- return function () {
- // Filter the timing entries to return only the one concerned by the last request made
- var entries = performance.getEntriesByType('resource').filter(function (entry) {
- return ~entry.name.indexOf(lastURLToken);
- });
- /**
- * A callback used to send back the timing entry.
- * @private
- * @callback HttpModule~timingCallback
- * @param {PerformanceResourceTiming} entry The Resource Timing entry associated to the current request.
- */
- callback(entries.length ? entries[0] : null);
- };
- }(this._lastURLToken), 0);
- return this;
- }
- /**
- * Override the requesting status of the module.
- * @protected
- * @method HttpModule#_setRequesting
- * @param {boolean} isRequesting The requesting status.
- * @returns {HttpModule}
- */
- }, {
- key: '_setRequesting',
- value: function _setRequesting(isRequesting) {
- this._requestingOverridden = true;
- this._requesting = isRequesting;
- return this;
- }
- }], null, _instanceInitializers);
- return HttpModule;
- }(_EventDispatcher3['default']);
- exports['default'] = HttpModule;
- module.exports = exports['default'];
- /**
- * The default settings.
- * @private
- * @member {?Object} HttpModule#_defaultSettings
- */
- }, {
- "../../utils/decorators": 7,
- "../../utils/helpers": 8,
- "../EventDispatcher": 1
- }],
- 4: [function (require, module, exports) {
- 'use strict';
- Object.defineProperty(exports, '__esModule', {
- value: true
- });
- var _createDecoratedClass = function () {
- function defineProperties(target, descriptors, initializers) {
- for (var i = 0; i < descriptors.length; i++) {
- var descriptor = descriptors[i];
- var decorators = descriptor.decorators;
- var key = descriptor.key;
- delete descriptor.key;
- delete descriptor.decorators;
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ('value' in descriptor || descriptor.initializer) descriptor.writable = true;
- if (decorators) {
- for (var f = 0; f < decorators.length; f++) {
- var decorator = decorators[f];
- if (typeof decorator === 'function') {
- descriptor = decorator(target, key, descriptor) || descriptor;
- } else {
- throw new TypeError('The decorator for method ' + descriptor.key + ' is of the invalid type ' + typeof decorator);
- }
- }
- if (descriptor.initializer !== undefined) {
- initializers[key] = descriptor;
- continue;
- }
- }
- Object.defineProperty(target, key, descriptor);
- }
- }
- return function (Constructor, protoProps, staticProps, protoInitializers, staticInitializers) {
- if (protoProps) defineProperties(Constructor.prototype, protoProps, protoInitializers);
- if (staticProps) defineProperties(Constructor, staticProps, staticInitializers);
- return Constructor;
- };
- }();
- var _get = function get(_x5, _x6, _x7) {
- var _again = true;
- _function: while (_again) {
- var object = _x5,
- property = _x6,
- receiver = _x7;
- desc = parent = getter = undefined;
- _again = false;
- if (object === null) object = Function.prototype;
- var desc = Object.getOwnPropertyDescriptor(object, property);
- if (desc === undefined) {
- var parent = Object.getPrototypeOf(object);
- if (parent === null) {
- return undefined;
- } else {
- _x5 = parent;
- _x6 = property;
- _x7 = receiver;
- _again = true;
- continue _function;
- }
- } else if ('value' in desc) {
- return desc.value;
- } else {
- var getter = desc.get;
- if (getter === undefined) {
- return undefined;
- }
- return getter.call(receiver);
- }
- }
- };
- function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : {
- 'default': obj
- };
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError('Cannot call a class as a function');
- }
- }
- function _inherits(subClass, superClass) {
- if (typeof superClass !== 'function' && superClass !== null) {
- throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass);
- }
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
- if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
- }
- function _defineDecoratedPropertyDescriptor(target, key, descriptors) {
- var _descriptor = descriptors[key];
- if (!_descriptor) return;
- var descriptor = {};
- for (var _key in _descriptor) descriptor[_key] = _descriptor[_key];
- descriptor.value = descriptor.initializer.call(target);
- Object.defineProperty(target, key, descriptor);
- }
- var _HttpModule2 = require('./HttpModule');
- var _HttpModule3 = _interopRequireDefault(_HttpModule2);
- var _Timing = require('../Timing');
- var _Timing2 = _interopRequireDefault(_Timing);
- var _utilsHelpers = require('../../utils/helpers');
- var _utilsDecorators = require('../../utils/decorators');
- /**
- * @public
- * @typedef {Object} LatencyModule~settingsObject
- * @property {string} [endpoint=./network.php] Where is located your `network.php` file.
- * @property {number} [measures=5] How many measures should be returned.
- * @property {number} [attempts=3] How much attempts to get a valid value should be done for each measure.
- */
- /**
- * @class LatencyModule
- * @extends HttpModule
- * @param {LatencyModule~settingsObject} [settings={}] A set of custom settings.
- */
- var LatencyModule = function (_HttpModule) {
- var _instanceInitializers = {};
- var _instanceInitializers = {};
- _inherits(LatencyModule, _HttpModule);
- _createDecoratedClass(LatencyModule, [{
- key: '_supportsResourceTiming',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return undefined;
- },
- /**
- * The total number of requests left.
- * @private
- * @member {number} LatencyModule#_requestsLeft
- */
- enumerable: true
- }, {
- key: '_requestsLeft',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return undefined;
- },
- /**
- * The total number of attempts left.
- * @private
- * @member {number} LatencyModule#_attemptsLeft
- */
- enumerable: true
- }, {
- key: '_attemptsLeft',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return undefined;
- },
- /**
- * The measured latencies.
- * @private
- * @member {number[]} LatencyModule#_latencies
- */
- enumerable: true
- }, {
- key: '_latencies',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return undefined;
- },
- /**
- * The ID of the current request.
- * @private
- * @member {number} LatencyModule#_requestID
- */
- enumerable: true
- }, {
- key: '_requestID',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return 0;
- },
- /**
- * Unique labels for each request, exclusively used to make measures.
- * @private
- * @member {Object} LatencyModule#_requestID
- * @property {?string} start
- * @property {?string} end
- * @property {?string} measure
- */
- enumerable: true
- }, {
- key: '_timingLabels',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return {
- start: null,
- end: null,
- measure: null
- };
- },
- enumerable: true
- }], null, _instanceInitializers);
- function LatencyModule() {
- var settings = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
- _classCallCheck(this, LatencyModule);
- _get(Object.getPrototypeOf(LatencyModule.prototype), 'constructor', this).call(this, 'latency');
- _defineDecoratedPropertyDescriptor(this, '_supportsResourceTiming', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_requestsLeft', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_attemptsLeft', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_latencies', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_requestID', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_timingLabels', _instanceInitializers);
- this._extendDefaultSettings({
- measures: 5,
- attempts: 3
- }).settings(settings);
- this._defineResourceTimingSupport();
- }
- /**
- * Apply a new set of custom settings.
- * @public
- * @method LatencyModule#settings
- * @param {LatencyModule~settingsObject} settings A set of custom settings.
- * @returns {LatencyModule}
- */
- /**
- * Return the current set of settings.
- * @public
- * @method LatencyModule#settings^2
- * @returns {LatencyModule~settingsObject}
- */
- _createDecoratedClass(LatencyModule, [{
- key: 'settings',
- value: function settings() {
- var _settings = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];
- if ((0, _utilsHelpers.isObject)(_settings)) {
- return _get(Object.getPrototypeOf(LatencyModule.prototype), 'settings', this).call(this, (0, _utilsHelpers.assignStrict)(_settings, {
- delay: 0 // We dont want any timeout during a latency calculation
- }));
- } else {
- return (0, _utilsHelpers.except)(_get(Object.getPrototypeOf(LatencyModule.prototype), 'settings', this).call(this), ['delay']);
- }
- }
- /**
- * Start requesting the server to make measures.
- * @public
- * @method LatencyModule#start
- * @returns {LatencyModule}
- */
- }, {
- key: 'start',
- value: function start() {
- var _settings2 = this.settings(); // Set the number of requests required to establish the network latency.
- var measures = _settings2.measures;
- var attempts = _settings2.attempts;
- this._requestsLeft = measures;
- this._attemptsLeft = attempts * measures; // If the browser doesn't support the Resource Timing API, add a request that will be ignored to avoid a longer
- // request due to a possible DNS/whatever fetch.
- if (!this._supportsResourceTiming) {
- this._requestsLeft++;
- this._attemptsLeft++;
- } // Override the requesting value since a complete latency request consists off multiple ones
- this._setRequesting(true);
- this._latencies = [];
- this._nextRequest();
- return this;
- }
- /**
- * Define if the module should support the Resource Timing API.
- * @private
- * @method LatencyModule#_defineResourceTimingSupport
- * @param {boolean} supportsResourceTiming If `undefined`, the support will be determined by feature detection.
- * @returns {LatencyModule}
- */
- }, {
- key: '_defineResourceTimingSupport',
- value: function _defineResourceTimingSupport(supportsResourceTiming) {
- var _this = this;
- if (typeof supportsResourceTiming !== 'boolean') supportsResourceTiming = _Timing2['default'].supportsResourceTiming;
- this._supportsResourceTiming = supportsResourceTiming; // Unregisters all the previously registered events, since this method can be called multiple times.
- this.off(['xhr-load', 'xhr-loadstart', 'xhr-readystatechange']); // Measure the latency with the Resource Timing API once the request is finished
- if (supportsResourceTiming) {
- this.on('xhr-load', function () {
- return _this._measure();
- });
- } // If the browser doesn't support the Resource Timing API, we fallback on a Datetime solution.
- else {
- // Set a mark when the request starts
- this.on('xhr-loadstart', function () {
- return _Timing2['default'].mark(_this._timingLabels.start);
- }); // Then make a measure with the previous mark
- this.on('xhr-readystatechange', function (xhr) {
- return _this._measure(xhr);
- });
- }
- }
- /**
- * Initiate the next request used for latency measures.
- * @private
- * @method LatencyModule#_nextRequest
- * @param {boolean} [retry=false] Defines if the next request is a retry due to a failing request or not.
- * @returns {LatencyModule}
- */
- }, {
- key: '_nextRequest',
- value: function _nextRequest() {
- var _this2 = this;
- var retry = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0];
- var reqID = this._requestID++;
- var requestsLeft = retry ? this._requestsLeft : this._requestsLeft--;
- if (this._attemptsLeft-- && (requestsLeft || retry)) {
- // Create unique timing labels for the new request
- var labels = this._timingLabels;
- labels.start = 'latency-' + reqID + '-start';
- labels.end = 'latency-' + reqID + '-end';
- labels.measure = 'latency-' + reqID + '-measure'; // Create the new request and send it
- this._newRequest('GET')._sendRequest();
- } else {
- // All the requests are finished, set the requesting status to false.
- this._setRequesting(false); // If all the requests have been executed, calculate the average latency. Since the _getTimingEntry() method
- // is asynchronous, wait for the next process tick to execute the _end() method, to be sure that all the
- // latencies have been retrieved.
- setTimeout(function () {
- return _this2._end();
- }, 0);
- }
- return this;
- }
- /**
- * Make latency measures for the last request.
- * @private
- * @method LatencyModule#_measure
- * @param {?XMLHttpRequest} [xhr=null] The concerned XMLHttpRequest if the browser doesn't support the Resource Timing API.
- * @returns {LatencyModule}
- */
- }, {
- key: '_measure',
- value: function _measure() {
- var _this3 = this;
- var xhr = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0]; // With Resource Timing API
- if (!xhr) {
- this._getTimingEntry(function (entry) {
- // The latency calculation differs between an HTTP and an HTTPS connection
- // See: http://www.w3.org/TR/resource-timing/#processing-model
- var latency = !entry.secureConnectionStart ? entry.connectEnd - entry.connectStart : entry.secureConnectionStart - entry.connectStart;
- if (latency) _this3._latencies.push(latency);
- _this3._nextRequest(!latency);
- });
- } // Without Resource Timing API
- else if (this._requestsLeft < this.settings().measures) {
- // Measure and save the latency if the headers have been received
- if (xhr.readyState == XMLHttpRequest.HEADERS_RECEIVED) {
- var labels = this._timingLabels;
- _Timing2['default'].mark(labels.end);
- var latency = _Timing2['default'].measure(labels.measure, labels.start, labels.end);
- if (latency) this._latencies.push(latency); // Abort the current request before we run a new one
- this._abort();
- this._nextRequest(!latency);
- }
- } // Ignore the first request when using the XHR states. See the comments in the start() method for explanations.
- else {
- this._nextRequest();
- }
- return this;
- }
- /**
- * End the measures.
- * @private
- * @method LatencyModule#_end
- * @returns {LatencyModule}
- */
- }, {
- key: '_end',
- value: function _end() {
- var latencies = this._latencies; // Get the average latency
- var avgLatency = latencies.reduce(function (a, b) {
- return a + b;
- }, 0) / (latencies.length || 1);
- avgLatency = avgLatency || null; // If there is no measures, restart with the polyfill.
- if (!latencies.length) {
- this._defineResourceTimingSupport(false);
- this.start();
- return this;
- } // If there is not enough measures, display a warning.
- if (latencies.length < this.settings().measures) {
- var _settings3 = this.settings();
- var measures = _settings3.measures;
- var attempts = _settings3.attempts;
- console.warn('\n An insufficient number of measures have been processed, this could be due to your web server using\n persistant connections or to your client settings (measures: ' + measures + ', attempts: ' + attempts + ').\n ');
- } // Trigger the "end" event with the average latency and the latency list as parameters
- this.trigger('end', avgLatency, latencies);
- return this;
- }
- }], null, _instanceInitializers);
- return LatencyModule;
- }(_HttpModule3['default']);
- exports['default'] = LatencyModule;
- module.exports = exports['default'];
- /**
- * Defines if the module supports the Resource Timing API.
- * @private
- * @member {number} LatencyModule#_requestsLeft
- */
- }, {
- "../../utils/decorators": 7,
- "../../utils/helpers": 8,
- "../Timing": 6,
- "./HttpModule": 3
- }],
- 5: [function (require, module, exports) {
- 'use strict';
- Object.defineProperty(exports, '__esModule', {
- value: true
- });
- var _createDecoratedClass = function () {
- function defineProperties(target, descriptors, initializers) {
- for (var i = 0; i < descriptors.length; i++) {
- var descriptor = descriptors[i];
- var decorators = descriptor.decorators;
- var key = descriptor.key;
- delete descriptor.key;
- delete descriptor.decorators;
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ('value' in descriptor || descriptor.initializer) descriptor.writable = true;
- if (decorators) {
- for (var f = 0; f < decorators.length; f++) {
- var decorator = decorators[f];
- if (typeof decorator === 'function') {
- descriptor = decorator(target, key, descriptor) || descriptor;
- } else {
- throw new TypeError('The decorator for method ' + descriptor.key + ' is of the invalid type ' + typeof decorator);
- }
- }
- if (descriptor.initializer !== undefined) {
- initializers[key] = descriptor;
- continue;
- }
- }
- Object.defineProperty(target, key, descriptor);
- }
- }
- return function (Constructor, protoProps, staticProps, protoInitializers, staticInitializers) {
- if (protoProps) defineProperties(Constructor.prototype, protoProps, protoInitializers);
- if (staticProps) defineProperties(Constructor, staticProps, staticInitializers);
- return Constructor;
- };
- }();
- function _interopRequireDefault(obj) {
- return obj && obj.__esModule ? obj : {
- 'default': obj
- };
- }
- function _defineProperty(obj, key, value) {
- if (key in obj) {
- Object.defineProperty(obj, key, {
- value: value,
- enumerable: true,
- configurable: true,
- writable: true
- });
- } else {
- obj[key] = value;
- }
- return obj;
- }
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError('Cannot call a class as a function');
- }
- }
- function _defineDecoratedPropertyDescriptor(target, key, descriptors) {
- var _descriptor = descriptors[key];
- if (!_descriptor) return;
- var descriptor = {};
- for (var _key in _descriptor) descriptor[_key] = _descriptor[_key];
- descriptor.value = descriptor.initializer.call(target);
- Object.defineProperty(target, key, descriptor);
- }
- var _EventDispatcher = require('./EventDispatcher');
- var _EventDispatcher2 = _interopRequireDefault(_EventDispatcher);
- var _HttpHttpModule = require('./Http/HttpModule');
- var _HttpHttpModule2 = _interopRequireDefault(_HttpHttpModule);
- var _HttpLatencyModule = require('./Http/LatencyModule');
- var _HttpLatencyModule2 = _interopRequireDefault(_HttpLatencyModule);
- var _HttpBandwidthModule = require('./Http/BandwidthModule');
- var _HttpBandwidthModule2 = _interopRequireDefault(_HttpBandwidthModule);
- var _Timing = require('./Timing');
- var _Timing2 = _interopRequireDefault(_Timing);
- var _utilsHelpers = require('../utils/helpers');
- var _utilsDecorators = require('../utils/decorators');
- /**
- * @public
- * @typedef {Object} Network~settingsObject
- * @property {LatencyModule~settingsObject} latency
- * @property {BandwidthModule~settingsObject} upload
- * @property {BandwidthModule~settingsObject} download
- * @example
- * {
- * // Top-level properties are applied to all the modules
- * endpoint: './my-new-endpoint/',
- *
- * // Top-level properties will be overridden by the ones specified in each module
- * latency: {
- * endpoint: './my-new-latency-endpoint/'
- * }
- * }
- */
- /**
- * @class Network
- * @param {Network~settingsObject} [settings={}] A set of custom settings.
- * @member {LatencyModule} latency The latency module.
- * @member {BandwidthModule} upload The upload module.
- * @member {BandwidthModule} download The download module.
- */
- var Network = function () {
- var _instanceInitializers = {};
- var _instanceInitializers = {};
- _createDecoratedClass(Network, [{
- key: '_modules',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return {};
- },
- /**
- * Defines if the registered modules have been initialized.
- * @private
- * @member {boolean} Network#_modulesInitialized
- */
- enumerable: true
- }, {
- key: '_modulesInitialized',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return false;
- },
- /**
- * The settings defined via the constructor, they will be applied once the modules are initialized.
- * @private
- * @member {Network~settingsObject} Network#_pendingSettings
- */
- enumerable: true
- }, {
- key: '_pendingSettings',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return {};
- },
- /**
- * Expose all the internal classes to the global scope. Only for testing purposes!
- * @private
- * @method Network._exposeInternalClasses
- * @returns {Network}
- */
- enumerable: true
- }], [{
- key: '_exposeInternalClasses',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- value: function _exposeInternalClasses() {
- var global = (0, _utilsHelpers.getGlobalObject)(),
- classes = {
- EventDispatcher: _EventDispatcher2['default'],
- HttpModule: _HttpHttpModule2['default'],
- LatencyModule: _HttpLatencyModule2['default'],
- BandwidthModule: _HttpBandwidthModule2['default'],
- Timing: _Timing2['default']
- };
- Object.keys(classes).forEach(function (name) {
- global[name] = classes[name];
- });
- return this;
- }
- }, {
- key: 'supportsResourceTiming',
- /**
- * Defines if the current browser supports the Resource Timing API.
- * @public
- * @readonly
- * @member {boolean} Network#supportsResourceTiming
- */
- get: function get() {
- return _Timing2['default'].supportsResourceTiming;
- }
- /**
- * The registered modules.
- * @private
- * @member {Object} Network#_modules
- */
- }], _instanceInitializers);
- function Network() {
- var settings = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
- _classCallCheck(this, Network);
- _defineDecoratedPropertyDescriptor(this, '_modules', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_modulesInitialized', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_pendingSettings', _instanceInitializers);
- this._registerModule('latency', function (settings) {
- return new _HttpLatencyModule2['default'](settings);
- })._registerModule('upload', function (settings) {
- return new _HttpBandwidthModule2['default']('upload', settings);
- })._registerModule('download', function (settings) {
- return new _HttpBandwidthModule2['default']('download', settings);
- });
- this._initModules(this.settings(settings));
- }
- /**
- * Apply a new set of custom settings.
- * @public
- * @method Network#settings
- * @param {Network~settingsObject} settings A set of custom settings.
- * @returns {Network}
- */
- /**
- * Return the current set of settings.
- * @public
- * @method Network#settings^2
- * @returns {Network~settingsObject}
- */
- _createDecoratedClass(Network, [{
- key: 'settings',
- value: function settings() {
- var _this = this;
- var _settings = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];
- var moduleNames = Object.keys(this._modules);
- if ((0, _utilsHelpers.isObject)(_settings)) {
- var _ret = function () {
- // Extract the global settings
- var globalSettings = (0, _utilsHelpers.except)(_settings, moduleNames); // Extract the local settings
- var localSettings = (0, _utilsHelpers.except)(_settings, Object.keys(globalSettings)); // Create new settings with the global ones nested in the local ones
- _settings = moduleNames.reduce(function (settings, moduleName) {
- return (0, _utilsHelpers.assign)(settings, _defineProperty({}, moduleName, globalSettings));
- }, {}); // Apply the local settings to the new settings
- _settings = (0, _utilsHelpers.assign)(_settings, localSettings); // Apply the settings to the modules
- if (_this._modulesInitialized) {
- Object.keys(_this._modules).forEach(function (name) {
- _this._modules[name].settings(_settings[name]);
- });
- } // If the modules aren't instanciated, store the settings.
- else {
- _this._pendingSettings = _settings;
- }
- return {
- v: _this
- };
- }();
- if (typeof _ret === 'object') return _ret.v;
- } else {
- return moduleNames.reduce(function (settings, moduleName) {
- return (0, _utilsHelpers.assign)(settings, _defineProperty({}, moduleName, _this._modules[moduleName].settings()));
- }, {});
- }
- }
- /**
- * Return if a module is currently making a request.
- * @public
- * @method Network#isRequesting
- * @returns {boolean} `true` if a module is requesting, otherwise `false`.
- */
- }, {
- key: 'isRequesting',
- value: function isRequesting() {
- var requesting = false;
- for (var _name in this._modules) {
- if (this._modules.hasOwnProperty(_name)) {
- requesting = requesting || this._modules[_name].isRequesting();
- }
- }
- return requesting;
- }
- /**
- * Register a new module for the current `Network` instance.
- * @private
- * @method Network#registerModule
- * @param {string} name The name of the module. Will be used to create the property `Network.<name>`.
- * @param {Network~moduleCallback} moduleCallback A callback used to initialize a module with a set of settings.
- * @returns {Network}
- */
- }, {
- key: '_registerModule',
- value: function _registerModule(name, moduleCallback) {
- /**
- * A callback used to initialize a module with a set of settings.
- * @private
- * @callback Network~moduleCallback
- * @param {Object} settings A set of custom settings.
- * @returns {HttpModule} An instanciated subclass of `HttpModule`.
- */
- this._modules[name] = moduleCallback;
- return this;
- }
- /**
- * Initialize all the registered modules with the settings passed to the constructor.
- * @private
- * @method Network#_initModules
- * @returns {Network}
- */
- }, {
- key: '_initModules',
- value: function _initModules() {
- var _this2 = this;
- if (!this._modulesInitialized) {
- // Initialize the modules with their respective settings
- Object.keys(this._modules).forEach(function (name) {
- _this2._modules[name] = _this2._modules[name](_this2._pendingSettings[name]).on('_newRequest', function () {
- return !_this2.isRequesting();
- });
- _this2[name] = _this2._modules[name];
- });
- this._modulesInitialized = true;
- }
- return this;
- }
- }], null, _instanceInitializers);
- return Network;
- }();
- exports['default'] = Network;
- module.exports = exports['default'];
- }, {
- "../utils/decorators": 7,
- "../utils/helpers": 8,
- "./EventDispatcher": 1,
- "./Http/BandwidthModule": 2,
- "./Http/HttpModule": 3,
- "./Http/LatencyModule": 4,
- "./Timing": 6
- }],
- 6: [function (require, module, exports) {
- 'use strict';
- Object.defineProperty(exports, '__esModule', {
- value: true
- });
- var _createDecoratedClass = function () {
- function defineProperties(target, descriptors, initializers) {
- for (var i = 0; i < descriptors.length; i++) {
- var descriptor = descriptors[i];
- var decorators = descriptor.decorators;
- var key = descriptor.key;
- delete descriptor.key;
- delete descriptor.decorators;
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ('value' in descriptor || descriptor.initializer) descriptor.writable = true;
- if (decorators) {
- for (var f = 0; f < decorators.length; f++) {
- var decorator = decorators[f];
- if (typeof decorator === 'function') {
- descriptor = decorator(target, key, descriptor) || descriptor;
- } else {
- throw new TypeError('The decorator for method ' + descriptor.key + ' is of the invalid type ' + typeof decorator);
- }
- }
- if (descriptor.initializer !== undefined) {
- initializers[key] = descriptor;
- continue;
- }
- }
- Object.defineProperty(target, key, descriptor);
- }
- }
- return function (Constructor, protoProps, staticProps, protoInitializers, staticInitializers) {
- if (protoProps) defineProperties(Constructor.prototype, protoProps, protoInitializers);
- if (staticProps) defineProperties(Constructor, staticProps, staticInitializers);
- return Constructor;
- };
- }();
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError('Cannot call a class as a function');
- }
- }
- function _defineDecoratedPropertyDescriptor(target, key, descriptors) {
- var _descriptor = descriptors[key];
- if (!_descriptor) return;
- var descriptor = {};
- for (var _key in _descriptor) descriptor[_key] = _descriptor[_key];
- descriptor.value = descriptor.initializer.call(target);
- Object.defineProperty(target, key, descriptor);
- }
- var _utilsHelpers = require('../utils/helpers');
- var _utilsDecorators = require('../utils/decorators');
- /**
- * @private
- * @class Timing
- */
- var Timing = function () {
- var _instanceInitializers = {};
- var _instanceInitializers = {};
- _createDecoratedClass(Timing, [{
- key: 'supportsResourceTiming',
- /**
- * Defines if the current browser supports the Resource Timing API.
- * @public
- * @readonly
- * @member {boolean} Timing#supportsResourceTiming
- */
- get: function get() {
- return Boolean(this._support.resourceTiming);
- }
- /**
- * Defines if the current browser supports some specific Timing APIs.
- * @private
- * @member {Object} Timing#_support
- * @property {boolean} performance `true` if the Performance API is available.
- * @property {boolean} userTiming `true` if the User Timing API is available.
- * @property {boolean} resourceTiming `true` if the Resource Timing API is available.
- */
- }, {
- key: '_support',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return {};
- },
- /**
- * All the marks created by the `mark` method.
- * @private
- * @member {Object} Timing#_marks
- */
- enumerable: true
- }, {
- key: '_marks',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return {};
- },
- /**
- * All the measures created by the `measure` method.
- * @private
- * @member {Object} Timing#_measures
- */
- enumerable: true
- }, {
- key: '_measures',
- decorators: [(0, _utilsDecorators.enumerable)(false)],
- initializer: function initializer() {
- return {};
- },
- enumerable: true
- }], null, _instanceInitializers);
- function Timing() {
- _classCallCheck(this, Timing);
- _defineDecoratedPropertyDescriptor(this, '_support', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_marks', _instanceInitializers);
- _defineDecoratedPropertyDescriptor(this, '_measures', _instanceInitializers);
- var global = (0, _utilsHelpers.getGlobalObject)();
- this._support = {
- performance: !!global.performance,
- userTiming: global.performance && performance.mark,
- resourceTiming: global.performance && typeof performance.getEntriesByType == "function" && performance.timing
- };
- }
- /**
- * Create a new timing mark.
- * @public
- * @method Timing#mark
- * @param {string} label A label associated to the mark.
- * @returns {Timing}
- */
- _createDecoratedClass(Timing, [{
- key: 'mark',
- value: function mark(label) {
- var support = this._support,
- marks = this._marks;
- if (support.userTiming) {
- performance.mark(label);
- }
- if (support.performance) {
- marks[label] = performance.now();
- } else {
- marks[label] = new Date().getTime();
- }
- return this;
- }
- /**
- * Measure the delay between two marks.
- * @public
- * @method Timing#measure
- * @param {string} measureLabel A label associated to the measure.
- * @param {string} markLabelA The label of the first mark.
- * @param {string} markLabelB The label of the second mark.
- * @returns {number} The measured value.
- */
- }, {
- key: 'measure',
- value: function measure(measureLabel, markLabelA, markLabelB) {
- var support = this._support,
- marks = this._marks,
- measures = this._measures;
- if (typeof measures[measureLabel] == 'undefined') {
- var measureWithoutUserTiming = marks[markLabelB] - marks[markLabelA];
- if (support.userTiming) {
- performance.measure(measureLabel, markLabelA, markLabelB);
- var entriesByName = performance.getEntriesByName(measureLabel); // The performance API could return no corresponding entries in Firefox so we must use a fallback.
- // See: https://github.com/nesk/network.js/issues/32#issuecomment-118434305
- measures[measureLabel] = entriesByName.length ? entriesByName[0].duration : measureWithoutUserTiming;
- } else {
- measures[measureLabel] = measureWithoutUserTiming;
- }
- }
- return measures[measureLabel];
- }
- }], null, _instanceInitializers);
- return Timing;
- }();
- exports['default'] = new Timing();
- module.exports = exports['default'];
- }, {
- "../utils/decorators": 7,
- "../utils/helpers": 8
- }],
- 7: [function (require, module, exports) {
- /**
- * @callback propertyDecorator
- * @param target
- * @param key
- * @param descriptor
- */
- /**
- * Set the enumerability of a property.
- * @private
- * @function enumerable
- * @param {boolean} isEnumerable Whether the property should be enumerable or not.
- * @returns {propertyDecorator}
- */
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.enumerable = enumerable;
- function enumerable(isEnumerable) {
- return function (target, key, descriptor) {
- descriptor.enumerable = isEnumerable;
- return descriptor;
- };
- }
- }, {}],
- 8: [function (require, module, exports) {
- (function (global) {
- /**
- * Return the global object.
- * @private
- * @function getGlobalObject
- * @return {Object}
- * @see https://gist.github.com/rauschma/1bff02da66472f555c75
- */
- 'use strict';
- Object.defineProperty(exports, '__esModule', {
- value: true
- });
- var _createClass = function () {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ('value' in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
- return function (Constructor, protoProps, staticProps) {
- if (protoProps) defineProperties(Constructor.prototype, protoProps);
- if (staticProps) defineProperties(Constructor, staticProps);
- return Constructor;
- };
- }();
- exports.getGlobalObject = getGlobalObject;
- exports.isObject = isObject;
- exports.copy = copy;
- exports.assign = assign;
- exports.assignStrict = assignStrict;
- exports.except = except;
- exports.defer = defer;
- function _classCallCheck(instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError('Cannot call a class as a function');
- }
- }
- function getGlobalObject() {
- // Workers don’t have `window`, only `self`.
- if (typeof self !== 'undefined') {
- return self;
- }
- if (typeof global !== 'undefined') {
- return global;
- } // Not all environments allow `eval` and `Function`, use only as a last resort.
- return new Function('return this')();
- }
- /**
- * Determine if the provided value is an object.
- * @private
- * @function isObject
- * @param {*} obj The value to check.
- * @returns {boolean} `true` if the value is an object, otherwise `false`.
- */
- function isObject(obj) {
- return obj != undefined && obj != null && typeof obj.valueOf() == 'object';
- }
- /**
- * Make a deep copy of any value.
- * @private
- * @function copy
- * @param {*} value The value to copy.
- * @returns {*} The copied value.
- */
- function copy(value) {
- return JSON.parse(JSON.stringify(value));
- }
- /**
- * Copy the properties in the source objects over to the destination object.
- * @private
- * @function _assign
- * @param {boolean} strict Given `true`, new properties will not be copied.
- * @param {Object} [target={}] The destination object.
- * @param {...Object} sources The source objects.
- * @returns {Object} The destination object once the properties are copied.
- */
- function _assign(strict) {
- var target = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
- target = copy(target);
- for (var _len = arguments.length, sources = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
- sources[_key - 2] = arguments[_key];
- }
- sources.forEach(function (source) {
- Object.keys(source).forEach(function (key) {
- if (!strict || target.hasOwnProperty(key)) {
- var value = source[key];
- target[key] = isObject(value) ? _assign(strict, target[key], value) : value;
- }
- });
- });
- return target;
- }
- /**
- * Copy all the properties in the source objects over to the destination object.
- * @private
- * @function assign
- * @param {Object} [target={}] The destination object.
- * @param {...Object} sources The source objects.
- * @returns {Object} The destination object once the properties are copied.
- */
- function assign() {
- var target = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
- for (var _len2 = arguments.length, sources = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
- sources[_key2 - 1] = arguments[_key2];
- }
- return _assign.apply(undefined, [false, target].concat(sources));
- }
- /**
- * Copy the properties (but no new ones) in the source objects over to the destination object.
- * @private
- * @function assignStrict
- * @param {Object} [target={}] The destination object.
- * @param {...Object} sources The source objects.
- * @returns {Object} The destination object once the properties are copied.
- */
- function assignStrict() {
- var target = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
- for (var _len3 = arguments.length, sources = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
- sources[_key3 - 1] = arguments[_key3];
- }
- return _assign.apply(undefined, [true, target].concat(sources));
- }
- /**
- * Get a copy of an object without some of its properties.
- * @private
- * @function except
- * @param {Object} obj The original object.
- * @param {string[]} properties The properties to exclude from the copied object.
- * @returns {Object} The copied object without the specified properties.
- */
- function except(obj, properties) {
- var objCopy = copy(obj);
- properties.forEach(function (index) {
- return delete objCopy[index];
- });
- return objCopy;
- }
- /**
- * Defer the execution of a function.
- * @private
- * @function defer
- * @param {Function} func The function to defer.
- * @returns {Defer} The Defer object used to execute the function when needed.
- */
- function defer() {
- var func = arguments.length <= 0 || arguments[0] === undefined ? function () {} : arguments[0];
- /**
- * @private
- * @class Defer
- */
- return new (function () {
- function _class() {
- _classCallCheck(this, _class);
- this.func = func;
- }
- /**
- * Execute the deferred function.
- * @public
- * @method Defer#run
- */
- _createClass(_class, [{
- key: 'run',
- value: function run() {
- if (this.func) this.func();
- delete this.func;
- }
- }]);
- return _class;
- }())();
- }
- }).call(this, typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
- }, {}]
- }, {}, [5])(5);
- });
- /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(21)))
- })
- ]);
- });
|