phpunit.phar 3.0 MB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197331983319933200332013320233203332043320533206332073320833209332103321133212332133321433215332163321733218332193322033221332223322333224332253322633227332283322933230332313323233233332343323533236332373323833239332403324133242332433324433245332463324733248332493325033251332523325333254332553325633257332583325933260332613326233263332643326533266332673326833269332703327133272332733327433275332763327733278332793328033281332823328333284332853328633287332883328933290332913329233293332943329533296332973329833299333003330133302333033330433305333063330733308333093331033311333123331333314333153331633317333183331933320333213332233323333243332533326333273332833329333303333133332333333333433335333363333733338333393334033341333423334333344333453334633347333483334933350333513335233353333543335533356333573335833359333603336133362333633336433365333663336733368333693337033371333723337333374333753337633377333783337933380333813338233383333843338533386333873338833389333903339133392333933339433395333963339733398333993340033401334023340333404334053340633407334083340933410334113341233413334143341533416334173341833419334203342133422334233342433425334263342733428334293343033431334323343333434334353343633437334383343933440334413344233443334443344533446334473344833449334503345133452334533345433455334563345733458334593346033461334623346333464334653346633467334683346933470334713347233473334743347533476334773347833479334803348133482334833348433485334863348733488334893349033491334923349333494334953349633497334983349933500335013350233503335043350533506335073350833509335103351133512335133351433515335163351733518335193352033521335223352333524335253352633527335283352933530335313353233533335343353533536335373353833539335403354133542335433354433545335463354733548335493355033551335523355333554335553355633557335583355933560335613356233563335643356533566335673356833569335703357133572335733357433575335763357733578335793358033581335823358333584335853358633587335883358933590335913359233593335943359533596335973359833599336003360133602336033360433605336063360733608336093361033611336123361333614336153361633617336183361933620336213362233623336243362533626336273362833629336303363133632336333363433635336363363733638336393364033641336423364333644336453364633647336483364933650336513365233653336543365533656336573365833659336603366133662336633366433665336663366733668336693367033671336723367333674336753367633677336783367933680336813368233683336843368533686336873368833689336903369133692336933369433695336963369733698336993370033701337023370333704337053370633707337083370933710337113371233713337143371533716337173371833719337203372133722337233372433725337263372733728337293373033731337323373333734337353373633737337383373933740337413374233743337443374533746337473374833749337503375133752337533375433755337563375733758337593376033761337623376333764337653376633767337683376933770337713377233773337743377533776337773377833779337803378133782337833378433785337863378733788337893379033791337923379333794337953379633797337983379933800338013380233803338043380533806338073380833809338103381133812338133381433815338163381733818338193382033821338223382333824338253382633827338283382933830338313383233833338343383533836338373383833839338403384133842338433384433845338463384733848338493385033851338523385333854338553385633857338583385933860338613386233863338643386533866338673386833869338703387133872338733387433875338763387733878338793388033881338823388333884338853388633887338883388933890338913389233893338943389533896338973389833899339003390133902339033390433905339063390733908339093391033911339123391333914339153391633917339183391933920339213392233923339243392533926339273392833929339303393133932339333393433935339363393733938339393394033941339423394333944339453394633947339483394933950339513395233953339543395533956339573395833959339603396133962339633396433965339663396733968339693397033971339723397333974339753397633977339783397933980339813398233983339843398533986339873398833989339903399133992339933399433995339963399733998339993400034001340023400334004340053400634007340083400934010340113401234013340143401534016340173401834019340203402134022340233402434025340263402734028340293403034031340323403334034340353403634037340383403934040340413404234043340443404534046340473404834049340503405134052340533405434055340563405734058340593406034061340623406334064340653406634067340683406934070340713407234073340743407534076340773407834079340803408134082340833408434085340863408734088340893409034091340923409334094340953409634097340983409934100341013410234103341043410534106341073410834109341103411134112341133411434115341163411734118341193412034121341223412334124341253412634127341283412934130341313413234133341343413534136341373413834139341403414134142341433414434145341463414734148341493415034151341523415334154341553415634157341583415934160341613416234163341643416534166341673416834169341703417134172341733417434175341763417734178341793418034181341823418334184341853418634187341883418934190341913419234193341943419534196341973419834199342003420134202342033420434205342063420734208342093421034211342123421334214342153421634217342183421934220342213422234223342243422534226342273422834229342303423134232342333423434235342363423734238342393424034241342423424334244342453424634247342483424934250342513425234253342543425534256342573425834259342603426134262342633426434265342663426734268342693427034271342723427334274342753427634277342783427934280342813428234283342843428534286342873428834289342903429134292342933429434295342963429734298342993430034301343023430334304343053430634307343083430934310343113431234313343143431534316343173431834319343203432134322343233432434325343263432734328343293433034331343323433334334343353433634337343383433934340343413434234343343443434534346343473434834349343503435134352343533435434355343563435734358343593436034361343623436334364343653436634367343683436934370343713437234373343743437534376343773437834379343803438134382343833438434385343863438734388343893439034391343923439334394343953439634397343983439934400344013440234403344043440534406344073440834409344103441134412344133441434415344163441734418344193442034421344223442334424344253442634427344283442934430344313443234433344343443534436344373443834439344403444134442344433444434445344463444734448344493445034451344523445334454344553445634457344583445934460344613446234463344643446534466344673446834469344703447134472344733447434475344763447734478344793448034481344823448334484344853448634487344883448934490344913449234493344943449534496344973449834499345003450134502345033450434505345063450734508345093451034511345123451334514345153451634517345183451934520345213452234523345243452534526345273452834529345303453134532345333453434535345363453734538345393454034541345423454334544345453454634547345483454934550345513455234553345543455534556345573455834559345603456134562345633456434565345663456734568345693457034571345723457334574345753457634577345783457934580345813458234583345843458534586345873458834589345903459134592345933459434595345963459734598345993460034601346023460334604346053460634607346083460934610346113461234613346143461534616346173461834619346203462134622346233462434625346263462734628346293463034631346323463334634346353463634637346383463934640346413464234643346443464534646346473464834649346503465134652346533465434655346563465734658346593466034661346623466334664346653466634667346683466934670346713467234673346743467534676346773467834679346803468134682346833468434685346863468734688346893469034691346923469334694346953469634697346983469934700347013470234703347043470534706347073470834709347103471134712347133471434715347163471734718347193472034721347223472334724347253472634727347283472934730347313473234733347343473534736347373473834739347403474134742347433474434745347463474734748347493475034751347523475334754347553475634757347583475934760347613476234763347643476534766347673476834769347703477134772347733477434775347763477734778347793478034781347823478334784347853478634787347883478934790347913479234793347943479534796347973479834799348003480134802348033480434805348063480734808348093481034811348123481334814348153481634817348183481934820348213482234823348243482534826348273482834829348303483134832348333483434835348363483734838348393484034841348423484334844348453484634847348483484934850348513485234853348543485534856348573485834859348603486134862348633486434865348663486734868348693487034871348723487334874348753487634877348783487934880348813488234883348843488534886348873488834889348903489134892348933489434895348963489734898348993490034901349023490334904349053490634907349083490934910349113491234913349143491534916349173491834919349203492134922349233492434925349263492734928349293493034931349323493334934349353493634937349383493934940349413494234943349443494534946349473494834949349503495134952349533495434955349563495734958349593496034961349623496334964349653496634967349683496934970349713497234973349743497534976349773497834979349803498134982349833498434985349863498734988349893499034991349923499334994349953499634997349983499935000350013500235003350043500535006350073500835009350103501135012350133501435015350163501735018350193502035021350223502335024350253502635027350283502935030350313503235033350343503535036350373503835039350403504135042350433504435045350463504735048350493505035051350523505335054350553505635057350583505935060350613506235063350643506535066350673506835069350703507135072350733507435075350763507735078350793508035081350823508335084350853508635087350883508935090350913509235093350943509535096350973509835099351003510135102351033510435105351063510735108351093511035111351123511335114351153511635117351183511935120351213512235123351243512535126351273512835129351303513135132351333513435135351363513735138351393514035141351423514335144351453514635147351483514935150351513515235153351543515535156351573515835159351603516135162351633516435165351663516735168351693517035171351723517335174351753517635177351783517935180351813518235183351843518535186351873518835189351903519135192351933519435195351963519735198351993520035201352023520335204352053520635207352083520935210352113521235213352143521535216352173521835219352203522135222352233522435225352263522735228352293523035231352323523335234352353523635237352383523935240352413524235243352443524535246352473524835249352503525135252352533525435255352563525735258352593526035261352623526335264352653526635267352683526935270352713527235273352743527535276352773527835279352803528135282352833528435285352863528735288352893529035291352923529335294352953529635297352983529935300353013530235303353043530535306353073530835309353103531135312353133531435315353163531735318353193532035321353223532335324353253532635327353283532935330353313533235333353343533535336353373533835339353403534135342353433534435345353463534735348353493535035351353523535335354353553535635357353583535935360353613536235363353643536535366353673536835369353703537135372353733537435375353763537735378353793538035381353823538335384353853538635387353883538935390353913539235393353943539535396353973539835399354003540135402354033540435405354063540735408354093541035411354123541335414354153541635417354183541935420354213542235423354243542535426354273542835429354303543135432354333543435435354363543735438354393544035441354423544335444354453544635447354483544935450354513545235453354543545535456354573545835459354603546135462354633546435465354663546735468354693547035471354723547335474354753547635477354783547935480354813548235483354843548535486354873548835489354903549135492354933549435495354963549735498354993550035501355023550335504355053550635507355083550935510355113551235513355143551535516355173551835519355203552135522355233552435525355263552735528355293553035531355323553335534355353553635537355383553935540355413554235543355443554535546355473554835549355503555135552355533555435555355563555735558355593556035561355623556335564355653556635567355683556935570355713557235573355743557535576355773557835579355803558135582355833558435585355863558735588355893559035591355923559335594355953559635597355983559935600356013560235603356043560535606356073560835609356103561135612356133561435615356163561735618356193562035621356223562335624356253562635627356283562935630356313563235633356343563535636356373563835639356403564135642356433564435645356463564735648356493565035651356523565335654356553565635657356583565935660356613566235663356643566535666356673566835669356703567135672356733567435675356763567735678356793568035681356823568335684356853568635687356883568935690356913569235693356943569535696356973569835699357003570135702357033570435705357063570735708357093571035711357123571335714357153571635717357183571935720357213572235723357243572535726357273572835729357303573135732357333573435735357363573735738357393574035741357423574335744357453574635747357483574935750357513575235753357543575535756357573575835759357603576135762357633576435765357663576735768357693577035771357723577335774357753577635777357783577935780357813578235783357843578535786357873578835789357903579135792357933579435795357963579735798357993580035801358023580335804358053580635807358083580935810358113581235813358143581535816358173581835819358203582135822358233582435825358263582735828358293583035831358323583335834358353583635837358383583935840358413584235843358443584535846358473584835849358503585135852358533585435855358563585735858358593586035861358623586335864358653586635867358683586935870358713587235873358743587535876358773587835879358803588135882358833588435885358863588735888358893589035891358923589335894358953589635897358983589935900359013590235903359043590535906359073590835909359103591135912359133591435915359163591735918359193592035921359223592335924359253592635927359283592935930359313593235933359343593535936359373593835939359403594135942359433594435945359463594735948359493595035951359523595335954359553595635957359583595935960359613596235963359643596535966359673596835969359703597135972359733597435975359763597735978359793598035981359823598335984359853598635987359883598935990359913599235993359943599535996359973599835999360003600136002360033600436005360063600736008360093601036011360123601336014360153601636017360183601936020360213602236023360243602536026360273602836029360303603136032360333603436035360363603736038360393604036041360423604336044360453604636047360483604936050360513605236053360543605536056360573605836059360603606136062360633606436065360663606736068360693607036071360723607336074360753607636077360783607936080360813608236083360843608536086360873608836089360903609136092360933609436095360963609736098360993610036101361023610336104361053610636107361083610936110361113611236113361143611536116361173611836119361203612136122361233612436125361263612736128361293613036131361323613336134361353613636137361383613936140361413614236143361443614536146361473614836149361503615136152361533615436155361563615736158361593616036161361623616336164361653616636167361683616936170361713617236173361743617536176361773617836179361803618136182361833618436185361863618736188361893619036191361923619336194361953619636197361983619936200362013620236203362043620536206362073620836209362103621136212362133621436215362163621736218362193622036221362223622336224362253622636227362283622936230362313623236233362343623536236362373623836239362403624136242362433624436245362463624736248362493625036251362523625336254362553625636257362583625936260362613626236263362643626536266362673626836269362703627136272362733627436275362763627736278362793628036281362823628336284362853628636287362883628936290362913629236293362943629536296362973629836299363003630136302363033630436305363063630736308363093631036311363123631336314363153631636317363183631936320363213632236323363243632536326363273632836329363303633136332363333633436335363363633736338363393634036341363423634336344363453634636347363483634936350363513635236353363543635536356363573635836359363603636136362363633636436365363663636736368363693637036371363723637336374363753637636377363783637936380363813638236383363843638536386363873638836389363903639136392363933639436395363963639736398363993640036401364023640336404364053640636407364083640936410364113641236413364143641536416364173641836419364203642136422364233642436425364263642736428364293643036431364323643336434364353643636437364383643936440364413644236443364443644536446364473644836449364503645136452364533645436455364563645736458364593646036461364623646336464364653646636467364683646936470364713647236473364743647536476364773647836479364803648136482364833648436485364863648736488364893649036491364923649336494364953649636497364983649936500365013650236503365043650536506365073650836509365103651136512365133651436515365163651736518365193652036521365223652336524365253652636527365283652936530365313653236533365343653536536365373653836539365403654136542365433654436545365463654736548365493655036551365523655336554365553655636557365583655936560365613656236563365643656536566365673656836569365703657136572365733657436575365763657736578365793658036581365823658336584365853658636587365883658936590365913659236593365943659536596365973659836599366003660136602366033660436605366063660736608366093661036611366123661336614366153661636617366183661936620366213662236623366243662536626366273662836629366303663136632366333663436635366363663736638366393664036641366423664336644366453664636647366483664936650366513665236653366543665536656366573665836659366603666136662366633666436665366663666736668366693667036671366723667336674366753667636677366783667936680366813668236683366843668536686366873668836689366903669136692366933669436695366963669736698366993670036701367023670336704367053670636707367083670936710367113671236713367143671536716367173671836719367203672136722367233672436725367263672736728367293673036731367323673336734367353673636737367383673936740367413674236743367443674536746367473674836749367503675136752367533675436755367563675736758367593676036761367623676336764367653676636767367683676936770367713677236773367743677536776367773677836779367803678136782367833678436785367863678736788367893679036791367923679336794367953679636797367983679936800368013680236803368043680536806368073680836809368103681136812368133681436815368163681736818368193682036821368223682336824368253682636827368283682936830368313683236833368343683536836368373683836839368403684136842368433684436845368463684736848368493685036851368523685336854368553685636857368583685936860368613686236863368643686536866368673686836869368703687136872368733687436875368763687736878368793688036881368823688336884368853688636887368883688936890368913689236893368943689536896368973689836899369003690136902369033690436905369063690736908369093691036911369123691336914369153691636917369183691936920369213692236923369243692536926369273692836929369303693136932369333693436935369363693736938369393694036941369423694336944369453694636947369483694936950369513695236953369543695536956369573695836959369603696136962369633696436965369663696736968369693697036971369723697336974369753697636977369783697936980369813698236983369843698536986369873698836989369903699136992369933699436995369963699736998369993700037001370023700337004370053700637007370083700937010370113701237013370143701537016370173701837019370203702137022370233702437025370263702737028370293703037031370323703337034370353703637037370383703937040370413704237043370443704537046370473704837049370503705137052370533705437055370563705737058370593706037061370623706337064370653706637067370683706937070370713707237073370743707537076370773707837079370803708137082370833708437085370863708737088370893709037091370923709337094370953709637097370983709937100371013710237103371043710537106371073710837109371103711137112371133711437115371163711737118371193712037121371223712337124371253712637127371283712937130371313713237133371343713537136371373713837139371403714137142371433714437145371463714737148371493715037151371523715337154371553715637157371583715937160371613716237163371643716537166371673716837169371703717137172371733717437175371763717737178371793718037181371823718337184371853718637187371883718937190371913719237193371943719537196371973719837199372003720137202372033720437205372063720737208372093721037211372123721337214372153721637217372183721937220372213722237223372243722537226372273722837229372303723137232372333723437235372363723737238372393724037241372423724337244372453724637247372483724937250372513725237253372543725537256372573725837259372603726137262372633726437265372663726737268372693727037271372723727337274372753727637277372783727937280372813728237283372843728537286372873728837289372903729137292372933729437295372963729737298372993730037301373023730337304373053730637307373083730937310373113731237313373143731537316373173731837319373203732137322373233732437325373263732737328373293733037331373323733337334373353733637337373383733937340373413734237343373443734537346373473734837349373503735137352373533735437355373563735737358373593736037361373623736337364373653736637367373683736937370373713737237373373743737537376373773737837379373803738137382373833738437385373863738737388373893739037391373923739337394373953739637397373983739937400374013740237403374043740537406374073740837409374103741137412374133741437415374163741737418374193742037421374223742337424374253742637427374283742937430374313743237433374343743537436374373743837439374403744137442374433744437445374463744737448374493745037451374523745337454374553745637457374583745937460374613746237463374643746537466374673746837469374703747137472374733747437475374763747737478374793748037481374823748337484374853748637487374883748937490374913749237493374943749537496374973749837499375003750137502375033750437505375063750737508375093751037511375123751337514375153751637517375183751937520375213752237523375243752537526375273752837529375303753137532375333753437535375363753737538375393754037541375423754337544375453754637547375483754937550375513755237553375543755537556375573755837559375603756137562375633756437565375663756737568375693757037571375723757337574375753757637577375783757937580375813758237583375843758537586375873758837589375903759137592375933759437595375963759737598375993760037601376023760337604376053760637607376083760937610376113761237613376143761537616376173761837619376203762137622376233762437625376263762737628376293763037631376323763337634376353763637637376383763937640376413764237643376443764537646376473764837649376503765137652376533765437655376563765737658376593766037661376623766337664376653766637667376683766937670376713767237673376743767537676376773767837679376803768137682376833768437685376863768737688376893769037691376923769337694376953769637697376983769937700377013770237703377043770537706377073770837709377103771137712377133771437715377163771737718377193772037721377223772337724377253772637727377283772937730377313773237733377343773537736377373773837739377403774137742377433774437745377463774737748377493775037751377523775337754377553775637757377583775937760377613776237763377643776537766377673776837769377703777137772377733777437775377763777737778377793778037781377823778337784377853778637787377883778937790377913779237793377943779537796377973779837799378003780137802378033780437805378063780737808378093781037811378123781337814378153781637817378183781937820378213782237823378243782537826378273782837829378303783137832378333783437835378363783737838378393784037841378423784337844378453784637847378483784937850378513785237853378543785537856378573785837859378603786137862378633786437865378663786737868378693787037871378723787337874378753787637877378783787937880378813788237883378843788537886378873788837889378903789137892378933789437895378963789737898378993790037901379023790337904379053790637907379083790937910379113791237913379143791537916379173791837919379203792137922379233792437925379263792737928379293793037931379323793337934379353793637937379383793937940379413794237943379443794537946379473794837949379503795137952379533795437955379563795737958379593796037961379623796337964379653796637967379683796937970379713797237973379743797537976379773797837979379803798137982379833798437985379863798737988379893799037991379923799337994379953799637997379983799938000380013800238003380043800538006380073800838009380103801138012380133801438015380163801738018380193802038021380223802338024380253802638027380283802938030380313803238033380343803538036380373803838039380403804138042380433804438045380463804738048380493805038051380523805338054380553805638057380583805938060380613806238063380643806538066380673806838069380703807138072380733807438075380763807738078380793808038081380823808338084380853808638087380883808938090380913809238093380943809538096380973809838099381003810138102381033810438105381063810738108381093811038111381123811338114381153811638117381183811938120381213812238123381243812538126381273812838129381303813138132381333813438135381363813738138381393814038141381423814338144381453814638147381483814938150381513815238153381543815538156381573815838159381603816138162381633816438165381663816738168381693817038171381723817338174381753817638177381783817938180381813818238183381843818538186381873818838189381903819138192381933819438195381963819738198381993820038201382023820338204382053820638207382083820938210382113821238213382143821538216382173821838219382203822138222382233822438225382263822738228382293823038231382323823338234382353823638237382383823938240382413824238243382443824538246382473824838249382503825138252382533825438255382563825738258382593826038261382623826338264382653826638267382683826938270382713827238273382743827538276382773827838279382803828138282382833828438285382863828738288382893829038291382923829338294382953829638297382983829938300383013830238303383043830538306383073830838309383103831138312383133831438315383163831738318383193832038321383223832338324383253832638327383283832938330383313833238333383343833538336383373833838339383403834138342383433834438345383463834738348383493835038351383523835338354383553835638357383583835938360383613836238363383643836538366383673836838369383703837138372383733837438375383763837738378383793838038381383823838338384383853838638387383883838938390383913839238393383943839538396383973839838399384003840138402384033840438405384063840738408384093841038411384123841338414384153841638417384183841938420384213842238423384243842538426384273842838429384303843138432384333843438435384363843738438384393844038441384423844338444384453844638447384483844938450384513845238453384543845538456384573845838459384603846138462384633846438465384663846738468384693847038471384723847338474384753847638477384783847938480384813848238483384843848538486384873848838489384903849138492384933849438495384963849738498384993850038501385023850338504385053850638507385083850938510385113851238513385143851538516385173851838519385203852138522385233852438525385263852738528385293853038531385323853338534385353853638537385383853938540385413854238543385443854538546385473854838549385503855138552385533855438555385563855738558385593856038561385623856338564385653856638567385683856938570385713857238573385743857538576385773857838579385803858138582385833858438585385863858738588385893859038591385923859338594385953859638597385983859938600386013860238603386043860538606386073860838609386103861138612386133861438615386163861738618386193862038621386223862338624386253862638627386283862938630386313863238633386343863538636386373863838639386403864138642386433864438645386463864738648386493865038651386523865338654386553865638657386583865938660386613866238663386643866538666386673866838669386703867138672386733867438675386763867738678386793868038681386823868338684386853868638687386883868938690386913869238693386943869538696386973869838699387003870138702387033870438705387063870738708387093871038711387123871338714387153871638717387183871938720387213872238723387243872538726387273872838729387303873138732387333873438735387363873738738387393874038741387423874338744387453874638747387483874938750387513875238753387543875538756387573875838759387603876138762387633876438765387663876738768387693877038771387723877338774387753877638777387783877938780387813878238783387843878538786387873878838789387903879138792387933879438795387963879738798387993880038801388023880338804388053880638807388083880938810388113881238813388143881538816388173881838819388203882138822388233882438825388263882738828388293883038831388323883338834388353883638837388383883938840388413884238843388443884538846388473884838849388503885138852388533885438855388563885738858388593886038861388623886338864388653886638867388683886938870388713887238873388743887538876388773887838879388803888138882388833888438885388863888738888388893889038891388923889338894388953889638897388983889938900389013890238903389043890538906389073890838909389103891138912389133891438915389163891738918389193892038921389223892338924389253892638927389283892938930389313893238933389343893538936389373893838939389403894138942389433894438945389463894738948389493895038951389523895338954389553895638957389583895938960389613896238963389643896538966389673896838969389703897138972389733897438975389763897738978389793898038981389823898338984389853898638987389883898938990389913899238993389943899538996389973899838999390003900139002390033900439005390063900739008390093901039011390123901339014390153901639017390183901939020390213902239023390243902539026390273902839029390303903139032390333903439035390363903739038390393904039041390423904339044390453904639047390483904939050390513905239053390543905539056390573905839059390603906139062390633906439065390663906739068390693907039071390723907339074390753907639077390783907939080390813908239083390843908539086390873908839089390903909139092390933909439095390963909739098390993910039101391023910339104391053910639107391083910939110391113911239113391143911539116391173911839119391203912139122391233912439125391263912739128391293913039131391323913339134391353913639137391383913939140391413914239143391443914539146391473914839149391503915139152391533915439155391563915739158391593916039161391623916339164391653916639167391683916939170391713917239173391743917539176391773917839179391803918139182391833918439185391863918739188391893919039191391923919339194391953919639197391983919939200392013920239203392043920539206392073920839209392103921139212392133921439215392163921739218392193922039221392223922339224392253922639227392283922939230392313923239233392343923539236392373923839239392403924139242392433924439245392463924739248392493925039251392523925339254392553925639257392583925939260392613926239263392643926539266392673926839269392703927139272392733927439275392763927739278392793928039281392823928339284392853928639287392883928939290392913929239293392943929539296392973929839299393003930139302393033930439305393063930739308393093931039311393123931339314393153931639317393183931939320393213932239323393243932539326393273932839329393303933139332393333933439335393363933739338393393934039341393423934339344393453934639347393483934939350393513935239353393543935539356393573935839359393603936139362393633936439365393663936739368393693937039371393723937339374393753937639377393783937939380393813938239383393843938539386393873938839389393903939139392393933939439395393963939739398393993940039401394023940339404394053940639407394083940939410394113941239413394143941539416394173941839419394203942139422394233942439425394263942739428394293943039431394323943339434394353943639437394383943939440394413944239443394443944539446394473944839449394503945139452394533945439455394563945739458394593946039461394623946339464394653946639467394683946939470394713947239473394743947539476394773947839479394803948139482394833948439485394863948739488394893949039491394923949339494394953949639497394983949939500395013950239503395043950539506395073950839509395103951139512395133951439515395163951739518395193952039521395223952339524395253952639527395283952939530395313953239533395343953539536395373953839539395403954139542395433954439545395463954739548395493955039551395523955339554395553955639557395583955939560395613956239563395643956539566395673956839569395703957139572395733957439575395763957739578395793958039581395823958339584395853958639587395883958939590395913959239593395943959539596395973959839599396003960139602396033960439605396063960739608396093961039611396123961339614396153961639617396183961939620396213962239623396243962539626396273962839629396303963139632396333963439635396363963739638396393964039641396423964339644396453964639647396483964939650396513965239653396543965539656396573965839659396603966139662396633966439665396663966739668396693967039671396723967339674396753967639677396783967939680396813968239683396843968539686396873968839689396903969139692396933969439695396963969739698396993970039701397023970339704397053970639707397083970939710397113971239713397143971539716397173971839719397203972139722397233972439725397263972739728397293973039731397323973339734397353973639737397383973939740397413974239743397443974539746397473974839749397503975139752397533975439755397563975739758397593976039761397623976339764397653976639767397683976939770397713977239773397743977539776397773977839779397803978139782397833978439785397863978739788397893979039791397923979339794397953979639797397983979939800398013980239803398043980539806398073980839809398103981139812398133981439815398163981739818398193982039821398223982339824398253982639827398283982939830398313983239833398343983539836398373983839839398403984139842398433984439845398463984739848398493985039851398523985339854398553985639857398583985939860398613986239863398643986539866398673986839869398703987139872398733987439875398763987739878398793988039881398823988339884398853988639887398883988939890398913989239893398943989539896398973989839899399003990139902399033990439905399063990739908399093991039911399123991339914399153991639917399183991939920399213992239923399243992539926399273992839929399303993139932399333993439935399363993739938399393994039941399423994339944399453994639947399483994939950399513995239953399543995539956399573995839959399603996139962399633996439965399663996739968399693997039971399723997339974399753997639977399783997939980399813998239983399843998539986399873998839989399903999139992399933999439995399963999739998399994000040001400024000340004400054000640007400084000940010400114001240013400144001540016400174001840019400204002140022400234002440025400264002740028400294003040031400324003340034400354003640037400384003940040400414004240043400444004540046400474004840049400504005140052400534005440055400564005740058400594006040061400624006340064400654006640067400684006940070400714007240073400744007540076400774007840079400804008140082400834008440085400864008740088400894009040091400924009340094400954009640097400984009940100401014010240103401044010540106401074010840109401104011140112401134011440115401164011740118401194012040121401224012340124401254012640127401284012940130401314013240133401344013540136401374013840139401404014140142401434014440145401464014740148401494015040151401524015340154401554015640157401584015940160401614016240163401644016540166401674016840169401704017140172401734017440175401764017740178401794018040181401824018340184401854018640187401884018940190401914019240193401944019540196401974019840199402004020140202402034020440205402064020740208402094021040211402124021340214402154021640217402184021940220402214022240223402244022540226402274022840229402304023140232402334023440235402364023740238402394024040241402424024340244402454024640247402484024940250402514025240253402544025540256402574025840259402604026140262402634026440265402664026740268402694027040271402724027340274402754027640277402784027940280402814028240283402844028540286402874028840289402904029140292402934029440295402964029740298402994030040301403024030340304403054030640307403084030940310403114031240313403144031540316403174031840319403204032140322403234032440325403264032740328403294033040331403324033340334403354033640337403384033940340403414034240343403444034540346403474034840349403504035140352403534035440355403564035740358403594036040361403624036340364403654036640367403684036940370403714037240373403744037540376403774037840379403804038140382403834038440385403864038740388403894039040391403924039340394403954039640397403984039940400404014040240403404044040540406404074040840409404104041140412404134041440415404164041740418404194042040421404224042340424404254042640427404284042940430404314043240433404344043540436404374043840439404404044140442404434044440445404464044740448404494045040451404524045340454404554045640457404584045940460404614046240463404644046540466404674046840469404704047140472404734047440475404764047740478404794048040481404824048340484404854048640487404884048940490404914049240493404944049540496404974049840499405004050140502405034050440505405064050740508405094051040511405124051340514405154051640517405184051940520405214052240523405244052540526405274052840529405304053140532405334053440535405364053740538405394054040541405424054340544405454054640547405484054940550405514055240553405544055540556405574055840559405604056140562405634056440565405664056740568405694057040571405724057340574405754057640577405784057940580405814058240583405844058540586405874058840589405904059140592405934059440595405964059740598405994060040601406024060340604406054060640607406084060940610406114061240613406144061540616406174061840619406204062140622406234062440625406264062740628406294063040631406324063340634406354063640637406384063940640406414064240643406444064540646406474064840649406504065140652406534065440655406564065740658406594066040661406624066340664406654066640667406684066940670406714067240673406744067540676406774067840679406804068140682406834068440685406864068740688406894069040691406924069340694406954069640697406984069940700407014070240703407044070540706407074070840709407104071140712407134071440715407164071740718407194072040721407224072340724407254072640727407284072940730407314073240733407344073540736407374073840739407404074140742407434074440745407464074740748407494075040751407524075340754407554075640757407584075940760407614076240763407644076540766407674076840769407704077140772407734077440775407764077740778407794078040781407824078340784407854078640787407884078940790407914079240793407944079540796407974079840799408004080140802408034080440805408064080740808408094081040811408124081340814408154081640817408184081940820408214082240823408244082540826408274082840829408304083140832408334083440835408364083740838408394084040841408424084340844408454084640847408484084940850408514085240853408544085540856408574085840859408604086140862408634086440865408664086740868408694087040871408724087340874408754087640877408784087940880408814088240883408844088540886408874088840889408904089140892408934089440895408964089740898408994090040901409024090340904409054090640907409084090940910409114091240913409144091540916409174091840919409204092140922409234092440925409264092740928409294093040931409324093340934409354093640937409384093940940409414094240943409444094540946409474094840949409504095140952409534095440955409564095740958409594096040961409624096340964409654096640967409684096940970409714097240973409744097540976409774097840979409804098140982409834098440985409864098740988409894099040991409924099340994409954099640997409984099941000410014100241003410044100541006410074100841009410104101141012410134101441015410164101741018410194102041021410224102341024410254102641027410284102941030410314103241033410344103541036410374103841039410404104141042410434104441045410464104741048410494105041051410524105341054410554105641057410584105941060410614106241063410644106541066410674106841069410704107141072410734107441075410764107741078410794108041081410824108341084410854108641087410884108941090410914109241093410944109541096410974109841099411004110141102411034110441105411064110741108411094111041111411124111341114411154111641117411184111941120411214112241123411244112541126411274112841129411304113141132411334113441135411364113741138411394114041141411424114341144411454114641147411484114941150411514115241153411544115541156411574115841159411604116141162411634116441165411664116741168411694117041171411724117341174411754117641177411784117941180411814118241183411844118541186411874118841189411904119141192411934119441195411964119741198411994120041201412024120341204412054120641207412084120941210412114121241213412144121541216412174121841219412204122141222412234122441225412264122741228412294123041231412324123341234412354123641237412384123941240412414124241243412444124541246412474124841249412504125141252412534125441255412564125741258412594126041261412624126341264412654126641267412684126941270412714127241273412744127541276412774127841279412804128141282412834128441285412864128741288412894129041291412924129341294412954129641297412984129941300413014130241303413044130541306413074130841309413104131141312413134131441315413164131741318413194132041321413224132341324413254132641327413284132941330413314133241333413344133541336413374133841339413404134141342413434134441345413464134741348413494135041351413524135341354413554135641357413584135941360413614136241363413644136541366413674136841369413704137141372413734137441375413764137741378413794138041381413824138341384413854138641387413884138941390413914139241393413944139541396413974139841399414004140141402414034140441405414064140741408414094141041411414124141341414414154141641417414184141941420414214142241423414244142541426414274142841429414304143141432414334143441435414364143741438414394144041441414424144341444414454144641447414484144941450414514145241453414544145541456414574145841459414604146141462414634146441465414664146741468414694147041471414724147341474414754147641477414784147941480414814148241483414844148541486414874148841489414904149141492414934149441495414964149741498414994150041501415024150341504415054150641507415084150941510415114151241513415144151541516415174151841519415204152141522415234152441525415264152741528415294153041531415324153341534415354153641537415384153941540415414154241543415444154541546415474154841549415504155141552415534155441555415564155741558415594156041561415624156341564415654156641567415684156941570415714157241573415744157541576415774157841579415804158141582415834158441585415864158741588415894159041591415924159341594415954159641597415984159941600416014160241603416044160541606416074160841609416104161141612416134161441615416164161741618416194162041621416224162341624416254162641627416284162941630416314163241633416344163541636416374163841639416404164141642416434164441645416464164741648416494165041651416524165341654416554165641657416584165941660416614166241663416644166541666416674166841669416704167141672416734167441675416764167741678416794168041681416824168341684416854168641687416884168941690416914169241693416944169541696416974169841699417004170141702417034170441705417064170741708417094171041711417124171341714417154171641717417184171941720417214172241723417244172541726417274172841729417304173141732417334173441735417364173741738417394174041741417424174341744417454174641747417484174941750417514175241753417544175541756417574175841759417604176141762417634176441765417664176741768417694177041771417724177341774417754177641777417784177941780417814178241783417844178541786417874178841789417904179141792417934179441795417964179741798417994180041801418024180341804418054180641807418084180941810418114181241813418144181541816418174181841819418204182141822418234182441825418264182741828418294183041831418324183341834418354183641837418384183941840418414184241843418444184541846418474184841849418504185141852418534185441855418564185741858418594186041861418624186341864418654186641867418684186941870418714187241873418744187541876418774187841879418804188141882418834188441885418864188741888418894189041891418924189341894418954189641897418984189941900419014190241903419044190541906419074190841909419104191141912419134191441915419164191741918419194192041921419224192341924419254192641927419284192941930419314193241933419344193541936419374193841939419404194141942419434194441945419464194741948419494195041951419524195341954419554195641957419584195941960419614196241963419644196541966419674196841969419704197141972419734197441975419764197741978419794198041981419824198341984419854198641987419884198941990419914199241993419944199541996419974199841999420004200142002420034200442005420064200742008420094201042011420124201342014420154201642017420184201942020420214202242023420244202542026420274202842029420304203142032420334203442035420364203742038420394204042041420424204342044420454204642047420484204942050420514205242053420544205542056420574205842059420604206142062420634206442065420664206742068420694207042071420724207342074420754207642077420784207942080420814208242083420844208542086420874208842089420904209142092420934209442095420964209742098420994210042101421024210342104421054210642107421084210942110421114211242113421144211542116421174211842119421204212142122421234212442125421264212742128421294213042131421324213342134421354213642137421384213942140421414214242143421444214542146421474214842149421504215142152421534215442155421564215742158421594216042161421624216342164421654216642167421684216942170421714217242173421744217542176421774217842179421804218142182421834218442185421864218742188421894219042191421924219342194421954219642197421984219942200422014220242203422044220542206422074220842209422104221142212422134221442215422164221742218422194222042221422224222342224422254222642227422284222942230422314223242233422344223542236422374223842239422404224142242422434224442245422464224742248422494225042251422524225342254422554225642257422584225942260422614226242263422644226542266422674226842269422704227142272422734227442275422764227742278422794228042281422824228342284422854228642287422884228942290422914229242293422944229542296422974229842299423004230142302423034230442305423064230742308423094231042311423124231342314423154231642317423184231942320423214232242323423244232542326423274232842329423304233142332423334233442335423364233742338423394234042341423424234342344423454234642347423484234942350423514235242353423544235542356423574235842359423604236142362423634236442365423664236742368423694237042371423724237342374423754237642377423784237942380423814238242383423844238542386423874238842389423904239142392423934239442395423964239742398423994240042401424024240342404424054240642407424084240942410424114241242413424144241542416424174241842419424204242142422424234242442425424264242742428424294243042431424324243342434424354243642437424384243942440424414244242443424444244542446424474244842449424504245142452424534245442455424564245742458424594246042461424624246342464424654246642467424684246942470424714247242473424744247542476424774247842479424804248142482424834248442485424864248742488424894249042491424924249342494424954249642497424984249942500425014250242503425044250542506425074250842509425104251142512425134251442515425164251742518425194252042521425224252342524425254252642527425284252942530425314253242533425344253542536425374253842539425404254142542425434254442545425464254742548425494255042551425524255342554425554255642557425584255942560425614256242563425644256542566425674256842569425704257142572425734257442575425764257742578425794258042581425824258342584425854258642587425884258942590425914259242593425944259542596425974259842599426004260142602426034260442605426064260742608426094261042611426124261342614426154261642617426184261942620426214262242623426244262542626426274262842629426304263142632426334263442635426364263742638426394264042641426424264342644426454264642647426484264942650426514265242653426544265542656426574265842659426604266142662426634266442665426664266742668426694267042671426724267342674426754267642677426784267942680426814268242683426844268542686426874268842689426904269142692426934269442695426964269742698426994270042701427024270342704427054270642707427084270942710427114271242713427144271542716427174271842719427204272142722427234272442725427264272742728427294273042731427324273342734427354273642737427384273942740427414274242743427444274542746427474274842749427504275142752427534275442755427564275742758427594276042761427624276342764427654276642767427684276942770427714277242773427744277542776427774277842779427804278142782427834278442785427864278742788427894279042791427924279342794427954279642797427984279942800428014280242803428044280542806428074280842809428104281142812428134281442815428164281742818428194282042821428224282342824428254282642827428284282942830428314283242833428344283542836428374283842839428404284142842428434284442845428464284742848428494285042851428524285342854428554285642857428584285942860428614286242863428644286542866428674286842869428704287142872428734287442875428764287742878428794288042881428824288342884428854288642887428884288942890428914289242893428944289542896428974289842899429004290142902429034290442905429064290742908429094291042911429124291342914429154291642917429184291942920429214292242923429244292542926429274292842929429304293142932429334293442935429364293742938429394294042941429424294342944429454294642947429484294942950429514295242953429544295542956429574295842959429604296142962429634296442965429664296742968429694297042971429724297342974429754297642977429784297942980429814298242983429844298542986429874298842989429904299142992429934299442995429964299742998429994300043001430024300343004430054300643007430084300943010430114301243013430144301543016430174301843019430204302143022430234302443025430264302743028430294303043031430324303343034430354303643037430384303943040430414304243043430444304543046430474304843049430504305143052430534305443055430564305743058430594306043061430624306343064430654306643067430684306943070430714307243073430744307543076430774307843079430804308143082430834308443085430864308743088430894309043091430924309343094430954309643097430984309943100431014310243103431044310543106431074310843109431104311143112431134311443115431164311743118431194312043121431224312343124431254312643127431284312943130431314313243133431344313543136431374313843139431404314143142431434314443145431464314743148431494315043151431524315343154431554315643157431584315943160431614316243163431644316543166431674316843169431704317143172431734317443175431764317743178431794318043181431824318343184431854318643187431884318943190431914319243193431944319543196431974319843199432004320143202432034320443205432064320743208432094321043211432124321343214432154321643217432184321943220432214322243223432244322543226432274322843229432304323143232432334323443235432364323743238432394324043241432424324343244432454324643247432484324943250432514325243253432544325543256432574325843259432604326143262432634326443265432664326743268432694327043271432724327343274432754327643277432784327943280432814328243283432844328543286432874328843289432904329143292432934329443295432964329743298432994330043301433024330343304433054330643307433084330943310433114331243313433144331543316433174331843319433204332143322433234332443325433264332743328433294333043331433324333343334433354333643337433384333943340433414334243343433444334543346433474334843349433504335143352433534335443355433564335743358433594336043361433624336343364433654336643367433684336943370433714337243373433744337543376433774337843379433804338143382433834338443385433864338743388433894339043391433924339343394433954339643397433984339943400434014340243403434044340543406434074340843409434104341143412434134341443415434164341743418434194342043421434224342343424434254342643427434284342943430434314343243433434344343543436434374343843439434404344143442434434344443445434464344743448434494345043451434524345343454434554345643457434584345943460434614346243463434644346543466434674346843469434704347143472434734347443475434764347743478434794348043481434824348343484434854348643487434884348943490434914349243493434944349543496434974349843499435004350143502435034350443505435064350743508435094351043511435124351343514435154351643517435184351943520435214352243523435244352543526435274352843529435304353143532435334353443535435364353743538435394354043541435424354343544435454354643547435484354943550435514355243553435544355543556435574355843559435604356143562435634356443565435664356743568435694357043571435724357343574435754357643577435784357943580435814358243583435844358543586435874358843589435904359143592435934359443595435964359743598435994360043601436024360343604436054360643607436084360943610436114361243613436144361543616436174361843619436204362143622436234362443625436264362743628436294363043631436324363343634436354363643637436384363943640436414364243643436444364543646436474364843649436504365143652436534365443655436564365743658436594366043661436624366343664436654366643667436684366943670436714367243673436744367543676436774367843679436804368143682436834368443685436864368743688436894369043691436924369343694436954369643697436984369943700437014370243703437044370543706437074370843709437104371143712437134371443715437164371743718437194372043721437224372343724437254372643727437284372943730437314373243733437344373543736437374373843739437404374143742437434374443745437464374743748437494375043751437524375343754437554375643757437584375943760437614376243763437644376543766437674376843769437704377143772437734377443775437764377743778437794378043781437824378343784437854378643787437884378943790437914379243793437944379543796437974379843799438004380143802438034380443805438064380743808438094381043811438124381343814438154381643817438184381943820438214382243823438244382543826438274382843829438304383143832438334383443835438364383743838438394384043841438424384343844438454384643847438484384943850438514385243853438544385543856438574385843859438604386143862438634386443865438664386743868438694387043871438724387343874438754387643877438784387943880438814388243883438844388543886438874388843889438904389143892438934389443895438964389743898438994390043901439024390343904439054390643907439084390943910439114391243913439144391543916439174391843919439204392143922439234392443925439264392743928439294393043931439324393343934439354393643937439384393943940439414394243943439444394543946439474394843949439504395143952439534395443955439564395743958439594396043961439624396343964439654396643967439684396943970439714397243973439744397543976439774397843979439804398143982439834398443985439864398743988439894399043991439924399343994439954399643997439984399944000440014400244003440044400544006440074400844009440104401144012440134401444015440164401744018440194402044021440224402344024440254402644027440284402944030440314403244033440344403544036440374403844039440404404144042440434404444045440464404744048440494405044051440524405344054440554405644057440584405944060440614406244063440644406544066440674406844069440704407144072440734407444075440764407744078440794408044081440824408344084440854408644087440884408944090440914409244093440944409544096440974409844099441004410144102441034410444105441064410744108441094411044111441124411344114441154411644117441184411944120441214412244123441244412544126441274412844129441304413144132441334413444135441364413744138441394414044141441424414344144441454414644147441484414944150441514415244153441544415544156441574415844159441604416144162441634416444165441664416744168441694417044171441724417344174441754417644177441784417944180441814418244183441844418544186441874418844189441904419144192441934419444195441964419744198441994420044201442024420344204442054420644207442084420944210442114421244213442144421544216442174421844219442204422144222442234422444225442264422744228442294423044231442324423344234442354423644237442384423944240442414424244243442444424544246442474424844249442504425144252442534425444255442564425744258442594426044261442624426344264442654426644267442684426944270442714427244273442744427544276442774427844279442804428144282442834428444285442864428744288442894429044291442924429344294442954429644297442984429944300443014430244303443044430544306443074430844309443104431144312443134431444315443164431744318443194432044321443224432344324443254432644327443284432944330443314433244333443344433544336443374433844339443404434144342443434434444345443464434744348443494435044351443524435344354443554435644357443584435944360443614436244363443644436544366443674436844369443704437144372443734437444375443764437744378443794438044381443824438344384443854438644387443884438944390443914439244393443944439544396443974439844399444004440144402444034440444405444064440744408444094441044411444124441344414444154441644417444184441944420444214442244423444244442544426444274442844429444304443144432444334443444435444364443744438444394444044441444424444344444444454444644447444484444944450444514445244453444544445544456444574445844459444604446144462444634446444465444664446744468444694447044471444724447344474444754447644477444784447944480444814448244483444844448544486444874448844489444904449144492444934449444495444964449744498444994450044501445024450344504445054450644507445084450944510445114451244513445144451544516445174451844519445204452144522445234452444525445264452744528445294453044531445324453344534445354453644537445384453944540445414454244543445444454544546445474454844549445504455144552445534455444555445564455744558445594456044561445624456344564445654456644567445684456944570445714457244573445744457544576445774457844579445804458144582445834458444585445864458744588445894459044591445924459344594445954459644597445984459944600446014460244603446044460544606446074460844609446104461144612446134461444615446164461744618446194462044621446224462344624446254462644627446284462944630446314463244633446344463544636446374463844639446404464144642446434464444645446464464744648446494465044651446524465344654446554465644657446584465944660446614466244663446644466544666446674466844669446704467144672446734467444675446764467744678446794468044681446824468344684446854468644687446884468944690446914469244693446944469544696446974469844699447004470144702447034470444705447064470744708447094471044711447124471344714447154471644717447184471944720447214472244723447244472544726447274472844729447304473144732447334473444735447364473744738447394474044741447424474344744447454474644747447484474944750447514475244753447544475544756447574475844759447604476144762447634476444765447664476744768447694477044771447724477344774447754477644777447784477944780447814478244783447844478544786447874478844789447904479144792447934479444795447964479744798447994480044801448024480344804448054480644807448084480944810448114481244813448144481544816448174481844819448204482144822448234482444825448264482744828448294483044831448324483344834448354483644837448384483944840448414484244843448444484544846448474484844849448504485144852448534485444855448564485744858448594486044861448624486344864448654486644867448684486944870448714487244873448744487544876448774487844879448804488144882448834488444885448864488744888448894489044891448924489344894448954489644897448984489944900449014490244903449044490544906449074490844909449104491144912449134491444915449164491744918449194492044921449224492344924449254492644927449284492944930449314493244933449344493544936449374493844939449404494144942449434494444945449464494744948449494495044951449524495344954449554495644957449584495944960449614496244963449644496544966449674496844969449704497144972449734497444975449764497744978449794498044981449824498344984449854498644987449884498944990449914499244993449944499544996449974499844999450004500145002450034500445005450064500745008450094501045011450124501345014450154501645017450184501945020450214502245023450244502545026450274502845029450304503145032450334503445035450364503745038450394504045041450424504345044450454504645047450484504945050450514505245053450544505545056450574505845059450604506145062450634506445065450664506745068450694507045071450724507345074450754507645077450784507945080450814508245083450844508545086450874508845089450904509145092450934509445095450964509745098450994510045101451024510345104451054510645107451084510945110451114511245113451144511545116451174511845119451204512145122451234512445125451264512745128451294513045131451324513345134451354513645137451384513945140451414514245143451444514545146451474514845149451504515145152451534515445155451564515745158451594516045161451624516345164451654516645167451684516945170451714517245173451744517545176451774517845179451804518145182451834518445185451864518745188451894519045191451924519345194451954519645197451984519945200452014520245203452044520545206452074520845209452104521145212452134521445215452164521745218452194522045221452224522345224452254522645227452284522945230452314523245233452344523545236452374523845239452404524145242452434524445245452464524745248452494525045251452524525345254452554525645257452584525945260452614526245263452644526545266452674526845269452704527145272452734527445275452764527745278452794528045281452824528345284452854528645287452884528945290452914529245293452944529545296452974529845299453004530145302453034530445305453064530745308453094531045311453124531345314453154531645317453184531945320453214532245323453244532545326453274532845329453304533145332453334533445335453364533745338453394534045341453424534345344453454534645347453484534945350453514535245353453544535545356453574535845359453604536145362453634536445365453664536745368453694537045371453724537345374453754537645377453784537945380453814538245383453844538545386453874538845389453904539145392453934539445395453964539745398453994540045401454024540345404454054540645407454084540945410454114541245413454144541545416454174541845419454204542145422454234542445425454264542745428454294543045431454324543345434454354543645437454384543945440454414544245443454444544545446454474544845449454504545145452454534545445455454564545745458454594546045461454624546345464454654546645467454684546945470454714547245473454744547545476454774547845479454804548145482454834548445485454864548745488454894549045491454924549345494454954549645497454984549945500455014550245503455044550545506455074550845509455104551145512455134551445515455164551745518455194552045521455224552345524455254552645527455284552945530455314553245533455344553545536455374553845539455404554145542455434554445545455464554745548455494555045551455524555345554455554555645557455584555945560455614556245563455644556545566455674556845569455704557145572455734557445575455764557745578455794558045581455824558345584455854558645587455884558945590455914559245593455944559545596455974559845599456004560145602456034560445605456064560745608456094561045611456124561345614456154561645617456184561945620456214562245623456244562545626456274562845629456304563145632456334563445635456364563745638456394564045641456424564345644456454564645647456484564945650456514565245653456544565545656456574565845659456604566145662456634566445665456664566745668456694567045671456724567345674456754567645677456784567945680456814568245683456844568545686456874568845689456904569145692456934569445695456964569745698456994570045701457024570345704457054570645707457084570945710457114571245713457144571545716457174571845719457204572145722457234572445725457264572745728457294573045731457324573345734457354573645737457384573945740457414574245743457444574545746457474574845749457504575145752457534575445755457564575745758457594576045761457624576345764457654576645767457684576945770457714577245773457744577545776457774577845779457804578145782457834578445785457864578745788457894579045791457924579345794457954579645797457984579945800458014580245803458044580545806458074580845809458104581145812458134581445815458164581745818458194582045821458224582345824458254582645827458284582945830458314583245833458344583545836458374583845839458404584145842458434584445845458464584745848458494585045851458524585345854458554585645857458584585945860458614586245863458644586545866458674586845869458704587145872458734587445875458764587745878458794588045881458824588345884458854588645887458884588945890458914589245893458944589545896458974589845899459004590145902459034590445905459064590745908459094591045911459124591345914459154591645917459184591945920459214592245923459244592545926459274592845929459304593145932459334593445935459364593745938459394594045941459424594345944459454594645947459484594945950459514595245953459544595545956459574595845959459604596145962459634596445965459664596745968459694597045971459724597345974459754597645977459784597945980459814598245983459844598545986459874598845989459904599145992459934599445995459964599745998459994600046001460024600346004460054600646007460084600946010460114601246013460144601546016460174601846019460204602146022460234602446025460264602746028460294603046031460324603346034460354603646037460384603946040460414604246043460444604546046460474604846049460504605146052460534605446055460564605746058460594606046061460624606346064460654606646067460684606946070460714607246073460744607546076460774607846079460804608146082460834608446085460864608746088460894609046091460924609346094460954609646097460984609946100461014610246103461044610546106461074610846109461104611146112461134611446115461164611746118461194612046121461224612346124461254612646127461284612946130461314613246133461344613546136461374613846139461404614146142461434614446145461464614746148461494615046151461524615346154461554615646157461584615946160461614616246163461644616546166461674616846169461704617146172461734617446175461764617746178461794618046181461824618346184461854618646187461884618946190461914619246193461944619546196461974619846199462004620146202462034620446205462064620746208462094621046211462124621346214462154621646217462184621946220462214622246223462244622546226462274622846229462304623146232462334623446235462364623746238462394624046241462424624346244462454624646247462484624946250462514625246253462544625546256462574625846259462604626146262462634626446265462664626746268462694627046271462724627346274462754627646277462784627946280462814628246283462844628546286462874628846289462904629146292462934629446295462964629746298462994630046301463024630346304463054630646307463084630946310463114631246313463144631546316463174631846319463204632146322463234632446325463264632746328463294633046331463324633346334463354633646337463384633946340463414634246343463444634546346463474634846349463504635146352463534635446355463564635746358463594636046361463624636346364463654636646367463684636946370463714637246373463744637546376463774637846379463804638146382463834638446385463864638746388463894639046391463924639346394463954639646397463984639946400464014640246403464044640546406464074640846409464104641146412464134641446415464164641746418464194642046421464224642346424464254642646427464284642946430464314643246433464344643546436464374643846439464404644146442464434644446445464464644746448464494645046451464524645346454464554645646457464584645946460464614646246463464644646546466464674646846469464704647146472464734647446475464764647746478464794648046481464824648346484464854648646487464884648946490464914649246493464944649546496464974649846499465004650146502465034650446505465064650746508465094651046511465124651346514465154651646517465184651946520465214652246523465244652546526465274652846529465304653146532465334653446535465364653746538465394654046541465424654346544465454654646547465484654946550465514655246553465544655546556465574655846559465604656146562465634656446565465664656746568465694657046571465724657346574465754657646577465784657946580465814658246583465844658546586465874658846589465904659146592465934659446595465964659746598465994660046601466024660346604466054660646607466084660946610466114661246613466144661546616466174661846619466204662146622466234662446625466264662746628466294663046631466324663346634466354663646637466384663946640466414664246643466444664546646466474664846649466504665146652466534665446655466564665746658466594666046661466624666346664466654666646667466684666946670466714667246673466744667546676466774667846679466804668146682466834668446685466864668746688466894669046691466924669346694466954669646697466984669946700467014670246703467044670546706467074670846709467104671146712467134671446715467164671746718467194672046721467224672346724467254672646727467284672946730467314673246733467344673546736467374673846739467404674146742467434674446745467464674746748467494675046751467524675346754467554675646757467584675946760467614676246763467644676546766467674676846769467704677146772467734677446775467764677746778467794678046781467824678346784467854678646787467884678946790467914679246793467944679546796467974679846799468004680146802468034680446805468064680746808468094681046811468124681346814468154681646817468184681946820468214682246823468244682546826468274682846829468304683146832468334683446835468364683746838468394684046841468424684346844468454684646847468484684946850468514685246853468544685546856468574685846859468604686146862468634686446865468664686746868468694687046871468724687346874468754687646877468784687946880468814688246883468844688546886468874688846889468904689146892468934689446895468964689746898468994690046901469024690346904469054690646907469084690946910469114691246913469144691546916469174691846919469204692146922469234692446925469264692746928469294693046931469324693346934469354693646937469384693946940469414694246943469444694546946469474694846949469504695146952469534695446955469564695746958469594696046961469624696346964469654696646967469684696946970469714697246973469744697546976469774697846979469804698146982469834698446985469864698746988469894699046991469924699346994469954699646997469984699947000470014700247003470044700547006470074700847009470104701147012470134701447015470164701747018470194702047021470224702347024470254702647027470284702947030470314703247033470344703547036470374703847039470404704147042470434704447045470464704747048470494705047051470524705347054470554705647057470584705947060470614706247063470644706547066470674706847069470704707147072470734707447075470764707747078470794708047081470824708347084470854708647087470884708947090470914709247093470944709547096470974709847099471004710147102471034710447105471064710747108471094711047111471124711347114471154711647117471184711947120471214712247123471244712547126471274712847129471304713147132471334713447135471364713747138471394714047141471424714347144471454714647147471484714947150471514715247153471544715547156471574715847159471604716147162471634716447165471664716747168471694717047171471724717347174471754717647177471784717947180471814718247183471844718547186471874718847189471904719147192471934719447195471964719747198471994720047201472024720347204472054720647207472084720947210472114721247213472144721547216472174721847219472204722147222472234722447225472264722747228472294723047231472324723347234472354723647237472384723947240472414724247243472444724547246472474724847249472504725147252472534725447255472564725747258472594726047261472624726347264472654726647267472684726947270472714727247273472744727547276472774727847279472804728147282472834728447285472864728747288472894729047291472924729347294472954729647297472984729947300473014730247303473044730547306473074730847309473104731147312473134731447315473164731747318473194732047321473224732347324473254732647327473284732947330473314733247333473344733547336473374733847339473404734147342473434734447345473464734747348473494735047351473524735347354473554735647357473584735947360473614736247363473644736547366473674736847369473704737147372473734737447375473764737747378473794738047381473824738347384473854738647387473884738947390473914739247393473944739547396473974739847399474004740147402474034740447405474064740747408474094741047411474124741347414474154741647417474184741947420474214742247423474244742547426474274742847429474304743147432474334743447435474364743747438474394744047441474424744347444474454744647447474484744947450474514745247453474544745547456474574745847459474604746147462474634746447465474664746747468474694747047471474724747347474474754747647477474784747947480474814748247483474844748547486474874748847489474904749147492474934749447495474964749747498474994750047501475024750347504475054750647507475084750947510475114751247513475144751547516475174751847519475204752147522475234752447525475264752747528475294753047531475324753347534475354753647537475384753947540475414754247543475444754547546475474754847549475504755147552475534755447555475564755747558475594756047561475624756347564475654756647567475684756947570475714757247573475744757547576475774757847579475804758147582475834758447585475864758747588475894759047591475924759347594475954759647597475984759947600476014760247603476044760547606476074760847609476104761147612476134761447615476164761747618476194762047621476224762347624476254762647627476284762947630476314763247633476344763547636476374763847639476404764147642476434764447645476464764747648476494765047651476524765347654476554765647657476584765947660476614766247663476644766547666476674766847669476704767147672476734767447675476764767747678476794768047681476824768347684476854768647687476884768947690476914769247693476944769547696476974769847699477004770147702477034770447705477064770747708477094771047711477124771347714477154771647717477184771947720477214772247723477244772547726477274772847729477304773147732477334773447735477364773747738477394774047741477424774347744477454774647747477484774947750477514775247753477544775547756477574775847759477604776147762477634776447765477664776747768477694777047771477724777347774477754777647777477784777947780477814778247783477844778547786477874778847789477904779147792477934779447795477964779747798477994780047801478024780347804478054780647807478084780947810478114781247813478144781547816478174781847819478204782147822478234782447825478264782747828478294783047831478324783347834478354783647837478384783947840478414784247843478444784547846478474784847849478504785147852478534785447855478564785747858478594786047861478624786347864478654786647867478684786947870478714787247873478744787547876478774787847879478804788147882478834788447885478864788747888478894789047891478924789347894478954789647897478984789947900479014790247903479044790547906479074790847909479104791147912479134791447915479164791747918479194792047921479224792347924479254792647927479284792947930479314793247933479344793547936479374793847939479404794147942479434794447945479464794747948479494795047951479524795347954479554795647957479584795947960479614796247963479644796547966479674796847969479704797147972479734797447975479764797747978479794798047981479824798347984479854798647987479884798947990479914799247993479944799547996479974799847999480004800148002480034800448005480064800748008480094801048011480124801348014480154801648017480184801948020480214802248023480244802548026480274802848029480304803148032480334803448035480364803748038480394804048041480424804348044480454804648047480484804948050480514805248053480544805548056480574805848059480604806148062480634806448065480664806748068480694807048071480724807348074480754807648077480784807948080480814808248083480844808548086480874808848089480904809148092480934809448095480964809748098480994810048101481024810348104481054810648107481084810948110481114811248113481144811548116481174811848119481204812148122481234812448125481264812748128481294813048131481324813348134481354813648137481384813948140481414814248143481444814548146481474814848149481504815148152481534815448155481564815748158481594816048161481624816348164481654816648167481684816948170481714817248173481744817548176481774817848179481804818148182481834818448185481864818748188481894819048191481924819348194481954819648197481984819948200482014820248203482044820548206482074820848209482104821148212482134821448215482164821748218482194822048221482224822348224482254822648227482284822948230482314823248233482344823548236482374823848239482404824148242482434824448245482464824748248482494825048251482524825348254482554825648257482584825948260482614826248263482644826548266482674826848269482704827148272482734827448275482764827748278482794828048281482824828348284482854828648287482884828948290482914829248293482944829548296482974829848299483004830148302483034830448305483064830748308483094831048311483124831348314483154831648317483184831948320483214832248323483244832548326483274832848329483304833148332483334833448335483364833748338483394834048341483424834348344483454834648347483484834948350483514835248353483544835548356483574835848359483604836148362483634836448365483664836748368483694837048371483724837348374483754837648377483784837948380483814838248383483844838548386483874838848389483904839148392483934839448395483964839748398483994840048401484024840348404484054840648407484084840948410484114841248413484144841548416484174841848419484204842148422484234842448425484264842748428484294843048431484324843348434484354843648437484384843948440484414844248443484444844548446484474844848449484504845148452484534845448455484564845748458484594846048461484624846348464484654846648467484684846948470484714847248473484744847548476484774847848479484804848148482484834848448485484864848748488484894849048491484924849348494484954849648497484984849948500485014850248503485044850548506485074850848509485104851148512485134851448515485164851748518485194852048521485224852348524485254852648527485284852948530485314853248533485344853548536485374853848539485404854148542485434854448545485464854748548485494855048551485524855348554485554855648557485584855948560485614856248563485644856548566485674856848569485704857148572485734857448575485764857748578485794858048581485824858348584485854858648587485884858948590485914859248593485944859548596485974859848599486004860148602486034860448605486064860748608486094861048611486124861348614486154861648617486184861948620486214862248623486244862548626486274862848629486304863148632486334863448635486364863748638486394864048641486424864348644486454864648647486484864948650486514865248653486544865548656486574865848659486604866148662486634866448665486664866748668486694867048671486724867348674486754867648677486784867948680486814868248683486844868548686486874868848689486904869148692486934869448695486964869748698486994870048701487024870348704487054870648707487084870948710487114871248713487144871548716487174871848719487204872148722487234872448725487264872748728487294873048731487324873348734487354873648737487384873948740487414874248743487444874548746487474874848749487504875148752487534875448755487564875748758487594876048761487624876348764487654876648767487684876948770487714877248773487744877548776487774877848779487804878148782487834878448785487864878748788487894879048791487924879348794487954879648797487984879948800488014880248803488044880548806488074880848809488104881148812488134881448815488164881748818488194882048821488224882348824488254882648827488284882948830488314883248833488344883548836488374883848839488404884148842488434884448845488464884748848488494885048851488524885348854488554885648857488584885948860488614886248863488644886548866488674886848869488704887148872488734887448875488764887748878488794888048881488824888348884488854888648887488884888948890488914889248893488944889548896488974889848899489004890148902489034890448905489064890748908489094891048911489124891348914489154891648917489184891948920489214892248923489244892548926489274892848929489304893148932489334893448935489364893748938489394894048941489424894348944489454894648947489484894948950489514895248953489544895548956489574895848959489604896148962489634896448965489664896748968489694897048971489724897348974489754897648977489784897948980489814898248983489844898548986489874898848989489904899148992489934899448995489964899748998489994900049001490024900349004490054900649007490084900949010490114901249013490144901549016490174901849019490204902149022490234902449025490264902749028490294903049031490324903349034490354903649037490384903949040490414904249043490444904549046490474904849049490504905149052490534905449055490564905749058490594906049061490624906349064490654906649067490684906949070490714907249073490744907549076490774907849079490804908149082490834908449085490864908749088490894909049091490924909349094490954909649097490984909949100491014910249103491044910549106491074910849109491104911149112491134911449115491164911749118491194912049121491224912349124491254912649127491284912949130491314913249133491344913549136491374913849139491404914149142491434914449145491464914749148491494915049151491524915349154491554915649157491584915949160491614916249163491644916549166491674916849169491704917149172491734917449175491764917749178491794918049181491824918349184491854918649187491884918949190491914919249193491944919549196491974919849199492004920149202492034920449205492064920749208492094921049211492124921349214492154921649217492184921949220492214922249223492244922549226492274922849229492304923149232492334923449235492364923749238492394924049241492424924349244492454924649247492484924949250492514925249253492544925549256492574925849259492604926149262492634926449265492664926749268492694927049271492724927349274492754927649277492784927949280492814928249283492844928549286492874928849289492904929149292492934929449295492964929749298492994930049301493024930349304493054930649307493084930949310493114931249313493144931549316493174931849319493204932149322493234932449325493264932749328493294933049331493324933349334493354933649337493384933949340493414934249343493444934549346493474934849349493504935149352493534935449355493564935749358493594936049361493624936349364493654936649367493684936949370493714937249373493744937549376493774937849379493804938149382493834938449385493864938749388493894939049391493924939349394493954939649397493984939949400494014940249403494044940549406494074940849409494104941149412494134941449415494164941749418494194942049421494224942349424494254942649427494284942949430494314943249433494344943549436494374943849439494404944149442494434944449445494464944749448494494945049451494524945349454494554945649457494584945949460494614946249463494644946549466494674946849469494704947149472494734947449475494764947749478494794948049481494824948349484494854948649487494884948949490494914949249493494944949549496494974949849499495004950149502495034950449505495064950749508495094951049511495124951349514495154951649517495184951949520495214952249523495244952549526495274952849529495304953149532495334953449535495364953749538495394954049541495424954349544495454954649547495484954949550495514955249553495544955549556495574955849559495604956149562495634956449565495664956749568495694957049571495724957349574495754957649577495784957949580495814958249583495844958549586495874958849589495904959149592495934959449595495964959749598495994960049601496024960349604496054960649607496084960949610496114961249613496144961549616496174961849619496204962149622496234962449625496264962749628496294963049631496324963349634496354963649637496384963949640496414964249643496444964549646496474964849649496504965149652496534965449655496564965749658496594966049661496624966349664496654966649667496684966949670496714967249673496744967549676496774967849679496804968149682496834968449685496864968749688496894969049691496924969349694496954969649697496984969949700497014970249703497044970549706497074970849709497104971149712497134971449715497164971749718497194972049721497224972349724497254972649727497284972949730497314973249733497344973549736497374973849739497404974149742497434974449745497464974749748497494975049751497524975349754497554975649757497584975949760497614976249763497644976549766497674976849769497704977149772497734977449775497764977749778497794978049781497824978349784497854978649787497884978949790497914979249793497944979549796497974979849799498004980149802498034980449805498064980749808498094981049811498124981349814498154981649817498184981949820498214982249823498244982549826498274982849829498304983149832498334983449835498364983749838498394984049841498424984349844498454984649847498484984949850498514985249853498544985549856498574985849859498604986149862498634986449865498664986749868498694987049871498724987349874498754987649877498784987949880498814988249883498844988549886498874988849889498904989149892498934989449895498964989749898498994990049901499024990349904499054990649907499084990949910499114991249913499144991549916499174991849919499204992149922499234992449925499264992749928499294993049931499324993349934499354993649937499384993949940499414994249943499444994549946499474994849949499504995149952499534995449955499564995749958499594996049961499624996349964499654996649967499684996949970499714997249973499744997549976499774997849979499804998149982499834998449985499864998749988499894999049991499924999349994499954999649997499984999950000500015000250003500045000550006500075000850009500105001150012500135001450015500165001750018500195002050021500225002350024500255002650027500285002950030500315003250033500345003550036500375003850039500405004150042500435004450045500465004750048500495005050051500525005350054500555005650057500585005950060500615006250063500645006550066500675006850069500705007150072500735007450075500765007750078500795008050081500825008350084500855008650087500885008950090500915009250093500945009550096500975009850099501005010150102501035010450105501065010750108501095011050111501125011350114501155011650117501185011950120501215012250123501245012550126501275012850129501305013150132501335013450135501365013750138501395014050141501425014350144501455014650147501485014950150501515015250153501545015550156501575015850159501605016150162501635016450165501665016750168501695017050171501725017350174501755017650177501785017950180501815018250183501845018550186501875018850189501905019150192501935019450195501965019750198501995020050201502025020350204502055020650207502085020950210502115021250213502145021550216502175021850219502205022150222502235022450225502265022750228502295023050231502325023350234502355023650237502385023950240502415024250243502445024550246502475024850249502505025150252502535025450255502565025750258502595026050261502625026350264502655026650267502685026950270502715027250273502745027550276502775027850279502805028150282502835028450285502865028750288502895029050291502925029350294502955029650297502985029950300503015030250303503045030550306503075030850309503105031150312503135031450315503165031750318503195032050321503225032350324503255032650327503285032950330503315033250333503345033550336503375033850339503405034150342503435034450345503465034750348503495035050351503525035350354503555035650357503585035950360503615036250363503645036550366503675036850369503705037150372503735037450375503765037750378503795038050381503825038350384503855038650387503885038950390503915039250393503945039550396503975039850399504005040150402504035040450405504065040750408504095041050411504125041350414504155041650417504185041950420504215042250423504245042550426504275042850429504305043150432504335043450435504365043750438504395044050441504425044350444504455044650447504485044950450504515045250453504545045550456504575045850459504605046150462504635046450465504665046750468504695047050471504725047350474504755047650477504785047950480504815048250483504845048550486504875048850489504905049150492504935049450495504965049750498504995050050501505025050350504505055050650507505085050950510505115051250513505145051550516505175051850519505205052150522505235052450525505265052750528505295053050531505325053350534505355053650537505385053950540505415054250543505445054550546505475054850549505505055150552505535055450555505565055750558505595056050561505625056350564505655056650567505685056950570505715057250573505745057550576505775057850579505805058150582505835058450585505865058750588505895059050591505925059350594505955059650597505985059950600506015060250603506045060550606506075060850609506105061150612506135061450615506165061750618506195062050621506225062350624506255062650627506285062950630506315063250633506345063550636506375063850639506405064150642506435064450645506465064750648506495065050651506525065350654506555065650657506585065950660506615066250663506645066550666506675066850669506705067150672506735067450675506765067750678506795068050681506825068350684506855068650687506885068950690506915069250693506945069550696506975069850699507005070150702507035070450705507065070750708507095071050711507125071350714507155071650717507185071950720507215072250723507245072550726507275072850729507305073150732507335073450735507365073750738507395074050741507425074350744507455074650747507485074950750507515075250753507545075550756507575075850759507605076150762507635076450765507665076750768507695077050771507725077350774507755077650777507785077950780507815078250783507845078550786507875078850789507905079150792507935079450795507965079750798507995080050801508025080350804508055080650807508085080950810508115081250813508145081550816508175081850819508205082150822508235082450825508265082750828508295083050831508325083350834508355083650837508385083950840508415084250843508445084550846508475084850849508505085150852508535085450855508565085750858508595086050861508625086350864508655086650867508685086950870508715087250873508745087550876508775087850879508805088150882508835088450885508865088750888508895089050891508925089350894508955089650897508985089950900509015090250903509045090550906509075090850909509105091150912509135091450915509165091750918509195092050921509225092350924509255092650927509285092950930509315093250933509345093550936509375093850939509405094150942509435094450945509465094750948509495095050951509525095350954509555095650957509585095950960509615096250963509645096550966509675096850969509705097150972509735097450975509765097750978509795098050981509825098350984509855098650987509885098950990509915099250993509945099550996509975099850999510005100151002510035100451005510065100751008510095101051011510125101351014510155101651017510185101951020510215102251023510245102551026510275102851029510305103151032510335103451035510365103751038510395104051041510425104351044510455104651047510485104951050510515105251053510545105551056510575105851059510605106151062510635106451065510665106751068510695107051071510725107351074510755107651077510785107951080510815108251083510845108551086510875108851089510905109151092510935109451095510965109751098510995110051101511025110351104511055110651107511085110951110511115111251113511145111551116511175111851119511205112151122511235112451125511265112751128511295113051131511325113351134511355113651137511385113951140511415114251143511445114551146511475114851149511505115151152511535115451155511565115751158511595116051161511625116351164511655116651167511685116951170511715117251173511745117551176511775117851179511805118151182511835118451185511865118751188511895119051191511925119351194511955119651197511985119951200512015120251203512045120551206512075120851209512105121151212512135121451215512165121751218512195122051221512225122351224512255122651227512285122951230512315123251233512345123551236512375123851239512405124151242512435124451245512465124751248512495125051251512525125351254512555125651257512585125951260512615126251263512645126551266512675126851269512705127151272512735127451275512765127751278512795128051281512825128351284512855128651287512885128951290512915129251293512945129551296512975129851299513005130151302513035130451305513065130751308513095131051311513125131351314513155131651317513185131951320513215132251323513245132551326513275132851329513305133151332513335133451335513365133751338513395134051341513425134351344513455134651347513485134951350513515135251353513545135551356513575135851359513605136151362513635136451365513665136751368513695137051371513725137351374513755137651377513785137951380513815138251383513845138551386513875138851389513905139151392513935139451395513965139751398513995140051401514025140351404514055140651407514085140951410514115141251413514145141551416514175141851419514205142151422514235142451425514265142751428514295143051431514325143351434514355143651437514385143951440514415144251443514445144551446514475144851449514505145151452514535145451455514565145751458514595146051461514625146351464514655146651467514685146951470514715147251473514745147551476514775147851479514805148151482514835148451485514865148751488514895149051491514925149351494514955149651497514985149951500515015150251503515045150551506515075150851509515105151151512515135151451515515165151751518515195152051521515225152351524515255152651527515285152951530515315153251533515345153551536515375153851539515405154151542515435154451545515465154751548515495155051551515525155351554515555155651557515585155951560515615156251563515645156551566515675156851569515705157151572515735157451575515765157751578515795158051581515825158351584515855158651587515885158951590515915159251593515945159551596515975159851599516005160151602516035160451605516065160751608516095161051611516125161351614516155161651617516185161951620516215162251623516245162551626516275162851629516305163151632516335163451635516365163751638516395164051641516425164351644516455164651647516485164951650516515165251653516545165551656516575165851659516605166151662516635166451665516665166751668516695167051671516725167351674516755167651677516785167951680516815168251683516845168551686516875168851689516905169151692516935169451695516965169751698516995170051701517025170351704517055170651707517085170951710517115171251713517145171551716517175171851719517205172151722517235172451725517265172751728517295173051731517325173351734517355173651737517385173951740517415174251743517445174551746517475174851749517505175151752517535175451755517565175751758517595176051761517625176351764517655176651767517685176951770517715177251773517745177551776517775177851779517805178151782517835178451785517865178751788517895179051791517925179351794517955179651797517985179951800518015180251803518045180551806518075180851809518105181151812518135181451815518165181751818518195182051821518225182351824518255182651827518285182951830518315183251833518345183551836518375183851839518405184151842518435184451845518465184751848518495185051851518525185351854518555185651857518585185951860518615186251863518645186551866518675186851869518705187151872518735187451875518765187751878518795188051881518825188351884518855188651887518885188951890518915189251893518945189551896518975189851899519005190151902519035190451905519065190751908519095191051911519125191351914519155191651917519185191951920519215192251923519245192551926519275192851929519305193151932519335193451935519365193751938519395194051941519425194351944519455194651947519485194951950519515195251953519545195551956519575195851959519605196151962519635196451965519665196751968519695197051971519725197351974519755197651977519785197951980519815198251983519845198551986519875198851989519905199151992519935199451995519965199751998519995200052001520025200352004520055200652007520085200952010520115201252013520145201552016520175201852019520205202152022520235202452025520265202752028520295203052031520325203352034520355203652037520385203952040520415204252043520445204552046520475204852049520505205152052520535205452055520565205752058520595206052061520625206352064520655206652067520685206952070520715207252073520745207552076520775207852079520805208152082520835208452085520865208752088520895209052091520925209352094520955209652097520985209952100521015210252103521045210552106521075210852109521105211152112521135211452115521165211752118521195212052121521225212352124521255212652127521285212952130521315213252133521345213552136521375213852139521405214152142521435214452145521465214752148521495215052151521525215352154521555215652157521585215952160521615216252163521645216552166521675216852169521705217152172521735217452175521765217752178521795218052181521825218352184521855218652187521885218952190521915219252193521945219552196521975219852199522005220152202522035220452205522065220752208522095221052211522125221352214522155221652217522185221952220522215222252223522245222552226522275222852229522305223152232522335223452235522365223752238522395224052241522425224352244522455224652247522485224952250522515225252253522545225552256522575225852259522605226152262522635226452265522665226752268522695227052271522725227352274522755227652277522785227952280522815228252283522845228552286522875228852289522905229152292522935229452295522965229752298522995230052301523025230352304523055230652307523085230952310523115231252313523145231552316523175231852319523205232152322523235232452325523265232752328523295233052331523325233352334523355233652337523385233952340523415234252343523445234552346523475234852349523505235152352523535235452355523565235752358523595236052361523625236352364523655236652367523685236952370523715237252373523745237552376523775237852379523805238152382523835238452385523865238752388523895239052391523925239352394523955239652397523985239952400524015240252403524045240552406524075240852409524105241152412524135241452415524165241752418524195242052421524225242352424524255242652427524285242952430524315243252433524345243552436524375243852439524405244152442524435244452445524465244752448524495245052451524525245352454524555245652457524585245952460524615246252463524645246552466524675246852469524705247152472524735247452475524765247752478524795248052481524825248352484524855248652487524885248952490524915249252493524945249552496524975249852499525005250152502525035250452505525065250752508525095251052511525125251352514525155251652517525185251952520525215252252523525245252552526525275252852529525305253152532525335253452535525365253752538525395254052541525425254352544525455254652547525485254952550525515255252553525545255552556525575255852559525605256152562525635256452565525665256752568525695257052571525725257352574525755257652577525785257952580525815258252583525845258552586525875258852589525905259152592525935259452595525965259752598525995260052601526025260352604526055260652607526085260952610526115261252613526145261552616526175261852619526205262152622526235262452625526265262752628526295263052631526325263352634526355263652637526385263952640526415264252643526445264552646526475264852649526505265152652526535265452655526565265752658526595266052661526625266352664526655266652667526685266952670526715267252673526745267552676526775267852679526805268152682526835268452685526865268752688526895269052691526925269352694526955269652697526985269952700527015270252703527045270552706527075270852709527105271152712527135271452715527165271752718527195272052721527225272352724527255272652727527285272952730527315273252733527345273552736527375273852739527405274152742527435274452745527465274752748527495275052751527525275352754527555275652757527585275952760527615276252763527645276552766527675276852769527705277152772527735277452775527765277752778527795278052781527825278352784527855278652787527885278952790527915279252793527945279552796527975279852799528005280152802528035280452805528065280752808528095281052811528125281352814528155281652817528185281952820528215282252823528245282552826528275282852829528305283152832528335283452835528365283752838528395284052841528425284352844528455284652847528485284952850528515285252853528545285552856528575285852859528605286152862528635286452865528665286752868528695287052871528725287352874528755287652877528785287952880528815288252883528845288552886528875288852889528905289152892528935289452895528965289752898528995290052901529025290352904529055290652907529085290952910529115291252913529145291552916529175291852919529205292152922529235292452925529265292752928529295293052931529325293352934529355293652937529385293952940529415294252943529445294552946529475294852949529505295152952529535295452955529565295752958529595296052961529625296352964529655296652967529685296952970529715297252973529745297552976529775297852979529805298152982529835298452985529865298752988529895299052991529925299352994529955299652997529985299953000530015300253003530045300553006530075300853009530105301153012530135301453015530165301753018530195302053021530225302353024530255302653027530285302953030530315303253033530345303553036530375303853039530405304153042530435304453045530465304753048530495305053051530525305353054530555305653057530585305953060530615306253063530645306553066530675306853069530705307153072530735307453075530765307753078530795308053081530825308353084530855308653087530885308953090530915309253093530945309553096530975309853099531005310153102531035310453105531065310753108531095311053111531125311353114531155311653117531185311953120531215312253123531245312553126531275312853129531305313153132531335313453135531365313753138531395314053141531425314353144531455314653147531485314953150531515315253153531545315553156531575315853159531605316153162531635316453165531665316753168531695317053171531725317353174531755317653177531785317953180531815318253183531845318553186531875318853189531905319153192531935319453195531965319753198531995320053201532025320353204532055320653207532085320953210532115321253213532145321553216532175321853219532205322153222532235322453225532265322753228532295323053231532325323353234532355323653237532385323953240532415324253243532445324553246532475324853249532505325153252532535325453255532565325753258532595326053261532625326353264532655326653267532685326953270532715327253273532745327553276532775327853279532805328153282532835328453285532865328753288532895329053291532925329353294532955329653297532985329953300533015330253303533045330553306533075330853309533105331153312533135331453315533165331753318533195332053321533225332353324533255332653327533285332953330533315333253333533345333553336533375333853339533405334153342533435334453345533465334753348533495335053351533525335353354533555335653357533585335953360533615336253363533645336553366533675336853369533705337153372533735337453375533765337753378533795338053381533825338353384533855338653387533885338953390533915339253393533945339553396533975339853399534005340153402534035340453405534065340753408534095341053411534125341353414534155341653417534185341953420534215342253423534245342553426534275342853429534305343153432534335343453435534365343753438534395344053441534425344353444534455344653447534485344953450534515345253453534545345553456534575345853459534605346153462534635346453465534665346753468534695347053471534725347353474534755347653477534785347953480534815348253483534845348553486534875348853489534905349153492534935349453495534965349753498534995350053501535025350353504535055350653507535085350953510535115351253513535145351553516535175351853519535205352153522535235352453525535265352753528535295353053531535325353353534535355353653537535385353953540535415354253543535445354553546535475354853549535505355153552535535355453555535565355753558535595356053561535625356353564535655356653567535685356953570535715357253573535745357553576535775357853579535805358153582535835358453585535865358753588535895359053591535925359353594535955359653597535985359953600536015360253603536045360553606536075360853609536105361153612536135361453615536165361753618536195362053621536225362353624536255362653627536285362953630536315363253633536345363553636536375363853639536405364153642536435364453645536465364753648536495365053651536525365353654536555365653657536585365953660536615366253663536645366553666536675366853669536705367153672536735367453675536765367753678536795368053681536825368353684536855368653687536885368953690536915369253693536945369553696536975369853699537005370153702537035370453705537065370753708537095371053711537125371353714537155371653717537185371953720537215372253723537245372553726537275372853729537305373153732537335373453735537365373753738537395374053741537425374353744537455374653747537485374953750537515375253753537545375553756537575375853759537605376153762537635376453765537665376753768537695377053771537725377353774537755377653777537785377953780537815378253783537845378553786537875378853789537905379153792537935379453795537965379753798537995380053801538025380353804538055380653807538085380953810538115381253813538145381553816538175381853819538205382153822538235382453825538265382753828538295383053831538325383353834538355383653837538385383953840538415384253843538445384553846538475384853849538505385153852538535385453855538565385753858538595386053861538625386353864538655386653867538685386953870538715387253873538745387553876538775387853879538805388153882538835388453885538865388753888538895389053891538925389353894538955389653897538985389953900539015390253903539045390553906539075390853909539105391153912539135391453915539165391753918539195392053921539225392353924539255392653927539285392953930539315393253933539345393553936539375393853939539405394153942539435394453945539465394753948539495395053951539525395353954539555395653957539585395953960539615396253963539645396553966539675396853969539705397153972539735397453975539765397753978539795398053981539825398353984539855398653987539885398953990539915399253993539945399553996539975399853999540005400154002540035400454005540065400754008540095401054011540125401354014540155401654017540185401954020540215402254023540245402554026540275402854029540305403154032540335403454035540365403754038540395404054041540425404354044540455404654047540485404954050540515405254053540545405554056540575405854059540605406154062540635406454065540665406754068540695407054071540725407354074540755407654077540785407954080540815408254083540845408554086540875408854089540905409154092540935409454095540965409754098540995410054101541025410354104541055410654107541085410954110541115411254113541145411554116541175411854119541205412154122541235412454125541265412754128541295413054131541325413354134541355413654137541385413954140541415414254143541445414554146541475414854149541505415154152541535415454155541565415754158541595416054161541625416354164541655416654167541685416954170541715417254173541745417554176541775417854179541805418154182541835418454185541865418754188541895419054191541925419354194541955419654197541985419954200542015420254203542045420554206542075420854209542105421154212542135421454215542165421754218542195422054221542225422354224542255422654227542285422954230542315423254233542345423554236542375423854239542405424154242542435424454245542465424754248542495425054251542525425354254542555425654257542585425954260542615426254263542645426554266542675426854269542705427154272542735427454275542765427754278542795428054281542825428354284542855428654287542885428954290542915429254293542945429554296542975429854299543005430154302543035430454305543065430754308543095431054311543125431354314543155431654317543185431954320543215432254323543245432554326543275432854329543305433154332543335433454335543365433754338543395434054341543425434354344543455434654347543485434954350543515435254353543545435554356543575435854359543605436154362543635436454365543665436754368543695437054371543725437354374543755437654377543785437954380543815438254383543845438554386543875438854389543905439154392543935439454395543965439754398543995440054401544025440354404544055440654407544085440954410544115441254413544145441554416544175441854419544205442154422544235442454425544265442754428544295443054431544325443354434544355443654437544385443954440544415444254443544445444554446544475444854449544505445154452544535445454455544565445754458544595446054461544625446354464544655446654467544685446954470544715447254473544745447554476544775447854479544805448154482544835448454485544865448754488544895449054491544925449354494544955449654497544985449954500545015450254503545045450554506545075450854509545105451154512545135451454515545165451754518545195452054521545225452354524545255452654527545285452954530545315453254533545345453554536545375453854539545405454154542545435454454545545465454754548545495455054551545525455354554545555455654557545585455954560545615456254563545645456554566545675456854569545705457154572545735457454575545765457754578545795458054581545825458354584545855458654587545885458954590545915459254593545945459554596545975459854599546005460154602546035460454605546065460754608546095461054611546125461354614546155461654617546185461954620546215462254623546245462554626546275462854629546305463154632546335463454635546365463754638546395464054641546425464354644546455464654647546485464954650546515465254653546545465554656546575465854659546605466154662546635466454665546665466754668546695467054671546725467354674546755467654677546785467954680546815468254683546845468554686546875468854689546905469154692546935469454695546965469754698546995470054701547025470354704547055470654707547085470954710547115471254713547145471554716547175471854719547205472154722547235472454725547265472754728547295473054731547325473354734547355473654737547385473954740547415474254743547445474554746547475474854749547505475154752547535475454755547565475754758547595476054761547625476354764547655476654767547685476954770547715477254773547745477554776547775477854779547805478154782547835478454785547865478754788547895479054791547925479354794547955479654797547985479954800548015480254803548045480554806548075480854809548105481154812548135481454815548165481754818548195482054821548225482354824548255482654827548285482954830548315483254833548345483554836548375483854839548405484154842548435484454845548465484754848548495485054851548525485354854548555485654857548585485954860548615486254863548645486554866548675486854869548705487154872548735487454875548765487754878548795488054881548825488354884548855488654887548885488954890548915489254893548945489554896548975489854899549005490154902549035490454905549065490754908549095491054911549125491354914549155491654917549185491954920549215492254923549245492554926549275492854929549305493154932549335493454935549365493754938549395494054941549425494354944549455494654947549485494954950549515495254953549545495554956549575495854959549605496154962549635496454965549665496754968549695497054971549725497354974549755497654977549785497954980549815498254983549845498554986549875498854989549905499154992549935499454995549965499754998549995500055001550025500355004550055500655007550085500955010550115501255013550145501555016550175501855019550205502155022550235502455025550265502755028550295503055031550325503355034550355503655037550385503955040550415504255043550445504555046550475504855049550505505155052550535505455055550565505755058550595506055061550625506355064550655506655067550685506955070550715507255073550745507555076550775507855079550805508155082550835508455085550865508755088550895509055091550925509355094550955509655097550985509955100551015510255103551045510555106551075510855109551105511155112551135511455115551165511755118551195512055121551225512355124551255512655127551285512955130551315513255133551345513555136551375513855139551405514155142551435514455145551465514755148551495515055151551525515355154551555515655157551585515955160551615516255163551645516555166551675516855169551705517155172551735517455175551765517755178551795518055181551825518355184551855518655187551885518955190551915519255193551945519555196551975519855199552005520155202552035520455205552065520755208552095521055211552125521355214552155521655217552185521955220552215522255223552245522555226552275522855229552305523155232552335523455235552365523755238552395524055241552425524355244552455524655247552485524955250552515525255253552545525555256552575525855259552605526155262552635526455265552665526755268552695527055271552725527355274552755527655277552785527955280552815528255283552845528555286552875528855289552905529155292552935529455295552965529755298552995530055301553025530355304553055530655307553085530955310553115531255313553145531555316553175531855319553205532155322553235532455325553265532755328553295533055331553325533355334553355533655337553385533955340553415534255343553445534555346553475534855349553505535155352553535535455355553565535755358553595536055361553625536355364553655536655367553685536955370553715537255373553745537555376553775537855379553805538155382553835538455385553865538755388553895539055391553925539355394553955539655397553985539955400554015540255403554045540555406554075540855409554105541155412554135541455415554165541755418554195542055421554225542355424554255542655427554285542955430554315543255433554345543555436554375543855439554405544155442554435544455445554465544755448554495545055451554525545355454554555545655457554585545955460554615546255463554645546555466554675546855469554705547155472554735547455475554765547755478554795548055481554825548355484554855548655487554885548955490554915549255493554945549555496554975549855499555005550155502555035550455505555065550755508555095551055511555125551355514555155551655517555185551955520555215552255523555245552555526555275552855529555305553155532555335553455535555365553755538555395554055541555425554355544555455554655547555485554955550555515555255553555545555555556555575555855559555605556155562555635556455565555665556755568555695557055571555725557355574555755557655577555785557955580555815558255583555845558555586555875558855589555905559155592555935559455595555965559755598555995560055601556025560355604556055560655607556085560955610556115561255613556145561555616556175561855619556205562155622556235562455625556265562755628556295563055631556325563355634556355563655637556385563955640556415564255643556445564555646556475564855649556505565155652556535565455655556565565755658556595566055661556625566355664556655566655667556685566955670556715567255673556745567555676556775567855679556805568155682556835568455685556865568755688556895569055691556925569355694556955569655697556985569955700557015570255703557045570555706557075570855709557105571155712557135571455715557165571755718557195572055721557225572355724557255572655727557285572955730557315573255733557345573555736557375573855739557405574155742557435574455745557465574755748557495575055751557525575355754557555575655757557585575955760557615576255763557645576555766557675576855769557705577155772557735577455775557765577755778557795578055781557825578355784557855578655787557885578955790557915579255793557945579555796557975579855799558005580155802558035580455805558065580755808558095581055811558125581355814558155581655817558185581955820558215582255823558245582555826558275582855829558305583155832558335583455835558365583755838558395584055841558425584355844558455584655847558485584955850558515585255853558545585555856558575585855859558605586155862558635586455865558665586755868558695587055871558725587355874558755587655877558785587955880558815588255883558845588555886558875588855889558905589155892558935589455895558965589755898558995590055901559025590355904559055590655907559085590955910559115591255913559145591555916559175591855919559205592155922559235592455925559265592755928559295593055931559325593355934559355593655937559385593955940559415594255943559445594555946559475594855949559505595155952559535595455955559565595755958559595596055961559625596355964559655596655967559685596955970559715597255973559745597555976559775597855979559805598155982559835598455985559865598755988559895599055991559925599355994559955599655997559985599956000560015600256003560045600556006560075600856009560105601156012560135601456015560165601756018560195602056021560225602356024560255602656027560285602956030560315603256033560345603556036560375603856039560405604156042560435604456045560465604756048560495605056051560525605356054560555605656057560585605956060560615606256063560645606556066560675606856069560705607156072560735607456075560765607756078560795608056081560825608356084560855608656087560885608956090560915609256093560945609556096560975609856099561005610156102561035610456105561065610756108561095611056111561125611356114561155611656117561185611956120561215612256123561245612556126561275612856129561305613156132561335613456135561365613756138561395614056141561425614356144561455614656147561485614956150561515615256153561545615556156561575615856159561605616156162561635616456165561665616756168561695617056171561725617356174561755617656177561785617956180561815618256183561845618556186561875618856189561905619156192561935619456195561965619756198561995620056201562025620356204562055620656207562085620956210562115621256213562145621556216562175621856219562205622156222562235622456225562265622756228562295623056231562325623356234562355623656237562385623956240562415624256243562445624556246562475624856249562505625156252562535625456255562565625756258562595626056261562625626356264562655626656267562685626956270562715627256273562745627556276562775627856279562805628156282562835628456285562865628756288562895629056291562925629356294562955629656297562985629956300563015630256303563045630556306563075630856309563105631156312563135631456315563165631756318563195632056321563225632356324563255632656327563285632956330563315633256333563345633556336563375633856339563405634156342563435634456345563465634756348563495635056351563525635356354563555635656357563585635956360563615636256363563645636556366563675636856369563705637156372563735637456375563765637756378563795638056381563825638356384563855638656387563885638956390563915639256393563945639556396563975639856399564005640156402564035640456405564065640756408564095641056411564125641356414564155641656417564185641956420564215642256423564245642556426564275642856429564305643156432564335643456435564365643756438564395644056441564425644356444564455644656447564485644956450564515645256453564545645556456564575645856459564605646156462564635646456465564665646756468564695647056471564725647356474564755647656477564785647956480564815648256483564845648556486564875648856489564905649156492564935649456495564965649756498564995650056501565025650356504565055650656507565085650956510565115651256513565145651556516565175651856519565205652156522565235652456525565265652756528565295653056531565325653356534565355653656537565385653956540565415654256543565445654556546565475654856549565505655156552565535655456555565565655756558565595656056561565625656356564565655656656567565685656956570565715657256573565745657556576565775657856579565805658156582565835658456585565865658756588565895659056591565925659356594565955659656597565985659956600566015660256603566045660556606566075660856609566105661156612566135661456615566165661756618566195662056621566225662356624566255662656627566285662956630566315663256633566345663556636566375663856639566405664156642566435664456645566465664756648566495665056651566525665356654566555665656657566585665956660566615666256663566645666556666566675666856669566705667156672566735667456675566765667756678566795668056681566825668356684566855668656687566885668956690566915669256693566945669556696566975669856699567005670156702567035670456705567065670756708567095671056711567125671356714567155671656717567185671956720567215672256723567245672556726567275672856729567305673156732567335673456735567365673756738567395674056741567425674356744567455674656747567485674956750567515675256753567545675556756567575675856759567605676156762567635676456765567665676756768567695677056771567725677356774567755677656777567785677956780567815678256783567845678556786567875678856789567905679156792567935679456795567965679756798567995680056801568025680356804568055680656807568085680956810568115681256813568145681556816568175681856819568205682156822568235682456825568265682756828568295683056831568325683356834568355683656837568385683956840568415684256843568445684556846568475684856849568505685156852568535685456855568565685756858568595686056861568625686356864568655686656867568685686956870568715687256873568745687556876568775687856879568805688156882568835688456885568865688756888568895689056891568925689356894568955689656897568985689956900569015690256903569045690556906569075690856909569105691156912569135691456915569165691756918569195692056921569225692356924569255692656927569285692956930569315693256933569345693556936569375693856939569405694156942569435694456945569465694756948569495695056951569525695356954569555695656957569585695956960569615696256963569645696556966569675696856969569705697156972569735697456975569765697756978569795698056981569825698356984569855698656987569885698956990569915699256993569945699556996569975699856999570005700157002570035700457005570065700757008570095701057011570125701357014570155701657017570185701957020570215702257023570245702557026570275702857029570305703157032570335703457035570365703757038570395704057041570425704357044570455704657047570485704957050570515705257053570545705557056570575705857059570605706157062570635706457065570665706757068570695707057071570725707357074570755707657077570785707957080570815708257083570845708557086570875708857089570905709157092570935709457095570965709757098570995710057101571025710357104571055710657107571085710957110571115711257113571145711557116571175711857119571205712157122571235712457125571265712757128571295713057131571325713357134571355713657137571385713957140571415714257143571445714557146571475714857149571505715157152571535715457155571565715757158571595716057161571625716357164571655716657167571685716957170571715717257173571745717557176571775717857179571805718157182571835718457185571865718757188571895719057191571925719357194571955719657197571985719957200572015720257203572045720557206572075720857209572105721157212572135721457215572165721757218572195722057221572225722357224572255722657227572285722957230572315723257233572345723557236572375723857239572405724157242572435724457245572465724757248572495725057251572525725357254572555725657257572585725957260572615726257263572645726557266572675726857269572705727157272572735727457275572765727757278572795728057281572825728357284572855728657287572885728957290572915729257293572945729557296572975729857299573005730157302573035730457305573065730757308573095731057311573125731357314573155731657317573185731957320573215732257323573245732557326573275732857329573305733157332573335733457335573365733757338573395734057341573425734357344573455734657347573485734957350573515735257353573545735557356573575735857359573605736157362573635736457365573665736757368573695737057371573725737357374573755737657377573785737957380573815738257383573845738557386573875738857389573905739157392573935739457395573965739757398573995740057401574025740357404574055740657407574085740957410574115741257413574145741557416574175741857419574205742157422574235742457425574265742757428574295743057431574325743357434574355743657437574385743957440574415744257443574445744557446574475744857449574505745157452574535745457455574565745757458574595746057461574625746357464574655746657467574685746957470574715747257473574745747557476574775747857479574805748157482574835748457485574865748757488574895749057491574925749357494574955749657497574985749957500575015750257503575045750557506575075750857509575105751157512575135751457515575165751757518575195752057521575225752357524575255752657527575285752957530575315753257533575345753557536575375753857539575405754157542575435754457545575465754757548575495755057551575525755357554575555755657557575585755957560575615756257563575645756557566575675756857569575705757157572575735757457575575765757757578575795758057581575825758357584575855758657587575885758957590575915759257593575945759557596575975759857599576005760157602576035760457605576065760757608576095761057611576125761357614576155761657617576185761957620576215762257623576245762557626576275762857629576305763157632576335763457635576365763757638576395764057641576425764357644576455764657647576485764957650576515765257653576545765557656576575765857659576605766157662576635766457665576665766757668576695767057671576725767357674576755767657677576785767957680576815768257683576845768557686576875768857689576905769157692576935769457695576965769757698576995770057701577025770357704577055770657707577085770957710577115771257713577145771557716577175771857719577205772157722577235772457725577265772757728577295773057731577325773357734577355773657737577385773957740577415774257743577445774557746577475774857749577505775157752577535775457755577565775757758577595776057761577625776357764577655776657767577685776957770577715777257773577745777557776577775777857779577805778157782577835778457785577865778757788577895779057791577925779357794577955779657797577985779957800578015780257803578045780557806578075780857809578105781157812578135781457815578165781757818578195782057821578225782357824578255782657827578285782957830578315783257833578345783557836578375783857839578405784157842578435784457845578465784757848578495785057851578525785357854578555785657857578585785957860578615786257863578645786557866578675786857869578705787157872578735787457875578765787757878578795788057881578825788357884578855788657887578885788957890578915789257893578945789557896578975789857899579005790157902579035790457905579065790757908579095791057911579125791357914579155791657917579185791957920579215792257923579245792557926579275792857929579305793157932579335793457935579365793757938579395794057941579425794357944579455794657947579485794957950579515795257953579545795557956579575795857959579605796157962579635796457965579665796757968579695797057971579725797357974579755797657977579785797957980579815798257983579845798557986579875798857989579905799157992579935799457995579965799757998579995800058001580025800358004580055800658007580085800958010580115801258013580145801558016580175801858019580205802158022580235802458025580265802758028580295803058031580325803358034580355803658037580385803958040580415804258043580445804558046580475804858049580505805158052580535805458055580565805758058580595806058061580625806358064580655806658067580685806958070580715807258073580745807558076580775807858079580805808158082580835808458085580865808758088580895809058091580925809358094580955809658097580985809958100581015810258103581045810558106581075810858109581105811158112581135811458115581165811758118581195812058121581225812358124581255812658127581285812958130581315813258133581345813558136581375813858139581405814158142581435814458145581465814758148581495815058151581525815358154581555815658157581585815958160581615816258163581645816558166581675816858169581705817158172581735817458175581765817758178581795818058181581825818358184581855818658187581885818958190581915819258193581945819558196581975819858199582005820158202582035820458205582065820758208582095821058211582125821358214582155821658217582185821958220582215822258223582245822558226582275822858229582305823158232582335823458235582365823758238582395824058241582425824358244582455824658247582485824958250582515825258253582545825558256582575825858259582605826158262582635826458265582665826758268582695827058271582725827358274582755827658277582785827958280582815828258283582845828558286582875828858289582905829158292582935829458295582965829758298582995830058301583025830358304583055830658307583085830958310583115831258313583145831558316583175831858319583205832158322583235832458325583265832758328583295833058331583325833358334583355833658337583385833958340583415834258343583445834558346583475834858349583505835158352583535835458355583565835758358583595836058361583625836358364583655836658367583685836958370583715837258373583745837558376583775837858379583805838158382583835838458385583865838758388583895839058391583925839358394583955839658397583985839958400584015840258403584045840558406584075840858409584105841158412584135841458415584165841758418584195842058421584225842358424584255842658427584285842958430584315843258433584345843558436584375843858439584405844158442584435844458445584465844758448584495845058451584525845358454584555845658457584585845958460584615846258463584645846558466584675846858469584705847158472584735847458475584765847758478584795848058481584825848358484584855848658487584885848958490584915849258493584945849558496584975849858499585005850158502585035850458505585065850758508585095851058511585125851358514585155851658517585185851958520585215852258523585245852558526585275852858529585305853158532585335853458535585365853758538585395854058541585425854358544585455854658547585485854958550585515855258553585545855558556585575855858559585605856158562585635856458565585665856758568585695857058571585725857358574585755857658577585785857958580585815858258583585845858558586585875858858589585905859158592585935859458595585965859758598585995860058601586025860358604586055860658607586085860958610586115861258613586145861558616586175861858619586205862158622586235862458625586265862758628586295863058631586325863358634586355863658637586385863958640586415864258643586445864558646586475864858649586505865158652586535865458655586565865758658586595866058661586625866358664586655866658667586685866958670586715867258673586745867558676586775867858679586805868158682586835868458685586865868758688586895869058691586925869358694586955869658697586985869958700587015870258703587045870558706587075870858709587105871158712587135871458715587165871758718587195872058721587225872358724587255872658727587285872958730587315873258733587345873558736587375873858739587405874158742587435874458745587465874758748587495875058751587525875358754587555875658757587585875958760587615876258763587645876558766587675876858769587705877158772587735877458775587765877758778587795878058781587825878358784587855878658787587885878958790587915879258793587945879558796587975879858799588005880158802588035880458805588065880758808588095881058811588125881358814588155881658817588185881958820588215882258823588245882558826588275882858829588305883158832588335883458835588365883758838588395884058841588425884358844588455884658847588485884958850588515885258853588545885558856588575885858859588605886158862588635886458865588665886758868588695887058871588725887358874588755887658877588785887958880588815888258883588845888558886588875888858889588905889158892588935889458895588965889758898588995890058901589025890358904589055890658907589085890958910589115891258913589145891558916589175891858919589205892158922589235892458925589265892758928589295893058931589325893358934589355893658937589385893958940589415894258943589445894558946589475894858949589505895158952589535895458955589565895758958589595896058961589625896358964589655896658967589685896958970589715897258973589745897558976589775897858979589805898158982589835898458985589865898758988589895899058991589925899358994589955899658997589985899959000590015900259003590045900559006590075900859009590105901159012590135901459015590165901759018590195902059021590225902359024590255902659027590285902959030590315903259033590345903559036590375903859039590405904159042590435904459045590465904759048590495905059051590525905359054590555905659057590585905959060590615906259063590645906559066590675906859069590705907159072590735907459075590765907759078590795908059081590825908359084590855908659087590885908959090590915909259093590945909559096590975909859099591005910159102591035910459105591065910759108591095911059111591125911359114591155911659117591185911959120591215912259123591245912559126591275912859129591305913159132591335913459135591365913759138591395914059141591425914359144591455914659147591485914959150591515915259153591545915559156591575915859159591605916159162591635916459165591665916759168591695917059171591725917359174591755917659177591785917959180591815918259183591845918559186591875918859189591905919159192591935919459195591965919759198591995920059201592025920359204592055920659207592085920959210592115921259213592145921559216592175921859219592205922159222592235922459225592265922759228592295923059231592325923359234592355923659237592385923959240592415924259243592445924559246592475924859249592505925159252592535925459255592565925759258592595926059261592625926359264592655926659267592685926959270592715927259273592745927559276592775927859279592805928159282592835928459285592865928759288592895929059291592925929359294592955929659297592985929959300593015930259303593045930559306593075930859309593105931159312593135931459315593165931759318593195932059321593225932359324593255932659327593285932959330593315933259333593345933559336593375933859339593405934159342593435934459345593465934759348593495935059351593525935359354593555935659357593585935959360593615936259363593645936559366593675936859369593705937159372593735937459375593765937759378593795938059381593825938359384593855938659387593885938959390593915939259393593945939559396593975939859399594005940159402594035940459405594065940759408594095941059411594125941359414594155941659417594185941959420594215942259423594245942559426594275942859429594305943159432594335943459435594365943759438594395944059441594425944359444594455944659447594485944959450594515945259453594545945559456594575945859459594605946159462594635946459465594665946759468594695947059471594725947359474594755947659477594785947959480594815948259483594845948559486594875948859489594905949159492594935949459495594965949759498594995950059501595025950359504595055950659507595085950959510595115951259513595145951559516595175951859519595205952159522595235952459525595265952759528595295953059531595325953359534595355953659537595385953959540595415954259543595445954559546595475954859549595505955159552595535955459555595565955759558595595956059561595625956359564595655956659567595685956959570595715957259573595745957559576595775957859579595805958159582595835958459585595865958759588595895959059591595925959359594595955959659597595985959959600596015960259603596045960559606596075960859609596105961159612596135961459615596165961759618596195962059621596225962359624596255962659627596285962959630596315963259633596345963559636596375963859639596405964159642596435964459645596465964759648596495965059651596525965359654596555965659657596585965959660596615966259663596645966559666596675966859669596705967159672596735967459675596765967759678596795968059681596825968359684596855968659687596885968959690596915969259693596945969559696596975969859699597005970159702597035970459705597065970759708597095971059711597125971359714597155971659717597185971959720597215972259723597245972559726597275972859729597305973159732597335973459735597365973759738597395974059741597425974359744597455974659747597485974959750597515975259753597545975559756597575975859759597605976159762597635976459765597665976759768597695977059771597725977359774597755977659777597785977959780597815978259783597845978559786597875978859789597905979159792597935979459795597965979759798597995980059801598025980359804598055980659807598085980959810598115981259813598145981559816598175981859819598205982159822598235982459825598265982759828598295983059831598325983359834598355983659837598385983959840598415984259843598445984559846598475984859849598505985159852598535985459855598565985759858598595986059861598625986359864598655986659867598685986959870598715987259873598745987559876598775987859879598805988159882598835988459885598865988759888598895989059891598925989359894598955989659897598985989959900599015990259903599045990559906599075990859909599105991159912599135991459915599165991759918599195992059921599225992359924599255992659927599285992959930599315993259933599345993559936599375993859939599405994159942599435994459945599465994759948599495995059951599525995359954599555995659957599585995959960599615996259963599645996559966599675996859969599705997159972599735997459975599765997759978599795998059981599825998359984599855998659987599885998959990599915999259993599945999559996599975999859999600006000160002600036000460005600066000760008600096001060011600126001360014600156001660017600186001960020600216002260023600246002560026600276002860029600306003160032600336003460035600366003760038600396004060041600426004360044600456004660047600486004960050600516005260053600546005560056600576005860059600606006160062600636006460065600666006760068600696007060071600726007360074600756007660077600786007960080600816008260083600846008560086600876008860089600906009160092600936009460095600966009760098600996010060101601026010360104601056010660107601086010960110601116011260113601146011560116601176011860119601206012160122601236012460125601266012760128601296013060131601326013360134601356013660137601386013960140601416014260143601446014560146601476014860149601506015160152601536015460155601566015760158601596016060161601626016360164601656016660167601686016960170601716017260173601746017560176601776017860179601806018160182601836018460185601866018760188601896019060191601926019360194601956019660197601986019960200602016020260203602046020560206602076020860209602106021160212602136021460215602166021760218602196022060221602226022360224602256022660227602286022960230602316023260233602346023560236602376023860239602406024160242602436024460245602466024760248602496025060251602526025360254602556025660257602586025960260602616026260263602646026560266602676026860269602706027160272602736027460275602766027760278602796028060281602826028360284602856028660287602886028960290602916029260293602946029560296602976029860299603006030160302603036030460305603066030760308603096031060311603126031360314603156031660317603186031960320603216032260323603246032560326603276032860329603306033160332603336033460335603366033760338603396034060341603426034360344603456034660347603486034960350603516035260353603546035560356603576035860359603606036160362603636036460365603666036760368603696037060371603726037360374603756037660377603786037960380603816038260383603846038560386603876038860389603906039160392603936039460395603966039760398603996040060401604026040360404604056040660407604086040960410604116041260413604146041560416604176041860419604206042160422604236042460425604266042760428604296043060431604326043360434604356043660437604386043960440604416044260443604446044560446604476044860449604506045160452604536045460455604566045760458604596046060461604626046360464604656046660467604686046960470604716047260473604746047560476604776047860479604806048160482604836048460485604866048760488604896049060491604926049360494604956049660497604986049960500605016050260503605046050560506605076050860509605106051160512605136051460515605166051760518605196052060521605226052360524605256052660527605286052960530605316053260533605346053560536605376053860539605406054160542605436054460545605466054760548605496055060551605526055360554605556055660557605586055960560605616056260563605646056560566605676056860569605706057160572605736057460575605766057760578605796058060581605826058360584605856058660587605886058960590605916059260593605946059560596605976059860599606006060160602606036060460605606066060760608606096061060611606126061360614606156061660617606186061960620606216062260623606246062560626606276062860629606306063160632606336063460635606366063760638606396064060641606426064360644606456064660647606486064960650606516065260653606546065560656606576065860659606606066160662606636066460665606666066760668606696067060671606726067360674606756067660677606786067960680606816068260683606846068560686606876068860689606906069160692606936069460695606966069760698606996070060701607026070360704607056070660707607086070960710607116071260713607146071560716607176071860719607206072160722607236072460725607266072760728607296073060731607326073360734607356073660737607386073960740607416074260743607446074560746607476074860749607506075160752607536075460755607566075760758607596076060761607626076360764607656076660767607686076960770607716077260773607746077560776607776077860779607806078160782607836078460785607866078760788607896079060791607926079360794607956079660797607986079960800608016080260803608046080560806608076080860809608106081160812608136081460815608166081760818608196082060821608226082360824608256082660827608286082960830608316083260833608346083560836608376083860839608406084160842608436084460845608466084760848608496085060851608526085360854608556085660857608586085960860608616086260863608646086560866608676086860869608706087160872608736087460875608766087760878608796088060881608826088360884608856088660887608886088960890608916089260893608946089560896608976089860899609006090160902609036090460905609066090760908609096091060911609126091360914609156091660917609186091960920609216092260923609246092560926609276092860929609306093160932609336093460935609366093760938609396094060941609426094360944609456094660947609486094960950609516095260953609546095560956609576095860959609606096160962609636096460965609666096760968609696097060971609726097360974609756097660977609786097960980609816098260983609846098560986609876098860989609906099160992609936099460995609966099760998609996100061001610026100361004610056100661007610086100961010610116101261013610146101561016610176101861019610206102161022610236102461025610266102761028610296103061031610326103361034610356103661037610386103961040610416104261043610446104561046610476104861049610506105161052610536105461055610566105761058610596106061061610626106361064610656106661067610686106961070610716107261073610746107561076610776107861079610806108161082610836108461085610866108761088610896109061091610926109361094610956109661097610986109961100611016110261103611046110561106611076110861109611106111161112611136111461115611166111761118611196112061121611226112361124611256112661127611286112961130611316113261133611346113561136611376113861139611406114161142611436114461145611466114761148611496115061151611526115361154611556115661157611586115961160611616116261163611646116561166611676116861169611706117161172611736117461175611766117761178611796118061181611826118361184611856118661187611886118961190611916119261193611946119561196611976119861199612006120161202612036120461205612066120761208612096121061211612126121361214612156121661217612186121961220612216122261223612246122561226612276122861229612306123161232612336123461235612366123761238612396124061241612426124361244612456124661247612486124961250612516125261253612546125561256612576125861259612606126161262612636126461265612666126761268612696127061271612726127361274612756127661277612786127961280612816128261283612846128561286612876128861289612906129161292612936129461295612966129761298612996130061301613026130361304613056130661307613086130961310613116131261313613146131561316613176131861319613206132161322613236132461325613266132761328613296133061331613326133361334613356133661337613386133961340613416134261343613446134561346613476134861349613506135161352613536135461355613566135761358613596136061361613626136361364613656136661367613686136961370613716137261373613746137561376613776137861379613806138161382613836138461385613866138761388613896139061391613926139361394613956139661397613986139961400614016140261403614046140561406614076140861409614106141161412614136141461415614166141761418614196142061421614226142361424614256142661427614286142961430614316143261433614346143561436614376143861439614406144161442614436144461445614466144761448614496145061451614526145361454614556145661457614586145961460614616146261463614646146561466614676146861469614706147161472614736147461475614766147761478614796148061481614826148361484614856148661487614886148961490614916149261493614946149561496614976149861499615006150161502615036150461505615066150761508615096151061511615126151361514615156151661517615186151961520615216152261523615246152561526615276152861529615306153161532615336153461535615366153761538615396154061541615426154361544615456154661547615486154961550615516155261553615546155561556615576155861559615606156161562615636156461565615666156761568615696157061571615726157361574615756157661577615786157961580615816158261583615846158561586615876158861589615906159161592615936159461595615966159761598615996160061601616026160361604616056160661607616086160961610616116161261613616146161561616616176161861619616206162161622616236162461625616266162761628616296163061631616326163361634616356163661637616386163961640616416164261643616446164561646616476164861649616506165161652616536165461655616566165761658616596166061661616626166361664616656166661667616686166961670616716167261673616746167561676616776167861679616806168161682616836168461685616866168761688616896169061691616926169361694616956169661697616986169961700617016170261703617046170561706617076170861709617106171161712617136171461715617166171761718617196172061721617226172361724617256172661727617286172961730617316173261733617346173561736617376173861739617406174161742617436174461745617466174761748617496175061751617526175361754617556175661757617586175961760617616176261763617646176561766617676176861769617706177161772617736177461775617766177761778617796178061781617826178361784617856178661787617886178961790617916179261793617946179561796617976179861799618006180161802618036180461805618066180761808618096181061811618126181361814618156181661817618186181961820618216182261823618246182561826618276182861829618306183161832618336183461835618366183761838618396184061841618426184361844618456184661847618486184961850618516185261853618546185561856618576185861859618606186161862618636186461865618666186761868618696187061871618726187361874618756187661877618786187961880618816188261883618846188561886618876188861889618906189161892618936189461895618966189761898618996190061901619026190361904619056190661907619086190961910619116191261913619146191561916619176191861919619206192161922619236192461925619266192761928619296193061931619326193361934619356193661937619386193961940619416194261943619446194561946619476194861949619506195161952619536195461955619566195761958619596196061961619626196361964619656196661967619686196961970619716197261973619746197561976619776197861979619806198161982619836198461985619866198761988619896199061991619926199361994619956199661997619986199962000620016200262003620046200562006620076200862009620106201162012620136201462015620166201762018620196202062021620226202362024620256202662027620286202962030620316203262033620346203562036620376203862039620406204162042620436204462045620466204762048620496205062051620526205362054620556205662057620586205962060620616206262063620646206562066620676206862069620706207162072620736207462075620766207762078620796208062081620826208362084620856208662087620886208962090620916209262093620946209562096620976209862099621006210162102621036210462105621066210762108621096211062111621126211362114621156211662117621186211962120621216212262123621246212562126621276212862129621306213162132621336213462135621366213762138621396214062141621426214362144621456214662147621486214962150621516215262153621546215562156621576215862159621606216162162621636216462165621666216762168621696217062171621726217362174621756217662177621786217962180621816218262183621846218562186621876218862189621906219162192621936219462195621966219762198621996220062201622026220362204622056220662207622086220962210622116221262213622146221562216622176221862219622206222162222622236222462225622266222762228622296223062231622326223362234622356223662237622386223962240622416224262243622446224562246622476224862249622506225162252622536225462255622566225762258622596226062261622626226362264622656226662267622686226962270622716227262273622746227562276622776227862279622806228162282622836228462285622866228762288622896229062291622926229362294622956229662297622986229962300623016230262303623046230562306623076230862309623106231162312623136231462315623166231762318623196232062321623226232362324623256232662327623286232962330623316233262333623346233562336623376233862339623406234162342623436234462345623466234762348623496235062351623526235362354623556235662357623586235962360623616236262363623646236562366623676236862369623706237162372623736237462375623766237762378623796238062381623826238362384623856238662387623886238962390623916239262393623946239562396623976239862399624006240162402624036240462405624066240762408624096241062411624126241362414624156241662417624186241962420624216242262423624246242562426624276242862429624306243162432624336243462435624366243762438624396244062441624426244362444624456244662447624486244962450624516245262453624546245562456624576245862459624606246162462624636246462465624666246762468624696247062471624726247362474624756247662477624786247962480624816248262483624846248562486624876248862489624906249162492624936249462495624966249762498624996250062501625026250362504625056250662507625086250962510625116251262513625146251562516625176251862519625206252162522625236252462525625266252762528625296253062531625326253362534625356253662537625386253962540625416254262543625446254562546625476254862549625506255162552625536255462555625566255762558625596256062561625626256362564625656256662567625686256962570625716257262573625746257562576625776257862579625806258162582625836258462585625866258762588625896259062591625926259362594625956259662597625986259962600626016260262603626046260562606626076260862609626106261162612626136261462615626166261762618626196262062621626226262362624626256262662627626286262962630626316263262633626346263562636626376263862639626406264162642626436264462645626466264762648626496265062651626526265362654626556265662657626586265962660626616266262663626646266562666626676266862669626706267162672626736267462675626766267762678626796268062681626826268362684626856268662687626886268962690626916269262693626946269562696626976269862699627006270162702627036270462705627066270762708627096271062711627126271362714627156271662717627186271962720627216272262723627246272562726627276272862729627306273162732627336273462735627366273762738627396274062741627426274362744627456274662747627486274962750627516275262753627546275562756627576275862759627606276162762627636276462765627666276762768627696277062771627726277362774627756277662777627786277962780627816278262783627846278562786627876278862789627906279162792627936279462795627966279762798627996280062801628026280362804628056280662807628086280962810628116281262813628146281562816628176281862819628206282162822628236282462825628266282762828628296283062831628326283362834628356283662837628386283962840628416284262843628446284562846628476284862849628506285162852628536285462855628566285762858628596286062861628626286362864628656286662867628686286962870628716287262873628746287562876628776287862879628806288162882628836288462885628866288762888628896289062891628926289362894628956289662897628986289962900629016290262903629046290562906629076290862909629106291162912629136291462915629166291762918629196292062921629226292362924629256292662927629286292962930629316293262933629346293562936629376293862939629406294162942629436294462945629466294762948629496295062951629526295362954629556295662957629586295962960629616296262963629646296562966629676296862969629706297162972629736297462975629766297762978629796298062981629826298362984629856298662987629886298962990629916299262993629946299562996629976299862999630006300163002630036300463005630066300763008630096301063011630126301363014630156301663017630186301963020630216302263023630246302563026630276302863029630306303163032630336303463035630366303763038630396304063041630426304363044630456304663047630486304963050630516305263053630546305563056630576305863059630606306163062630636306463065630666306763068630696307063071630726307363074630756307663077630786307963080630816308263083630846308563086630876308863089630906309163092630936309463095630966309763098630996310063101631026310363104631056310663107631086310963110631116311263113631146311563116631176311863119631206312163122631236312463125631266312763128631296313063131631326313363134631356313663137631386313963140631416314263143631446314563146631476314863149631506315163152631536315463155631566315763158631596316063161631626316363164631656316663167631686316963170631716317263173631746317563176631776317863179631806318163182631836318463185631866318763188631896319063191631926319363194631956319663197631986319963200632016320263203632046320563206632076320863209632106321163212632136321463215632166321763218632196322063221632226322363224632256322663227632286322963230632316323263233632346323563236632376323863239632406324163242632436324463245632466324763248632496325063251632526325363254632556325663257632586325963260632616326263263632646326563266632676326863269632706327163272632736327463275632766327763278632796328063281632826328363284632856328663287632886328963290632916329263293632946329563296632976329863299633006330163302633036330463305633066330763308633096331063311633126331363314633156331663317633186331963320633216332263323633246332563326633276332863329633306333163332633336333463335633366333763338633396334063341633426334363344633456334663347633486334963350633516335263353633546335563356633576335863359633606336163362633636336463365633666336763368633696337063371633726337363374633756337663377633786337963380633816338263383633846338563386633876338863389633906339163392633936339463395633966339763398633996340063401634026340363404634056340663407634086340963410634116341263413634146341563416634176341863419634206342163422634236342463425634266342763428634296343063431634326343363434634356343663437634386343963440634416344263443634446344563446634476344863449634506345163452634536345463455634566345763458634596346063461634626346363464634656346663467634686346963470634716347263473634746347563476634776347863479634806348163482634836348463485634866348763488634896349063491634926349363494634956349663497634986349963500635016350263503635046350563506635076350863509635106351163512635136351463515635166351763518635196352063521635226352363524635256352663527635286352963530635316353263533635346353563536635376353863539635406354163542635436354463545635466354763548635496355063551635526355363554635556355663557635586355963560635616356263563635646356563566635676356863569635706357163572635736357463575635766357763578635796358063581635826358363584635856358663587635886358963590635916359263593635946359563596635976359863599636006360163602636036360463605636066360763608636096361063611636126361363614636156361663617636186361963620636216362263623636246362563626636276362863629636306363163632636336363463635636366363763638636396364063641636426364363644636456364663647636486364963650636516365263653636546365563656636576365863659636606366163662636636366463665636666366763668636696367063671636726367363674636756367663677636786367963680636816368263683636846368563686636876368863689636906369163692636936369463695636966369763698636996370063701637026370363704637056370663707637086370963710637116371263713637146371563716637176371863719637206372163722637236372463725637266372763728637296373063731637326373363734637356373663737637386373963740637416374263743637446374563746637476374863749637506375163752637536375463755637566375763758637596376063761637626376363764637656376663767637686376963770637716377263773637746377563776637776377863779637806378163782637836378463785637866378763788637896379063791637926379363794637956379663797637986379963800638016380263803638046380563806638076380863809638106381163812638136381463815638166381763818638196382063821638226382363824638256382663827638286382963830638316383263833638346383563836638376383863839638406384163842638436384463845638466384763848638496385063851638526385363854638556385663857638586385963860638616386263863638646386563866638676386863869638706387163872638736387463875638766387763878638796388063881638826388363884638856388663887638886388963890638916389263893638946389563896638976389863899639006390163902639036390463905639066390763908639096391063911639126391363914639156391663917639186391963920639216392263923639246392563926639276392863929639306393163932639336393463935639366393763938639396394063941639426394363944639456394663947639486394963950639516395263953639546395563956639576395863959639606396163962639636396463965639666396763968639696397063971639726397363974639756397663977639786397963980639816398263983639846398563986639876398863989639906399163992639936399463995639966399763998639996400064001640026400364004640056400664007640086400964010640116401264013640146401564016640176401864019640206402164022640236402464025640266402764028640296403064031640326403364034640356403664037640386403964040640416404264043640446404564046640476404864049640506405164052640536405464055640566405764058640596406064061640626406364064640656406664067640686406964070640716407264073640746407564076640776407864079640806408164082640836408464085640866408764088640896409064091640926409364094640956409664097640986409964100641016410264103641046410564106641076410864109641106411164112641136411464115641166411764118641196412064121641226412364124641256412664127641286412964130641316413264133641346413564136641376413864139641406414164142641436414464145641466414764148641496415064151641526415364154641556415664157641586415964160641616416264163641646416564166641676416864169641706417164172641736417464175641766417764178641796418064181641826418364184641856418664187641886418964190641916419264193641946419564196641976419864199642006420164202642036420464205642066420764208642096421064211642126421364214642156421664217642186421964220642216422264223642246422564226642276422864229642306423164232642336423464235642366423764238642396424064241642426424364244642456424664247642486424964250642516425264253642546425564256642576425864259642606426164262642636426464265642666426764268642696427064271642726427364274642756427664277642786427964280642816428264283642846428564286642876428864289642906429164292642936429464295642966429764298642996430064301643026430364304643056430664307643086430964310643116431264313643146431564316643176431864319643206432164322643236432464325643266432764328643296433064331643326433364334643356433664337643386433964340643416434264343643446434564346643476434864349643506435164352643536435464355643566435764358643596436064361643626436364364643656436664367643686436964370643716437264373643746437564376643776437864379643806438164382643836438464385643866438764388643896439064391643926439364394643956439664397643986439964400644016440264403644046440564406644076440864409644106441164412644136441464415644166441764418644196442064421644226442364424644256442664427644286442964430644316443264433644346443564436644376443864439644406444164442644436444464445644466444764448644496445064451644526445364454644556445664457644586445964460644616446264463644646446564466644676446864469644706447164472644736447464475644766447764478644796448064481644826448364484644856448664487644886448964490644916449264493644946449564496644976449864499645006450164502645036450464505645066450764508645096451064511645126451364514645156451664517645186451964520645216452264523645246452564526645276452864529645306453164532645336453464535645366453764538645396454064541645426454364544645456454664547645486454964550645516455264553645546455564556645576455864559645606456164562645636456464565645666456764568645696457064571645726457364574645756457664577645786457964580645816458264583645846458564586645876458864589645906459164592645936459464595645966459764598645996460064601646026460364604646056460664607646086460964610646116461264613646146461564616646176461864619646206462164622646236462464625646266462764628646296463064631646326463364634646356463664637646386463964640646416464264643646446464564646646476464864649646506465164652646536465464655646566465764658646596466064661646626466364664646656466664667646686466964670646716467264673646746467564676646776467864679646806468164682646836468464685646866468764688646896469064691646926469364694646956469664697646986469964700647016470264703647046470564706647076470864709647106471164712647136471464715647166471764718647196472064721647226472364724647256472664727647286472964730647316473264733647346473564736647376473864739647406474164742647436474464745647466474764748647496475064751647526475364754647556475664757647586475964760647616476264763647646476564766647676476864769647706477164772647736477464775647766477764778647796478064781647826478364784647856478664787647886478964790647916479264793647946479564796647976479864799648006480164802648036480464805648066480764808648096481064811648126481364814648156481664817648186481964820648216482264823648246482564826648276482864829648306483164832648336483464835648366483764838648396484064841648426484364844648456484664847648486484964850648516485264853648546485564856648576485864859648606486164862648636486464865648666486764868648696487064871648726487364874648756487664877648786487964880648816488264883648846488564886648876488864889648906489164892648936489464895648966489764898648996490064901649026490364904649056490664907649086490964910649116491264913649146491564916649176491864919649206492164922649236492464925649266492764928649296493064931649326493364934649356493664937649386493964940649416494264943649446494564946649476494864949649506495164952649536495464955649566495764958649596496064961649626496364964649656496664967649686496964970649716497264973649746497564976649776497864979649806498164982649836498464985649866498764988649896499064991649926499364994649956499664997649986499965000650016500265003650046500565006650076500865009650106501165012650136501465015650166501765018650196502065021650226502365024650256502665027650286502965030650316503265033650346503565036650376503865039650406504165042650436504465045650466504765048650496505065051650526505365054650556505665057650586505965060650616506265063650646506565066650676506865069650706507165072650736507465075650766507765078650796508065081650826508365084650856508665087650886508965090650916509265093650946509565096650976509865099651006510165102651036510465105651066510765108651096511065111651126511365114651156511665117651186511965120651216512265123651246512565126651276512865129651306513165132651336513465135651366513765138651396514065141651426514365144651456514665147651486514965150651516515265153651546515565156651576515865159651606516165162651636516465165651666516765168651696517065171651726517365174651756517665177651786517965180651816518265183651846518565186651876518865189651906519165192651936519465195651966519765198651996520065201652026520365204652056520665207652086520965210652116521265213652146521565216652176521865219652206522165222652236522465225652266522765228652296523065231652326523365234652356523665237652386523965240652416524265243652446524565246652476524865249652506525165252652536525465255652566525765258652596526065261652626526365264652656526665267652686526965270652716527265273652746527565276652776527865279652806528165282652836528465285652866528765288652896529065291652926529365294652956529665297652986529965300653016530265303653046530565306653076530865309653106531165312653136531465315653166531765318653196532065321653226532365324653256532665327653286532965330653316533265333653346533565336653376533865339653406534165342653436534465345653466534765348653496535065351653526535365354653556535665357653586535965360653616536265363653646536565366653676536865369653706537165372653736537465375653766537765378653796538065381653826538365384653856538665387653886538965390653916539265393653946539565396653976539865399654006540165402654036540465405654066540765408654096541065411654126541365414654156541665417654186541965420654216542265423654246542565426654276542865429654306543165432654336543465435654366543765438654396544065441654426544365444654456544665447654486544965450654516545265453654546545565456654576545865459654606546165462654636546465465654666546765468654696547065471654726547365474654756547665477654786547965480654816548265483654846548565486654876548865489654906549165492654936549465495654966549765498654996550065501655026550365504655056550665507655086550965510655116551265513655146551565516655176551865519655206552165522655236552465525655266552765528655296553065531655326553365534655356553665537655386553965540655416554265543655446554565546655476554865549655506555165552655536555465555655566555765558655596556065561655626556365564655656556665567655686556965570655716557265573655746557565576655776557865579655806558165582655836558465585655866558765588655896559065591655926559365594655956559665597655986559965600656016560265603656046560565606656076560865609656106561165612656136561465615656166561765618656196562065621656226562365624656256562665627656286562965630656316563265633656346563565636656376563865639656406564165642656436564465645656466564765648656496565065651656526565365654656556565665657656586565965660656616566265663656646566565666656676566865669656706567165672656736567465675656766567765678656796568065681656826568365684656856568665687656886568965690656916569265693656946569565696656976569865699657006570165702657036570465705657066570765708657096571065711657126571365714657156571665717657186571965720657216572265723657246572565726657276572865729657306573165732657336573465735657366573765738657396574065741657426574365744657456574665747657486574965750657516575265753657546575565756657576575865759657606576165762657636576465765657666576765768657696577065771657726577365774657756577665777657786577965780657816578265783657846578565786657876578865789657906579165792657936579465795657966579765798657996580065801658026580365804658056580665807658086580965810658116581265813658146581565816658176581865819658206582165822658236582465825658266582765828658296583065831658326583365834658356583665837658386583965840658416584265843658446584565846658476584865849658506585165852658536585465855658566585765858658596586065861658626586365864658656586665867658686586965870658716587265873658746587565876658776587865879658806588165882658836588465885658866588765888658896589065891658926589365894658956589665897658986589965900659016590265903659046590565906659076590865909659106591165912659136591465915659166591765918659196592065921659226592365924659256592665927659286592965930659316593265933659346593565936659376593865939659406594165942659436594465945659466594765948659496595065951659526595365954659556595665957659586595965960659616596265963659646596565966659676596865969659706597165972659736597465975659766597765978659796598065981659826598365984659856598665987659886598965990659916599265993659946599565996659976599865999660006600166002660036600466005660066600766008660096601066011660126601366014660156601666017660186601966020660216602266023660246602566026660276602866029660306603166032660336603466035660366603766038660396604066041660426604366044660456604666047660486604966050660516605266053660546605566056660576605866059660606606166062660636606466065660666606766068660696607066071660726607366074660756607666077660786607966080660816608266083660846608566086660876608866089660906609166092660936609466095660966609766098660996610066101661026610366104661056610666107661086610966110661116611266113661146611566116661176611866119661206612166122661236612466125661266612766128661296613066131661326613366134661356613666137661386613966140661416614266143661446614566146661476614866149661506615166152661536615466155661566615766158661596616066161661626616366164661656616666167661686616966170661716617266173661746617566176661776617866179661806618166182661836618466185661866618766188661896619066191661926619366194661956619666197661986619966200662016620266203662046620566206662076620866209662106621166212662136621466215662166621766218662196622066221662226622366224662256622666227662286622966230662316623266233662346623566236662376623866239662406624166242662436624466245662466624766248662496625066251662526625366254662556625666257662586625966260662616626266263662646626566266662676626866269662706627166272662736627466275662766627766278662796628066281662826628366284662856628666287662886628966290662916629266293662946629566296662976629866299663006630166302663036630466305663066630766308663096631066311663126631366314663156631666317663186631966320663216632266323663246632566326663276632866329663306633166332663336633466335663366633766338663396634066341663426634366344663456634666347663486634966350663516635266353663546635566356663576635866359663606636166362663636636466365663666636766368663696637066371663726637366374663756637666377663786637966380663816638266383663846638566386663876638866389663906639166392663936639466395663966639766398663996640066401664026640366404664056640666407664086640966410664116641266413664146641566416664176641866419664206642166422664236642466425664266642766428664296643066431664326643366434664356643666437664386643966440664416644266443664446644566446664476644866449664506645166452664536645466455664566645766458664596646066461664626646366464664656646666467664686646966470664716647266473664746647566476664776647866479664806648166482664836648466485664866648766488664896649066491664926649366494664956649666497664986649966500665016650266503665046650566506665076650866509665106651166512665136651466515665166651766518665196652066521665226652366524665256652666527665286652966530665316653266533665346653566536665376653866539665406654166542665436654466545665466654766548665496655066551665526655366554665556655666557665586655966560665616656266563665646656566566665676656866569665706657166572665736657466575665766657766578665796658066581665826658366584665856658666587665886658966590665916659266593665946659566596665976659866599666006660166602666036660466605666066660766608666096661066611666126661366614666156661666617666186661966620666216662266623666246662566626666276662866629666306663166632666336663466635666366663766638666396664066641666426664366644666456664666647666486664966650666516665266653666546665566656666576665866659666606666166662666636666466665666666666766668666696667066671666726667366674666756667666677666786667966680666816668266683666846668566686666876668866689666906669166692666936669466695666966669766698666996670066701667026670366704667056670666707667086670966710667116671266713667146671566716667176671866719667206672166722667236672466725667266672766728667296673066731667326673366734667356673666737667386673966740667416674266743667446674566746667476674866749667506675166752667536675466755667566675766758667596676066761667626676366764667656676666767667686676966770667716677266773667746677566776667776677866779667806678166782667836678466785667866678766788667896679066791667926679366794667956679666797667986679966800668016680266803668046680566806668076680866809668106681166812668136681466815668166681766818668196682066821668226682366824668256682666827668286682966830668316683266833668346683566836668376683866839668406684166842668436684466845668466684766848668496685066851668526685366854668556685666857668586685966860668616686266863668646686566866668676686866869668706687166872668736687466875668766687766878668796688066881668826688366884668856688666887668886688966890668916689266893668946689566896668976689866899669006690166902669036690466905669066690766908669096691066911669126691366914669156691666917669186691966920669216692266923669246692566926669276692866929669306693166932669336693466935669366693766938669396694066941669426694366944669456694666947669486694966950669516695266953669546695566956669576695866959669606696166962669636696466965669666696766968669696697066971669726697366974669756697666977669786697966980669816698266983669846698566986669876698866989669906699166992669936699466995669966699766998669996700067001670026700367004670056700667007670086700967010670116701267013670146701567016670176701867019670206702167022670236702467025670266702767028670296703067031670326703367034670356703667037670386703967040670416704267043670446704567046670476704867049670506705167052670536705467055670566705767058670596706067061670626706367064670656706667067670686706967070670716707267073670746707567076670776707867079670806708167082670836708467085670866708767088670896709067091670926709367094670956709667097670986709967100671016710267103671046710567106671076710867109671106711167112671136711467115671166711767118671196712067121671226712367124671256712667127671286712967130671316713267133671346713567136671376713867139671406714167142671436714467145671466714767148671496715067151671526715367154671556715667157671586715967160671616716267163671646716567166671676716867169671706717167172671736717467175671766717767178671796718067181671826718367184671856718667187671886718967190671916719267193671946719567196671976719867199672006720167202672036720467205672066720767208672096721067211672126721367214672156721667217672186721967220672216722267223672246722567226672276722867229672306723167232672336723467235672366723767238672396724067241672426724367244672456724667247672486724967250672516725267253672546725567256672576725867259672606726167262672636726467265672666726767268672696727067271672726727367274672756727667277672786727967280672816728267283672846728567286672876728867289672906729167292672936729467295672966729767298672996730067301673026730367304673056730667307673086730967310673116731267313673146731567316673176731867319673206732167322673236732467325673266732767328673296733067331673326733367334673356733667337673386733967340673416734267343673446734567346673476734867349673506735167352673536735467355673566735767358673596736067361673626736367364673656736667367673686736967370673716737267373673746737567376673776737867379673806738167382673836738467385673866738767388673896739067391673926739367394673956739667397673986739967400674016740267403674046740567406674076740867409674106741167412674136741467415674166741767418674196742067421674226742367424674256742667427674286742967430674316743267433674346743567436674376743867439674406744167442674436744467445674466744767448674496745067451674526745367454674556745667457674586745967460674616746267463674646746567466674676746867469674706747167472674736747467475674766747767478674796748067481674826748367484674856748667487674886748967490674916749267493674946749567496674976749867499675006750167502675036750467505675066750767508675096751067511675126751367514675156751667517675186751967520675216752267523675246752567526675276752867529675306753167532675336753467535675366753767538675396754067541675426754367544675456754667547675486754967550675516755267553675546755567556675576755867559675606756167562675636756467565675666756767568675696757067571675726757367574675756757667577675786757967580675816758267583675846758567586675876758867589675906759167592675936759467595675966759767598675996760067601676026760367604676056760667607676086760967610676116761267613676146761567616676176761867619676206762167622676236762467625676266762767628676296763067631676326763367634676356763667637676386763967640676416764267643676446764567646676476764867649676506765167652676536765467655676566765767658676596766067661676626766367664676656766667667676686766967670676716767267673676746767567676676776767867679676806768167682676836768467685676866768767688676896769067691676926769367694676956769667697676986769967700677016770267703677046770567706677076770867709677106771167712677136771467715677166771767718677196772067721677226772367724677256772667727677286772967730677316773267733677346773567736677376773867739677406774167742677436774467745677466774767748677496775067751677526775367754677556775667757677586775967760677616776267763677646776567766677676776867769677706777167772677736777467775677766777767778677796778067781677826778367784677856778667787677886778967790677916779267793677946779567796677976779867799678006780167802678036780467805678066780767808678096781067811678126781367814678156781667817678186781967820678216782267823678246782567826678276782867829678306783167832678336783467835678366783767838678396784067841678426784367844678456784667847678486784967850678516785267853678546785567856678576785867859678606786167862678636786467865678666786767868678696787067871678726787367874678756787667877678786787967880678816788267883678846788567886678876788867889678906789167892678936789467895678966789767898678996790067901679026790367904679056790667907679086790967910679116791267913679146791567916679176791867919679206792167922679236792467925679266792767928679296793067931679326793367934679356793667937679386793967940679416794267943679446794567946679476794867949679506795167952679536795467955679566795767958679596796067961679626796367964679656796667967679686796967970679716797267973679746797567976679776797867979679806798167982679836798467985679866798767988679896799067991679926799367994679956799667997679986799968000680016800268003680046800568006680076800868009680106801168012680136801468015680166801768018680196802068021680226802368024680256802668027680286802968030680316803268033680346803568036680376803868039680406804168042680436804468045680466804768048680496805068051680526805368054680556805668057680586805968060680616806268063680646806568066680676806868069680706807168072680736807468075680766807768078680796808068081680826808368084680856808668087680886808968090680916809268093680946809568096680976809868099681006810168102681036810468105681066810768108681096811068111681126811368114681156811668117681186811968120681216812268123681246812568126681276812868129681306813168132681336813468135681366813768138681396814068141681426814368144681456814668147681486814968150681516815268153681546815568156681576815868159681606816168162681636816468165681666816768168681696817068171681726817368174681756817668177681786817968180681816818268183681846818568186681876818868189681906819168192681936819468195681966819768198681996820068201682026820368204682056820668207682086820968210682116821268213682146821568216682176821868219682206822168222682236822468225682266822768228682296823068231682326823368234682356823668237682386823968240682416824268243682446824568246682476824868249682506825168252682536825468255682566825768258682596826068261682626826368264682656826668267682686826968270682716827268273682746827568276682776827868279682806828168282682836828468285682866828768288682896829068291682926829368294682956829668297682986829968300683016830268303683046830568306683076830868309683106831168312683136831468315683166831768318683196832068321683226832368324683256832668327683286832968330683316833268333683346833568336683376833868339683406834168342683436834468345683466834768348683496835068351683526835368354683556835668357683586835968360683616836268363683646836568366683676836868369683706837168372683736837468375683766837768378683796838068381683826838368384683856838668387683886838968390683916839268393683946839568396683976839868399684006840168402684036840468405684066840768408684096841068411684126841368414684156841668417684186841968420684216842268423684246842568426684276842868429684306843168432684336843468435684366843768438684396844068441684426844368444684456844668447684486844968450684516845268453684546845568456684576845868459684606846168462684636846468465684666846768468684696847068471684726847368474684756847668477684786847968480684816848268483684846848568486684876848868489684906849168492684936849468495684966849768498684996850068501685026850368504685056850668507685086850968510685116851268513685146851568516685176851868519685206852168522685236852468525685266852768528685296853068531685326853368534685356853668537685386853968540685416854268543685446854568546685476854868549685506855168552685536855468555685566855768558685596856068561685626856368564685656856668567685686856968570685716857268573685746857568576685776857868579685806858168582685836858468585685866858768588685896859068591685926859368594685956859668597685986859968600686016860268603686046860568606686076860868609686106861168612686136861468615686166861768618686196862068621686226862368624686256862668627686286862968630686316863268633686346863568636686376863868639686406864168642686436864468645686466864768648686496865068651686526865368654686556865668657686586865968660686616866268663686646866568666686676866868669686706867168672686736867468675686766867768678686796868068681686826868368684686856868668687686886868968690686916869268693686946869568696686976869868699687006870168702687036870468705687066870768708687096871068711687126871368714687156871668717687186871968720687216872268723687246872568726687276872868729687306873168732687336873468735687366873768738687396874068741687426874368744687456874668747687486874968750687516875268753687546875568756687576875868759687606876168762687636876468765687666876768768687696877068771687726877368774687756877668777687786877968780687816878268783687846878568786687876878868789687906879168792687936879468795687966879768798687996880068801688026880368804688056880668807688086880968810688116881268813688146881568816688176881868819688206882168822688236882468825688266882768828688296883068831688326883368834688356883668837688386883968840688416884268843688446884568846688476884868849688506885168852688536885468855688566885768858688596886068861688626886368864688656886668867688686886968870688716887268873688746887568876688776887868879688806888168882688836888468885688866888768888688896889068891688926889368894688956889668897688986889968900689016890268903689046890568906689076890868909689106891168912689136891468915689166891768918689196892068921689226892368924689256892668927689286892968930689316893268933689346893568936689376893868939689406894168942689436894468945689466894768948689496895068951689526895368954689556895668957689586895968960689616896268963689646896568966689676896868969689706897168972689736897468975689766897768978689796898068981689826898368984689856898668987689886898968990689916899268993689946899568996689976899868999690006900169002690036900469005690066900769008690096901069011690126901369014690156901669017690186901969020690216902269023690246902569026690276902869029690306903169032690336903469035690366903769038690396904069041690426904369044690456904669047690486904969050690516905269053690546905569056690576905869059690606906169062690636906469065690666906769068690696907069071690726907369074690756907669077690786907969080690816908269083690846908569086690876908869089690906909169092690936909469095690966909769098690996910069101691026910369104691056910669107691086910969110691116911269113691146911569116691176911869119691206912169122691236912469125691266912769128691296913069131691326913369134691356913669137691386913969140691416914269143691446914569146691476914869149691506915169152691536915469155691566915769158691596916069161691626916369164691656916669167691686916969170691716917269173691746917569176691776917869179691806918169182691836918469185691866918769188691896919069191691926919369194691956919669197691986919969200692016920269203692046920569206692076920869209692106921169212692136921469215692166921769218692196922069221692226922369224692256922669227692286922969230692316923269233692346923569236692376923869239692406924169242692436924469245692466924769248692496925069251692526925369254692556925669257692586925969260692616926269263692646926569266692676926869269692706927169272692736927469275692766927769278692796928069281692826928369284692856928669287692886928969290692916929269293692946929569296692976929869299693006930169302693036930469305693066930769308693096931069311693126931369314693156931669317693186931969320693216932269323693246932569326693276932869329693306933169332693336933469335693366933769338693396934069341693426934369344693456934669347693486934969350693516935269353693546935569356693576935869359693606936169362693636936469365693666936769368693696937069371693726937369374693756937669377693786937969380693816938269383693846938569386693876938869389693906939169392693936939469395693966939769398693996940069401694026940369404694056940669407694086940969410694116941269413694146941569416694176941869419694206942169422694236942469425694266942769428694296943069431694326943369434694356943669437694386943969440694416944269443694446944569446694476944869449694506945169452694536945469455694566945769458694596946069461694626946369464694656946669467694686946969470694716947269473694746947569476694776947869479694806948169482694836948469485694866948769488694896949069491694926949369494694956949669497694986949969500695016950269503695046950569506695076950869509695106951169512695136951469515695166951769518695196952069521695226952369524695256952669527695286952969530695316953269533695346953569536695376953869539695406954169542695436954469545695466954769548695496955069551695526955369554695556955669557695586955969560695616956269563695646956569566695676956869569695706957169572695736957469575695766957769578695796958069581695826958369584695856958669587695886958969590695916959269593695946959569596695976959869599696006960169602696036960469605696066960769608696096961069611696126961369614696156961669617696186961969620696216962269623696246962569626696276962869629696306963169632696336963469635696366963769638696396964069641696426964369644696456964669647696486964969650696516965269653696546965569656696576965869659696606966169662696636966469665696666966769668696696967069671696726967369674696756967669677696786967969680696816968269683696846968569686696876968869689696906969169692696936969469695696966969769698696996970069701697026970369704697056970669707697086970969710697116971269713697146971569716697176971869719697206972169722697236972469725697266972769728697296973069731697326973369734697356973669737697386973969740697416974269743697446974569746697476974869749697506975169752697536975469755697566975769758697596976069761697626976369764697656976669767697686976969770697716977269773697746977569776697776977869779697806978169782697836978469785697866978769788697896979069791697926979369794697956979669797697986979969800698016980269803698046980569806698076980869809698106981169812698136981469815698166981769818698196982069821698226982369824698256982669827698286982969830698316983269833698346983569836698376983869839698406984169842698436984469845698466984769848698496985069851698526985369854698556985669857698586985969860698616986269863698646986569866698676986869869698706987169872698736987469875698766987769878698796988069881698826988369884698856988669887698886988969890698916989269893698946989569896698976989869899699006990169902699036990469905699066990769908699096991069911699126991369914699156991669917699186991969920699216992269923699246992569926699276992869929699306993169932699336993469935699366993769938699396994069941699426994369944699456994669947699486994969950699516995269953699546995569956699576995869959699606996169962699636996469965699666996769968699696997069971699726997369974699756997669977699786997969980699816998269983699846998569986699876998869989699906999169992699936999469995699966999769998699997000070001700027000370004700057000670007700087000970010700117001270013700147001570016700177001870019700207002170022700237002470025700267002770028700297003070031700327003370034700357003670037700387003970040700417004270043700447004570046700477004870049700507005170052700537005470055700567005770058700597006070061700627006370064700657006670067700687006970070700717007270073700747007570076700777007870079700807008170082700837008470085700867008770088700897009070091700927009370094700957009670097700987009970100701017010270103701047010570106701077010870109701107011170112701137011470115701167011770118701197012070121701227012370124701257012670127701287012970130701317013270133701347013570136701377013870139701407014170142701437014470145701467014770148701497015070151701527015370154701557015670157701587015970160701617016270163701647016570166701677016870169701707017170172701737017470175701767017770178701797018070181701827018370184701857018670187701887018970190701917019270193701947019570196701977019870199702007020170202702037020470205702067020770208702097021070211702127021370214702157021670217702187021970220702217022270223702247022570226702277022870229702307023170232702337023470235702367023770238702397024070241702427024370244702457024670247702487024970250702517025270253702547025570256702577025870259702607026170262702637026470265702667026770268702697027070271702727027370274702757027670277702787027970280702817028270283702847028570286702877028870289702907029170292702937029470295702967029770298702997030070301703027030370304703057030670307703087030970310703117031270313703147031570316703177031870319703207032170322703237032470325703267032770328703297033070331703327033370334703357033670337703387033970340703417034270343703447034570346703477034870349703507035170352703537035470355703567035770358703597036070361703627036370364703657036670367703687036970370703717037270373703747037570376703777037870379703807038170382703837038470385703867038770388703897039070391703927039370394703957039670397703987039970400704017040270403704047040570406704077040870409704107041170412704137041470415704167041770418704197042070421704227042370424704257042670427704287042970430704317043270433704347043570436704377043870439704407044170442704437044470445704467044770448704497045070451704527045370454704557045670457704587045970460704617046270463704647046570466704677046870469704707047170472704737047470475704767047770478704797048070481704827048370484704857048670487704887048970490704917049270493704947049570496704977049870499705007050170502705037050470505705067050770508705097051070511705127051370514705157051670517705187051970520705217052270523705247052570526705277052870529705307053170532705337053470535705367053770538705397054070541705427054370544705457054670547705487054970550705517055270553705547055570556705577055870559705607056170562705637056470565705667056770568705697057070571705727057370574705757057670577705787057970580705817058270583705847058570586705877058870589705907059170592705937059470595705967059770598705997060070601706027060370604706057060670607706087060970610706117061270613706147061570616706177061870619706207062170622706237062470625706267062770628706297063070631706327063370634706357063670637706387063970640706417064270643706447064570646706477064870649706507065170652706537065470655706567065770658706597066070661706627066370664706657066670667706687066970670706717067270673706747067570676706777067870679706807068170682706837068470685706867068770688706897069070691706927069370694706957069670697706987069970700707017070270703707047070570706707077070870709707107071170712707137071470715707167071770718707197072070721707227072370724707257072670727707287072970730707317073270733707347073570736707377073870739707407074170742707437074470745707467074770748707497075070751707527075370754707557075670757707587075970760707617076270763707647076570766707677076870769707707077170772707737077470775707767077770778707797078070781707827078370784707857078670787707887078970790707917079270793707947079570796707977079870799708007080170802708037080470805708067080770808708097081070811708127081370814708157081670817708187081970820708217082270823708247082570826708277082870829708307083170832708337083470835708367083770838708397084070841708427084370844708457084670847708487084970850708517085270853708547085570856708577085870859708607086170862708637086470865708667086770868708697087070871708727087370874708757087670877708787087970880708817088270883708847088570886708877088870889708907089170892708937089470895708967089770898708997090070901709027090370904709057090670907709087090970910709117091270913709147091570916709177091870919709207092170922709237092470925709267092770928709297093070931709327093370934709357093670937709387093970940709417094270943709447094570946709477094870949709507095170952709537095470955709567095770958709597096070961709627096370964709657096670967709687096970970709717097270973709747097570976709777097870979709807098170982709837098470985709867098770988709897099070991709927099370994709957099670997709987099971000710017100271003710047100571006710077100871009710107101171012710137101471015710167101771018710197102071021710227102371024710257102671027710287102971030710317103271033710347103571036710377103871039710407104171042710437104471045710467104771048710497105071051710527105371054710557105671057710587105971060710617106271063710647106571066710677106871069710707107171072710737107471075710767107771078710797108071081710827108371084710857108671087710887108971090710917109271093710947109571096710977109871099711007110171102711037110471105711067110771108711097111071111711127111371114711157111671117711187111971120711217112271123711247112571126711277112871129711307113171132711337113471135711367113771138711397114071141711427114371144711457114671147711487114971150711517115271153711547115571156711577115871159711607116171162711637116471165711667116771168711697117071171711727117371174711757117671177711787117971180711817118271183711847118571186711877118871189711907119171192711937119471195711967119771198711997120071201712027120371204712057120671207712087120971210712117121271213712147121571216712177121871219712207122171222712237122471225712267122771228712297123071231712327123371234712357123671237712387123971240712417124271243712447124571246712477124871249712507125171252712537125471255712567125771258712597126071261712627126371264712657126671267712687126971270712717127271273712747127571276712777127871279712807128171282712837128471285712867128771288712897129071291712927129371294712957129671297712987129971300713017130271303713047130571306713077130871309713107131171312713137131471315713167131771318713197132071321713227132371324713257132671327713287132971330713317133271333713347133571336713377133871339713407134171342713437134471345713467134771348713497135071351713527135371354713557135671357713587135971360713617136271363713647136571366713677136871369713707137171372713737137471375713767137771378713797138071381713827138371384713857138671387713887138971390713917139271393713947139571396713977139871399714007140171402714037140471405714067140771408714097141071411714127141371414714157141671417714187141971420714217142271423714247142571426714277142871429714307143171432714337143471435714367143771438714397144071441714427144371444714457144671447714487144971450714517145271453714547145571456714577145871459714607146171462714637146471465714667146771468714697147071471714727147371474714757147671477714787147971480714817148271483714847148571486714877148871489714907149171492714937149471495714967149771498714997150071501715027150371504715057150671507715087150971510715117151271513715147151571516715177151871519715207152171522715237152471525715267152771528715297153071531715327153371534715357153671537715387153971540715417154271543715447154571546715477154871549715507155171552715537155471555715567155771558715597156071561715627156371564715657156671567715687156971570715717157271573715747157571576715777157871579715807158171582715837158471585715867158771588715897159071591715927159371594715957159671597715987159971600716017160271603716047160571606716077160871609716107161171612716137161471615716167161771618716197162071621716227162371624716257162671627716287162971630716317163271633716347163571636716377163871639716407164171642716437164471645716467164771648716497165071651716527165371654716557165671657716587165971660716617166271663716647166571666716677166871669716707167171672716737167471675716767167771678716797168071681716827168371684716857168671687716887168971690716917169271693716947169571696716977169871699717007170171702717037170471705717067170771708717097171071711717127171371714717157171671717717187171971720717217172271723717247172571726717277172871729717307173171732717337173471735717367173771738717397174071741717427174371744717457174671747717487174971750717517175271753717547175571756717577175871759717607176171762717637176471765717667176771768717697177071771717727177371774717757177671777717787177971780717817178271783717847178571786717877178871789717907179171792717937179471795717967179771798717997180071801718027180371804718057180671807718087180971810718117181271813718147181571816718177181871819718207182171822718237182471825718267182771828718297183071831718327183371834718357183671837718387183971840718417184271843718447184571846718477184871849718507185171852718537185471855718567185771858718597186071861718627186371864718657186671867718687186971870718717187271873718747187571876718777187871879718807188171882718837188471885718867188771888718897189071891718927189371894718957189671897718987189971900719017190271903719047190571906719077190871909719107191171912719137191471915719167191771918719197192071921719227192371924719257192671927719287192971930719317193271933719347193571936719377193871939719407194171942719437194471945719467194771948719497195071951719527195371954719557195671957719587195971960719617196271963719647196571966719677196871969719707197171972719737197471975719767197771978719797198071981719827198371984719857198671987719887198971990719917199271993719947199571996719977199871999720007200172002720037200472005720067200772008720097201072011720127201372014720157201672017720187201972020720217202272023720247202572026720277202872029720307203172032720337203472035720367203772038720397204072041720427204372044720457204672047720487204972050720517205272053720547205572056720577205872059720607206172062720637206472065720667206772068720697207072071720727207372074720757207672077720787207972080720817208272083720847208572086720877208872089720907209172092720937209472095720967209772098720997210072101721027210372104721057210672107721087210972110721117211272113721147211572116721177211872119721207212172122721237212472125721267212772128721297213072131721327213372134721357213672137721387213972140721417214272143721447214572146721477214872149721507215172152721537215472155721567215772158721597216072161721627216372164721657216672167721687216972170721717217272173721747217572176721777217872179721807218172182721837218472185721867218772188721897219072191721927219372194721957219672197721987219972200722017220272203722047220572206722077220872209722107221172212722137221472215722167221772218722197222072221722227222372224722257222672227722287222972230722317223272233722347223572236722377223872239722407224172242722437224472245722467224772248722497225072251722527225372254722557225672257722587225972260722617226272263722647226572266722677226872269722707227172272722737227472275722767227772278722797228072281722827228372284722857228672287722887228972290722917229272293722947229572296722977229872299723007230172302723037230472305723067230772308723097231072311723127231372314723157231672317723187231972320723217232272323723247232572326723277232872329723307233172332723337233472335723367233772338723397234072341723427234372344723457234672347723487234972350723517235272353723547235572356723577235872359723607236172362723637236472365723667236772368723697237072371723727237372374723757237672377723787237972380723817238272383723847238572386723877238872389723907239172392723937239472395723967239772398723997240072401724027240372404724057240672407724087240972410724117241272413724147241572416724177241872419724207242172422724237242472425724267242772428724297243072431724327243372434724357243672437724387243972440724417244272443724447244572446724477244872449724507245172452724537245472455724567245772458724597246072461724627246372464724657246672467724687246972470724717247272473724747247572476724777247872479724807248172482724837248472485724867248772488724897249072491724927249372494724957249672497724987249972500725017250272503725047250572506725077250872509725107251172512725137251472515725167251772518725197252072521725227252372524725257252672527725287252972530725317253272533725347253572536725377253872539725407254172542725437254472545725467254772548725497255072551725527255372554725557255672557725587255972560725617256272563725647256572566725677256872569725707257172572725737257472575725767257772578725797258072581725827258372584725857258672587725887258972590725917259272593725947259572596725977259872599726007260172602726037260472605726067260772608726097261072611726127261372614726157261672617726187261972620726217262272623726247262572626726277262872629726307263172632726337263472635726367263772638726397264072641726427264372644726457264672647726487264972650726517265272653726547265572656726577265872659726607266172662726637266472665726667266772668726697267072671726727267372674726757267672677726787267972680726817268272683726847268572686726877268872689726907269172692726937269472695726967269772698726997270072701727027270372704727057270672707727087270972710727117271272713727147271572716727177271872719727207272172722727237272472725727267272772728727297273072731727327273372734727357273672737727387273972740727417274272743727447274572746727477274872749727507275172752727537275472755727567275772758727597276072761727627276372764727657276672767727687276972770727717277272773727747277572776727777277872779727807278172782727837278472785727867278772788727897279072791727927279372794727957279672797727987279972800728017280272803728047280572806728077280872809728107281172812728137281472815728167281772818728197282072821728227282372824728257282672827728287282972830728317283272833728347283572836728377283872839728407284172842728437284472845728467284772848728497285072851728527285372854728557285672857728587285972860728617286272863728647286572866728677286872869728707287172872728737287472875728767287772878728797288072881728827288372884728857288672887728887288972890728917289272893728947289572896728977289872899729007290172902729037290472905729067290772908729097291072911729127291372914729157291672917729187291972920729217292272923729247292572926729277292872929729307293172932729337293472935729367293772938729397294072941729427294372944729457294672947729487294972950729517295272953729547295572956729577295872959729607296172962729637296472965729667296772968729697297072971729727297372974729757297672977729787297972980729817298272983729847298572986729877298872989729907299172992729937299472995729967299772998729997300073001730027300373004730057300673007730087300973010730117301273013730147301573016730177301873019730207302173022730237302473025730267302773028730297303073031730327303373034730357303673037730387303973040730417304273043730447304573046730477304873049730507305173052730537305473055730567305773058730597306073061730627306373064730657306673067730687306973070730717307273073
  1. #!/usr/bin/env php
  2. <?php
  3. if (__FILE__ == realpath($GLOBALS['_SERVER']['SCRIPT_NAME'])) {
  4. $phar = realpath($GLOBALS['_SERVER']['SCRIPT_NAME']);
  5. $execute = true;
  6. } else {
  7. $files = get_included_files();
  8. $phar = $files[0];
  9. $execute = false;
  10. }
  11. define('__PHPUNIT_PHAR__', str_replace(DIRECTORY_SEPARATOR, '/', $phar));
  12. define('__PHPUNIT_PHAR_ROOT__', 'phar://phpunit-4.7.7.phar');
  13. Phar::mapPhar('phpunit-4.7.7.phar');
  14. require 'phar://phpunit-4.7.7.phar' . '/doctrine-instantiator/Doctrine/Instantiator/Exception/ExceptionInterface.php';
  15. require 'phar://phpunit-4.7.7.phar' . '/doctrine-instantiator/Doctrine/Instantiator/Exception/InvalidArgumentException.php';
  16. require 'phar://phpunit-4.7.7.phar' . '/doctrine-instantiator/Doctrine/Instantiator/Exception/UnexpectedValueException.php';
  17. require 'phar://phpunit-4.7.7.phar' . '/doctrine-instantiator/Doctrine/Instantiator/InstantiatorInterface.php';
  18. require 'phar://phpunit-4.7.7.phar' . '/doctrine-instantiator/Doctrine/Instantiator/Instantiator.php';
  19. require 'phar://phpunit-4.7.7.phar' . '/php-file-iterator/Iterator.php';
  20. require 'phar://phpunit-4.7.7.phar' . '/php-file-iterator/Facade.php';
  21. require 'phar://phpunit-4.7.7.phar' . '/php-file-iterator/Factory.php';
  22. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage.php';
  23. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Driver.php';
  24. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Driver/HHVM.php';
  25. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Driver/Xdebug.php';
  26. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Exception.php';
  27. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Exception/UnintentionallyCoveredCode.php';
  28. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Filter.php';
  29. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/Clover.php';
  30. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/Crap4j.php';
  31. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/Factory.php';
  32. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/HTML.php';
  33. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/HTML/Renderer.php';
  34. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/HTML/Renderer/Dashboard.php';
  35. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/HTML/Renderer/Directory.php';
  36. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/HTML/Renderer/File.php';
  37. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/Node.php';
  38. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/Node/Directory.php';
  39. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/Node/File.php';
  40. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/Node/Iterator.php';
  41. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/PHP.php';
  42. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/Text.php';
  43. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/XML.php';
  44. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/XML/Node.php';
  45. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/XML/Directory.php';
  46. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/XML/File.php';
  47. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/XML/File/Coverage.php';
  48. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/XML/File/Method.php';
  49. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/XML/File/Report.php';
  50. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/XML/File/Unit.php';
  51. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/XML/Project.php';
  52. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/XML/Tests.php';
  53. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Report/XML/Totals.php';
  54. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Util.php';
  55. require 'phar://phpunit-4.7.7.phar' . '/php-code-coverage/CodeCoverage/Util/InvalidArgumentHelper.php';
  56. require 'phar://phpunit-4.7.7.phar' . '/php-invoker/Invoker.php';
  57. require 'phar://phpunit-4.7.7.phar' . '/php-invoker/TimeoutException.php';
  58. require 'phar://phpunit-4.7.7.phar' . '/php-timer/Timer.php';
  59. require 'phar://phpunit-4.7.7.phar' . '/php-token-stream/Token.php';
  60. require 'phar://phpunit-4.7.7.phar' . '/php-token-stream/Token/Stream.php';
  61. require 'phar://phpunit-4.7.7.phar' . '/php-token-stream/Token/Stream/CachingFactory.php';
  62. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock.php';
  63. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Context.php';
  64. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Description.php';
  65. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Location.php';
  66. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Serializer.php';
  67. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag.php';
  68. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/AuthorTag.php';
  69. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/SeeTag.php';
  70. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/CoversTag.php';
  71. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/VersionTag.php';
  72. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/DeprecatedTag.php';
  73. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/SourceTag.php';
  74. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/ExampleTag.php';
  75. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/LinkTag.php';
  76. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/ReturnTag.php';
  77. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/MethodTag.php';
  78. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/ParamTag.php';
  79. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/PropertyTag.php';
  80. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/PropertyReadTag.php';
  81. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/PropertyWriteTag.php';
  82. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/SinceTag.php';
  83. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/ThrowsTag.php';
  84. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/UsesTag.php';
  85. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/VarTag.php';
  86. require 'phar://phpunit-4.7.7.phar' . '/phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Type/Collection.php';
  87. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Exception.php';
  88. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/ITester.php';
  89. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/AbstractTester.php';
  90. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/SelfDescribing.php';
  91. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint.php';
  92. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/Constraint/DataSetIsEqual.php';
  93. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/Constraint/TableIsEqual.php';
  94. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/Constraint/TableRowCount.php';
  95. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/IDataSet.php';
  96. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/AbstractDataSet.php';
  97. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/ITable.php';
  98. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/AbstractTable.php';
  99. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/ITableMetaData.php';
  100. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/AbstractTableMetaData.php';
  101. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/AbstractXmlDataSet.php';
  102. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/ArrayDataSet.php';
  103. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/CompositeDataSet.php';
  104. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/CsvDataSet.php';
  105. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/DataSetFilter.php';
  106. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/DefaultDataSet.php';
  107. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/DefaultTable.php';
  108. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/ITableIterator.php';
  109. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/DefaultTableIterator.php';
  110. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/DefaultTableMetaData.php';
  111. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/FlatXmlDataSet.php';
  112. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/IPersistable.php';
  113. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/ISpec.php';
  114. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/IYamlParser.php';
  115. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/MysqlXmlDataSet.php';
  116. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/Abstract.php';
  117. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/Factory.php';
  118. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/FlatXml.php';
  119. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/MysqlXml.php';
  120. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/Xml.php';
  121. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/Yaml.php';
  122. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/QueryDataSet.php';
  123. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/QueryTable.php';
  124. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/ReplacementDataSet.php';
  125. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/ReplacementTable.php';
  126. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/ReplacementTableIterator.php';
  127. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/Specs/Csv.php';
  128. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/IDatabaseListConsumer.php';
  129. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/Specs/DbQuery.php';
  130. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/Specs/DbTable.php';
  131. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/Specs/IFactory.php';
  132. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/Specs/Factory.php';
  133. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/Specs/FlatXml.php';
  134. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/Specs/Xml.php';
  135. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/Specs/Yaml.php';
  136. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/SymfonyYamlParser.php';
  137. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/TableFilter.php';
  138. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/TableMetaDataFilter.php';
  139. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/XmlDataSet.php';
  140. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DataSet/YamlDataSet.php';
  141. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/DataSet.php';
  142. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/IDatabaseConnection.php';
  143. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/DefaultDatabaseConnection.php';
  144. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/FilteredDataSet.php';
  145. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/IMetaData.php';
  146. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/MetaData.php';
  147. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/MetaData/Dblib.php';
  148. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/MetaData/Firebird.php';
  149. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/MetaData/InformationSchema.php';
  150. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/MetaData/MySQL.php';
  151. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/MetaData/Oci.php';
  152. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/MetaData/PgSQL.php';
  153. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/MetaData/Sqlite.php';
  154. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/MetaData/SqlSrv.php';
  155. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/ResultSetTable.php';
  156. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/Table.php';
  157. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/TableIterator.php';
  158. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DB/TableMetaData.php';
  159. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/DefaultTester.php';
  160. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/Exception.php';
  161. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/Operation/IDatabaseOperation.php';
  162. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/Operation/Composite.php';
  163. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/Operation/RowBased.php';
  164. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/Operation/Delete.php';
  165. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/Operation/DeleteAll.php';
  166. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/Operation/Exception.php';
  167. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/Operation/Factory.php';
  168. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/Operation/Insert.php';
  169. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/Operation/Null.php';
  170. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/Operation/Replace.php';
  171. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/Operation/Truncate.php';
  172. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/Operation/Update.php';
  173. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Test.php';
  174. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Assert.php';
  175. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/TestCase.php';
  176. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/TestCase.php';
  177. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/UI/Command.php';
  178. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/UI/Context.php';
  179. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/UI/IMediumPrinter.php';
  180. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/UI/IMedium.php';
  181. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/UI/IMode.php';
  182. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/UI/IModeFactory.php';
  183. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/UI/InvalidModeException.php';
  184. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/UI/Mediums/Text.php';
  185. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/UI/ModeFactory.php';
  186. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/UI/Modes/ExportDataSet.php';
  187. require 'phar://phpunit-4.7.7.phar' . '/dbunit/Extensions/Database/UI/Modes/ExportDataSet/Arguments.php';
  188. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/TestSuite.php';
  189. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Extensions/GroupTestSuite.php';
  190. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Extensions/PhptTestCase.php';
  191. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Extensions/PhptTestSuite.php';
  192. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Extensions/TestDecorator.php';
  193. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Extensions/RepeatedTest.php';
  194. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase.php';
  195. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Command.php';
  196. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/CommandsHolder.php';
  197. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Driver.php';
  198. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Element/Accessor.php';
  199. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Element.php';
  200. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Element/Select.php';
  201. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Attribute.php';
  202. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Click.php';
  203. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Css.php';
  204. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Equals.php';
  205. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericAccessor.php';
  206. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericPost.php';
  207. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Keys.php';
  208. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Value.php';
  209. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCriteria.php';
  210. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Exception.php';
  211. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Keys.php';
  212. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/KeysHolder.php';
  213. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/NoSeleniumException.php';
  214. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Response.php';
  215. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/TestListener.php';
  216. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/ScreenshotListener.php';
  217. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Session.php';
  218. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie.php';
  219. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie/Builder.php';
  220. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Session/Storage.php';
  221. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Session/Timeouts.php';
  222. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AcceptAlert.php';
  223. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Active.php';
  224. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AlertText.php';
  225. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Click.php';
  226. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/DismissAlert.php';
  227. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/File.php';
  228. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Frame.php';
  229. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAccessor.php';
  230. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAttribute.php';
  231. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Location.php';
  232. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Log.php';
  233. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/MoveTo.php';
  234. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Orientation.php';
  235. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Url.php';
  236. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Window.php';
  237. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy.php';
  238. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Isolated.php';
  239. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Shared.php';
  240. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/StateCommand.php';
  241. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/URL.php';
  242. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/WaitUntil.php';
  243. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/WebDriverException.php';
  244. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/Selenium2TestCase/Window.php';
  245. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/SeleniumBrowserSuite.php';
  246. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/SeleniumCommon/ExitHandler.php';
  247. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/SeleniumCommon/RemoteCoverage.php';
  248. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/SeleniumTestCase.php';
  249. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/SeleniumTestCase/Driver.php';
  250. require 'phar://phpunit-4.7.7.phar' . '/phpunit-selenium/Extensions/SeleniumTestSuite.php';
  251. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Extensions/TicketListener.php';
  252. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Exception.php';
  253. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/AssertionFailedError.php';
  254. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/BaseTestListener.php';
  255. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/CodeCoverageException.php';
  256. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/And.php';
  257. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/ArrayHasKey.php';
  258. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/ArraySubset.php';
  259. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/Composite.php';
  260. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/Attribute.php';
  261. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/Callback.php';
  262. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/ClassHasAttribute.php';
  263. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/ClassHasStaticAttribute.php';
  264. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/Count.php';
  265. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/Exception.php';
  266. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/ExceptionCode.php';
  267. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/ExceptionMessage.php';
  268. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/ExceptionMessageRegExp.php';
  269. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/FileExists.php';
  270. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/GreaterThan.php';
  271. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/IsAnything.php';
  272. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/IsEmpty.php';
  273. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/IsEqual.php';
  274. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/IsFalse.php';
  275. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/IsIdentical.php';
  276. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/IsInstanceOf.php';
  277. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/IsJson.php';
  278. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/IsNull.php';
  279. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/IsTrue.php';
  280. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/IsType.php';
  281. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/JsonMatches.php';
  282. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/JsonMatches/ErrorMessageProvider.php';
  283. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/LessThan.php';
  284. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/Not.php';
  285. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/ObjectHasAttribute.php';
  286. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/Or.php';
  287. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/PCREMatch.php';
  288. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/SameSize.php';
  289. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/StringContains.php';
  290. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/StringEndsWith.php';
  291. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/StringMatches.php';
  292. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/StringStartsWith.php';
  293. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/TraversableContains.php';
  294. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/TraversableContainsOnly.php';
  295. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Constraint/Xor.php';
  296. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Error.php';
  297. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Error/Deprecated.php';
  298. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Error/Notice.php';
  299. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Error/Warning.php';
  300. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/ExceptionWrapper.php';
  301. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/ExpectationFailedException.php';
  302. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/IncompleteTest.php';
  303. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/IncompleteTestCase.php';
  304. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/IncompleteTestError.php';
  305. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/SkippedTest.php';
  306. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/InvalidCoversTargetError.php';
  307. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/InvalidCoversTargetException.php';
  308. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Exception/Exception.php';
  309. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Exception/BadMethodCallException.php';
  310. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/Identity.php';
  311. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/Stub.php';
  312. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/Match.php';
  313. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/ParametersMatch.php';
  314. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/MethodNameMatch.php';
  315. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/InvocationMocker.php';
  316. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/Namespace.php';
  317. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Generator.php';
  318. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Invocation.php';
  319. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Invocation/Static.php';
  320. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Invocation/Object.php';
  321. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/MatcherCollection.php';
  322. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Verifiable.php';
  323. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Invokable.php';
  324. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/InvocationMocker.php';
  325. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/Invocation.php';
  326. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher.php';
  327. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedRecorder.php';
  328. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/AnyInvokedCount.php';
  329. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/StatelessInvocation.php';
  330. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/AnyParameters.php';
  331. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/ConsecutiveParameters.php';
  332. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtIndex.php';
  333. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastCount.php';
  334. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastOnce.php';
  335. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtMostCount.php';
  336. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedCount.php';
  337. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/MethodName.php';
  338. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/Parameters.php';
  339. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/MockBuilder.php';
  340. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/MockObject.php';
  341. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Exception/RuntimeException.php';
  342. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub.php';
  343. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/ConsecutiveCalls.php';
  344. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/Exception.php';
  345. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/Return.php';
  346. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnArgument.php';
  347. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnCallback.php';
  348. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnSelf.php';
  349. require 'phar://phpunit-4.7.7.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnValueMap.php';
  350. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/OutputError.php';
  351. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/RiskyTest.php';
  352. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/RiskyTestError.php';
  353. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/SkippedTestCase.php';
  354. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/SkippedTestError.php';
  355. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/SkippedTestSuiteError.php';
  356. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/SyntheticError.php';
  357. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/TestFailure.php';
  358. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/TestResult.php';
  359. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/TestSuite/DataProvider.php';
  360. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/UnintentionallyCoveredCodeError.php';
  361. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Framework/Warning.php';
  362. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Runner/BaseTestRunner.php';
  363. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Runner/Exception.php';
  364. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Runner/Filter/Factory.php';
  365. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Runner/Filter/Group.php';
  366. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Runner/Filter/Group/Exclude.php';
  367. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Runner/Filter/Group/Include.php';
  368. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Runner/Filter/Test.php';
  369. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Runner/TestSuiteLoader.php';
  370. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Runner/StandardTestSuiteLoader.php';
  371. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Runner/Version.php';
  372. require 'phar://phpunit-4.7.7.phar' . '/phpunit/TextUI/Command.php';
  373. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/Printer.php';
  374. require 'phar://phpunit-4.7.7.phar' . '/phpunit/TextUI/ResultPrinter.php';
  375. require 'phar://phpunit-4.7.7.phar' . '/phpunit/TextUI/TestRunner.php';
  376. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/Blacklist.php';
  377. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/Configuration.php';
  378. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/ErrorHandler.php';
  379. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/Fileloader.php';
  380. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/Filesystem.php';
  381. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/Filter.php';
  382. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/Getopt.php';
  383. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/GlobalState.php';
  384. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/InvalidArgumentHelper.php';
  385. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/Log/JSON.php';
  386. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/Log/JUnit.php';
  387. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/Log/TAP.php';
  388. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/PHP.php';
  389. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/PHP/Default.php';
  390. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/PHP/Windows.php';
  391. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/Regex.php';
  392. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/String.php';
  393. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/Test.php';
  394. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/TestDox/NamePrettifier.php';
  395. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/TestDox/ResultPrinter.php';
  396. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/TestDox/ResultPrinter/HTML.php';
  397. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/TestDox/ResultPrinter/Text.php';
  398. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/TestSuiteIterator.php';
  399. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/Type.php';
  400. require 'phar://phpunit-4.7.7.phar' . '/phpunit/Util/XML.php';
  401. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Argument.php';
  402. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Argument/ArgumentsWildcard.php';
  403. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/TokenInterface.php';
  404. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/AnyValuesToken.php';
  405. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/AnyValueToken.php';
  406. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/ArrayCountToken.php';
  407. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/ArrayEntryToken.php';
  408. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/ArrayEveryEntryToken.php';
  409. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/CallbackToken.php';
  410. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/ExactValueToken.php';
  411. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/IdenticalValueToken.php';
  412. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/LogicalAndToken.php';
  413. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/LogicalNotToken.php';
  414. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/ObjectStateToken.php';
  415. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/StringContainsToken.php';
  416. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/TypeToken.php';
  417. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Call/Call.php';
  418. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Call/CallCenter.php';
  419. require 'phar://phpunit-4.7.7.phar' . '/sebastian-comparator/Comparator.php';
  420. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Comparator/ClosureComparator.php';
  421. require 'phar://phpunit-4.7.7.phar' . '/sebastian-comparator/Factory.php';
  422. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Comparator/Factory.php';
  423. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/Doubler.php';
  424. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/CachedDoubler.php';
  425. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php';
  426. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php';
  427. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/HhvmExceptionPatch.php';
  428. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/KeywordPatch.php';
  429. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/MagicCallPatch.php';
  430. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php';
  431. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php';
  432. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php';
  433. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/TraversablePatch.php';
  434. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/DoubleInterface.php';
  435. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/ClassCodeGenerator.php';
  436. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/ClassCreator.php';
  437. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/ClassMirror.php';
  438. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/Node/ArgumentNode.php';
  439. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/Node/ClassNode.php';
  440. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/Node/MethodNode.php';
  441. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/ReflectionInterface.php';
  442. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/LazyDouble.php';
  443. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Doubler/NameGenerator.php';
  444. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Exception.php';
  445. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Prophecy/ProphecyException.php';
  446. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Prophecy/ObjectProphecyException.php';
  447. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Call/UnexpectedCallException.php';
  448. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/DoublerException.php';
  449. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/ClassCreatorException.php';
  450. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/ClassMirrorException.php';
  451. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/DoubleException.php';
  452. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/ClassNotFoundException.php';
  453. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/InterfaceNotFoundException.php';
  454. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/MethodNotFoundException.php';
  455. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/ReturnByReferenceException.php';
  456. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/InvalidArgumentException.php';
  457. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/PredictionException.php';
  458. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/AggregateException.php';
  459. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/FailedPredictionException.php';
  460. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Prophecy/MethodProphecyException.php';
  461. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/NoCallsException.php';
  462. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/UnexpectedCallsException.php';
  463. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php';
  464. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Prediction/PredictionInterface.php';
  465. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Prediction/CallbackPrediction.php';
  466. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Prediction/CallPrediction.php';
  467. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Prediction/CallTimesPrediction.php';
  468. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Prediction/NoCallsPrediction.php';
  469. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Promise/PromiseInterface.php';
  470. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Promise/CallbackPromise.php';
  471. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Promise/ReturnArgumentPromise.php';
  472. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Promise/ReturnPromise.php';
  473. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Promise/ThrowPromise.php';
  474. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Prophecy/MethodProphecy.php';
  475. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Prophecy/ProphecyInterface.php';
  476. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Prophecy/ObjectProphecy.php';
  477. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Prophecy/ProphecySubjectInterface.php';
  478. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Prophecy/RevealerInterface.php';
  479. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Prophecy/Revealer.php';
  480. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Prophet.php';
  481. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Util/ExportUtil.php';
  482. require 'phar://phpunit-4.7.7.phar' . '/phpspec-prophecy/Prophecy/Util/StringUtil.php';
  483. require 'phar://phpunit-4.7.7.phar' . '/sebastian-comparator/ArrayComparator.php';
  484. require 'phar://phpunit-4.7.7.phar' . '/sebastian-comparator/ComparisonFailure.php';
  485. require 'phar://phpunit-4.7.7.phar' . '/sebastian-comparator/ObjectComparator.php';
  486. require 'phar://phpunit-4.7.7.phar' . '/sebastian-comparator/DateTimeComparator.php';
  487. require 'phar://phpunit-4.7.7.phar' . '/sebastian-comparator/DOMNodeComparator.php';
  488. require 'phar://phpunit-4.7.7.phar' . '/sebastian-comparator/ScalarComparator.php';
  489. require 'phar://phpunit-4.7.7.phar' . '/sebastian-comparator/NumericComparator.php';
  490. require 'phar://phpunit-4.7.7.phar' . '/sebastian-comparator/DoubleComparator.php';
  491. require 'phar://phpunit-4.7.7.phar' . '/sebastian-comparator/ExceptionComparator.php';
  492. require 'phar://phpunit-4.7.7.phar' . '/sebastian-comparator/MockObjectComparator.php';
  493. require 'phar://phpunit-4.7.7.phar' . '/sebastian-comparator/ResourceComparator.php';
  494. require 'phar://phpunit-4.7.7.phar' . '/sebastian-comparator/SplObjectStorageComparator.php';
  495. require 'phar://phpunit-4.7.7.phar' . '/sebastian-comparator/TypeComparator.php';
  496. require 'phar://phpunit-4.7.7.phar' . '/sebastian-diff/Chunk.php';
  497. require 'phar://phpunit-4.7.7.phar' . '/sebastian-diff/Diff.php';
  498. require 'phar://phpunit-4.7.7.phar' . '/sebastian-diff/Differ.php';
  499. require 'phar://phpunit-4.7.7.phar' . '/sebastian-diff/LCS/LongestCommonSubsequence.php';
  500. require 'phar://phpunit-4.7.7.phar' . '/sebastian-diff/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php';
  501. require 'phar://phpunit-4.7.7.phar' . '/sebastian-diff/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php';
  502. require 'phar://phpunit-4.7.7.phar' . '/sebastian-diff/Line.php';
  503. require 'phar://phpunit-4.7.7.phar' . '/sebastian-diff/Parser.php';
  504. require 'phar://phpunit-4.7.7.phar' . '/sebastian-environment/Console.php';
  505. require 'phar://phpunit-4.7.7.phar' . '/sebastian-environment/Runtime.php';
  506. require 'phar://phpunit-4.7.7.phar' . '/sebastian-exporter/Exporter.php';
  507. require 'phar://phpunit-4.7.7.phar' . '/sebastian-global-state/Blacklist.php';
  508. require 'phar://phpunit-4.7.7.phar' . '/sebastian-global-state/Exception.php';
  509. require 'phar://phpunit-4.7.7.phar' . '/sebastian-global-state/Restorer.php';
  510. require 'phar://phpunit-4.7.7.phar' . '/sebastian-global-state/RuntimeException.php';
  511. require 'phar://phpunit-4.7.7.phar' . '/sebastian-global-state/Snapshot.php';
  512. require 'phar://phpunit-4.7.7.phar' . '/sebastian-recursion-context/Context.php';
  513. require 'phar://phpunit-4.7.7.phar' . '/sebastian-recursion-context/Exception.php';
  514. require 'phar://phpunit-4.7.7.phar' . '/sebastian-recursion-context/InvalidArgumentException.php';
  515. require 'phar://phpunit-4.7.7.phar' . '/sebastian-version/Version.php';
  516. require 'phar://phpunit-4.7.7.phar' . '/symfony/yaml/Dumper.php';
  517. require 'phar://phpunit-4.7.7.phar' . '/symfony/yaml/Escaper.php';
  518. require 'phar://phpunit-4.7.7.phar' . '/symfony/yaml/Exception/ExceptionInterface.php';
  519. require 'phar://phpunit-4.7.7.phar' . '/symfony/yaml/Exception/RuntimeException.php';
  520. require 'phar://phpunit-4.7.7.phar' . '/symfony/yaml/Exception/DumpException.php';
  521. require 'phar://phpunit-4.7.7.phar' . '/symfony/yaml/Exception/ParseException.php';
  522. require 'phar://phpunit-4.7.7.phar' . '/symfony/yaml/Inline.php';
  523. require 'phar://phpunit-4.7.7.phar' . '/symfony/yaml/Parser.php';
  524. require 'phar://phpunit-4.7.7.phar' . '/symfony/yaml/Unescaper.php';
  525. require 'phar://phpunit-4.7.7.phar' . '/symfony/yaml/Yaml.php';
  526. require 'phar://phpunit-4.7.7.phar' . '/php-text-template/Template.php';
  527. if ($execute) {
  528. if (isset($_SERVER['argv'][1]) && $_SERVER['argv'][1] == '--manifest') {
  529. print file_get_contents(__PHPUNIT_PHAR_ROOT__ . '/manifest.txt');
  530. exit;
  531. }
  532. PHPUnit_TextUI_Command::main();
  533. }
  534. __HALT_COMPILER(); ?>
  535. =³��9���������phpunit-4.7.7.phar����$���sebastian-global-state/Exception.phpþ��¡£Uþ�� ª„´¶������#���sebastian-global-state/Snapshot.php',��¡£U',��5+å ¶���������sebastian-global-state/LICENSE
  536. ��¡£U
  537. ��êâ¶������#���sebastian-global-state/Restorer.phpž��¡£Už��­}FÔ¶������$���sebastian-global-state/Blacklist.php#��¡£U#��Òf1“¶������+���sebastian-global-state/RuntimeException.php0 ��¡£U0 ���Èyv¶���������php-text-template/LICENSE ��¡£U ��Sñ:ü¶���������php-text-template/Template.php” ��¡£U” ��¯w4¯¶���������sebastian-diff/LICENSE��¡£U��vEvö������/���sebastian-diff/LCS/LongestCommonSubsequence.phpº��¡£Uº��»Ø›¶������L���sebastian-diff/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.phpô
  538. ��¡£Uô
  539. ��ƒÓg8¶������J���sebastian-diff/LCS/TimeEfficientLongestCommonSubsequenceImplementation.phpá��¡£Uá��н¸r¶���������sebastian-diff/Line.phpé��¡£Ué��ü¼éζ���������sebastian-diff/Differ.php��¡£U��ºŒ<6¶���������sebastian-diff/Parser.phps ��¡£Us ��vÚ ^¶���������sebastian-diff/Diff.php��¡£U��²ª¶���������sebastian-diff/Chunk.php��¡£U��9LKé¶���������php-timer/Timer.phps
  540. ��¡£Us
  541. ��æQ—™¶���������php-timer/LICENSE��¡£U��ǨAE¶���������sebastian-comparator/LICENSE ��¡£U ��”:¶������#���sebastian-comparator/Comparator.php ��¡£U ��o:7¶������3���sebastian-comparator/SplObjectStorageComparator.php6 ��¡£U6 ��íÃÓɶ������'���sebastian-comparator/TypeComparator.php@ ��¡£U@ ��ÍFòñ¶������)���sebastian-comparator/ObjectComparator.php.��¡£U.��˯?ð¶������+���sebastian-comparator/ResourceComparator.phpŠ��¡£UŠ��aõµV¶������(���sebastian-comparator/ArrayComparator.phpv��¡£Uv�� ÀíÕ¶������+���sebastian-comparator/DateTimeComparator.php™ ��¡£U™ ��JzM¶������,���sebastian-comparator/ExceptionComparator.php��¡£U��ƒîÔ¶������*���sebastian-comparator/DOMNodeComparator.php,��¡£U,��ûû�W¶������)���sebastian-comparator/ScalarComparator.phpÏ��¡£UÏ��"’18¶������-���sebastian-comparator/MockObjectComparator.phpé��¡£Ué��ÂÌSö¶������*���sebastian-comparator/NumericComparator.phpF ��¡£UF ��»š`¶������ ���sebastian-comparator/Factory.php‰ ��¡£U‰ ��@‹Ø¶������)���sebastian-comparator/DoubleComparator.phpÐ��¡£UÐ��š¼ž×¶������*���sebastian-comparator/ComparisonFailure.phpÅ ��¡£UÅ ��ƒÓºª¶���������phpspec-prophecy/LICENSE}��¡£U}��òÅ6¶������8���phpspec-prophecy/Prophecy/Prophecy/RevealerInterface.phpH��¡£UH��‡gZ¶¶������?���phpspec-prophecy/Prophecy/Prophecy/ProphecySubjectInterface.phpß��¡£Uß��i²¶������/���phpspec-prophecy/Prophecy/Prophecy/Revealer.php���¡£U���jÉɸ¶������8���phpspec-prophecy/Prophecy/Prophecy/ProphecyInterface.php,��¡£U,��¡W¶������5���phpspec-prophecy/Prophecy/Prophecy/ObjectProphecy.phpk��¡£Uk��k„ʶ������5���phpspec-prophecy/Prophecy/Prophecy/MethodProphecy.php(��¡£U(��ç�ÔŶ������:���phpspec-prophecy/Prophecy/Comparator/ClosureComparator.phpK��¡£UK��)RQã¶������0���phpspec-prophecy/Prophecy/Comparator/Factory.php¡��¡£U¡��Aê϶������&���phpspec-prophecy/Prophecy/Argument.php^��¡£U^��l”¶������%���phpspec-prophecy/Prophecy/Prophet.php��¡£U��çvq޶������1���phpspec-prophecy/Prophecy/Exception/Exception.php+��¡£U+��¸µ‘¶������H���phpspec-prophecy/Prophecy/Exception/Prophecy/ObjectProphecyException.php��¡£U��†:‚F¶������B���phpspec-prophecy/Prophecy/Exception/Prophecy/ProphecyException.php™��¡£U™��Üê$϶������H���phpspec-prophecy/Prophecy/Exception/Prophecy/MethodProphecyException.php)��¡£U)��Fù¢4¶������J���phpspec-prophecy/Prophecy/Exception/Doubler/InterfaceNotFoundException.phpà��¡£Uà��õ¡…ý¶������D���phpspec-prophecy/Prophecy/Exception/Doubler/ClassMirrorException.phpª��¡£Uª��Û‰?¶������?���phpspec-prophecy/Prophecy/Exception/Doubler/DoubleException.php©��¡£U©��zéFƒ¶������@���phpspec-prophecy/Prophecy/Exception/Doubler/DoublerException.php—��¡£U—��ÃZ^¶������G���phpspec-prophecy/Prophecy/Exception/Doubler/MethodNotFoundException.phpÖ��¡£UÖ��iÞhó¶������J���phpspec-prophecy/Prophecy/Exception/Doubler/ReturnByReferenceException.php���¡£U���ýª¶������E���phpspec-prophecy/Prophecy/Exception/Doubler/ClassCreatorException.phpµ��¡£Uµ��77/%¶������F���phpspec-prophecy/Prophecy/Exception/Doubler/ClassNotFoundException.phpÅ��¡£UÅ��h+������K���phpspec-prophecy/Prophecy/Exception/Prediction/UnexpectedCallsException.php,��¡£U,����õa¶������F���phpspec-prophecy/Prophecy/Exception/Prediction/PredictionException.php���¡£U���2T¢Ñ¶������L���phpspec-prophecy/Prophecy/Exception/Prediction/FailedPredictionException.phpJ��¡£UJ��~ÐãD¶������C���phpspec-prophecy/Prophecy/Exception/Prediction/NoCallsException.phpÚ��¡£UÚ��Ál<�¶������E���phpspec-prophecy/Prophecy/Exception/Prediction/AggregateException.php»��¡£U»��?D<ζ������P���phpspec-prophecy/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php��¡£U��æ Æ¶������D���phpspec-prophecy/Prophecy/Exception/Call/UnexpectedCallException.phpÖ��¡£UÖ��£Áó¸¶������@���phpspec-prophecy/Prophecy/Exception/InvalidArgumentException.php•��¡£U•��¨gì¶������3���phpspec-prophecy/Prophecy/Doubler/CachedDoubler.phpƒ��¡£Uƒ��̇gè¶������5���phpspec-prophecy/Prophecy/Doubler/DoubleInterface.phpâ��¡£Uâ��8d�j¶������-���phpspec-prophecy/Prophecy/Doubler/Doubler.php���¡£U���8]Õ^¶������B���phpspec-prophecy/Prophecy/Doubler/Generator/ClassCodeGenerator.phpU
  542. ��¡£UU
  543. ��J9½y¶������<���phpspec-prophecy/Prophecy/Doubler/Generator/ClassCreator.phpÔ��¡£UÔ��ä?Br¶������C���phpspec-prophecy/Prophecy/Doubler/Generator/ReflectionInterface.phpò��¡£Uò��çûªå¶������;���phpspec-prophecy/Prophecy/Doubler/Generator/ClassMirror.phpŒ��¡£UŒ��p%f¶������A���phpspec-prophecy/Prophecy/Doubler/Generator/Node/ArgumentNode.phpš��¡£Uš��^ž¶������?���phpspec-prophecy/Prophecy/Doubler/Generator/Node/MethodNode.phpÛ
  544. ��¡£UÛ
  545. ��ÿ¸Ó¶������>���phpspec-prophecy/Prophecy/Doubler/Generator/Node/ClassNode.phpP
  546. ��¡£UP
  547. ��M°-ж������0���phpspec-prophecy/Prophecy/Doubler/LazyDouble.phpF ��¡£UF ��¼ël¦¶������=���phpspec-prophecy/Prophecy/Doubler/ClassPatch/KeywordPatch.php½ ��¡£U½ ��û/@ȶ������E���phpspec-prophecy/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.phpô
  548. ��¡£Uô
  549. ��Ân–i¶������?���phpspec-prophecy/Prophecy/Doubler/ClassPatch/MagicCallPatch.phpâ��¡£Uâ��Áyú¶������A���phpspec-prophecy/Prophecy/Doubler/ClassPatch/TraversablePatch.php ��¡£U ��§€jN¶������A���phpspec-prophecy/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php���¡£U���!h^¶������H���phpspec-prophecy/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php’��¡£U’��:0`ò¶������C���phpspec-prophecy/Prophecy/Doubler/ClassPatch/HhvmExceptionPatch.phpÑ��¡£UÑ��x“Â^¶������P���phpspec-prophecy/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.phpp��¡£Up��x¤¿ˆ¶������D���phpspec-prophecy/Prophecy/Doubler/ClassPatch/ClassPatchInterface.phpl��¡£Ul��)Š5:¶������3���phpspec-prophecy/Prophecy/Doubler/NameGenerator.phpŠ��¡£UŠ��õÑ7¶������<���phpspec-prophecy/Prophecy/Prediction/CallTimesPrediction.php“ ��¡£U“ ��XŠü¶������:���phpspec-prophecy/Prophecy/Prediction/NoCallsPrediction.phpå��¡£Uå��L9%¶������<���phpspec-prophecy/Prophecy/Prediction/PredictionInterface.phpŸ��¡£UŸ��`IE¶������;���phpspec-prophecy/Prophecy/Prediction/CallbackPrediction.php“��¡£U“��Vb{ζ������7���phpspec-prophecy/Prophecy/Prediction/CallPrediction.phpQ ��¡£UQ ��Iæ“é¶������'���phpspec-prophecy/Prophecy/Call/Call.phpÓ ��¡£UÓ ��{:å%¶������-���phpspec-prophecy/Prophecy/Call/CallCenter.phpm��¡£Um��š[µ9¶������2���phpspec-prophecy/Prophecy/Promise/ThrowPromise.php9
  550. ��¡£U9
  551. ��˜½cu¶������;���phpspec-prophecy/Prophecy/Promise/ReturnArgumentPromise.php��¡£U��¨ô%A¶������3���phpspec-prophecy/Prophecy/Promise/ReturnPromise.php��¡£U��çØ�ä¶������5���phpspec-prophecy/Prophecy/Promise/CallbackPromise.php���¡£U���[žÜ¶������6���phpspec-prophecy/Prophecy/Promise/PromiseInterface.phpK��¡£UK��¾¬…ë¶������8���phpspec-prophecy/Prophecy/Argument/ArgumentsWildcard.php4 ��¡£U4 ��A;K2¶������:���phpspec-prophecy/Prophecy/Argument/Token/AnyValueToken.php«��¡£U«��F�h¶������A���phpspec-prophecy/Prophecy/Argument/Token/ArrayEveryEntryToken.php’��¡£U’��pbø�¶������<���phpspec-prophecy/Prophecy/Argument/Token/LogicalAndToken.phpø��¡£Uø�� Nãv¶������;���phpspec-prophecy/Prophecy/Argument/Token/TokenInterface.php���¡£U���Ù°Š¼¶������<���phpspec-prophecy/Prophecy/Argument/Token/ArrayEntryToken.php”��¡£U”��ÞJú:¶������<���phpspec-prophecy/Prophecy/Argument/Token/ArrayCountToken.phpá��¡£Uá��‚4®Ì¶������;���phpspec-prophecy/Prophecy/Argument/Token/AnyValuesToken.phpÚ��¡£UÚ��ÖbN/¶������@���phpspec-prophecy/Prophecy/Argument/Token/StringContainsToken.phpü��¡£Uü��‰ÑÊ>¶������<���phpspec-prophecy/Prophecy/Argument/Token/ExactValueToken.php¡ ��¡£U¡ ���…3�¶������=���phpspec-prophecy/Prophecy/Argument/Token/ObjectStateToken.php9
  552. ��¡£U9
  553. ��_ÛJg¶������:���phpspec-prophecy/Prophecy/Argument/Token/CallbackToken.php,��¡£U,��cRÊ̶������@���phpspec-prophecy/Prophecy/Argument/Token/IdenticalValueToken.phpæ��¡£Uæ���¯Êý¶������<���phpspec-prophecy/Prophecy/Argument/Token/LogicalNotToken.php��¡£U��ܼr¶������6���phpspec-prophecy/Prophecy/Argument/Token/TypeToken.php¥��¡£U¥��®næ\¶������-���phpspec-prophecy/Prophecy/Util/ExportUtil.php„��¡£U„��ѪzH¶������-���phpspec-prophecy/Prophecy/Util/StringUtil.phpì ��¡£Uì ��%ø¶���������sebastian-exporter/LICENSE��¡£U��Aªe)¶���������sebastian-exporter/Exporter.php*#��¡£U*#��žÓl×¶���������php-file-iterator/LICENSE ��¡£U ��¶És‰¶���������php-file-iterator/Iterator.php²��¡£U²��¬É¶���������php-file-iterator/Facade.phpô ��¡£Uô ��Q–í›¶���������php-file-iterator/Factory.php¸
  554. ��¡£U¸
  555. ��dÂŽ¶������ ���manifest.txt_��¡£U_��Ë8 U¶������)���sebastian-recursion-context/Exception.phpˆ��¡£Uˆ��>å™3¶������#���sebastian-recursion-context/LICENSE��¡£U��Éðζ������'���sebastian-recursion-context/Context.php°��¡£U°��ø¿Nê¶������8���sebastian-recursion-context/InvalidArgumentException.phpÐ��¡£UÐ��Ê ¨ú¶������0���phpunit-selenium/Extensions/SeleniumTestCase.phpÀ—��¡£UÀ—��Ãv�K¶������1���phpunit-selenium/Extensions/SeleniumTestSuite.php���¡£U���®šä¶������7���phpunit-selenium/Extensions/SeleniumTestCase/Driver.phpM°��¡£UM°��0âR¶������6���phpunit-selenium/Extensions/Selenium2TestCase/Keys.phpI��¡£UI��î†Í¶������H���phpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie/Builder.php��¡£U��Ó¸q¶������B���phpunit-selenium/Extensions/Selenium2TestCase/Session/Timeouts.php]��¡£U]��œ/X¶������A���phpunit-selenium/Extensions/Selenium2TestCase/Session/Storage.php8 ��¡£U8 ��›‚º¶������@���phpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie.phpý��¡£Uý��$!¸–¶������;���phpunit-selenium/Extensions/Selenium2TestCase/Exception.phpã ��¡£Uã ��H"Ç[¶������@���phpunit-selenium/Extensions/Selenium2TestCase/CommandsHolder.phpË��¡£UË��Zew¶������D���phpunit-selenium/Extensions/Selenium2TestCase/ScreenshotListener.phpØ��¡£UØ��h­7Ƕ������9���phpunit-selenium/Extensions/Selenium2TestCase/Command.phpL ��¡£UL ��Îcyƶ������>���phpunit-selenium/Extensions/Selenium2TestCase/StateCommand.phpw
  556. ��¡£Uw
  557. �� e3Z¶������9���phpunit-selenium/Extensions/Selenium2TestCase/Element.php ��¡£U ��&éø¶������:���phpunit-selenium/Extensions/Selenium2TestCase/Response.php��¡£U��TZ¶������E���phpunit-selenium/Extensions/Selenium2TestCase/NoSeleniumException.phpÅ ��¡£UÅ ��Ûök¶������H���phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Shared.phpH��¡£UH��ÚVm’¶������J���phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Isolated.php’ ��¡£U’ ���ìͶ������F���phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Click.php+
  558. ��¡£U+
  559. ��¡Ä»¶������G���phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Equals.php` ��¡£U` ��Én±Õ¶������P���phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericAccessor.phpi
  560. ��¡£Ui
  561. ��•Pe¶������L���phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericPost.phpW
  562. ��¡£UW
  563. ��ëLq¶������F���phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Value.phpG ��¡£UG ��+Uç¶������J���phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Attribute.phpt ��¡£Ut �� ˈ¶������D���phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Css.phpi ��¡£Ui ��ó¶������A���phpunit-selenium/Extensions/Selenium2TestCase/ElementCriteria.phpN ��¡£UN ���ʶ������8���phpunit-selenium/Extensions/Selenium2TestCase/Window.phpO ��¡£UO ��S§ßô¶������8���phpunit-selenium/Extensions/Selenium2TestCase/Driver.phpÑ��¡£UÑ��eÅ5v¶������;���phpunit-selenium/Extensions/Selenium2TestCase/WaitUntil.php”��¡£U”��z“¶������D���phpunit-selenium/Extensions/Selenium2TestCase/WebDriverException.phpf ��¡£Uf ��ÍK1ï¶������E���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Keys.php$��¡£U$��wîͶ������F���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Click.php» ��¡£U» ��^ÿaé¶������I���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Location.phpÏ ��¡£UÏ ��ô¡Ë ¶������P���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAccessor.phpT
  564. ��¡£UT
  565. ��X·ì¶������E���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/File.phpè��¡£Uè��0“ß—¶������L���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AcceptAlert.php1
  566. ��¡£U1
  567. ��BHǶ������J���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AlertText.phpC ��¡£UC ��lXim¶������D���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Url.php ��¡£U ��K¸Ž¶������G���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Window.phpÜ
  568. ��¡£UÜ
  569. ��•ˆ’¶������Q���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAttribute.phpŸ
  570. ��¡£UŸ
  571. ��›Bí¶������G���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/MoveTo.phpÎ��¡£UÎ��£-
  572. ¶������L���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Orientation.phpÞ ��¡£UÞ ��@\WI¶������D���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Log.php ��¡£U ��œð"=¶������G���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Active.php
  573. ��¡£U
  574. ��×6¸¶������M���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/DismissAlert.php6
  575. ��¡£U6
  576. ��Ñv’l¶������F���phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Frame.php¶ ��¡£U¶ ��çz"¶������5���phpunit-selenium/Extensions/Selenium2TestCase/URL.php™��¡£U™��HFž¶������A���phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy.php¡ ��¡£U¡ ��̳ãr¶������<���phpunit-selenium/Extensions/Selenium2TestCase/KeysHolder.php��¡£U��Ñ|ÚH¶������B���phpunit-selenium/Extensions/Selenium2TestCase/Element/Accessor.php¯��¡£U¯��û\w€¶������@���phpunit-selenium/Extensions/Selenium2TestCase/Element/Select.php­��¡£U­��ëL@"¶������9���phpunit-selenium/Extensions/Selenium2TestCase/Session.php!1��¡£U!1��š ™¶������6���phpunit-selenium/Extensions/SeleniumCommon/prepend.php? ��¡£U? ��°·³¶������5���phpunit-selenium/Extensions/SeleniumCommon/append.php ��¡£U ��›·ú÷¶������=���phpunit-selenium/Extensions/SeleniumCommon/RemoteCoverage.phpI��¡£UI��Ý\´.¶������:���phpunit-selenium/Extensions/SeleniumCommon/ExitHandler.php*��¡£U*��¢èÏ϶������?���phpunit-selenium/Extensions/SeleniumCommon/phpunit_coverage.php`��¡£U`��½ùOm¶������4���phpunit-selenium/Extensions/SeleniumBrowserSuite.phpò��¡£Uò��D³¥¶������1���phpunit-selenium/Extensions/Selenium2TestCase.php!E��¡£U!E��ï[‘ñ¶������'���php-code-coverage/CodeCoverage/Util.phpÍ��¡£UÍ��¢K϶������,���php-code-coverage/CodeCoverage/Exception.php¤��¡£U¤��K)§¶������7���php-code-coverage/CodeCoverage/Report/HTML/Renderer.phpE��¡£UE��Ô+ç¶������A���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Dashboard.phpâ&��¡£Uâ&��b; ¶������<���php-code-coverage/CodeCoverage/Report/HTML/Renderer/File.php-L��¡£U-L��³g÷â¶������P���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/dashboard.html.dist��¡£U��ýò{¶������P���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/directory.html.diste��¡£Ue��Ç�¥ô¶������S���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/coverage_bar.html.dist1��¡£U1��itLì¶������P���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/bootstrap.min.jsoŒ��¡£UoŒ��;¦� ¶������I���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/d3.min.jsUN�¡£UUN�;Áë1¶������N���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/respond.min.js��¡£U��í{¶������P���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/html5shiv.min.jsL
  577. ��¡£UL
  578. ��F¨¶������M���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/holder.min.js m��¡£U m��JësѶ������L���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/nv.d3.min.jsú]�¡£Uú]�'Â]4¶������M���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/jquery.min.jsÕv�¡£UÕv�†e“¶������P���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/file_item.html.distg��¡£Ug��V³ P¶������R���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/method_item.html.distx��¡£Ux��*öŒ¶������U���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/directory_item.html.dist5��¡£U5��ñZˆ]¶������K���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/file.html.distþ
  579. ��¡£Uþ
  580. ��øýŠD¶������J���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/css/style.css+��¡£U+��Y`üg¶������N���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/css/nv.d3.min.cssX%��¡£UX%���0,¶������R���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/css/bootstrap.min.css9Ê�¡£U9Ê�Ü›2ø¶������c���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.ttf\±��¡£U\±��š<œ¶������e���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.woff2lF��¡£UlF��vèÃa¶������d���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.woff€[��¡£U€[��ê{õ¶������c���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.eotŸN��¡£UŸN��XDZœ¶������c���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.svg¨�¡£U¨�|îÆÉ¶������A���php-code-coverage/CodeCoverage/Report/HTML/Renderer/Directory.php| ��¡£U| ��¡Ü¶������0���php-code-coverage/CodeCoverage/Report/Crap4j.php-��¡£U-��{ý+ض������3���php-code-coverage/CodeCoverage/Report/XML/Tests.php×��¡£U×��h$­6¶������2���php-code-coverage/CodeCoverage/Report/XML/File.php0��¡£U0��Šä�Ú¶������2���php-code-coverage/CodeCoverage/Report/XML/Node.php^��¡£U^��¸ðN¶������5���php-code-coverage/CodeCoverage/Report/XML/Project.php]��¡£U]��×h>µ¶������4���php-code-coverage/CodeCoverage/Report/XML/Totals.phpÇ��¡£UÇ��o·F¶������7���php-code-coverage/CodeCoverage/Report/XML/Directory.php‰��¡£U‰��ÑÒçZ¶������9���php-code-coverage/CodeCoverage/Report/XML/File/Method.phpu��¡£Uu��èîʶ������9���php-code-coverage/CodeCoverage/Report/XML/File/Report.phpC��¡£UC��¨Y{ȶ������;���php-code-coverage/CodeCoverage/Report/XML/File/Coverage.php5��¡£U5��€(+R¶������7���php-code-coverage/CodeCoverage/Report/XML/File/Unit.phpB
  581. ��¡£UB
  582. �� kr¶������.���php-code-coverage/CodeCoverage/Report/Node.phpê��¡£Uê��»ä2Þ¶������7���php-code-coverage/CodeCoverage/Report/Node/Iterator.php‚��¡£U‚��M¶q¶������3���php-code-coverage/CodeCoverage/Report/Node/File.php³G��¡£U³G��Òöû`¶������8���php-code-coverage/CodeCoverage/Report/Node/Directory.phpS(��¡£US(��Íü¶������0���php-code-coverage/CodeCoverage/Report/Clover.phpË'��¡£UË'��’déV¶������.���php-code-coverage/CodeCoverage/Report/HTML.php=��¡£U=��É0©µ¶������1���php-code-coverage/CodeCoverage/Report/Factory.phpk��¡£Uk��rp2”¶������-���php-code-coverage/CodeCoverage/Report/XML.phpl��¡£Ul��šËs›¶������-���php-code-coverage/CodeCoverage/Report/PHP.php��¡£U��4�R}¶������.���php-code-coverage/CodeCoverage/Report/Text.phpx!��¡£Ux!��`”¹k¶������G���php-code-coverage/CodeCoverage/Exception/UnintentionallyCoveredCode.phpØ��¡£UØ��}¶������)���php-code-coverage/CodeCoverage/Driver.phpb��¡£Ub��“<Ã\¶������)���php-code-coverage/CodeCoverage/Filter.php��¡£U��ÍÅ#™¶������=���php-code-coverage/CodeCoverage/Util/InvalidArgumentHelper.php=��¡£U=��Êû¶������.���php-code-coverage/CodeCoverage/Driver/HHVM.php,��¡£U,��œ^Ù¶������0���php-code-coverage/CodeCoverage/Driver/Xdebug.php´ ��¡£U´ ��PØ@¶���������php-code-coverage/LICENSE��¡£U��ЉxZ¶������"���php-code-coverage/CodeCoverage.php·e��¡£U·e��ƒ÷v¶���������symfony/LICENSE)��¡£U)��ë&•¶���������symfony/yaml/Inline.phphM��¡£UhM��€</ʶ���������symfony/yaml/Unescaper.phpÐ��¡£UÐ��éÒ�m¶���������symfony/yaml/Yaml.php,��¡£U,��¹÷ �¶������)���symfony/yaml/Exception/ParseException.php��¡£U��Î79‹¶������(���symfony/yaml/Exception/DumpException.phpÒ��¡£UÒ��ؙ՚¶������+���symfony/yaml/Exception/RuntimeException.phpð��¡£Uð��Ï|�-¶������-���symfony/yaml/Exception/ExceptionInterface.phpÆ��¡£UÆ��î+­l¶���������symfony/yaml/Parser.phpuh��¡£Uuh��6Q²}¶���������symfony/yaml/Dumper.php� ��¡£U� ��l£D¶���������symfony/yaml/Escaper.php��¡£U��K‹ã¶���������ca.pemñ��¡£Uñ��‹byë¶���������doctrine-instantiator/LICENSE$��¡£U$��
  583. Í‚å¶������E���doctrine-instantiator/Doctrine/Instantiator/InstantiatorInterface.php~��¡£U~��¶ÿÌ:¶������L���doctrine-instantiator/Doctrine/Instantiator/Exception/ExceptionInterface.php¥��¡£U¥��ó.ðö������R���doctrine-instantiator/Doctrine/Instantiator/Exception/InvalidArgumentException.phpô��¡£Uô��hÅ7I¶������R���doctrine-instantiator/Doctrine/Instantiator/Exception/UnexpectedValueException.phpÎ
  584. ��¡£UÎ
  585. ��"Ÿè ¶������<���doctrine-instantiator/Doctrine/Instantiator/Instantiator.phpà ��¡£Uà ��ü&à¶���������php-token-stream/LICENSE��¡£U��ƒ-& ¶������0���php-token-stream/Token/Stream/CachingFactory.php��¡£U��_¶������!���php-token-stream/Token/Stream.php*@��¡£U*@��ª[<¶���������php-token-stream/Token.phpd_��¡£Ud_��~϶������(���dbunit/Extensions/Database/Exception.php4��¡£U4��ó¾Ù¶������0���dbunit/Extensions/Database/UI/IMediumPrinter.phpØ��¡£UØ��…e c¶������)���dbunit/Extensions/Database/UI/Command.php{��¡£U{��ÿëTD¶������.���dbunit/Extensions/Database/UI/Mediums/Text.phpÊ
  586. ��¡£UÊ
  587. ��ºÐ]Ó¶������6���dbunit/Extensions/Database/UI/InvalidModeException.phpõ��¡£Uõ��~Ë%¶������'���dbunit/Extensions/Database/UI/IMode.phpæ��¡£Uæ��é=̶������)���dbunit/Extensions/Database/UI/Context.phpC��¡£UC��îä]¶������?���dbunit/Extensions/Database/UI/Modes/ExportDataSet/Arguments.php7 ��¡£U7 ��@?¶������5���dbunit/Extensions/Database/UI/Modes/ExportDataSet.php$ ��¡£U$ ��×\±À¶������)���dbunit/Extensions/Database/UI/IMedium.php‚��¡£U‚��ÐPî÷¶������-���dbunit/Extensions/Database/UI/ModeFactory.phpR ��¡£UR ��£²–û¶������.���dbunit/Extensions/Database/UI/IModeFactory.php��¡£U��[E†¶������4���dbunit/Extensions/Database/IDatabaseListConsumer.phpj��¡£Uj��ƒ�‚¶������2���dbunit/Extensions/Database/Operation/Exception.phpó��¡£Uó��GLO�¶������0���dbunit/Extensions/Database/Operation/Replace.php���¡£U���Ä –?¶������/���dbunit/Extensions/Database/Operation/Insert.php
  588. ��¡£U
  589. ��{³;¶������/���dbunit/Extensions/Database/Operation/Delete.phpD��¡£UD��œ=Œ¶������;���dbunit/Extensions/Database/Operation/IDatabaseOperation.phpü��¡£Uü��“AÜʶ������-���dbunit/Extensions/Database/Operation/Null.php³��¡£U³��L?¶������2���dbunit/Extensions/Database/Operation/DeleteAll.phpË��¡£UË��z”¶������/���dbunit/Extensions/Database/Operation/Update.phpÐ ��¡£UÐ ��µNÐB¶������1���dbunit/Extensions/Database/Operation/RowBased.phpS��¡£US��hÈ=¶������0���dbunit/Extensions/Database/Operation/Factory.phpá ��¡£Uá ��~÷õ¶������2���dbunit/Extensions/Database/Operation/Composite.php¸��¡£U¸��€fn­¶������1���dbunit/Extensions/Database/Operation/Truncate.phpè
  590. ��¡£Uè
  591. ��{�÷>¶������'���dbunit/Extensions/Database/TestCase.phpw!��¡£Uw!��´ƒY¶������-���dbunit/Extensions/Database/AbstractTester.phpM��¡£UM��/ýÅh¶������1���dbunit/Extensions/Database/DB/MetaData/Sqlite.php] ��¡£U] �� ÂŒ¶������0���dbunit/Extensions/Database/DB/MetaData/Dblib.phpû ��¡£Uû ��Ý_¶������0���dbunit/Extensions/Database/DB/MetaData/MySQL.phpõ ��¡£Uõ ���’¥†¶������<���dbunit/Extensions/Database/DB/MetaData/InformationSchema.php“��¡£U“��ý뛜¶������3���dbunit/Extensions/Database/DB/MetaData/Firebird.php��¡£U��ã{ê™¶������.���dbunit/Extensions/Database/DB/MetaData/Oci.php|��¡£U|��•ÍhŸ¶������0���dbunit/Extensions/Database/DB/MetaData/PgSQL.phpÞ��¡£UÞ��¸Ç¾�¶������1���dbunit/Extensions/Database/DB/MetaData/SqlSrv.php´��¡£U´��¼N|¶������'���dbunit/Extensions/Database/DB/Table.phpÒ��¡£UÒ��Ú~˜P¶������1���dbunit/Extensions/Database/DB/FilteredDataSet.phpv��¡£Uv��[å—T¶������5���dbunit/Extensions/Database/DB/IDatabaseConnection.php½ ��¡£U½ ��G$Ú/¶������/���dbunit/Extensions/Database/DB/TableMetaData.phpI��¡£UI��âŠ9�¶������*���dbunit/Extensions/Database/DB/MetaData.phpu��¡£Uu��«ðƒ»¶������;���dbunit/Extensions/Database/DB/DefaultDatabaseConnection.php2��¡£U2��ô†ç¾¶������+���dbunit/Extensions/Database/DB/IMetaData.php_��¡£U_��aI ¶������/���dbunit/Extensions/Database/DB/TableIterator.php³ ��¡£U³ ��åE¢Ï¶������)���dbunit/Extensions/Database/DB/DataSet.php��¡£U��Ú«¥.¶������0���dbunit/Extensions/Database/DB/ResultSetTable.php��¡£U��‚ƒ%®¶������,���dbunit/Extensions/Database/DefaultTester.phpØ��¡£UØ��Õª\¶������6���dbunit/Extensions/Database/Constraint/TableIsEqual.php¬ ��¡£U¬ ��ý­G¶������8���dbunit/Extensions/Database/Constraint/DataSetIsEqual.phpº ��¡£Uº ��ž_ˆÑ¶������7���dbunit/Extensions/Database/Constraint/TableRowCount.php½��¡£U½��Reƶ������&���dbunit/Extensions/Database/ITester.phpÓ ��¡£UÓ ��–%V¶������6���dbunit/Extensions/Database/DataSet/MysqlXmlDataSet.phpV��¡£UV��#꥗¶������3���dbunit/Extensions/Database/DataSet/QueryDataSet.php˜
  592. ��¡£U˜
  593. ��Èß¡¶������2���dbunit/Extensions/Database/DataSet/YamlDataSet.php<��¡£U<��®Êƒ¶������6���dbunit/Extensions/Database/DataSet/AbstractDataSet.phpÒ��¡£UÒ��Ý„¿¶������,���dbunit/Extensions/Database/DataSet/ISpec.php²��¡£U²��<Ñòê¶������2���dbunit/Extensions/Database/DataSet/TableFilter.php ��¡£U ��}œ޶������<���dbunit/Extensions/Database/DataSet/AbstractTableMetaData.php��¡£U��bà�¶������7���dbunit/Extensions/Database/DataSet/CompositeDataSet.php: ��¡£U: ��¹°&c¶������;���dbunit/Extensions/Database/DataSet/DefaultTableIterator.phpÍ
  594. ��¡£UÍ
  595. ��ŽÆoP¶������4���dbunit/Extensions/Database/DataSet/DataSetFilter.php?��¡£U?��f9¶k¶������2���dbunit/Extensions/Database/DataSet/IYamlParser.php��¡£U��f*¹¶������1���dbunit/Extensions/Database/DataSet/XmlDataSet.php²��¡£U²��R�ç)¶������5���dbunit/Extensions/Database/DataSet/DefaultDataSet.phpÀ��¡£UÀ��É¥|}¶������8���dbunit/Extensions/Database/DataSet/SymfonyYamlParser.phpO��¡£UO��Kä¾�¶������/���dbunit/Extensions/Database/DataSet/IDataSet.phpù��¡£Uù��¼)V@¶������5���dbunit/Extensions/Database/DataSet/ITableMetaData.phpa��¡£Ua��£+϶������:���dbunit/Extensions/Database/DataSet/Persistors/Abstract.php ��¡£U ��.BEö������5���dbunit/Extensions/Database/DataSet/Persistors/Xml.php? ��¡£U? ��}©¥)¶������9���dbunit/Extensions/Database/DataSet/Persistors/FlatXml.php“ ��¡£U“ ��6gtæ¶������6���dbunit/Extensions/Database/DataSet/Persistors/Yaml.php��¡£U��÷п§¶������:���dbunit/Extensions/Database/DataSet/Persistors/MysqlXml.phpë��¡£Uë��=¹j¶������9���dbunit/Extensions/Database/DataSet/Persistors/Factory.phpÞ��¡£UÞ��Ù°Å�¶������1���dbunit/Extensions/Database/DataSet/CsvDataSet.php��¡£U�� b«¶������?���dbunit/Extensions/Database/DataSet/ReplacementTableIterator.php¹��¡£U¹��‚ú·1¶������9���dbunit/Extensions/Database/DataSet/ReplacementDataSet.php‰ ��¡£U‰ ��Á´à`¶������3���dbunit/Extensions/Database/DataSet/ArrayDataSet.phps ��¡£Us ��L¹#¶������3���dbunit/Extensions/Database/DataSet/DefaultTable.php¯ ��¡£U¯ ��È&íâ¶������5���dbunit/Extensions/Database/DataSet/ITableIterator.php3��¡£U3��IÕ)ã¶������5���dbunit/Extensions/Database/DataSet/FlatXmlDataSet.php��¡£U��ïëèJ¶������3���dbunit/Extensions/Database/DataSet/IPersistable.php½��¡£U½��´)ж������9���dbunit/Extensions/Database/DataSet/AbstractXmlDataSet.phpÚ ��¡£UÚ ��w~¶������:���dbunit/Extensions/Database/DataSet/TableMetaDataFilter.phpS��¡£US��íN4µ¶������7���dbunit/Extensions/Database/DataSet/ReplacementTable.php\��¡£U\��—/ ¶������4���dbunit/Extensions/Database/DataSet/Specs/DbQuery.php
  596. ��¡£U
  597. ��†@é¶������0���dbunit/Extensions/Database/DataSet/Specs/Xml.phpÓ��¡£UÓ��þ�ýÙ¶������4���dbunit/Extensions/Database/DataSet/Specs/FlatXml.phpí��¡£Uí��{Éýt¶������1���dbunit/Extensions/Database/DataSet/Specs/Yaml.phpÙ��¡£UÙ��b—"V¶������5���dbunit/Extensions/Database/DataSet/Specs/IFactory.phpz��¡£Uz��(r¼K¶������0���dbunit/Extensions/Database/DataSet/Specs/Csv.phpŠ ��¡£UŠ ��–ÚSu¶������4���dbunit/Extensions/Database/DataSet/Specs/DbTable.php­ ��¡£U­ ��/.¹É¶������4���dbunit/Extensions/Database/DataSet/Specs/Factory.phpè��¡£Uè��w_¸S¶������1���dbunit/Extensions/Database/DataSet/QueryTable.php-��¡£U-��dqgƒ¶������4���dbunit/Extensions/Database/DataSet/AbstractTable.php€��¡£U€��¾¦=ˆ¶������-���dbunit/Extensions/Database/DataSet/ITable.phpE��¡£UE��Ë”À¶������;���dbunit/Extensions/Database/DataSet/DefaultTableMetaData.phpË��¡£UË��˜âÒ˶���������php-invoker/Invoker.phpï��¡£Uï�� wà¶������ ���php-invoker/TimeoutException.phpp��¡£Up��~ªø¶���������phpunit-mock-objects/LICENSE��¡£U��C>©¶������5���phpunit-mock-objects/Framework/MockObject/Matcher.php¨ ��¡£U¨ ��7÷�/¶������8���phpunit-mock-objects/Framework/MockObject/Verifiable.php²��¡£U²��”'L¶������7���phpunit-mock-objects/Framework/MockObject/Invokable.php9��¡£U9��Ùÿ~†¶������9���phpunit-mock-objects/Framework/MockObject/MockBuilder.php��¡£U��\_¶������A���phpunit-mock-objects/Framework/MockObject/Exception/Exception.php¦��¡£U¦��]ÃT¶������N���phpunit-mock-objects/Framework/MockObject/Exception/BadMethodCallException.phpÁ��¡£UÁ��¥Ò).¶������H���phpunit-mock-objects/Framework/MockObject/Exception/RuntimeException.phpµ��¡£Uµ��Y·n4¶������8���phpunit-mock-objects/Framework/MockObject/Invocation.php���¡£U���«s¶������8���phpunit-mock-objects/Framework/MockObject/MockObject.php9��¡£U9��¾éC…¶������>���phpunit-mock-objects/Framework/MockObject/InvocationMocker.php��¡£U��Ì2…×¶������@���phpunit-mock-objects/Framework/MockObject/Matcher/MethodName.php ��¡£U ��v´ж������H���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastOnce.phpÐ��¡£UÐ��cîþI¶������C���phpunit-mock-objects/Framework/MockObject/Matcher/AnyParameters.phpC��¡£UC��¹£¶������@���phpunit-mock-objects/Framework/MockObject/Matcher/Parameters.phpª��¡£Uª��œPjî¶������E���phpunit-mock-objects/Framework/MockObject/Matcher/AnyInvokedCount.phpà��¡£Uà��“Ds$¶������I���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastCount.phpü��¡£Uü�� R�¶������@���phpunit-mock-objects/Framework/MockObject/Matcher/Invocation.php��¡£U��Kôb¶������K���phpunit-mock-objects/Framework/MockObject/Matcher/ConsecutiveParameters.php¨��¡£U¨��iOm¶������D���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtIndex.php ��¡£U ��•åY©¶������B���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedCount.php  ��¡£U  �� SžG¶������H���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtMostCount.phpñ��¡£Uñ��ÃË÷¶������E���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedRecorder.php`��¡£U`��!Íñè¶������I���phpunit-mock-objects/Framework/MockObject/Matcher/StatelessInvocation.phpk��¡£Uk��û•϶������7���phpunit-mock-objects/Framework/MockObject/Generator.phpí”��¡£Uí”��«>çš¶������H���phpunit-mock-objects/Framework/MockObject/Generator/wsdl_method.tpl.dist<���¡£U<���¾Ði‰¶������K���phpunit-mock-objects/Framework/MockObject/Generator/unmocked_clone.tpl.distŸ���¡£UŸ���8W}ض������I���phpunit-mock-objects/Framework/MockObject/Generator/mocked_class.tpl.dist ��¡£U ��¨ÑFZ¶������I���phpunit-mock-objects/Framework/MockObject/Generator/mocked_clone.tpl.dist„���¡£U„���œaT¶������K���phpunit-mock-objects/Framework/MockObject/Generator/proxied_method.tpl.distÌ��¡£UÌ��?a§¶������G���phpunit-mock-objects/Framework/MockObject/Generator/wsdl_class.tpl.dist³���¡£U³���w&S¶������H���phpunit-mock-objects/Framework/MockObject/Generator/trait_class.tpl.dist7���¡£U7���²[$~¶������J���phpunit-mock-objects/Framework/MockObject/Generator/mocked_method.tpl.dist„��¡£U„��ãbVæ¶������P���phpunit-mock-objects/Framework/MockObject/Generator/mocked_class_method.tpl.distí���¡£Uí���Ú4Þ¶������Q���phpunit-mock-objects/Framework/MockObject/Generator/mocked_static_method.tpl.dist—���¡£U—���+F°ƒ¶������;���phpunit-mock-objects/Framework/MockObject/Builder/Match.phpW��¡£UW��EƒA¶������>���phpunit-mock-objects/Framework/MockObject/Builder/Identity.php”��¡£U”��(²4ã¶������F���phpunit-mock-objects/Framework/MockObject/Builder/InvocationMocker.phpv��¡£Uv��ÔÐÂñ¶������E���phpunit-mock-objects/Framework/MockObject/Builder/ParametersMatch.php���¡£U���sґζ������?���phpunit-mock-objects/Framework/MockObject/Builder/Namespace.php²��¡£U²��M쉔¶������E���phpunit-mock-objects/Framework/MockObject/Builder/MethodNameMatch.php)��¡£U)��sòõ¶������:���phpunit-mock-objects/Framework/MockObject/Builder/Stub.phpo��¡£Uo��hrâ�¶������?���phpunit-mock-objects/Framework/MockObject/Invocation/Object.php¡��¡£U¡��ˆ¼†9¶������?���phpunit-mock-objects/Framework/MockObject/Invocation/Static.phpF��¡£UF��ÐKp¶������2���phpunit-mock-objects/Framework/MockObject/Stub.php\��¡£U\��f+Fж������<���phpunit-mock-objects/Framework/MockObject/Stub/Exception.phpˆ��¡£Uˆ��<)ÿ¥¶������9���phpunit-mock-objects/Framework/MockObject/Stub/Return.php_��¡£U_��ÐóH,¶������=���phpunit-mock-objects/Framework/MockObject/Stub/ReturnSelf.phpÂ��¡£UÂ��«¤�I¶������A���phpunit-mock-objects/Framework/MockObject/Stub/ReturnValueMap.php|��¡£U|��uB è¶������C���phpunit-mock-objects/Framework/MockObject/Stub/ConsecutiveCalls.phpN��¡£UN��¥�°¶������D���phpunit-mock-objects/Framework/MockObject/Stub/MatcherCollection.php:��¡£U:��µYж������A���phpunit-mock-objects/Framework/MockObject/Stub/ReturnCallback.php•��¡£U•��g‰´`¶������A���phpunit-mock-objects/Framework/MockObject/Stub/ReturnArgument.phpÿ��¡£Uÿ��9)�`¶���������phpunit/Exception.phps��¡£Us��y:ƒÛ¶���������phpunit/Framework/Test.phpŽ��¡£UŽ��ú;ì¶���������phpunit/Framework/Exception.php ��¡£U ��DËÿ³¶������!���phpunit/Framework/OutputError.phpç��¡£Uç��jÔ̶���������phpunit/Framework/Assert.phpB„�¡£UB„�àÛ¯¶������+���phpunit/Framework/CodeCoverageException.phpq��¡£Uq��E´•í¶���������phpunit/Framework/TestSuite.phpu��¡£Uu��ªÄÀ¶���������phpunit/Framework/RiskyTest.php®��¡£U®��Å\¶������$���phpunit/Framework/SelfDescribing.php��¡£U��:‹|ð¶������&���phpunit/Framework/Assert/Functions.phpï÷��¡£Uï÷��,?ƒ¶������$���phpunit/Framework/SyntheticError.php��¡£U��Æ·½¶������$���phpunit/Framework/RiskyTestError.php��¡£U��?Ÿv¶������"���phpunit/Framework/TestListener.phpR
  598. ��¡£UR
  599. ��…ŸÎݶ������&���phpunit/Framework/ExceptionWrapper.php˜��¡£U˜��ù“¶������!���phpunit/Framework/SkippedTest.php“��¡£U“��ã_ $¶������2���phpunit/Framework/InvalidCoversTargetException.php„��¡£U„��%M×à¶���������phpunit/Framework/TestCase.phpú��¡£Uú��R‡‹¶������0���phpunit/Framework/ExpectationFailedException.php™��¡£U™��_Sõ;¶���������phpunit/Framework/Error.php$��¡£U$��X%yW¶������ ���phpunit/Framework/Constraint.php†��¡£U†��WëSǶ������*���phpunit/Framework/AssertionFailedError.php{��¡£U{��+Áþ¶������(���phpunit/Framework/IncompleteTestCase.php5��¡£U5��.–Sž¶������,���phpunit/Framework/TestSuite/DataProvider.phpƒ��¡£Uƒ��‚<Us¶������&���phpunit/Framework/Error/Deprecated.phpF��¡£UF��´¢V¶������"���phpunit/Framework/Error/Notice.php0��¡£U0��ÜIŠ›¶������#���phpunit/Framework/Error/Warning.php3��¡£U3��mO‘¤¶������)���phpunit/Framework/IncompleteTestError.php��¡£U��Htº ¶������.���phpunit/Framework/InvalidCoversTargetError.phpB��¡£UB�� ‡ÿ|¶������+���phpunit/Framework/SkippedTestSuiteError.php��¡£U��àÕ7<¶������ ���phpunit/Framework/TestResult.phpîm��¡£Uîm��¿‡ñs¶������!���phpunit/Framework/TestFailure.php���¡£U���¡´·ª¶������$���phpunit/Framework/IncompleteTest.phpä��¡£Uä��òJì¶������%���phpunit/Framework/SkippedTestCase.phpê��¡£Uê��`¬uà¶������2���phpunit/Framework/Constraint/ClassHasAttribute.php¸��¡£U¸��øEÀ¶������4���phpunit/Framework/Constraint/TraversableContains.phpÞ ��¡£UÞ ��•Ç{¶������.���phpunit/Framework/Constraint/ExceptionCode.phpP��¡£UP��þv~D¶������*���phpunit/Framework/Constraint/Exception.phpX��¡£UX��î S϶������)���phpunit/Framework/Constraint/SameSize.phpS��¡£US��/#ÏS¶������,���phpunit/Framework/Constraint/JsonMatches.php��¡£U��ß9Ñ{¶������-���phpunit/Framework/Constraint/IsInstanceOf.php³��¡£U³��rȫǶ������3���phpunit/Framework/Constraint/ObjectHasAttribute.php—��¡£U—��è{G ¶������'���phpunit/Framework/Constraint/IsType.php_ ��¡£U_ ��ö¦—‡¶������)���phpunit/Framework/Constraint/LessThan.php¸��¡£U¸��¼®±ƒ¶������,���phpunit/Framework/Constraint/ArraySubset.php@��¡£U@��ýB+·¶������'���phpunit/Framework/Constraint/IsTrue.phpk��¡£Uk��ö¶������'���phpunit/Framework/Constraint/IsJson.phpŒ��¡£UŒ��C\œ¦¶������(���phpunit/Framework/Constraint/IsEqual.phpô��¡£Uô��#!·Ú¶������$���phpunit/Framework/Constraint/Xor.php9 ��¡£U9 ��Ãsu¶������A���phpunit/Framework/Constraint/JsonMatches/ErrorMessageProvider.php¤��¡£U¤��Wà¬J¶������.���phpunit/Framework/Constraint/StringMatches.php ��¡£U ��%½Àc¶������$���phpunit/Framework/Constraint/Not.phpî��¡£Uî��@öζ������7���phpunit/Framework/Constraint/ExceptionMessageRegExp.phpU��¡£UU��ô`]_¶������,���phpunit/Framework/Constraint/GreaterThan.phpÁ��¡£UÁ�� Ç?n¶������1���phpunit/Framework/Constraint/ExceptionMessage.php8��¡£U8��¾XŒz¶������)���phpunit/Framework/Constraint/Callback.php:��¡£U:��+Êî„¶������,���phpunit/Framework/Constraint/ArrayHasKey.php­��¡£U­��yú›6¶������/���phpunit/Framework/Constraint/StringContains.php,��¡£U,��G©zÚ¶������8���phpunit/Framework/Constraint/TraversableContainsOnly.php
  600. ��¡£U
  601. ��}=²¶������(���phpunit/Framework/Constraint/IsEmpty.php��¡£U��8—2�¶������*���phpunit/Framework/Constraint/PCREMatch.php·��¡£U·��ï•^#¶������'���phpunit/Framework/Constraint/IsNull.phpk��¡£Uk��KÀ:¶������*���phpunit/Framework/Constraint/Attribute.phpü ��¡£Uü ��LLp�¶������(���phpunit/Framework/Constraint/IsFalse.phpo��¡£Uo��Þì?A¶������8���phpunit/Framework/Constraint/ClassHasStaticAttribute.phpw��¡£Uw��RQîp¶������#���phpunit/Framework/Constraint/Or.phpÆ ��¡£UÆ ��^|§¶������,���phpunit/Framework/Constraint/IsIdentical.php7��¡£U7��—µܶ������+���phpunit/Framework/Constraint/FileExists.php¨��¡£U¨��Îß I¶������*���phpunit/Framework/Constraint/Composite.php+��¡£U+��©I«Y¶������1���phpunit/Framework/Constraint/StringStartsWith.phpÀ��¡£UÀ��|C�}¶������/���phpunit/Framework/Constraint/StringEndsWith.phpÑ��¡£UÑ��ùž^¶������+���phpunit/Framework/Constraint/IsAnything.phpÐ��¡£UÐ��£;ðð¶������&���phpunit/Framework/Constraint/Count.phpÔ ��¡£UÔ ��´!ôw¶������$���phpunit/Framework/Constraint/And.php� ��¡£U� ��AùÞ8¶������&���phpunit/Framework/BaseTestListener.phpp��¡£Up��ØM‹U¶������&���phpunit/Framework/SkippedTestError.php ��¡£U ���T¶������5���phpunit/Framework/UnintentionallyCoveredCodeError.php��¡£U��d^S¶���������phpunit/Framework/Warning.php³��¡£U³��«S”þ¶������%���phpunit/Extensions/GroupTestSuite.php„��¡£U„��ðÁ6¶������$���phpunit/Extensions/PhptTestSuite.php��¡£U��ȉ�ž¶������#���phpunit/Extensions/RepeatedTest.phpõ��¡£Uõ��,ìaÿ¶������%���phpunit/Extensions/TicketListener.php0��¡£U0��%öZÿ¶������$���phpunit/Extensions/TestDecorator.php: ��¡£U: ��0�v-¶������#���phpunit/Extensions/PhptTestCase.php(��¡£U(��À*V¶���������phpunit/TextUI/Command.php‘|��¡£U‘|��ar- ¶���������phpunit/TextUI/TestRunner.phpH ��¡£UH ��ßÿɶ������ ���phpunit/TextUI/ResultPrinter.phpæC��¡£UæC��µ×/޶���������phpunit/Util/Test.php‡{��¡£U‡{��`ßäÓ¶���������phpunit/Util/Filesystem.php‰��¡£U‰��ç(`O¶���������phpunit/Util/Getopt.phpÛ��¡£UÛ��À„<¶���������phpunit/Util/ErrorHandler.phpÁ ��¡£UÁ ��ŸQÎݶ���������phpunit/Util/String.phps��¡£Us��U)‹D¶������&���phpunit/Util/InvalidArgumentHelper.phpŽ��¡£UŽ��éW4¶���������phpunit/Util/Printer.php^��¡£U^��í
  602. ’¶���������phpunit/Util/Configuration.php‚‰��¡£U‚‰��ôü(L¶���������phpunit/Util/GlobalState.php/��¡£U/��KU|�¶���������phpunit/Util/Log/JSON.php%��¡£U%��“æÚ¶���������phpunit/Util/Log/TAP.php��¡£U��|%n¶���������phpunit/Util/Log/JUnit.php�2��¡£U�2��¤, ¶���������phpunit/Util/Blacklist.php���¡£U���!zWI¶������"���phpunit/Util/TestSuiteIterator.phpû��¡£Uû��Ïâ�˜¶���������phpunit/Util/Filter.phpË ��¡£UË ��þp¢Ä¶������+���phpunit/Util/TestDox/ResultPrinter/HTML.phpª��¡£Uª��pfµÊ¶������+���phpunit/Util/TestDox/ResultPrinter/Text.phpw��¡£Uw�� ;ÿ›¶������&���phpunit/Util/TestDox/ResultPrinter.phpO��¡£UO�� lë¶������'���phpunit/Util/TestDox/NamePrettifier.phpE ��¡£UE ��ߤ‡ ¶���������phpunit/Util/Regex.phpå��¡£Uå��±PÏd¶���������phpunit/Util/Type.php��¡£U��CÜ!Ò¶���������phpunit/Util/PHP/Default.phpÇ��¡£UÇ��>>L¶������1���phpunit/Util/PHP/Template/TestCaseMethod.tpl.dist¥��¡£U¥��ïó¶���������phpunit/Util/PHP/Windows.phpx
  603. ��¡£Ux
  604. ��˜"¶���������phpunit/Util/Fileloader.phpÝ��¡£UÝ��)ع�¶���������phpunit/Util/XML.phpŒr��¡£UŒr��<zÖ¶���������phpunit/Util/PHP.phpÑ��¡£UÑ��]QF¶���������phpunit/Runner/Exception.phpt��¡£Ut��€d§¿¶���������phpunit/Runner/Filter/Test.php ��¡£U ��aŸ޶������'���phpunit/Runner/Filter/Group/Exclude.phpâ��¡£Uâ��„ÊPF¶������'���phpunit/Runner/Filter/Group/Include.phpá��¡£Uá��Ve¶������!���phpunit/Runner/Filter/Factory.phpÜ��¡£UÜ��…õJ¶���������phpunit/Runner/Filter/Group.php���¡£U���c2{m¶������"���phpunit/Runner/TestSuiteLoader.phpë��¡£Uë��©9äɶ������!���phpunit/Runner/BaseTestRunner.php“��¡£U“��®Q޶������*���phpunit/Runner/StandardTestSuiteLoader.phpä ��¡£Uä ��ø-ù¥¶���������phpunit/Runner/Version.php°��¡£U°��ìÏÍq¶���������sebastian-environment/LICENSE
  605. ��¡£U
  606. ��¶îáß¶������!���sebastian-environment/Runtime.phpÄ��¡£UÄ�� ¹º¶������!���sebastian-environment/Console.php©��¡£U©��qí*¶������)���phpdocumentor-reflection-docblock/LICENSE8��¡£U8��á‰Ê¶������G���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock.phpc6��¡£Uc6��õËq¶������P���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Location.phpq��¡£Uq��uÁ/¶������T���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/SinceTag.php|��¡£U|��tøûR¶������R���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/SeeTag.phpÿ��¡£Uÿ��ià?$¶������V���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/VersionTag.phpx
  607. ��¡£Ux
  608. ��ÓËEƶ������W���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/PropertyTag.phpO��¡£UO��«Î#m¶������U���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/ReturnTag.phpÙ��¡£UÙ��pS�ž¶������Y���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/DeprecatedTag.php†��¡£U†��K § ¶������U���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/ThrowsTag.phpL��¡£UL��œ"â¶������U���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/CoversTag.phpI��¡£UI��9¹{¶������U���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/SourceTag.php� ��¡£U� ��äÙn*¶������S���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/UsesTag.phpE��¡£UE��.�„˶������U���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/MethodTag.php~��¡£U~��å!kͶ������[���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/PropertyReadTag.php[��¡£U[��Í< =¶������U���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/AuthorTag.phpM ��¡£UM ��1ôú¶������R���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/VarTag.phpE��¡£UE��ƒ•üͶ������S���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/LinkTag.phpL��¡£UL���ªF¶������V���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/ExampleTag.php™��¡£U™�� £
  609. ï¶������T���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/ParamTag.phpH ��¡£UH ��±ñ ¶������\���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag/PropertyWriteTag.php]��¡£U]��Rp¶������R���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Serializer.php��¡£U��òrж������O���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Context.php5��¡£U5��l.%¶������W���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Type/Collection.php���¡£U���+=4¶������K���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Tag.phpÛ(��¡£UÛ(��ŒE6 ¶������S���phpdocumentor-reflection-docblock/phpDocumentor/Reflection/DocBlock/Description.php—��¡£U—��ñԲض���������sebastian-version/LICENSE��¡£U��n¶���������sebastian-version/Version.php2��¡£U2��BŸâZ¶������<?php
  610. /**
  611. * GlobalState
  612. *
  613. * Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
  614. * All rights reserved.
  615. *
  616. * Redistribution and use in source and binary forms, with or without
  617. * modification, are permitted provided that the following conditions
  618. * are met:
  619. *
  620. * * Redistributions of source code must retain the above copyright
  621. * notice, this list of conditions and the following disclaimer.
  622. *
  623. * * Redistributions in binary form must reproduce the above copyright
  624. * notice, this list of conditions and the following disclaimer in
  625. * the documentation and/or other materials provided with the
  626. * distribution.
  627. *
  628. * * Neither the name of Sebastian Bergmann nor the names of his
  629. * contributors may be used to endorse or promote products derived
  630. * from this software without specific prior written permission.
  631. *
  632. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  633. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  634. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  635. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  636. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  637. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  638. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  639. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  640. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  641. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  642. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  643. * POSSIBILITY OF SUCH DAMAGE.
  644. *
  645. * @author Sebastian Bergmann <sebastian@phpunit.de>
  646. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  647. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  648. * @link http://www.github.com/sebastianbergmann/global-state
  649. */
  650. namespace SebastianBergmann\GlobalState;
  651. /**
  652. * @author Sebastian Bergmann <sebastian@phpunit.de>
  653. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  654. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  655. * @link http://www.github.com/sebastianbergmann/global-state
  656. */
  657. interface Exception
  658. {
  659. }
  660. <?php
  661. /**
  662. * GlobalState
  663. *
  664. * Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
  665. * All rights reserved.
  666. *
  667. * Redistribution and use in source and binary forms, with or without
  668. * modification, are permitted provided that the following conditions
  669. * are met:
  670. *
  671. * * Redistributions of source code must retain the above copyright
  672. * notice, this list of conditions and the following disclaimer.
  673. *
  674. * * Redistributions in binary form must reproduce the above copyright
  675. * notice, this list of conditions and the following disclaimer in
  676. * the documentation and/or other materials provided with the
  677. * distribution.
  678. *
  679. * * Neither the name of Sebastian Bergmann nor the names of his
  680. * contributors may be used to endorse or promote products derived
  681. * from this software without specific prior written permission.
  682. *
  683. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  684. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  685. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  686. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  687. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  688. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  689. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  690. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  691. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  692. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  693. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  694. * POSSIBILITY OF SUCH DAMAGE.
  695. *
  696. * @author Sebastian Bergmann <sebastian@phpunit.de>
  697. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  698. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  699. * @link http://www.github.com/sebastianbergmann/global-state
  700. */
  701. namespace SebastianBergmann\GlobalState;
  702. use Closure;
  703. use ReflectionClass;
  704. /**
  705. * A snapshot of global state.
  706. *
  707. * @author Sebastian Bergmann <sebastian@phpunit.de>
  708. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  709. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  710. * @link http://www.github.com/sebastianbergmann/global-state
  711. */
  712. class Snapshot
  713. {
  714. /**
  715. * @var Blacklist
  716. */
  717. private $blacklist;
  718. /**
  719. * @var array
  720. */
  721. private $globalVariables = array();
  722. /**
  723. * @var array
  724. */
  725. private $superGlobalArrays = array();
  726. /**
  727. * @var array
  728. */
  729. private $superGlobalVariables = array();
  730. /**
  731. * @var array
  732. */
  733. private $staticAttributes = array();
  734. /**
  735. * @var array
  736. */
  737. private $iniSettings = array();
  738. /**
  739. * @var array
  740. */
  741. private $includedFiles = array();
  742. /**
  743. * @var array
  744. */
  745. private $constants = array();
  746. /**
  747. * @var array
  748. */
  749. private $functions = array();
  750. /**
  751. * @var array
  752. */
  753. private $interfaces = array();
  754. /**
  755. * @var array
  756. */
  757. private $classes = array();
  758. /**
  759. * @var array
  760. */
  761. private $traits = array();
  762. /**
  763. * Creates a snapshot of the current global state.
  764. *
  765. * @param Blacklist $blacklist
  766. * @param boolean $includeGlobalVariables
  767. * @param boolean $includeStaticAttributes
  768. * @param boolean $includeConstants
  769. * @param boolean $includeFunctions
  770. * @param boolean $includeClasses
  771. * @param boolean $includeInterfaces
  772. * @param boolean $includeTraits
  773. * @param boolean $includeIniSettings
  774. * @param boolean $includeIncludedFiles
  775. */
  776. public function __construct(Blacklist $blacklist = null, $includeGlobalVariables = true, $includeStaticAttributes = true, $includeConstants = true, $includeFunctions = true, $includeClasses = true, $includeInterfaces = true, $includeTraits = true, $includeIniSettings = true, $includeIncludedFiles = true)
  777. {
  778. if ($blacklist === null) {
  779. $blacklist = new Blacklist;
  780. }
  781. $this->blacklist = $blacklist;
  782. if ($includeConstants) {
  783. $this->snapshotConstants();
  784. }
  785. if ($includeFunctions) {
  786. $this->snapshotFunctions();
  787. }
  788. if ($includeClasses || $includeStaticAttributes) {
  789. $this->snapshotClasses();
  790. }
  791. if ($includeInterfaces) {
  792. $this->snapshotInterfaces();
  793. }
  794. if ($includeGlobalVariables) {
  795. $this->setupSuperGlobalArrays();
  796. $this->snapshotGlobals();
  797. }
  798. if ($includeStaticAttributes) {
  799. $this->snapshotStaticAttributes();
  800. }
  801. if ($includeIniSettings) {
  802. $this->iniSettings = ini_get_all(null, false);
  803. }
  804. if ($includeIncludedFiles) {
  805. $this->includedFiles = get_included_files();
  806. }
  807. if (function_exists('get_declared_traits')) {
  808. $this->traits = get_declared_traits();
  809. }
  810. }
  811. /**
  812. * @return Blacklist
  813. */
  814. public function blacklist()
  815. {
  816. return $this->blacklist;
  817. }
  818. /**
  819. * @return array
  820. */
  821. public function globalVariables()
  822. {
  823. return $this->globalVariables;
  824. }
  825. /**
  826. * @return array
  827. */
  828. public function superGlobalVariables()
  829. {
  830. return $this->superGlobalVariables;
  831. }
  832. /**
  833. * Returns a list of all super-global variable arrays.
  834. *
  835. * @return array
  836. */
  837. public function superGlobalArrays()
  838. {
  839. return $this->superGlobalArrays;
  840. }
  841. /**
  842. * @return array
  843. */
  844. public function staticAttributes()
  845. {
  846. return $this->staticAttributes;
  847. }
  848. /**
  849. * @return array
  850. */
  851. public function iniSettings()
  852. {
  853. return $this->iniSettings;
  854. }
  855. /**
  856. * @return array
  857. */
  858. public function includedFiles()
  859. {
  860. return $this->includedFiles;
  861. }
  862. /**
  863. * @return array
  864. */
  865. public function constants()
  866. {
  867. return $this->constants;
  868. }
  869. /**
  870. * @return array
  871. */
  872. public function functions()
  873. {
  874. return $this->functions;
  875. }
  876. /**
  877. * @return array
  878. */
  879. public function interfaces()
  880. {
  881. return $this->interfaces;
  882. }
  883. /**
  884. * @return array
  885. */
  886. public function classes()
  887. {
  888. return $this->classes;
  889. }
  890. /**
  891. * @return array
  892. */
  893. public function traits()
  894. {
  895. return $this->traits;
  896. }
  897. /**
  898. * Creates a snapshot user-defined constants.
  899. */
  900. private function snapshotConstants()
  901. {
  902. $constants = get_defined_constants(true);
  903. if (isset($constants['user'])) {
  904. $this->constants = $constants['user'];
  905. }
  906. }
  907. /**
  908. * Creates a snapshot user-defined functions.
  909. */
  910. private function snapshotFunctions()
  911. {
  912. $functions = get_defined_functions();
  913. $this->functions = $functions['user'];
  914. }
  915. /**
  916. * Creates a snapshot user-defined classes.
  917. */
  918. private function snapshotClasses()
  919. {
  920. foreach (array_reverse(get_declared_classes()) as $className) {
  921. $class = new ReflectionClass($className);
  922. if (!$class->isUserDefined()) {
  923. break;
  924. }
  925. $this->classes[] = $className;
  926. }
  927. $this->classes = array_reverse($this->classes);
  928. }
  929. /**
  930. * Creates a snapshot user-defined interfaces.
  931. */
  932. private function snapshotInterfaces()
  933. {
  934. foreach (array_reverse(get_declared_interfaces()) as $interfaceName) {
  935. $class = new ReflectionClass($interfaceName);
  936. if (!$class->isUserDefined()) {
  937. break;
  938. }
  939. $this->interfaces[] = $interfaceName;
  940. }
  941. $this->interfaces = array_reverse($this->interfaces);
  942. }
  943. /**
  944. * Creates a snapshot of all global and super-global variables.
  945. */
  946. private function snapshotGlobals()
  947. {
  948. $superGlobalArrays = $this->superGlobalArrays();
  949. foreach ($superGlobalArrays as $superGlobalArray) {
  950. $this->snapshotSuperGlobalArray($superGlobalArray);
  951. }
  952. foreach (array_keys($GLOBALS) as $key) {
  953. if ($key != 'GLOBALS' &&
  954. !in_array($key, $superGlobalArrays) &&
  955. $this->canBeSerialized($GLOBALS[$key]) &&
  956. !$this->blacklist->isGlobalVariableBlacklisted($key)) {
  957. $this->globalVariables[$key] = unserialize(serialize($GLOBALS[$key]));
  958. }
  959. }
  960. }
  961. /**
  962. * Creates a snapshot a super-global variable array.
  963. *
  964. * @param $superGlobalArray
  965. */
  966. private function snapshotSuperGlobalArray($superGlobalArray)
  967. {
  968. $this->superGlobalVariables[$superGlobalArray] = array();
  969. if (isset($GLOBALS[$superGlobalArray]) && is_array($GLOBALS[$superGlobalArray])) {
  970. foreach ($GLOBALS[$superGlobalArray] as $key => $value) {
  971. $this->superGlobalVariables[$superGlobalArray][$key] = unserialize(serialize($value));
  972. }
  973. }
  974. }
  975. /**
  976. * Creates a snapshot of all static attributes in user-defined classes.
  977. */
  978. private function snapshotStaticAttributes()
  979. {
  980. foreach ($this->classes as $className) {
  981. $class = new ReflectionClass($className);
  982. $snapshot = array();
  983. foreach ($class->getProperties() as $attribute) {
  984. if ($attribute->isStatic()) {
  985. $name = $attribute->getName();
  986. if ($this->blacklist->isStaticAttributeBlacklisted($className, $name)) {
  987. continue;
  988. }
  989. $attribute->setAccessible(true);
  990. $value = $attribute->getValue();
  991. if ($this->canBeSerialized($value)) {
  992. $snapshot[$name] = unserialize(serialize($value));
  993. }
  994. }
  995. }
  996. if (!empty($snapshot)) {
  997. $this->staticAttributes[$className] = $snapshot;
  998. }
  999. }
  1000. }
  1001. /**
  1002. * Returns a list of all super-global variable arrays.
  1003. *
  1004. * @return array
  1005. */
  1006. private function setupSuperGlobalArrays()
  1007. {
  1008. $this->superGlobalArrays = array(
  1009. '_ENV',
  1010. '_POST',
  1011. '_GET',
  1012. '_COOKIE',
  1013. '_SERVER',
  1014. '_FILES',
  1015. '_REQUEST'
  1016. );
  1017. if (ini_get('register_long_arrays') == '1') {
  1018. $this->superGlobalArrays = array_merge(
  1019. $this->superGlobalArrays,
  1020. array(
  1021. 'HTTP_ENV_VARS',
  1022. 'HTTP_POST_VARS',
  1023. 'HTTP_GET_VARS',
  1024. 'HTTP_COOKIE_VARS',
  1025. 'HTTP_SERVER_VARS',
  1026. 'HTTP_POST_FILES'
  1027. )
  1028. );
  1029. }
  1030. }
  1031. /**
  1032. * @param mixed $variable
  1033. * @return boolean
  1034. * @todo Implement this properly
  1035. */
  1036. private function canBeSerialized($variable) {
  1037. return !$variable instanceof Closure;
  1038. }
  1039. }
  1040. GlobalState
  1041. Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
  1042. All rights reserved.
  1043. Redistribution and use in source and binary forms, with or without
  1044. modification, are permitted provided that the following conditions
  1045. are met:
  1046. * Redistributions of source code must retain the above copyright
  1047. notice, this list of conditions and the following disclaimer.
  1048. * Redistributions in binary form must reproduce the above copyright
  1049. notice, this list of conditions and the following disclaimer in
  1050. the documentation and/or other materials provided with the
  1051. distribution.
  1052. * Neither the name of Sebastian Bergmann nor the names of his
  1053. contributors may be used to endorse or promote products derived
  1054. from this software without specific prior written permission.
  1055. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  1056. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  1057. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  1058. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  1059. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  1060. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  1061. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1062. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  1063. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1064. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  1065. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  1066. POSSIBILITY OF SUCH DAMAGE.
  1067. <?php
  1068. /**
  1069. * GlobalState
  1070. *
  1071. * Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
  1072. * All rights reserved.
  1073. *
  1074. * Redistribution and use in source and binary forms, with or without
  1075. * modification, are permitted provided that the following conditions
  1076. * are met:
  1077. *
  1078. * * Redistributions of source code must retain the above copyright
  1079. * notice, this list of conditions and the following disclaimer.
  1080. *
  1081. * * Redistributions in binary form must reproduce the above copyright
  1082. * notice, this list of conditions and the following disclaimer in
  1083. * the documentation and/or other materials provided with the
  1084. * distribution.
  1085. *
  1086. * * Neither the name of Sebastian Bergmann nor the names of his
  1087. * contributors may be used to endorse or promote products derived
  1088. * from this software without specific prior written permission.
  1089. *
  1090. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  1091. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  1092. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  1093. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  1094. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  1095. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  1096. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1097. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  1098. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1099. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  1100. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  1101. * POSSIBILITY OF SUCH DAMAGE.
  1102. *
  1103. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1104. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  1105. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1106. * @link http://www.github.com/sebastianbergmann/global-state
  1107. */
  1108. namespace SebastianBergmann\GlobalState;
  1109. use ReflectionProperty;
  1110. /**
  1111. * Restorer of snapshots of global state.
  1112. *
  1113. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1114. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  1115. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1116. * @link http://www.github.com/sebastianbergmann/global-state
  1117. */
  1118. class Restorer
  1119. {
  1120. /**
  1121. * Deletes function definitions that are not defined in a snapshot.
  1122. *
  1123. * @param Snapshot $snapshot
  1124. * @throws RuntimeException when the uopz_delete() function is not available
  1125. * @see https://github.com/krakjoe/uopz
  1126. */
  1127. public function restoreFunctions(Snapshot $snapshot)
  1128. {
  1129. if (!function_exists('uopz_delete')) {
  1130. throw new RuntimeException('The uopz_delete() function is required for this operation');
  1131. }
  1132. $functions = get_defined_functions();
  1133. foreach (array_diff($functions['user'], $snapshot->functions()) as $function) {
  1134. uopz_delete($function);
  1135. }
  1136. }
  1137. /**
  1138. * Restores all global and super-global variables from a snapshot.
  1139. *
  1140. * @param Snapshot $snapshot
  1141. */
  1142. public function restoreGlobalVariables(Snapshot $snapshot)
  1143. {
  1144. $superGlobalArrays = $snapshot->superGlobalArrays();
  1145. foreach ($superGlobalArrays as $superGlobalArray) {
  1146. $this->restoreSuperGlobalArray($snapshot, $superGlobalArray);
  1147. }
  1148. $globalVariables = $snapshot->globalVariables();
  1149. foreach (array_keys($GLOBALS) as $key) {
  1150. if ($key != 'GLOBALS' &&
  1151. !in_array($key, $superGlobalArrays) &&
  1152. !$snapshot->blacklist()->isGlobalVariableBlacklisted($key)) {
  1153. if (isset($globalVariables[$key])) {
  1154. $GLOBALS[$key] = $globalVariables[$key];
  1155. } else {
  1156. unset($GLOBALS[$key]);
  1157. }
  1158. }
  1159. }
  1160. }
  1161. /**
  1162. * Restores all static attributes in user-defined classes from this snapshot.
  1163. *
  1164. * @param Snapshot $snapshot
  1165. */
  1166. public function restoreStaticAttributes(Snapshot $snapshot)
  1167. {
  1168. foreach ($snapshot->staticAttributes() as $className => $staticAttributes) {
  1169. foreach ($staticAttributes as $name => $value) {
  1170. $reflector = new ReflectionProperty($className, $name);
  1171. $reflector->setAccessible(true);
  1172. $reflector->setValue($value);
  1173. }
  1174. }
  1175. }
  1176. /**
  1177. * Restores a super-global variable array from this snapshot.
  1178. *
  1179. * @param Snapshot $snapshot
  1180. * @param $superGlobalArray
  1181. */
  1182. private function restoreSuperGlobalArray(Snapshot $snapshot, $superGlobalArray)
  1183. {
  1184. $superGlobalVariables = $snapshot->superGlobalVariables();
  1185. if (isset($GLOBALS[$superGlobalArray]) &&
  1186. is_array($GLOBALS[$superGlobalArray]) &&
  1187. isset($superGlobalVariables[$superGlobalArray])) {
  1188. $keys = array_keys(
  1189. array_merge(
  1190. $GLOBALS[$superGlobalArray],
  1191. $superGlobalVariables[$superGlobalArray]
  1192. )
  1193. );
  1194. foreach ($keys as $key) {
  1195. if (isset($superGlobalVariables[$superGlobalArray][$key])) {
  1196. $GLOBALS[$superGlobalArray][$key] = $superGlobalVariables[$superGlobalArray][$key];
  1197. } else {
  1198. unset($GLOBALS[$superGlobalArray][$key]);
  1199. }
  1200. }
  1201. }
  1202. }
  1203. }
  1204. <?php
  1205. /**
  1206. * GlobalState
  1207. *
  1208. * Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
  1209. * All rights reserved.
  1210. *
  1211. * Redistribution and use in source and binary forms, with or without
  1212. * modification, are permitted provided that the following conditions
  1213. * are met:
  1214. *
  1215. * * Redistributions of source code must retain the above copyright
  1216. * notice, this list of conditions and the following disclaimer.
  1217. *
  1218. * * Redistributions in binary form must reproduce the above copyright
  1219. * notice, this list of conditions and the following disclaimer in
  1220. * the documentation and/or other materials provided with the
  1221. * distribution.
  1222. *
  1223. * * Neither the name of Sebastian Bergmann nor the names of his
  1224. * contributors may be used to endorse or promote products derived
  1225. * from this software without specific prior written permission.
  1226. *
  1227. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  1228. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  1229. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  1230. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  1231. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  1232. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  1233. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1234. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  1235. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1236. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  1237. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  1238. * POSSIBILITY OF SUCH DAMAGE.
  1239. *
  1240. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1241. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  1242. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1243. * @link http://www.github.com/sebastianbergmann/global-state
  1244. */
  1245. namespace SebastianBergmann\GlobalState;
  1246. use ReflectionClass;
  1247. /**
  1248. * A blacklist for global state elements that should not be snapshotted.
  1249. *
  1250. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1251. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  1252. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1253. * @link http://www.github.com/sebastianbergmann/global-state
  1254. */
  1255. class Blacklist
  1256. {
  1257. /**
  1258. * @var array
  1259. */
  1260. private $globalVariables = array();
  1261. /**
  1262. * @var array
  1263. */
  1264. private $classes = array();
  1265. /**
  1266. * @var array
  1267. */
  1268. private $classNamePrefixes = array();
  1269. /**
  1270. * @var array
  1271. */
  1272. private $parentClasses = array();
  1273. /**
  1274. * @var array
  1275. */
  1276. private $interfaces = array();
  1277. /**
  1278. * @var array
  1279. */
  1280. private $staticAttributes = array();
  1281. /**
  1282. * @param string $variableName
  1283. */
  1284. public function addGlobalVariable($variableName)
  1285. {
  1286. $this->globalVariables[$variableName] = true;
  1287. }
  1288. /**
  1289. * @param string $className
  1290. */
  1291. public function addClass($className)
  1292. {
  1293. $this->classes[] = $className;
  1294. }
  1295. /**
  1296. * @param string $className
  1297. */
  1298. public function addSubclassesOf($className)
  1299. {
  1300. $this->parentClasses[] = $className;
  1301. }
  1302. /**
  1303. * @param string $interfaceName
  1304. */
  1305. public function addImplementorsOf($interfaceName)
  1306. {
  1307. $this->interfaces[] = $interfaceName;
  1308. }
  1309. /**
  1310. * @param string $classNamePrefix
  1311. */
  1312. public function addClassNamePrefix($classNamePrefix)
  1313. {
  1314. $this->classNamePrefixes[] = $classNamePrefix;
  1315. }
  1316. /**
  1317. * @param string $className
  1318. * @param string $attributeName
  1319. */
  1320. public function addStaticAttribute($className, $attributeName)
  1321. {
  1322. if (!isset($this->staticAttributes[$className])) {
  1323. $this->staticAttributes[$className] = array();
  1324. }
  1325. $this->staticAttributes[$className][$attributeName] = true;
  1326. }
  1327. /**
  1328. * @param string $variableName
  1329. * @return boolean
  1330. */
  1331. public function isGlobalVariableBlacklisted($variableName)
  1332. {
  1333. return isset($this->globalVariables[$variableName]);
  1334. }
  1335. /**
  1336. * @param string $className
  1337. * @param string $attributeName
  1338. * @return boolean
  1339. */
  1340. public function isStaticAttributeBlacklisted($className, $attributeName)
  1341. {
  1342. if (in_array($className, $this->classes)) {
  1343. return true;
  1344. }
  1345. foreach ($this->classNamePrefixes as $prefix) {
  1346. if (strpos($className, $prefix) === 0) {
  1347. return true;
  1348. }
  1349. }
  1350. $class = new ReflectionClass($className);
  1351. foreach ($this->parentClasses as $type) {
  1352. if ($class->isSubclassOf($type)) {
  1353. return true;
  1354. }
  1355. }
  1356. foreach ($this->interfaces as $type) {
  1357. if ($class->implementsInterface($type)) {
  1358. return true;
  1359. }
  1360. }
  1361. if (isset($this->staticAttributes[$className][$attributeName])) {
  1362. return true;
  1363. }
  1364. return false;
  1365. }
  1366. }
  1367. <?php
  1368. /**
  1369. * GlobalState
  1370. *
  1371. * Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
  1372. * All rights reserved.
  1373. *
  1374. * Redistribution and use in source and binary forms, with or without
  1375. * modification, are permitted provided that the following conditions
  1376. * are met:
  1377. *
  1378. * * Redistributions of source code must retain the above copyright
  1379. * notice, this list of conditions and the following disclaimer.
  1380. *
  1381. * * Redistributions in binary form must reproduce the above copyright
  1382. * notice, this list of conditions and the following disclaimer in
  1383. * the documentation and/or other materials provided with the
  1384. * distribution.
  1385. *
  1386. * * Neither the name of Sebastian Bergmann nor the names of his
  1387. * contributors may be used to endorse or promote products derived
  1388. * from this software without specific prior written permission.
  1389. *
  1390. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  1391. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  1392. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  1393. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  1394. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  1395. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  1396. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1397. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  1398. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1399. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  1400. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  1401. * POSSIBILITY OF SUCH DAMAGE.
  1402. *
  1403. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1404. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  1405. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1406. * @link http://www.github.com/sebastianbergmann/global-state
  1407. */
  1408. namespace SebastianBergmann\GlobalState;
  1409. /**
  1410. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1411. * @copyright 2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
  1412. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1413. * @link http://www.github.com/sebastianbergmann/global-state
  1414. */
  1415. class RuntimeException extends \RuntimeException implements Exception
  1416. {
  1417. }
  1418. Text_Template
  1419. Copyright (c) 2009-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  1420. All rights reserved.
  1421. Redistribution and use in source and binary forms, with or without
  1422. modification, are permitted provided that the following conditions
  1423. are met:
  1424. * Redistributions of source code must retain the above copyright
  1425. notice, this list of conditions and the following disclaimer.
  1426. * Redistributions in binary form must reproduce the above copyright
  1427. notice, this list of conditions and the following disclaimer in
  1428. the documentation and/or other materials provided with the
  1429. distribution.
  1430. * Neither the name of Sebastian Bergmann nor the names of his
  1431. contributors may be used to endorse or promote products derived
  1432. from this software without specific prior written permission.
  1433. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  1434. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  1435. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  1436. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  1437. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  1438. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  1439. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1440. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  1441. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1442. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  1443. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  1444. POSSIBILITY OF SUCH DAMAGE.
  1445. <?php
  1446. /*
  1447. * This file is part of the Text_Template package.
  1448. *
  1449. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  1450. *
  1451. * For the full copyright and license information, please view the LICENSE
  1452. * file that was distributed with this source code.
  1453. */
  1454. /**
  1455. * A simple template engine.
  1456. *
  1457. * @since Class available since Release 1.0.0
  1458. */
  1459. class Text_Template
  1460. {
  1461. /**
  1462. * @var string
  1463. */
  1464. protected $template = '';
  1465. /**
  1466. * @var string
  1467. */
  1468. protected $openDelimiter = '{';
  1469. /**
  1470. * @var string
  1471. */
  1472. protected $closeDelimiter = '}';
  1473. /**
  1474. * @var array
  1475. */
  1476. protected $values = array();
  1477. /**
  1478. * Constructor.
  1479. *
  1480. * @param string $file
  1481. * @throws InvalidArgumentException
  1482. */
  1483. public function __construct($file = '', $openDelimiter = '{', $closeDelimiter = '}')
  1484. {
  1485. $this->setFile($file);
  1486. $this->openDelimiter = $openDelimiter;
  1487. $this->closeDelimiter = $closeDelimiter;
  1488. }
  1489. /**
  1490. * Sets the template file.
  1491. *
  1492. * @param string $file
  1493. * @throws InvalidArgumentException
  1494. */
  1495. public function setFile($file)
  1496. {
  1497. $distFile = $file . '.dist';
  1498. if (file_exists($file)) {
  1499. $this->template = file_get_contents($file);
  1500. }
  1501. else if (file_exists($distFile)) {
  1502. $this->template = file_get_contents($distFile);
  1503. }
  1504. else {
  1505. throw new InvalidArgumentException(
  1506. 'Template file could not be loaded.'
  1507. );
  1508. }
  1509. }
  1510. /**
  1511. * Sets one or more template variables.
  1512. *
  1513. * @param array $values
  1514. * @param bool $merge
  1515. */
  1516. public function setVar(array $values, $merge = TRUE)
  1517. {
  1518. if (!$merge || empty($this->values)) {
  1519. $this->values = $values;
  1520. } else {
  1521. $this->values = array_merge($this->values, $values);
  1522. }
  1523. }
  1524. /**
  1525. * Renders the template and returns the result.
  1526. *
  1527. * @return string
  1528. */
  1529. public function render()
  1530. {
  1531. $keys = array();
  1532. foreach ($this->values as $key => $value) {
  1533. $keys[] = $this->openDelimiter . $key . $this->closeDelimiter;
  1534. }
  1535. return str_replace($keys, $this->values, $this->template);
  1536. }
  1537. /**
  1538. * Renders the template and writes the result to a file.
  1539. *
  1540. * @param string $target
  1541. */
  1542. public function renderTo($target)
  1543. {
  1544. $fp = @fopen($target, 'wt');
  1545. if ($fp) {
  1546. fwrite($fp, $this->render());
  1547. fclose($fp);
  1548. } else {
  1549. $error = error_get_last();
  1550. throw new RuntimeException(
  1551. sprintf(
  1552. 'Could not write to %s: %s',
  1553. $target,
  1554. substr(
  1555. $error['message'],
  1556. strpos($error['message'], ':') + 2
  1557. )
  1558. )
  1559. );
  1560. }
  1561. }
  1562. }
  1563. Diff
  1564. Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  1565. All rights reserved.
  1566. Redistribution and use in source and binary forms, with or without
  1567. modification, are permitted provided that the following conditions
  1568. are met:
  1569. * Redistributions of source code must retain the above copyright
  1570. notice, this list of conditions and the following disclaimer.
  1571. * Redistributions in binary form must reproduce the above copyright
  1572. notice, this list of conditions and the following disclaimer in
  1573. the documentation and/or other materials provided with the
  1574. distribution.
  1575. * Neither the name of Sebastian Bergmann nor the names of his
  1576. contributors may be used to endorse or promote products derived
  1577. from this software without specific prior written permission.
  1578. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  1579. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  1580. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  1581. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  1582. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  1583. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  1584. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1585. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  1586. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1587. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  1588. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  1589. POSSIBILITY OF SUCH DAMAGE.
  1590. <?php
  1591. /*
  1592. * This file is part of the Diff package.
  1593. *
  1594. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  1595. *
  1596. * For the full copyright and license information, please view the LICENSE
  1597. * file that was distributed with this source code.
  1598. */
  1599. namespace SebastianBergmann\Diff\LCS;
  1600. /**
  1601. * Interface for implementations of longest common subsequence calculation.
  1602. *
  1603. * @package Diff
  1604. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1605. * @author Kore Nordmann <mail@kore-nordmann.de>
  1606. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  1607. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1608. * @link http://www.github.com/sebastianbergmann/diff
  1609. */
  1610. interface LongestCommonSubsequence
  1611. {
  1612. /**
  1613. * Calculates the longest common subsequence of two arrays.
  1614. *
  1615. * @param array $from
  1616. * @param array $to
  1617. * @return array
  1618. */
  1619. public function calculate(array $from, array $to);
  1620. }
  1621. <?php
  1622. /*
  1623. * This file is part of the Diff package.
  1624. *
  1625. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  1626. *
  1627. * For the full copyright and license information, please view the LICENSE
  1628. * file that was distributed with this source code.
  1629. */
  1630. namespace SebastianBergmann\Diff\LCS;
  1631. /**
  1632. * Memory-efficient implementation of longest common subsequence calculation.
  1633. *
  1634. * @package Diff
  1635. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1636. * @author Denes Lados <lados.denes@gmail.com>
  1637. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  1638. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1639. * @link http://www.github.com/sebastianbergmann/diff
  1640. */
  1641. class MemoryEfficientImplementation implements LongestCommonSubsequence
  1642. {
  1643. /**
  1644. * Calculates the longest common subsequence of two arrays.
  1645. *
  1646. * @param array $from
  1647. * @param array $to
  1648. * @return array
  1649. */
  1650. public function calculate(array $from, array $to)
  1651. {
  1652. $cFrom = count($from);
  1653. $cTo = count($to);
  1654. if ($cFrom == 0) {
  1655. return array();
  1656. } elseif ($cFrom == 1) {
  1657. if (in_array($from[0], $to)) {
  1658. return array($from[0]);
  1659. } else {
  1660. return array();
  1661. }
  1662. } else {
  1663. $i = intval($cFrom / 2);
  1664. $fromStart = array_slice($from, 0, $i);
  1665. $fromEnd = array_slice($from, $i);
  1666. $llB = $this->length($fromStart, $to);
  1667. $llE = $this->length(array_reverse($fromEnd), array_reverse($to));
  1668. $jMax = 0;
  1669. $max = 0;
  1670. for ($j = 0; $j <= $cTo; $j++) {
  1671. $m = $llB[$j] + $llE[$cTo - $j];
  1672. if ($m >= $max) {
  1673. $max = $m;
  1674. $jMax = $j;
  1675. }
  1676. }
  1677. $toStart = array_slice($to, 0, $jMax);
  1678. $toEnd = array_slice($to, $jMax);
  1679. return array_merge(
  1680. $this->calculate($fromStart, $toStart),
  1681. $this->calculate($fromEnd, $toEnd)
  1682. );
  1683. }
  1684. }
  1685. /**
  1686. * @param array $from
  1687. * @param array $to
  1688. * @return array
  1689. */
  1690. private function length(array $from, array $to)
  1691. {
  1692. $current = array_fill(0, count($to) + 1, 0);
  1693. $cFrom = count($from);
  1694. $cTo = count($to);
  1695. for ($i = 0; $i < $cFrom; $i++) {
  1696. $prev = $current;
  1697. for ($j = 0; $j < $cTo; $j++) {
  1698. if ($from[$i] == $to[$j]) {
  1699. $current[$j + 1] = $prev[$j] + 1;
  1700. } else {
  1701. $current[$j + 1] = max($current[$j], $prev[$j + 1]);
  1702. }
  1703. }
  1704. }
  1705. return $current;
  1706. }
  1707. }
  1708. <?php
  1709. /*
  1710. * This file is part of the Diff package.
  1711. *
  1712. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  1713. *
  1714. * For the full copyright and license information, please view the LICENSE
  1715. * file that was distributed with this source code.
  1716. */
  1717. namespace SebastianBergmann\Diff\LCS;
  1718. /**
  1719. * Time-efficient implementation of longest common subsequence calculation.
  1720. *
  1721. * @package Diff
  1722. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1723. * @author Kore Nordmann <mail@kore-nordmann.de>
  1724. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  1725. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1726. * @link http://www.github.com/sebastianbergmann/diff
  1727. */
  1728. class TimeEfficientImplementation implements LongestCommonSubsequence
  1729. {
  1730. /**
  1731. * Calculates the longest common subsequence of two arrays.
  1732. *
  1733. * @param array $from
  1734. * @param array $to
  1735. * @return array
  1736. */
  1737. public function calculate(array $from, array $to)
  1738. {
  1739. $common = array();
  1740. $fromLength = count($from);
  1741. $toLength = count($to);
  1742. $width = $fromLength + 1;
  1743. $matrix = new \SplFixedArray($width * ($toLength + 1));
  1744. for ($i = 0; $i <= $fromLength; ++$i) {
  1745. $matrix[$i] = 0;
  1746. }
  1747. for ($j = 0; $j <= $toLength; ++$j) {
  1748. $matrix[$j * $width] = 0;
  1749. }
  1750. for ($i = 1; $i <= $fromLength; ++$i) {
  1751. for ($j = 1; $j <= $toLength; ++$j) {
  1752. $o = ($j * $width) + $i;
  1753. $matrix[$o] = max(
  1754. $matrix[$o - 1],
  1755. $matrix[$o - $width],
  1756. $from[$i - 1] === $to[$j - 1] ? $matrix[$o - $width - 1] + 1 : 0
  1757. );
  1758. }
  1759. }
  1760. $i = $fromLength;
  1761. $j = $toLength;
  1762. while ($i > 0 && $j > 0) {
  1763. if ($from[$i-1] === $to[$j-1]) {
  1764. $common[] = $from[$i-1];
  1765. --$i;
  1766. --$j;
  1767. } else {
  1768. $o = ($j * $width) + $i;
  1769. if ($matrix[$o - $width] > $matrix[$o - 1]) {
  1770. --$j;
  1771. } else {
  1772. --$i;
  1773. }
  1774. }
  1775. }
  1776. return array_reverse($common);
  1777. }
  1778. }
  1779. <?php
  1780. /*
  1781. * This file is part of the Diff package.
  1782. *
  1783. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  1784. *
  1785. * For the full copyright and license information, please view the LICENSE
  1786. * file that was distributed with this source code.
  1787. */
  1788. namespace SebastianBergmann\Diff;
  1789. /**
  1790. * @package Diff
  1791. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1792. * @author Kore Nordmann <mail@kore-nordmann.de>
  1793. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  1794. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1795. * @link http://www.github.com/sebastianbergmann/diff
  1796. */
  1797. class Line
  1798. {
  1799. const ADDED = 1;
  1800. const REMOVED = 2;
  1801. const UNCHANGED = 3;
  1802. /**
  1803. * @var int
  1804. */
  1805. private $type;
  1806. /**
  1807. * @var string
  1808. */
  1809. private $content;
  1810. /**
  1811. * @param int $type
  1812. * @param string $content
  1813. */
  1814. public function __construct($type = self::UNCHANGED, $content = '')
  1815. {
  1816. $this->type = $type;
  1817. $this->content = $content;
  1818. }
  1819. /**
  1820. * @return string
  1821. */
  1822. public function getContent()
  1823. {
  1824. return $this->content;
  1825. }
  1826. /**
  1827. * @return int
  1828. */
  1829. public function getType()
  1830. {
  1831. return $this->type;
  1832. }
  1833. }
  1834. <?php
  1835. /*
  1836. * This file is part of the Diff package.
  1837. *
  1838. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  1839. *
  1840. * For the full copyright and license information, please view the LICENSE
  1841. * file that was distributed with this source code.
  1842. */
  1843. namespace SebastianBergmann\Diff;
  1844. use SebastianBergmann\Diff\LCS\LongestCommonSubsequence;
  1845. use SebastianBergmann\Diff\LCS\TimeEfficientImplementation;
  1846. use SebastianBergmann\Diff\LCS\MemoryEfficientImplementation;
  1847. /**
  1848. * Diff implementation.
  1849. *
  1850. * @package Diff
  1851. * @author Sebastian Bergmann <sebastian@phpunit.de>
  1852. * @author Kore Nordmann <mail@kore-nordmann.de>
  1853. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  1854. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  1855. * @link http://www.github.com/sebastianbergmann/diff
  1856. */
  1857. class Differ
  1858. {
  1859. /**
  1860. * @var string
  1861. */
  1862. private $header;
  1863. /**
  1864. * @param string $header
  1865. */
  1866. public function __construct($header = "--- Original\n+++ New\n")
  1867. {
  1868. $this->header = $header;
  1869. }
  1870. /**
  1871. * Returns the diff between two arrays or strings as string.
  1872. *
  1873. * @param array|string $from
  1874. * @param array|string $to
  1875. * @param LongestCommonSubsequence $lcs
  1876. * @return string
  1877. */
  1878. public function diff($from, $to, LongestCommonSubsequence $lcs = null)
  1879. {
  1880. if (!is_array($from) && !is_string($from)) {
  1881. $from = (string) $from;
  1882. }
  1883. if (!is_array($to) && !is_string($to)) {
  1884. $to = (string) $to;
  1885. }
  1886. $buffer = $this->header;
  1887. $diff = $this->diffToArray($from, $to, $lcs);
  1888. $inOld = false;
  1889. $i = 0;
  1890. $old = array();
  1891. foreach ($diff as $line) {
  1892. if ($line[1] === 0 /* OLD */) {
  1893. if ($inOld === false) {
  1894. $inOld = $i;
  1895. }
  1896. } elseif ($inOld !== false) {
  1897. if (($i - $inOld) > 5) {
  1898. $old[$inOld] = $i - 1;
  1899. }
  1900. $inOld = false;
  1901. }
  1902. ++$i;
  1903. }
  1904. $start = isset($old[0]) ? $old[0] : 0;
  1905. $end = count($diff);
  1906. if ($tmp = array_search($end, $old)) {
  1907. $end = $tmp;
  1908. }
  1909. $newChunk = true;
  1910. for ($i = $start; $i < $end; $i++) {
  1911. if (isset($old[$i])) {
  1912. $buffer .= "\n";
  1913. $newChunk = true;
  1914. $i = $old[$i];
  1915. }
  1916. if ($newChunk) {
  1917. $buffer .= "@@ @@\n";
  1918. $newChunk = false;
  1919. }
  1920. if ($diff[$i][1] === 1 /* ADDED */) {
  1921. $buffer .= '+' . $diff[$i][0] . "\n";
  1922. } elseif ($diff[$i][1] === 2 /* REMOVED */) {
  1923. $buffer .= '-' . $diff[$i][0] . "\n";
  1924. } else {
  1925. $buffer .= ' ' . $diff[$i][0] . "\n";
  1926. }
  1927. }
  1928. return $buffer;
  1929. }
  1930. /**
  1931. * Returns the diff between two arrays or strings as array.
  1932. *
  1933. * Each array element contains two elements:
  1934. * - [0] => string $token
  1935. * - [1] => 2|1|0
  1936. *
  1937. * - 2: REMOVED: $token was removed from $from
  1938. * - 1: ADDED: $token was added to $from
  1939. * - 0: OLD: $token is not changed in $to
  1940. *
  1941. * @param array|string $from
  1942. * @param array|string $to
  1943. * @param LongestCommonSubsequence $lcs
  1944. * @return array
  1945. */
  1946. public function diffToArray($from, $to, LongestCommonSubsequence $lcs = null)
  1947. {
  1948. preg_match_all('(\r\n|\r|\n)', $from, $fromMatches);
  1949. preg_match_all('(\r\n|\r|\n)', $to, $toMatches);
  1950. if (is_string($from)) {
  1951. $from = preg_split('(\r\n|\r|\n)', $from);
  1952. }
  1953. if (is_string($to)) {
  1954. $to = preg_split('(\r\n|\r|\n)', $to);
  1955. }
  1956. $start = array();
  1957. $end = array();
  1958. $fromLength = count($from);
  1959. $toLength = count($to);
  1960. $length = min($fromLength, $toLength);
  1961. for ($i = 0; $i < $length; ++$i) {
  1962. if ($from[$i] === $to[$i]) {
  1963. $start[] = $from[$i];
  1964. unset($from[$i], $to[$i]);
  1965. } else {
  1966. break;
  1967. }
  1968. }
  1969. $length -= $i;
  1970. for ($i = 1; $i < $length; ++$i) {
  1971. if ($from[$fromLength - $i] === $to[$toLength - $i]) {
  1972. array_unshift($end, $from[$fromLength - $i]);
  1973. unset($from[$fromLength - $i], $to[$toLength - $i]);
  1974. } else {
  1975. break;
  1976. }
  1977. }
  1978. if ($lcs === null) {
  1979. $lcs = $this->selectLcsImplementation($from, $to);
  1980. }
  1981. $common = $lcs->calculate(array_values($from), array_values($to));
  1982. $diff = array();
  1983. if (isset($fromMatches[0]) && $toMatches[0] &&
  1984. count($fromMatches[0]) === count($toMatches[0]) &&
  1985. $fromMatches[0] !== $toMatches[0]) {
  1986. $diff[] = array(
  1987. '#Warning: Strings contain different line endings!', 0
  1988. );
  1989. }
  1990. foreach ($start as $token) {
  1991. $diff[] = array($token, 0 /* OLD */);
  1992. }
  1993. reset($from);
  1994. reset($to);
  1995. foreach ($common as $token) {
  1996. while ((($fromToken = reset($from)) !== $token)) {
  1997. $diff[] = array(array_shift($from), 2 /* REMOVED */);
  1998. }
  1999. while ((($toToken = reset($to)) !== $token)) {
  2000. $diff[] = array(array_shift($to), 1 /* ADDED */);
  2001. }
  2002. $diff[] = array($token, 0 /* OLD */);
  2003. array_shift($from);
  2004. array_shift($to);
  2005. }
  2006. while (($token = array_shift($from)) !== null) {
  2007. $diff[] = array($token, 2 /* REMOVED */);
  2008. }
  2009. while (($token = array_shift($to)) !== null) {
  2010. $diff[] = array($token, 1 /* ADDED */);
  2011. }
  2012. foreach ($end as $token) {
  2013. $diff[] = array($token, 0 /* OLD */);
  2014. }
  2015. return $diff;
  2016. }
  2017. /**
  2018. * @param array $from
  2019. * @param array $to
  2020. * @return LongestCommonSubsequence
  2021. */
  2022. private function selectLcsImplementation(array $from, array $to)
  2023. {
  2024. // We do not want to use the time-efficient implementation if its memory
  2025. // footprint will probably exceed this value. Note that the footprint
  2026. // calculation is only an estimation for the matrix and the LCS method
  2027. // will typically allocate a bit more memory than this.
  2028. $memoryLimit = 100 * 1024 * 1024;
  2029. if ($this->calculateEstimatedFootprint($from, $to) > $memoryLimit) {
  2030. return new MemoryEfficientImplementation;
  2031. }
  2032. return new TimeEfficientImplementation;
  2033. }
  2034. /**
  2035. * Calculates the estimated memory footprint for the DP-based method.
  2036. *
  2037. * @param array $from
  2038. * @param array $to
  2039. * @return integer
  2040. */
  2041. private function calculateEstimatedFootprint(array $from, array $to)
  2042. {
  2043. $itemSize = PHP_INT_SIZE == 4 ? 76 : 144;
  2044. return $itemSize * pow(min(count($from), count($to)), 2);
  2045. }
  2046. }
  2047. <?php
  2048. /*
  2049. * This file is part of the Diff package.
  2050. *
  2051. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2052. *
  2053. * For the full copyright and license information, please view the LICENSE
  2054. * file that was distributed with this source code.
  2055. */
  2056. namespace SebastianBergmann\Diff;
  2057. /**
  2058. * Unified diff parser.
  2059. *
  2060. * @package Diff
  2061. * @author Sebastian Bergmann <sebastian@phpunit.de>
  2062. * @author Kore Nordmann <mail@kore-nordmann.de>
  2063. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2064. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2065. * @link http://www.github.com/sebastianbergmann/diff
  2066. */
  2067. class Parser
  2068. {
  2069. /**
  2070. * @param string $string
  2071. * @return Diff[]
  2072. */
  2073. public function parse($string)
  2074. {
  2075. $lines = preg_split('(\r\n|\r|\n)', $string);
  2076. $lineCount = count($lines);
  2077. $diffs = array();
  2078. $diff = null;
  2079. $collected = array();
  2080. for ($i = 0; $i < $lineCount; ++$i) {
  2081. if (preg_match('(^---\\s+(?P<file>\\S+))', $lines[$i], $fromMatch) &&
  2082. preg_match('(^\\+\\+\\+\\s+(?P<file>\\S+))', $lines[$i + 1], $toMatch)) {
  2083. if ($diff !== null) {
  2084. $this->parseFileDiff($diff, $collected);
  2085. $diffs[] = $diff;
  2086. $collected = array();
  2087. }
  2088. $diff = new Diff($fromMatch['file'], $toMatch['file']);
  2089. ++$i;
  2090. } else {
  2091. if (preg_match('/^(?:diff --git |index [\da-f\.]+|[+-]{3} [ab])/', $lines[$i])) {
  2092. continue;
  2093. }
  2094. $collected[] = $lines[$i];
  2095. }
  2096. }
  2097. if (count($collected) && ($diff !== null)) {
  2098. $this->parseFileDiff($diff, $collected);
  2099. $diffs[] = $diff;
  2100. }
  2101. return $diffs;
  2102. }
  2103. /**
  2104. * @param Diff $diff
  2105. * @param array $lines
  2106. */
  2107. private function parseFileDiff(Diff $diff, array $lines)
  2108. {
  2109. $chunks = array();
  2110. foreach ($lines as $line) {
  2111. if (preg_match('/^@@\s+-(?P<start>\d+)(?:,\s*(?P<startrange>\d+))?\s+\+(?P<end>\d+)(?:,\s*(?P<endrange>\d+))?\s+@@/', $line, $match)) {
  2112. $chunk = new Chunk(
  2113. $match['start'],
  2114. isset($match['startrange']) ? max(1, $match['startrange']) : 1,
  2115. $match['end'],
  2116. isset($match['endrange']) ? max(1, $match['endrange']) : 1
  2117. );
  2118. $chunks[] = $chunk;
  2119. $diffLines = array();
  2120. continue;
  2121. }
  2122. if (preg_match('/^(?P<type>[+ -])?(?P<line>.*)/', $line, $match)) {
  2123. $type = Line::UNCHANGED;
  2124. if ($match['type'] == '+') {
  2125. $type = Line::ADDED;
  2126. } elseif ($match['type'] == '-') {
  2127. $type = Line::REMOVED;
  2128. }
  2129. $diffLines[] = new Line($type, $match['line']);
  2130. if (isset($chunk)) {
  2131. $chunk->setLines($diffLines);
  2132. }
  2133. }
  2134. }
  2135. $diff->setChunks($chunks);
  2136. }
  2137. }
  2138. <?php
  2139. /*
  2140. * This file is part of the Diff package.
  2141. *
  2142. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2143. *
  2144. * For the full copyright and license information, please view the LICENSE
  2145. * file that was distributed with this source code.
  2146. */
  2147. namespace SebastianBergmann\Diff;
  2148. /**
  2149. * @package Diff
  2150. * @author Sebastian Bergmann <sebastian@phpunit.de>
  2151. * @author Kore Nordmann <mail@kore-nordmann.de>
  2152. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2153. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2154. * @link http://www.github.com/sebastianbergmann/diff
  2155. */
  2156. class Diff
  2157. {
  2158. /**
  2159. * @var string
  2160. */
  2161. private $from;
  2162. /**
  2163. * @var string
  2164. */
  2165. private $to;
  2166. /**
  2167. * @var Chunk[]
  2168. */
  2169. private $chunks;
  2170. /**
  2171. * @param string $from
  2172. * @param string $to
  2173. * @param Chunk[] $chunks
  2174. */
  2175. public function __construct($from, $to, array $chunks = array())
  2176. {
  2177. $this->from = $from;
  2178. $this->to = $to;
  2179. $this->chunks = $chunks;
  2180. }
  2181. /**
  2182. * @return string
  2183. */
  2184. public function getFrom()
  2185. {
  2186. return $this->from;
  2187. }
  2188. /**
  2189. * @return string
  2190. */
  2191. public function getTo()
  2192. {
  2193. return $this->to;
  2194. }
  2195. /**
  2196. * @return Chunk[]
  2197. */
  2198. public function getChunks()
  2199. {
  2200. return $this->chunks;
  2201. }
  2202. /**
  2203. * @param Chunk[] $chunks
  2204. */
  2205. public function setChunks(array $chunks)
  2206. {
  2207. $this->chunks = $chunks;
  2208. }
  2209. }
  2210. <?php
  2211. /*
  2212. * This file is part of the Diff package.
  2213. *
  2214. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2215. *
  2216. * For the full copyright and license information, please view the LICENSE
  2217. * file that was distributed with this source code.
  2218. */
  2219. namespace SebastianBergmann\Diff;
  2220. /**
  2221. * @package Diff
  2222. * @author Sebastian Bergmann <sebastian@phpunit.de>
  2223. * @author Kore Nordmann <mail@kore-nordmann.de>
  2224. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2225. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2226. * @link http://www.github.com/sebastianbergmann/diff
  2227. */
  2228. class Chunk
  2229. {
  2230. /**
  2231. * @var int
  2232. */
  2233. private $start;
  2234. /**
  2235. * @var int
  2236. */
  2237. private $startRange;
  2238. /**
  2239. * @var int
  2240. */
  2241. private $end;
  2242. /**
  2243. * @var int
  2244. */
  2245. private $endRange;
  2246. /**
  2247. * @var array
  2248. */
  2249. private $lines;
  2250. /**
  2251. * @param int $start
  2252. * @param int $startRange
  2253. * @param int $end
  2254. * @param int $endRange
  2255. * @param array $lines
  2256. */
  2257. public function __construct($start = 0, $startRange = 1, $end = 0, $endRange = 1, array $lines = array())
  2258. {
  2259. $this->start = (int) $start;
  2260. $this->startRange = (int) $startRange;
  2261. $this->end = (int) $end;
  2262. $this->endRange = (int) $endRange;
  2263. $this->lines = $lines;
  2264. }
  2265. /**
  2266. * @return int
  2267. */
  2268. public function getStart()
  2269. {
  2270. return $this->start;
  2271. }
  2272. /**
  2273. * @return int
  2274. */
  2275. public function getStartRange()
  2276. {
  2277. return $this->startRange;
  2278. }
  2279. /**
  2280. * @return int
  2281. */
  2282. public function getEnd()
  2283. {
  2284. return $this->end;
  2285. }
  2286. /**
  2287. * @return int
  2288. */
  2289. public function getEndRange()
  2290. {
  2291. return $this->endRange;
  2292. }
  2293. /**
  2294. * @return array
  2295. */
  2296. public function getLines()
  2297. {
  2298. return $this->lines;
  2299. }
  2300. /**
  2301. * @param array $lines
  2302. */
  2303. public function setLines(array $lines)
  2304. {
  2305. $this->lines = $lines;
  2306. }
  2307. }
  2308. <?php
  2309. /*
  2310. * This file is part of the PHP_Timer package.
  2311. *
  2312. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2313. *
  2314. * For the full copyright and license information, please view the LICENSE
  2315. * file that was distributed with this source code.
  2316. */
  2317. /**
  2318. * Utility class for timing.
  2319. *
  2320. * @package PHP
  2321. * @subpackage Timer
  2322. * @author Sebastian Bergmann <sebastian@phpunit.de>
  2323. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2324. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2325. * @link http://github.com/sebastianbergmann/php-timer
  2326. * @since Class available since Release 1.0.0
  2327. */
  2328. class PHP_Timer
  2329. {
  2330. /**
  2331. * @var array
  2332. */
  2333. private static $times = array(
  2334. 'hour' => 3600000,
  2335. 'minute' => 60000,
  2336. 'second' => 1000
  2337. );
  2338. /**
  2339. * @var array
  2340. */
  2341. private static $startTimes = array();
  2342. /**
  2343. * @var float
  2344. */
  2345. public static $requestTime;
  2346. /**
  2347. * Starts the timer.
  2348. */
  2349. public static function start()
  2350. {
  2351. array_push(self::$startTimes, microtime(true));
  2352. }
  2353. /**
  2354. * Stops the timer and returns the elapsed time.
  2355. *
  2356. * @return float
  2357. */
  2358. public static function stop()
  2359. {
  2360. return microtime(true) - array_pop(self::$startTimes);
  2361. }
  2362. /**
  2363. * Formats the elapsed time as a string.
  2364. *
  2365. * @param float $time
  2366. * @return string
  2367. */
  2368. public static function secondsToTimeString($time)
  2369. {
  2370. $ms = round($time * 1000);
  2371. foreach (self::$times as $unit => $value) {
  2372. if ($ms >= $value) {
  2373. $time = floor($ms / $value * 100.0) / 100.0;
  2374. return $time . ' ' . ($time == 1 ? $unit : $unit . 's');
  2375. }
  2376. }
  2377. return $ms . ' ms';
  2378. }
  2379. /**
  2380. * Formats the elapsed time since the start of the request as a string.
  2381. *
  2382. * @return string
  2383. */
  2384. public static function timeSinceStartOfRequest()
  2385. {
  2386. return self::secondsToTimeString(microtime(true) - self::$requestTime);
  2387. }
  2388. /**
  2389. * Returns the resources (time, memory) of the request as a string.
  2390. *
  2391. * @return string
  2392. */
  2393. public static function resourceUsage()
  2394. {
  2395. return sprintf(
  2396. 'Time: %s, Memory: %4.2fMb',
  2397. self::timeSinceStartOfRequest(),
  2398. memory_get_peak_usage(true) / 1048576
  2399. );
  2400. }
  2401. }
  2402. if (isset($_SERVER['REQUEST_TIME_FLOAT'])) {
  2403. PHP_Timer::$requestTime = $_SERVER['REQUEST_TIME_FLOAT'];
  2404. } elseif (isset($_SERVER['REQUEST_TIME'])) {
  2405. PHP_Timer::$requestTime = $_SERVER['REQUEST_TIME'];
  2406. } else {
  2407. PHP_Timer::$requestTime = microtime(true);
  2408. }
  2409. PHP_Timer
  2410. Copyright (c) 2010-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  2411. All rights reserved.
  2412. Redistribution and use in source and binary forms, with or without
  2413. modification, are permitted provided that the following conditions
  2414. are met:
  2415. * Redistributions of source code must retain the above copyright
  2416. notice, this list of conditions and the following disclaimer.
  2417. * Redistributions in binary form must reproduce the above copyright
  2418. notice, this list of conditions and the following disclaimer in
  2419. the documentation and/or other materials provided with the
  2420. distribution.
  2421. * Neither the name of Sebastian Bergmann nor the names of his
  2422. contributors may be used to endorse or promote products derived
  2423. from this software without specific prior written permission.
  2424. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  2425. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  2426. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  2427. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  2428. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  2429. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  2430. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  2431. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  2432. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  2433. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  2434. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  2435. POSSIBILITY OF SUCH DAMAGE.
  2436. Comparator
  2437. Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  2438. All rights reserved.
  2439. Redistribution and use in source and binary forms, with or without
  2440. modification, are permitted provided that the following conditions
  2441. are met:
  2442. * Redistributions of source code must retain the above copyright
  2443. notice, this list of conditions and the following disclaimer.
  2444. * Redistributions in binary form must reproduce the above copyright
  2445. notice, this list of conditions and the following disclaimer in
  2446. the documentation and/or other materials provided with the
  2447. distribution.
  2448. * Neither the name of Sebastian Bergmann nor the names of his
  2449. contributors may be used to endorse or promote products derived
  2450. from this software without specific prior written permission.
  2451. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  2452. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  2453. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  2454. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  2455. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  2456. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  2457. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  2458. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  2459. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  2460. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  2461. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  2462. POSSIBILITY OF SUCH DAMAGE.
  2463. <?php
  2464. /*
  2465. * This file is part of the Comparator package.
  2466. *
  2467. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2468. *
  2469. * For the full copyright and license information, please view the LICENSE
  2470. * file that was distributed with this source code.
  2471. */
  2472. namespace SebastianBergmann\Comparator;
  2473. use SebastianBergmann\Exporter\Exporter;
  2474. /**
  2475. * Abstract base class for comparators which compare values for equality.
  2476. *
  2477. * @package Comparator
  2478. * @subpackage Framework
  2479. * @author Bernhard Schussek <bschussek@2bepublished.at>
  2480. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2481. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2482. * @link http://www.github.com/sebastianbergmann/comparator
  2483. */
  2484. abstract class Comparator
  2485. {
  2486. /**
  2487. * @var Factory
  2488. */
  2489. protected $factory;
  2490. /**
  2491. * @var Exporter
  2492. */
  2493. protected $exporter;
  2494. public function __construct()
  2495. {
  2496. $this->exporter = new Exporter;
  2497. }
  2498. /**
  2499. * @param Factory $factory
  2500. */
  2501. public function setFactory(Factory $factory)
  2502. {
  2503. $this->factory = $factory;
  2504. }
  2505. /**
  2506. * Returns whether the comparator can compare two values.
  2507. *
  2508. * @param mixed $expected The first value to compare
  2509. * @param mixed $actual The second value to compare
  2510. * @return boolean
  2511. */
  2512. abstract public function accepts($expected, $actual);
  2513. /**
  2514. * Asserts that two values are equal.
  2515. *
  2516. * @param mixed $expected The first value to compare
  2517. * @param mixed $actual The second value to compare
  2518. * @param float $delta The allowed numerical distance between two values to
  2519. * consider them equal
  2520. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  2521. * comparison
  2522. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  2523. * ignored when comparing string values
  2524. * @throws ComparisonFailure Thrown when the comparison
  2525. * fails. Contains information about the
  2526. * specific errors that lead to the failure.
  2527. */
  2528. abstract public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false);
  2529. }
  2530. <?php
  2531. /*
  2532. * This file is part of the Comparator package.
  2533. *
  2534. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2535. *
  2536. * For the full copyright and license information, please view the LICENSE
  2537. * file that was distributed with this source code.
  2538. */
  2539. namespace SebastianBergmann\Comparator;
  2540. /**
  2541. * Compares \SplObjectStorage instances for equality.
  2542. *
  2543. * @package Comparator
  2544. * @author Bernhard Schussek <bschussek@2bepublished.at>
  2545. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2546. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2547. * @link http://www.github.com/sebastianbergmann/comparator
  2548. */
  2549. class SplObjectStorageComparator extends Comparator
  2550. {
  2551. /**
  2552. * Returns whether the comparator can compare two values.
  2553. *
  2554. * @param mixed $expected The first value to compare
  2555. * @param mixed $actual The second value to compare
  2556. * @return boolean
  2557. */
  2558. public function accepts($expected, $actual)
  2559. {
  2560. return $expected instanceof \SplObjectStorage && $actual instanceof \SplObjectStorage;
  2561. }
  2562. /**
  2563. * Asserts that two values are equal.
  2564. *
  2565. * @param mixed $expected The first value to compare
  2566. * @param mixed $actual The second value to compare
  2567. * @param float $delta The allowed numerical distance between two values to
  2568. * consider them equal
  2569. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  2570. * comparison
  2571. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  2572. * ignored when comparing string values
  2573. * @throws ComparisonFailure Thrown when the comparison
  2574. * fails. Contains information about the
  2575. * specific errors that lead to the failure.
  2576. */
  2577. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  2578. {
  2579. foreach ($actual as $object) {
  2580. if (!$expected->contains($object)) {
  2581. throw new ComparisonFailure(
  2582. $expected,
  2583. $actual,
  2584. $this->exporter->export($expected),
  2585. $this->exporter->export($actual),
  2586. false,
  2587. 'Failed asserting that two objects are equal.'
  2588. );
  2589. }
  2590. }
  2591. foreach ($expected as $object) {
  2592. if (!$actual->contains($object)) {
  2593. throw new ComparisonFailure(
  2594. $expected,
  2595. $actual,
  2596. $this->exporter->export($expected),
  2597. $this->exporter->export($actual),
  2598. false,
  2599. 'Failed asserting that two objects are equal.'
  2600. );
  2601. }
  2602. }
  2603. }
  2604. }
  2605. <?php
  2606. /*
  2607. * This file is part of the Comparator package.
  2608. *
  2609. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2610. *
  2611. * For the full copyright and license information, please view the LICENSE
  2612. * file that was distributed with this source code.
  2613. */
  2614. namespace SebastianBergmann\Comparator;
  2615. /**
  2616. * Compares values for type equality.
  2617. *
  2618. * @package Comparator
  2619. * @author Bernhard Schussek <bschussek@2bepublished.at>
  2620. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2621. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2622. * @link http://www.github.com/sebastianbergmann/comparator
  2623. */
  2624. class TypeComparator extends Comparator
  2625. {
  2626. /**
  2627. * Returns whether the comparator can compare two values.
  2628. *
  2629. * @param mixed $expected The first value to compare
  2630. * @param mixed $actual The second value to compare
  2631. * @return boolean
  2632. */
  2633. public function accepts($expected, $actual)
  2634. {
  2635. return true;
  2636. }
  2637. /**
  2638. * Asserts that two values are equal.
  2639. *
  2640. * @param mixed $expected The first value to compare
  2641. * @param mixed $actual The second value to compare
  2642. * @param float $delta The allowed numerical distance between two values to
  2643. * consider them equal
  2644. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  2645. * comparison
  2646. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  2647. * ignored when comparing string values
  2648. * @throws ComparisonFailure Thrown when the comparison
  2649. * fails. Contains information about the
  2650. * specific errors that lead to the failure.
  2651. */
  2652. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  2653. {
  2654. if (gettype($expected) != gettype($actual)) {
  2655. throw new ComparisonFailure(
  2656. $expected,
  2657. $actual,
  2658. // we don't need a diff
  2659. '',
  2660. '',
  2661. false,
  2662. sprintf(
  2663. '%s does not match expected type "%s".',
  2664. $this->exporter->shortenedExport($actual),
  2665. gettype($expected)
  2666. )
  2667. );
  2668. }
  2669. }
  2670. }
  2671. <?php
  2672. /*
  2673. * This file is part of the Comparator package.
  2674. *
  2675. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2676. *
  2677. * For the full copyright and license information, please view the LICENSE
  2678. * file that was distributed with this source code.
  2679. */
  2680. namespace SebastianBergmann\Comparator;
  2681. /**
  2682. * Compares objects for equality.
  2683. *
  2684. * @package Comparator
  2685. * @author Bernhard Schussek <bschussek@2bepublished.at>
  2686. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2687. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2688. * @link http://www.github.com/sebastianbergmann/comparator
  2689. */
  2690. class ObjectComparator extends ArrayComparator
  2691. {
  2692. /**
  2693. * Returns whether the comparator can compare two values.
  2694. *
  2695. * @param mixed $expected The first value to compare
  2696. * @param mixed $actual The second value to compare
  2697. * @return boolean
  2698. */
  2699. public function accepts($expected, $actual)
  2700. {
  2701. return is_object($expected) && is_object($actual);
  2702. }
  2703. /**
  2704. * Asserts that two values are equal.
  2705. *
  2706. * @param mixed $expected The first value to compare
  2707. * @param mixed $actual The second value to compare
  2708. * @param float $delta The allowed numerical distance between two values to
  2709. * consider them equal
  2710. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  2711. * comparison
  2712. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  2713. * ignored when comparing string values
  2714. * @param array $processed
  2715. * @throws ComparisonFailure Thrown when the comparison
  2716. * fails. Contains information about the
  2717. * specific errors that lead to the failure.
  2718. */
  2719. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array())
  2720. {
  2721. if (get_class($actual) !== get_class($expected)) {
  2722. throw new ComparisonFailure(
  2723. $expected,
  2724. $actual,
  2725. $this->exporter->export($expected),
  2726. $this->exporter->export($actual),
  2727. false,
  2728. sprintf(
  2729. '%s is not instance of expected class "%s".',
  2730. $this->exporter->export($actual),
  2731. get_class($expected)
  2732. )
  2733. );
  2734. }
  2735. // don't compare twice to allow for cyclic dependencies
  2736. if (in_array(array($actual, $expected), $processed, true) ||
  2737. in_array(array($expected, $actual), $processed, true)) {
  2738. return;
  2739. }
  2740. $processed[] = array($actual, $expected);
  2741. // don't compare objects if they are identical
  2742. // this helps to avoid the error "maximum function nesting level reached"
  2743. // CAUTION: this conditional clause is not tested
  2744. if ($actual !== $expected) {
  2745. try {
  2746. parent::assertEquals(
  2747. $this->toArray($expected),
  2748. $this->toArray($actual),
  2749. $delta,
  2750. $canonicalize,
  2751. $ignoreCase,
  2752. $processed
  2753. );
  2754. } catch (ComparisonFailure $e) {
  2755. throw new ComparisonFailure(
  2756. $expected,
  2757. $actual,
  2758. // replace "Array" with "MyClass object"
  2759. substr_replace($e->getExpectedAsString(), get_class($expected) . ' Object', 0, 5),
  2760. substr_replace($e->getActualAsString(), get_class($actual) . ' Object', 0, 5),
  2761. false,
  2762. 'Failed asserting that two objects are equal.'
  2763. );
  2764. }
  2765. }
  2766. }
  2767. /**
  2768. * Converts an object to an array containing all of its private, protected
  2769. * and public properties.
  2770. *
  2771. * @param object $object
  2772. * @return array
  2773. */
  2774. protected function toArray($object)
  2775. {
  2776. return $this->exporter->toArray($object);
  2777. }
  2778. }
  2779. <?php
  2780. /*
  2781. * This file is part of the Comparator package.
  2782. *
  2783. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2784. *
  2785. * For the full copyright and license information, please view the LICENSE
  2786. * file that was distributed with this source code.
  2787. */
  2788. namespace SebastianBergmann\Comparator;
  2789. /**
  2790. * Compares resources for equality.
  2791. *
  2792. * @package Comparator
  2793. * @author Bernhard Schussek <bschussek@2bepublished.at>
  2794. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2795. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2796. * @link http://www.github.com/sebastianbergmann/comparator
  2797. */
  2798. class ResourceComparator extends Comparator
  2799. {
  2800. /**
  2801. * Returns whether the comparator can compare two values.
  2802. *
  2803. * @param mixed $expected The first value to compare
  2804. * @param mixed $actual The second value to compare
  2805. * @return boolean
  2806. */
  2807. public function accepts($expected, $actual)
  2808. {
  2809. return is_resource($expected) && is_resource($actual);
  2810. }
  2811. /**
  2812. * Asserts that two values are equal.
  2813. *
  2814. * @param mixed $expected The first value to compare
  2815. * @param mixed $actual The second value to compare
  2816. * @param float $delta The allowed numerical distance between two values to
  2817. * consider them equal
  2818. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  2819. * comparison
  2820. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  2821. * ignored when comparing string values
  2822. * @throws ComparisonFailure Thrown when the comparison
  2823. * fails. Contains information about the
  2824. * specific errors that lead to the failure.
  2825. */
  2826. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  2827. {
  2828. if ($actual != $expected) {
  2829. throw new ComparisonFailure(
  2830. $expected,
  2831. $actual,
  2832. $this->exporter->export($expected),
  2833. $this->exporter->export($actual)
  2834. );
  2835. }
  2836. }
  2837. }
  2838. <?php
  2839. /*
  2840. * This file is part of the Comparator package.
  2841. *
  2842. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2843. *
  2844. * For the full copyright and license information, please view the LICENSE
  2845. * file that was distributed with this source code.
  2846. */
  2847. namespace SebastianBergmann\Comparator;
  2848. /**
  2849. * Compares arrays for equality.
  2850. *
  2851. * @package Comparator
  2852. * @author Bernhard Schussek <bschussek@2bepublished.at>
  2853. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2854. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2855. * @link http://www.github.com/sebastianbergmann/comparator
  2856. */
  2857. class ArrayComparator extends Comparator
  2858. {
  2859. /**
  2860. * Returns whether the comparator can compare two values.
  2861. *
  2862. * @param mixed $expected The first value to compare
  2863. * @param mixed $actual The second value to compare
  2864. * @return boolean
  2865. */
  2866. public function accepts($expected, $actual)
  2867. {
  2868. return is_array($expected) && is_array($actual);
  2869. }
  2870. /**
  2871. * Asserts that two values are equal.
  2872. *
  2873. * @param mixed $expected The first value to compare
  2874. * @param mixed $actual The second value to compare
  2875. * @param float $delta The allowed numerical distance between two values to
  2876. * consider them equal
  2877. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  2878. * comparison
  2879. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  2880. * ignored when comparing string values
  2881. * @param array $processed
  2882. * @throws ComparisonFailure Thrown when the comparison
  2883. * fails. Contains information about the
  2884. * specific errors that lead to the failure.
  2885. */
  2886. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array())
  2887. {
  2888. if ($canonicalize) {
  2889. sort($expected);
  2890. sort($actual);
  2891. }
  2892. $remaining = $actual;
  2893. $expString = $actString = "Array (\n";
  2894. $equal = true;
  2895. foreach ($expected as $key => $value) {
  2896. unset($remaining[$key]);
  2897. if (!array_key_exists($key, $actual)) {
  2898. $expString .= sprintf(
  2899. " %s => %s\n",
  2900. $this->exporter->export($key),
  2901. $this->exporter->shortenedExport($value)
  2902. );
  2903. $equal = false;
  2904. continue;
  2905. }
  2906. try {
  2907. $comparator = $this->factory->getComparatorFor($value, $actual[$key]);
  2908. $comparator->assertEquals($value, $actual[$key], $delta, $canonicalize, $ignoreCase, $processed);
  2909. $expString .= sprintf(
  2910. " %s => %s\n",
  2911. $this->exporter->export($key),
  2912. $this->exporter->shortenedExport($value)
  2913. );
  2914. $actString .= sprintf(
  2915. " %s => %s\n",
  2916. $this->exporter->export($key),
  2917. $this->exporter->shortenedExport($actual[$key])
  2918. );
  2919. } catch (ComparisonFailure $e) {
  2920. $expString .= sprintf(
  2921. " %s => %s\n",
  2922. $this->exporter->export($key),
  2923. $e->getExpectedAsString()
  2924. ? $this->indent($e->getExpectedAsString())
  2925. : $this->exporter->shortenedExport($e->getExpected())
  2926. );
  2927. $actString .= sprintf(
  2928. " %s => %s\n",
  2929. $this->exporter->export($key),
  2930. $e->getActualAsString()
  2931. ? $this->indent($e->getActualAsString())
  2932. : $this->exporter->shortenedExport($e->getActual())
  2933. );
  2934. $equal = false;
  2935. }
  2936. }
  2937. foreach ($remaining as $key => $value) {
  2938. $actString .= sprintf(
  2939. " %s => %s\n",
  2940. $this->exporter->export($key),
  2941. $this->exporter->shortenedExport($value)
  2942. );
  2943. $equal = false;
  2944. }
  2945. $expString .= ')';
  2946. $actString .= ')';
  2947. if (!$equal) {
  2948. throw new ComparisonFailure(
  2949. $expected,
  2950. $actual,
  2951. $expString,
  2952. $actString,
  2953. false,
  2954. 'Failed asserting that two arrays are equal.'
  2955. );
  2956. }
  2957. }
  2958. protected function indent($lines)
  2959. {
  2960. return trim(str_replace("\n", "\n ", $lines));
  2961. }
  2962. }
  2963. <?php
  2964. /*
  2965. * This file is part of the Comparator package.
  2966. *
  2967. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  2968. *
  2969. * For the full copyright and license information, please view the LICENSE
  2970. * file that was distributed with this source code.
  2971. */
  2972. namespace SebastianBergmann\Comparator;
  2973. /**
  2974. * Compares DateTime instances for equality.
  2975. *
  2976. * @package Comparator
  2977. * @author Jeff Welch <whatthejeff@gmail.com>
  2978. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  2979. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  2980. * @link http://www.github.com/sebastianbergmann/comparator
  2981. */
  2982. class DateTimeComparator extends ObjectComparator
  2983. {
  2984. /**
  2985. * Returns whether the comparator can compare two values.
  2986. *
  2987. * @param mixed $expected The first value to compare
  2988. * @param mixed $actual The second value to compare
  2989. * @return boolean
  2990. */
  2991. public function accepts($expected, $actual)
  2992. {
  2993. return $expected instanceof \DateTime && $actual instanceof \DateTime;
  2994. }
  2995. /**
  2996. * Asserts that two values are equal.
  2997. *
  2998. * @param mixed $expected The first value to compare
  2999. * @param mixed $actual The second value to compare
  3000. * @param float $delta The allowed numerical distance between two values to
  3001. * consider them equal
  3002. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  3003. * comparison
  3004. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  3005. * ignored when comparing string values
  3006. * @throws ComparisonFailure Thrown when the comparison
  3007. * fails. Contains information about the
  3008. * specific errors that lead to the failure.
  3009. */
  3010. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  3011. {
  3012. $delta = new \DateInterval(sprintf('PT%sS', abs($delta)));
  3013. $expectedLower = clone $expected;
  3014. $expectedUpper = clone $expected;
  3015. if ($actual < $expectedLower->sub($delta) ||
  3016. $actual > $expectedUpper->add($delta)) {
  3017. throw new ComparisonFailure(
  3018. $expected,
  3019. $actual,
  3020. $this->dateTimeToString($expected),
  3021. $this->dateTimeToString($actual),
  3022. false,
  3023. 'Failed asserting that two DateTime objects are equal.'
  3024. );
  3025. }
  3026. }
  3027. /**
  3028. * Returns an ISO 8601 formatted string representation of a datetime or
  3029. * 'Invalid DateTime object' if the provided DateTime was not properly
  3030. * initialized.
  3031. *
  3032. * @param \DateTime $datetime
  3033. * @return string
  3034. */
  3035. protected function dateTimeToString(\DateTime $datetime)
  3036. {
  3037. $string = $datetime->format(\DateTime::ISO8601);
  3038. return $string ? $string : 'Invalid DateTime object';
  3039. }
  3040. }
  3041. <?php
  3042. /*
  3043. * This file is part of the Comparator package.
  3044. *
  3045. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3046. *
  3047. * For the full copyright and license information, please view the LICENSE
  3048. * file that was distributed with this source code.
  3049. */
  3050. namespace SebastianBergmann\Comparator;
  3051. /**
  3052. * Compares Exception instances for equality.
  3053. *
  3054. * @package Comparator
  3055. * @author Bernhard Schussek <bschussek@2bepublished.at>
  3056. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3057. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3058. * @link http://www.github.com/sebastianbergmann/comparator
  3059. */
  3060. class ExceptionComparator extends ObjectComparator
  3061. {
  3062. /**
  3063. * Returns whether the comparator can compare two values.
  3064. *
  3065. * @param mixed $expected The first value to compare
  3066. * @param mixed $actual The second value to compare
  3067. * @return boolean
  3068. */
  3069. public function accepts($expected, $actual)
  3070. {
  3071. return $expected instanceof \Exception && $actual instanceof \Exception;
  3072. }
  3073. /**
  3074. * Converts an object to an array containing all of its private, protected
  3075. * and public properties.
  3076. *
  3077. * @param object $object
  3078. * @return array
  3079. */
  3080. protected function toArray($object)
  3081. {
  3082. $array = parent::toArray($object);
  3083. unset(
  3084. $array['file'],
  3085. $array['line'],
  3086. $array['trace'],
  3087. $array['string'],
  3088. $array['xdebug_message']
  3089. );
  3090. return $array;
  3091. }
  3092. }
  3093. <?php
  3094. /*
  3095. * This file is part of the Comparator package.
  3096. *
  3097. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3098. *
  3099. * For the full copyright and license information, please view the LICENSE
  3100. * file that was distributed with this source code.
  3101. */
  3102. namespace SebastianBergmann\Comparator;
  3103. use DOMDocument;
  3104. use DOMNode;
  3105. /**
  3106. * Compares DOMNode instances for equality.
  3107. *
  3108. * @package Comparator
  3109. * @author Bernhard Schussek <bschussek@2bepublished.at>
  3110. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3111. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3112. * @link http://www.github.com/sebastianbergmann/comparator
  3113. */
  3114. class DOMNodeComparator extends ObjectComparator
  3115. {
  3116. /**
  3117. * Returns whether the comparator can compare two values.
  3118. *
  3119. * @param mixed $expected The first value to compare
  3120. * @param mixed $actual The second value to compare
  3121. * @return boolean
  3122. */
  3123. public function accepts($expected, $actual)
  3124. {
  3125. return $expected instanceof DOMNode && $actual instanceof DOMNode;
  3126. }
  3127. /**
  3128. * Asserts that two values are equal.
  3129. *
  3130. * @param mixed $expected The first value to compare
  3131. * @param mixed $actual The second value to compare
  3132. * @param float $delta The allowed numerical distance between two values to
  3133. * consider them equal
  3134. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  3135. * comparison
  3136. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  3137. * ignored when comparing string values
  3138. * @throws ComparisonFailure Thrown when the comparison
  3139. * fails. Contains information about the
  3140. * specific errors that lead to the failure.
  3141. */
  3142. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  3143. {
  3144. $expectedAsString = $this->nodeToText($expected, true, $ignoreCase);
  3145. $actualAsString = $this->nodeToText($actual, true, $ignoreCase);
  3146. if ($expectedAsString !== $actualAsString) {
  3147. if ($expected instanceof DOMDocument) {
  3148. $type = 'documents';
  3149. } else {
  3150. $type = 'nodes';
  3151. }
  3152. throw new ComparisonFailure(
  3153. $expected,
  3154. $actual,
  3155. $expectedAsString,
  3156. $actualAsString,
  3157. false,
  3158. sprintf("Failed asserting that two DOM %s are equal.\n", $type)
  3159. );
  3160. }
  3161. }
  3162. /**
  3163. * Returns the normalized, whitespace-cleaned, and indented textual
  3164. * representation of a DOMNode.
  3165. *
  3166. * @param DOMNode $node
  3167. * @param boolean $canonicalize
  3168. * @param boolean $ignoreCase
  3169. * @return string
  3170. */
  3171. private function nodeToText(DOMNode $node, $canonicalize, $ignoreCase)
  3172. {
  3173. if ($canonicalize) {
  3174. $document = new DOMDocument;
  3175. $document->loadXML($node->C14N());
  3176. $node = $document;
  3177. }
  3178. if ($node instanceof DOMDocument) {
  3179. $document = $node;
  3180. } else {
  3181. $document = $node->ownerDocument;
  3182. }
  3183. $document->formatOutput = true;
  3184. $document->normalizeDocument();
  3185. if ($node instanceof DOMDocument) {
  3186. $text = $node->saveXML();
  3187. } else {
  3188. $text = $document->saveXML($node);
  3189. }
  3190. if ($ignoreCase) {
  3191. $text = strtolower($text);
  3192. }
  3193. return $text;
  3194. }
  3195. }
  3196. <?php
  3197. /*
  3198. * This file is part of the Comparator package.
  3199. *
  3200. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3201. *
  3202. * For the full copyright and license information, please view the LICENSE
  3203. * file that was distributed with this source code.
  3204. */
  3205. namespace SebastianBergmann\Comparator;
  3206. /**
  3207. * Compares scalar or NULL values for equality.
  3208. *
  3209. * @package Comparator
  3210. * @author Bernhard Schussek <bschussek@2bepublished.at>
  3211. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3212. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3213. * @link http://www.github.com/sebastianbergmann/comparator
  3214. */
  3215. class ScalarComparator extends Comparator
  3216. {
  3217. /**
  3218. * Returns whether the comparator can compare two values.
  3219. *
  3220. * @param mixed $expected The first value to compare
  3221. * @param mixed $actual The second value to compare
  3222. * @return boolean
  3223. * @since Method available since Release 3.6.0
  3224. */
  3225. public function accepts($expected, $actual)
  3226. {
  3227. return ((is_scalar($expected) xor null === $expected) &&
  3228. (is_scalar($actual) xor null === $actual))
  3229. // allow comparison between strings and objects featuring __toString()
  3230. || (is_string($expected) && is_object($actual) && method_exists($actual, '__toString'))
  3231. || (is_object($expected) && method_exists($expected, '__toString') && is_string($actual));
  3232. }
  3233. /**
  3234. * Asserts that two values are equal.
  3235. *
  3236. * @param mixed $expected The first value to compare
  3237. * @param mixed $actual The second value to compare
  3238. * @param float $delta The allowed numerical distance between two values to
  3239. * consider them equal
  3240. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  3241. * comparison
  3242. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  3243. * ignored when comparing string values
  3244. * @throws ComparisonFailure Thrown when the comparison
  3245. * fails. Contains information about the
  3246. * specific errors that lead to the failure.
  3247. */
  3248. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  3249. {
  3250. $expectedToCompare = $expected;
  3251. $actualToCompare = $actual;
  3252. // always compare as strings to avoid strange behaviour
  3253. // otherwise 0 == 'Foobar'
  3254. if (is_string($expected) || is_string($actual)) {
  3255. $expectedToCompare = (string)$expectedToCompare;
  3256. $actualToCompare = (string)$actualToCompare;
  3257. if ($ignoreCase) {
  3258. $expectedToCompare = strtolower($expectedToCompare);
  3259. $actualToCompare = strtolower($actualToCompare);
  3260. }
  3261. }
  3262. if ($expectedToCompare != $actualToCompare) {
  3263. if (is_string($expected) && is_string($actual)) {
  3264. throw new ComparisonFailure(
  3265. $expected,
  3266. $actual,
  3267. $this->exporter->export($expected),
  3268. $this->exporter->export($actual),
  3269. false,
  3270. 'Failed asserting that two strings are equal.'
  3271. );
  3272. }
  3273. throw new ComparisonFailure(
  3274. $expected,
  3275. $actual,
  3276. // no diff is required
  3277. '',
  3278. '',
  3279. false,
  3280. sprintf(
  3281. 'Failed asserting that %s matches expected %s.',
  3282. $this->exporter->export($actual),
  3283. $this->exporter->export($expected)
  3284. )
  3285. );
  3286. }
  3287. }
  3288. }
  3289. <?php
  3290. /*
  3291. * This file is part of the Comparator package.
  3292. *
  3293. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3294. *
  3295. * For the full copyright and license information, please view the LICENSE
  3296. * file that was distributed with this source code.
  3297. */
  3298. namespace SebastianBergmann\Comparator;
  3299. /**
  3300. * Compares PHPUnit_Framework_MockObject_MockObject instances for equality.
  3301. *
  3302. * @package Comparator
  3303. * @author Bernhard Schussek <bschussek@2bepublished.at>
  3304. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3305. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3306. * @link http://www.github.com/sebastianbergmann/comparator
  3307. */
  3308. class MockObjectComparator extends ObjectComparator
  3309. {
  3310. /**
  3311. * Returns whether the comparator can compare two values.
  3312. *
  3313. * @param mixed $expected The first value to compare
  3314. * @param mixed $actual The second value to compare
  3315. * @return boolean
  3316. */
  3317. public function accepts($expected, $actual)
  3318. {
  3319. return $expected instanceof \PHPUnit_Framework_MockObject_MockObject && $actual instanceof \PHPUnit_Framework_MockObject_MockObject;
  3320. }
  3321. /**
  3322. * Converts an object to an array containing all of its private, protected
  3323. * and public properties.
  3324. *
  3325. * @param object $object
  3326. * @return array
  3327. */
  3328. protected function toArray($object)
  3329. {
  3330. $array = parent::toArray($object);
  3331. unset($array['__phpunit_invocationMocker']);
  3332. return $array;
  3333. }
  3334. }<?php
  3335. /*
  3336. * This file is part of the Comparator package.
  3337. *
  3338. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3339. *
  3340. * For the full copyright and license information, please view the LICENSE
  3341. * file that was distributed with this source code.
  3342. */
  3343. namespace SebastianBergmann\Comparator;
  3344. /**
  3345. * Compares numerical values for equality.
  3346. *
  3347. * @package Comparator
  3348. * @author Bernhard Schussek <bschussek@2bepublished.at>
  3349. * @author Alexander <iam.asm89@gmail.com>
  3350. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3351. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3352. * @link http://www.github.com/sebastianbergmann/comparator
  3353. */
  3354. class NumericComparator extends ScalarComparator
  3355. {
  3356. /**
  3357. * Returns whether the comparator can compare two values.
  3358. *
  3359. * @param mixed $expected The first value to compare
  3360. * @param mixed $actual The second value to compare
  3361. * @return boolean
  3362. */
  3363. public function accepts($expected, $actual)
  3364. {
  3365. // all numerical values, but not if one of them is a double
  3366. // or both of them are strings
  3367. return is_numeric($expected) && is_numeric($actual) &&
  3368. !(is_double($expected) || is_double($actual)) &&
  3369. !(is_string($expected) && is_string($actual));
  3370. }
  3371. /**
  3372. * Asserts that two values are equal.
  3373. *
  3374. * @param mixed $expected The first value to compare
  3375. * @param mixed $actual The second value to compare
  3376. * @param float $delta The allowed numerical distance between two values to
  3377. * consider them equal
  3378. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  3379. * comparison
  3380. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  3381. * ignored when comparing string values
  3382. * @throws ComparisonFailure Thrown when the comparison
  3383. * fails. Contains information about the
  3384. * specific errors that lead to the failure.
  3385. */
  3386. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  3387. {
  3388. if (is_infinite($actual) && is_infinite($expected)) {
  3389. return;
  3390. }
  3391. if ((is_infinite($actual) xor is_infinite($expected)) ||
  3392. (is_nan($actual) or is_nan($expected)) ||
  3393. abs($actual - $expected) > $delta) {
  3394. throw new ComparisonFailure(
  3395. $expected,
  3396. $actual,
  3397. '',
  3398. '',
  3399. false,
  3400. sprintf(
  3401. 'Failed asserting that %s matches expected %s.',
  3402. $this->exporter->export($actual),
  3403. $this->exporter->export($expected)
  3404. )
  3405. );
  3406. }
  3407. }
  3408. }
  3409. <?php
  3410. /*
  3411. * This file is part of the Comparator package.
  3412. *
  3413. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3414. *
  3415. * For the full copyright and license information, please view the LICENSE
  3416. * file that was distributed with this source code.
  3417. */
  3418. namespace SebastianBergmann\Comparator;
  3419. /**
  3420. * Factory for comparators which compare values for equality.
  3421. *
  3422. * @package Comparator
  3423. * @author Bernhard Schussek <bschussek@2bepublished.at>
  3424. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3425. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3426. * @link http://www.github.com/sebastianbergmann/comparator
  3427. */
  3428. class Factory
  3429. {
  3430. /**
  3431. * @var Comparator[]
  3432. */
  3433. private $comparators = array();
  3434. /**
  3435. * @var Factory
  3436. */
  3437. private static $instance;
  3438. /**
  3439. * Constructs a new factory.
  3440. */
  3441. public function __construct()
  3442. {
  3443. $this->register(new TypeComparator);
  3444. $this->register(new ScalarComparator);
  3445. $this->register(new NumericComparator);
  3446. $this->register(new DoubleComparator);
  3447. $this->register(new ArrayComparator);
  3448. $this->register(new ResourceComparator);
  3449. $this->register(new ObjectComparator);
  3450. $this->register(new ExceptionComparator);
  3451. $this->register(new SplObjectStorageComparator);
  3452. $this->register(new DOMNodeComparator);
  3453. $this->register(new MockObjectComparator);
  3454. $this->register(new DateTimeComparator);
  3455. }
  3456. /**
  3457. * @return Factory
  3458. */
  3459. public static function getInstance()
  3460. {
  3461. if (self::$instance === null) {
  3462. self::$instance = new Factory;
  3463. }
  3464. return self::$instance;
  3465. }
  3466. /**
  3467. * Returns the correct comparator for comparing two values.
  3468. *
  3469. * @param mixed $expected The first value to compare
  3470. * @param mixed $actual The second value to compare
  3471. * @return Comparator
  3472. */
  3473. public function getComparatorFor($expected, $actual)
  3474. {
  3475. foreach ($this->comparators as $comparator) {
  3476. if ($comparator->accepts($expected, $actual)) {
  3477. return $comparator;
  3478. }
  3479. }
  3480. }
  3481. /**
  3482. * Registers a new comparator.
  3483. *
  3484. * This comparator will be returned by getInstance() if its accept() method
  3485. * returns TRUE for the compared values. It has higher priority than the
  3486. * existing comparators, meaning that its accept() method will be tested
  3487. * before those of the other comparators.
  3488. *
  3489. * @param Comparator $comparator The registered comparator
  3490. */
  3491. public function register(Comparator $comparator)
  3492. {
  3493. array_unshift($this->comparators, $comparator);
  3494. $comparator->setFactory($this);
  3495. }
  3496. /**
  3497. * Unregisters a comparator.
  3498. *
  3499. * This comparator will no longer be returned by getInstance().
  3500. *
  3501. * @param Comparator $comparator The unregistered comparator
  3502. */
  3503. public function unregister(Comparator $comparator)
  3504. {
  3505. foreach ($this->comparators as $key => $_comparator) {
  3506. if ($comparator === $_comparator) {
  3507. unset($this->comparators[$key]);
  3508. }
  3509. }
  3510. }
  3511. }
  3512. <?php
  3513. /*
  3514. * This file is part of the Comparator package.
  3515. *
  3516. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3517. *
  3518. * For the full copyright and license information, please view the LICENSE
  3519. * file that was distributed with this source code.
  3520. */
  3521. namespace SebastianBergmann\Comparator;
  3522. /**
  3523. * Compares doubles for equality.
  3524. *
  3525. * @package Comparator
  3526. * @author Bernhard Schussek <bschussek@2bepublished.at>
  3527. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3528. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3529. * @link http://www.github.com/sebastianbergmann/comparator
  3530. */
  3531. class DoubleComparator extends NumericComparator
  3532. {
  3533. /**
  3534. * Smallest value available in PHP.
  3535. *
  3536. * @var float
  3537. */
  3538. const EPSILON = 0.0000000001;
  3539. /**
  3540. * Returns whether the comparator can compare two values.
  3541. *
  3542. * @param mixed $expected The first value to compare
  3543. * @param mixed $actual The second value to compare
  3544. * @return boolean
  3545. */
  3546. public function accepts($expected, $actual)
  3547. {
  3548. return (is_double($expected) || is_double($actual)) && is_numeric($expected) && is_numeric($actual);
  3549. }
  3550. /**
  3551. * Asserts that two values are equal.
  3552. *
  3553. * @param mixed $expected The first value to compare
  3554. * @param mixed $actual The second value to compare
  3555. * @param float $delta The allowed numerical distance between two values to
  3556. * consider them equal
  3557. * @param bool $canonicalize If set to TRUE, arrays are sorted before
  3558. * comparison
  3559. * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is
  3560. * ignored when comparing string values
  3561. * @throws ComparisonFailure Thrown when the comparison
  3562. * fails. Contains information about the
  3563. * specific errors that lead to the failure.
  3564. */
  3565. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  3566. {
  3567. if ($delta == 0) {
  3568. $delta = self::EPSILON;
  3569. }
  3570. parent::assertEquals($expected, $actual, $delta, $canonicalize, $ignoreCase);
  3571. }
  3572. }
  3573. <?php
  3574. /*
  3575. * This file is part of the Comparator package.
  3576. *
  3577. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  3578. *
  3579. * For the full copyright and license information, please view the LICENSE
  3580. * file that was distributed with this source code.
  3581. */
  3582. namespace SebastianBergmann\Comparator;
  3583. use SebastianBergmann\Diff\Differ;
  3584. /**
  3585. * Thrown when an assertion for string equality failed.
  3586. *
  3587. * @package Comparator
  3588. * @author Sebastian Bergmann <sebastian@phpunit.de>
  3589. * @author Bernhard Schussek <bschussek@2bepublished.at>
  3590. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  3591. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  3592. * @link http://www.github.com/sebastianbergmann/comparator
  3593. */
  3594. class ComparisonFailure extends \RuntimeException
  3595. {
  3596. /**
  3597. * Expected value of the retrieval which does not match $actual.
  3598. * @var mixed
  3599. */
  3600. protected $expected;
  3601. /**
  3602. * Actually retrieved value which does not match $expected.
  3603. * @var mixed
  3604. */
  3605. protected $actual;
  3606. /**
  3607. * The string representation of the expected value
  3608. * @var string
  3609. */
  3610. protected $expectedAsString;
  3611. /**
  3612. * The string representation of the actual value
  3613. * @var string
  3614. */
  3615. protected $actualAsString;
  3616. /**
  3617. * @var boolean
  3618. */
  3619. protected $identical;
  3620. /**
  3621. * Optional message which is placed in front of the first line
  3622. * returned by toString().
  3623. * @var string
  3624. */
  3625. protected $message;
  3626. /**
  3627. * Initialises with the expected value and the actual value.
  3628. *
  3629. * @param mixed $expected Expected value retrieved.
  3630. * @param mixed $actual Actual value retrieved.
  3631. * @param string $expectedAsString
  3632. * @param string $actualAsString
  3633. * @param boolean $identical
  3634. * @param string $message A string which is prefixed on all returned lines
  3635. * in the difference output.
  3636. */
  3637. public function __construct($expected, $actual, $expectedAsString, $actualAsString, $identical = false, $message = '')
  3638. {
  3639. $this->expected = $expected;
  3640. $this->actual = $actual;
  3641. $this->expectedAsString = $expectedAsString;
  3642. $this->actualAsString = $actualAsString;
  3643. $this->message = $message;
  3644. }
  3645. /**
  3646. * @return mixed
  3647. */
  3648. public function getActual()
  3649. {
  3650. return $this->actual;
  3651. }
  3652. /**
  3653. * @return mixed
  3654. */
  3655. public function getExpected()
  3656. {
  3657. return $this->expected;
  3658. }
  3659. /**
  3660. * @return string
  3661. */
  3662. public function getActualAsString()
  3663. {
  3664. return $this->actualAsString;
  3665. }
  3666. /**
  3667. * @return string
  3668. */
  3669. public function getExpectedAsString()
  3670. {
  3671. return $this->expectedAsString;
  3672. }
  3673. /**
  3674. * @return string
  3675. */
  3676. public function getDiff()
  3677. {
  3678. if (!$this->actualAsString && !$this->expectedAsString) {
  3679. return '';
  3680. }
  3681. $differ = new Differ("\n--- Expected\n+++ Actual\n");
  3682. return $differ->diff($this->expectedAsString, $this->actualAsString);
  3683. }
  3684. /**
  3685. * @return string
  3686. */
  3687. public function toString()
  3688. {
  3689. return $this->message . $this->getDiff();
  3690. }
  3691. }
  3692. Copyright (c) 2013 Konstantin Kudryashov <ever.zet@gmail.com>
  3693. Marcello Duarte <marcello.duarte@gmail.com>
  3694. Permission is hereby granted, free of charge, to any person
  3695. obtaining a copy of this software and associated documentation
  3696. files (the "Software"), to deal in the Software without
  3697. restriction, including without limitation the rights to use,
  3698. copy, modify, merge, publish, distribute, sublicense, and/or sell
  3699. copies of the Software, and to permit persons to whom the
  3700. Software is furnished to do so, subject to the following
  3701. conditions:
  3702. The above copyright notice and this permission notice shall be
  3703. included in all copies or substantial portions of the Software.
  3704. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  3705. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  3706. OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  3707. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  3708. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  3709. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  3710. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  3711. OTHER DEALINGS IN THE SOFTWARE.
  3712. <?php
  3713. /*
  3714. * This file is part of the Prophecy.
  3715. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  3716. * Marcello Duarte <marcello.duarte@gmail.com>
  3717. *
  3718. * For the full copyright and license information, please view the LICENSE
  3719. * file that was distributed with this source code.
  3720. */
  3721. namespace Prophecy\Prophecy;
  3722. /**
  3723. * Prophecies revealer interface.
  3724. *
  3725. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  3726. */
  3727. interface RevealerInterface
  3728. {
  3729. /**
  3730. * Unwraps value(s).
  3731. *
  3732. * @param mixed $value
  3733. *
  3734. * @return mixed
  3735. */
  3736. public function reveal($value);
  3737. }
  3738. <?php
  3739. /*
  3740. * This file is part of the Prophecy.
  3741. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  3742. * Marcello Duarte <marcello.duarte@gmail.com>
  3743. *
  3744. * For the full copyright and license information, please view the LICENSE
  3745. * file that was distributed with this source code.
  3746. */
  3747. namespace Prophecy\Prophecy;
  3748. /**
  3749. * Controllable doubles interface.
  3750. *
  3751. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  3752. */
  3753. interface ProphecySubjectInterface
  3754. {
  3755. /**
  3756. * Sets subject prophecy.
  3757. *
  3758. * @param ProphecyInterface $prophecy
  3759. */
  3760. public function setProphecy(ProphecyInterface $prophecy);
  3761. /**
  3762. * Returns subject prophecy.
  3763. *
  3764. * @return ProphecyInterface
  3765. */
  3766. public function getProphecy();
  3767. }
  3768. <?php
  3769. /*
  3770. * This file is part of the Prophecy.
  3771. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  3772. * Marcello Duarte <marcello.duarte@gmail.com>
  3773. *
  3774. * For the full copyright and license information, please view the LICENSE
  3775. * file that was distributed with this source code.
  3776. */
  3777. namespace Prophecy\Prophecy;
  3778. /**
  3779. * Basic prophecies revealer.
  3780. *
  3781. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  3782. */
  3783. class Revealer implements RevealerInterface
  3784. {
  3785. /**
  3786. * Unwraps value(s).
  3787. *
  3788. * @param mixed $value
  3789. *
  3790. * @return mixed
  3791. */
  3792. public function reveal($value)
  3793. {
  3794. if (is_array($value)) {
  3795. return array_map(array($this, __FUNCTION__), $value);
  3796. }
  3797. if (!is_object($value)) {
  3798. return $value;
  3799. }
  3800. if ($value instanceof ProphecyInterface) {
  3801. $value = $value->reveal();
  3802. }
  3803. return $value;
  3804. }
  3805. }
  3806. <?php
  3807. /*
  3808. * This file is part of the Prophecy.
  3809. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  3810. * Marcello Duarte <marcello.duarte@gmail.com>
  3811. *
  3812. * For the full copyright and license information, please view the LICENSE
  3813. * file that was distributed with this source code.
  3814. */
  3815. namespace Prophecy\Prophecy;
  3816. /**
  3817. * Core Prophecy interface.
  3818. *
  3819. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  3820. */
  3821. interface ProphecyInterface
  3822. {
  3823. /**
  3824. * Reveals prophecy object (double) .
  3825. *
  3826. * @return object
  3827. */
  3828. public function reveal();
  3829. }
  3830. <?php
  3831. /*
  3832. * This file is part of the Prophecy.
  3833. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  3834. * Marcello Duarte <marcello.duarte@gmail.com>
  3835. *
  3836. * For the full copyright and license information, please view the LICENSE
  3837. * file that was distributed with this source code.
  3838. */
  3839. namespace Prophecy\Prophecy;
  3840. use SebastianBergmann\Comparator\ComparisonFailure;
  3841. use Prophecy\Comparator\Factory as ComparatorFactory;
  3842. use Prophecy\Call\Call;
  3843. use Prophecy\Doubler\LazyDouble;
  3844. use Prophecy\Argument\ArgumentsWildcard;
  3845. use Prophecy\Call\CallCenter;
  3846. use Prophecy\Exception\Prophecy\ObjectProphecyException;
  3847. use Prophecy\Exception\Prophecy\MethodProphecyException;
  3848. use Prophecy\Exception\Prediction\AggregateException;
  3849. use Prophecy\Exception\Prediction\PredictionException;
  3850. /**
  3851. * Object prophecy.
  3852. *
  3853. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  3854. */
  3855. class ObjectProphecy implements ProphecyInterface
  3856. {
  3857. private $lazyDouble;
  3858. private $callCenter;
  3859. private $revealer;
  3860. private $comparatorFactory;
  3861. /**
  3862. * @var MethodProphecy[][]
  3863. */
  3864. private $methodProphecies = array();
  3865. /**
  3866. * Initializes object prophecy.
  3867. *
  3868. * @param LazyDouble $lazyDouble
  3869. * @param CallCenter $callCenter
  3870. * @param RevealerInterface $revealer
  3871. * @param ComparatorFactory $comparatorFactory
  3872. */
  3873. public function __construct(
  3874. LazyDouble $lazyDouble,
  3875. CallCenter $callCenter = null,
  3876. RevealerInterface $revealer = null,
  3877. ComparatorFactory $comparatorFactory = null
  3878. ) {
  3879. $this->lazyDouble = $lazyDouble;
  3880. $this->callCenter = $callCenter ?: new CallCenter;
  3881. $this->revealer = $revealer ?: new Revealer;
  3882. $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance();
  3883. }
  3884. /**
  3885. * Forces double to extend specific class.
  3886. *
  3887. * @param string $class
  3888. *
  3889. * @return $this
  3890. */
  3891. public function willExtend($class)
  3892. {
  3893. $this->lazyDouble->setParentClass($class);
  3894. return $this;
  3895. }
  3896. /**
  3897. * Forces double to implement specific interface.
  3898. *
  3899. * @param string $interface
  3900. *
  3901. * @return $this
  3902. */
  3903. public function willImplement($interface)
  3904. {
  3905. $this->lazyDouble->addInterface($interface);
  3906. return $this;
  3907. }
  3908. /**
  3909. * Sets constructor arguments.
  3910. *
  3911. * @param array $arguments
  3912. *
  3913. * @return $this
  3914. */
  3915. public function willBeConstructedWith(array $arguments = null)
  3916. {
  3917. $this->lazyDouble->setArguments($arguments);
  3918. return $this;
  3919. }
  3920. /**
  3921. * Reveals double.
  3922. *
  3923. * @return object
  3924. *
  3925. * @throws \Prophecy\Exception\Prophecy\ObjectProphecyException If double doesn't implement needed interface
  3926. */
  3927. public function reveal()
  3928. {
  3929. $double = $this->lazyDouble->getInstance();
  3930. if (null === $double || !$double instanceof ProphecySubjectInterface) {
  3931. throw new ObjectProphecyException(
  3932. "Generated double must implement ProphecySubjectInterface, but it does not.\n".
  3933. 'It seems you have wrongly configured doubler without required ClassPatch.',
  3934. $this
  3935. );
  3936. }
  3937. $double->setProphecy($this);
  3938. return $double;
  3939. }
  3940. /**
  3941. * Adds method prophecy to object prophecy.
  3942. *
  3943. * @param MethodProphecy $methodProphecy
  3944. *
  3945. * @throws \Prophecy\Exception\Prophecy\MethodProphecyException If method prophecy doesn't
  3946. * have arguments wildcard
  3947. */
  3948. public function addMethodProphecy(MethodProphecy $methodProphecy)
  3949. {
  3950. $argumentsWildcard = $methodProphecy->getArgumentsWildcard();
  3951. if (null === $argumentsWildcard) {
  3952. throw new MethodProphecyException(sprintf(
  3953. "Can not add prophecy for a method `%s::%s()`\n".
  3954. "as you did not specify arguments wildcard for it.",
  3955. get_class($this->reveal()),
  3956. $methodProphecy->getMethodName()
  3957. ), $methodProphecy);
  3958. }
  3959. $methodName = $methodProphecy->getMethodName();
  3960. if (!isset($this->methodProphecies[$methodName])) {
  3961. $this->methodProphecies[$methodName] = array();
  3962. }
  3963. $this->methodProphecies[$methodName][] = $methodProphecy;
  3964. }
  3965. /**
  3966. * Returns either all or related to single method prophecies.
  3967. *
  3968. * @param null|string $methodName
  3969. *
  3970. * @return MethodProphecy[]
  3971. */
  3972. public function getMethodProphecies($methodName = null)
  3973. {
  3974. if (null === $methodName) {
  3975. return $this->methodProphecies;
  3976. }
  3977. if (!isset($this->methodProphecies[$methodName])) {
  3978. return array();
  3979. }
  3980. return $this->methodProphecies[$methodName];
  3981. }
  3982. /**
  3983. * Makes specific method call.
  3984. *
  3985. * @param string $methodName
  3986. * @param array $arguments
  3987. *
  3988. * @return mixed
  3989. */
  3990. public function makeProphecyMethodCall($methodName, array $arguments)
  3991. {
  3992. $arguments = $this->revealer->reveal($arguments);
  3993. $return = $this->callCenter->makeCall($this, $methodName, $arguments);
  3994. return $this->revealer->reveal($return);
  3995. }
  3996. /**
  3997. * Finds calls by method name & arguments wildcard.
  3998. *
  3999. * @param string $methodName
  4000. * @param ArgumentsWildcard $wildcard
  4001. *
  4002. * @return Call[]
  4003. */
  4004. public function findProphecyMethodCalls($methodName, ArgumentsWildcard $wildcard)
  4005. {
  4006. return $this->callCenter->findCalls($methodName, $wildcard);
  4007. }
  4008. /**
  4009. * Checks that registered method predictions do not fail.
  4010. *
  4011. * @throws \Prophecy\Exception\Prediction\AggregateException If any of registered predictions fail
  4012. */
  4013. public function checkProphecyMethodsPredictions()
  4014. {
  4015. $exception = new AggregateException(sprintf("%s:\n", get_class($this->reveal())));
  4016. $exception->setObjectProphecy($this);
  4017. foreach ($this->methodProphecies as $prophecies) {
  4018. foreach ($prophecies as $prophecy) {
  4019. try {
  4020. $prophecy->checkPrediction();
  4021. } catch (PredictionException $e) {
  4022. $exception->append($e);
  4023. }
  4024. }
  4025. }
  4026. if (count($exception->getExceptions())) {
  4027. throw $exception;
  4028. }
  4029. }
  4030. /**
  4031. * Creates new method prophecy using specified method name and arguments.
  4032. *
  4033. * @param string $methodName
  4034. * @param array $arguments
  4035. *
  4036. * @return MethodProphecy
  4037. */
  4038. public function __call($methodName, array $arguments)
  4039. {
  4040. $arguments = new ArgumentsWildcard($this->revealer->reveal($arguments));
  4041. foreach ($this->getMethodProphecies($methodName) as $prophecy) {
  4042. $argumentsWildcard = $prophecy->getArgumentsWildcard();
  4043. $comparator = $this->comparatorFactory->getComparatorFor(
  4044. $argumentsWildcard, $arguments
  4045. );
  4046. try {
  4047. $comparator->assertEquals($argumentsWildcard, $arguments);
  4048. return $prophecy;
  4049. } catch (ComparisonFailure $failure) {}
  4050. }
  4051. return new MethodProphecy($this, $methodName, $arguments);
  4052. }
  4053. /**
  4054. * Tries to get property value from double.
  4055. *
  4056. * @param string $name
  4057. */
  4058. public function __get($name)
  4059. {
  4060. return $this->reveal()->$name;
  4061. }
  4062. /**
  4063. * Tries to set property value to double.
  4064. *
  4065. * @param string $name
  4066. * @param string $value
  4067. */
  4068. public function __set($name, $value)
  4069. {
  4070. $this->reveal()->$name = $this->revealer->reveal($value);
  4071. }
  4072. }
  4073. <?php
  4074. /*
  4075. * This file is part of the Prophecy.
  4076. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4077. * Marcello Duarte <marcello.duarte@gmail.com>
  4078. *
  4079. * For the full copyright and license information, please view the LICENSE
  4080. * file that was distributed with this source code.
  4081. */
  4082. namespace Prophecy\Prophecy;
  4083. use Prophecy\Argument;
  4084. use Prophecy\Promise;
  4085. use Prophecy\Prediction;
  4086. use Prophecy\Exception\Doubler\MethodNotFoundException;
  4087. use Prophecy\Exception\InvalidArgumentException;
  4088. use Prophecy\Exception\Prophecy\MethodProphecyException;
  4089. /**
  4090. * Method prophecy.
  4091. *
  4092. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  4093. */
  4094. class MethodProphecy
  4095. {
  4096. private $objectProphecy;
  4097. private $methodName;
  4098. private $argumentsWildcard;
  4099. private $promise;
  4100. private $prediction;
  4101. private $checkedPredictions = array();
  4102. private $bound = false;
  4103. /**
  4104. * Initializes method prophecy.
  4105. *
  4106. * @param ObjectProphecy $objectProphecy
  4107. * @param string $methodName
  4108. * @param null|Argument\ArgumentsWildcard|array $arguments
  4109. *
  4110. * @throws \Prophecy\Exception\Doubler\MethodNotFoundException If method not found
  4111. */
  4112. public function __construct(ObjectProphecy $objectProphecy, $methodName, $arguments = null)
  4113. {
  4114. $double = $objectProphecy->reveal();
  4115. if (!method_exists($double, $methodName)) {
  4116. throw new MethodNotFoundException(sprintf(
  4117. 'Method `%s::%s()` is not defined.', get_class($double), $methodName
  4118. ), get_class($double), $methodName, $arguments);
  4119. }
  4120. $this->objectProphecy = $objectProphecy;
  4121. $this->methodName = $methodName;
  4122. $reflectedMethod = new \ReflectionMethod($double, $methodName);
  4123. if ($reflectedMethod->isFinal()) {
  4124. throw new MethodProphecyException(sprintf(
  4125. "Can not add prophecy for a method `%s::%s()`\n".
  4126. "as it is a final method.",
  4127. get_class($double),
  4128. $methodName
  4129. ), $this);
  4130. }
  4131. if (null !== $arguments) {
  4132. $this->withArguments($arguments);
  4133. }
  4134. }
  4135. /**
  4136. * Sets argument wildcard.
  4137. *
  4138. * @param array|Argument\ArgumentsWildcard $arguments
  4139. *
  4140. * @return $this
  4141. *
  4142. * @throws \Prophecy\Exception\InvalidArgumentException
  4143. */
  4144. public function withArguments($arguments)
  4145. {
  4146. if (is_array($arguments)) {
  4147. $arguments = new Argument\ArgumentsWildcard($arguments);
  4148. }
  4149. if (!$arguments instanceof Argument\ArgumentsWildcard) {
  4150. throw new InvalidArgumentException(sprintf(
  4151. "Either an array or an instance of ArgumentsWildcard expected as\n".
  4152. 'a `MethodProphecy::withArguments()` argument, but got %s.',
  4153. gettype($arguments)
  4154. ));
  4155. }
  4156. $this->argumentsWildcard = $arguments;
  4157. return $this;
  4158. }
  4159. /**
  4160. * Sets custom promise to the prophecy.
  4161. *
  4162. * @param callable|Promise\PromiseInterface $promise
  4163. *
  4164. * @return $this
  4165. *
  4166. * @throws \Prophecy\Exception\InvalidArgumentException
  4167. */
  4168. public function will($promise)
  4169. {
  4170. if (is_callable($promise)) {
  4171. $promise = new Promise\CallbackPromise($promise);
  4172. }
  4173. if (!$promise instanceof Promise\PromiseInterface) {
  4174. throw new InvalidArgumentException(sprintf(
  4175. 'Expected callable or instance of PromiseInterface, but got %s.',
  4176. gettype($promise)
  4177. ));
  4178. }
  4179. $this->bindToObjectProphecy();
  4180. $this->promise = $promise;
  4181. return $this;
  4182. }
  4183. /**
  4184. * Sets return promise to the prophecy.
  4185. *
  4186. * @see Prophecy\Promise\ReturnPromise
  4187. *
  4188. * @return $this
  4189. */
  4190. public function willReturn()
  4191. {
  4192. return $this->will(new Promise\ReturnPromise(func_get_args()));
  4193. }
  4194. /**
  4195. * Sets return argument promise to the prophecy.
  4196. *
  4197. * @param int $index The zero-indexed number of the argument to return
  4198. *
  4199. * @see Prophecy\Promise\ReturnArgumentPromise
  4200. *
  4201. * @return $this
  4202. */
  4203. public function willReturnArgument($index = 0)
  4204. {
  4205. return $this->will(new Promise\ReturnArgumentPromise($index));
  4206. }
  4207. /**
  4208. * Sets throw promise to the prophecy.
  4209. *
  4210. * @see Prophecy\Promise\ThrowPromise
  4211. *
  4212. * @param string|\Exception $exception Exception class or instance
  4213. *
  4214. * @return $this
  4215. */
  4216. public function willThrow($exception)
  4217. {
  4218. return $this->will(new Promise\ThrowPromise($exception));
  4219. }
  4220. /**
  4221. * Sets custom prediction to the prophecy.
  4222. *
  4223. * @param callable|Prediction\PredictionInterface $prediction
  4224. *
  4225. * @return $this
  4226. *
  4227. * @throws \Prophecy\Exception\InvalidArgumentException
  4228. */
  4229. public function should($prediction)
  4230. {
  4231. if (is_callable($prediction)) {
  4232. $prediction = new Prediction\CallbackPrediction($prediction);
  4233. }
  4234. if (!$prediction instanceof Prediction\PredictionInterface) {
  4235. throw new InvalidArgumentException(sprintf(
  4236. 'Expected callable or instance of PredictionInterface, but got %s.',
  4237. gettype($prediction)
  4238. ));
  4239. }
  4240. $this->bindToObjectProphecy();
  4241. $this->prediction = $prediction;
  4242. return $this;
  4243. }
  4244. /**
  4245. * Sets call prediction to the prophecy.
  4246. *
  4247. * @see Prophecy\Prediction\CallPrediction
  4248. *
  4249. * @return $this
  4250. */
  4251. public function shouldBeCalled()
  4252. {
  4253. return $this->should(new Prediction\CallPrediction);
  4254. }
  4255. /**
  4256. * Sets no calls prediction to the prophecy.
  4257. *
  4258. * @see Prophecy\Prediction\NoCallsPrediction
  4259. *
  4260. * @return $this
  4261. */
  4262. public function shouldNotBeCalled()
  4263. {
  4264. return $this->should(new Prediction\NoCallsPrediction);
  4265. }
  4266. /**
  4267. * Sets call times prediction to the prophecy.
  4268. *
  4269. * @see Prophecy\Prediction\CallTimesPrediction
  4270. *
  4271. * @param $count
  4272. *
  4273. * @return $this
  4274. */
  4275. public function shouldBeCalledTimes($count)
  4276. {
  4277. return $this->should(new Prediction\CallTimesPrediction($count));
  4278. }
  4279. /**
  4280. * Checks provided prediction immediately.
  4281. *
  4282. * @param callable|Prediction\PredictionInterface $prediction
  4283. *
  4284. * @return $this
  4285. *
  4286. * @throws \Prophecy\Exception\InvalidArgumentException
  4287. */
  4288. public function shouldHave($prediction)
  4289. {
  4290. if (is_callable($prediction)) {
  4291. $prediction = new Prediction\CallbackPrediction($prediction);
  4292. }
  4293. if (!$prediction instanceof Prediction\PredictionInterface) {
  4294. throw new InvalidArgumentException(sprintf(
  4295. 'Expected callable or instance of PredictionInterface, but got %s.',
  4296. gettype($prediction)
  4297. ));
  4298. }
  4299. if (null === $this->promise) {
  4300. $this->willReturn();
  4301. }
  4302. $calls = $this->getObjectProphecy()->findProphecyMethodCalls(
  4303. $this->getMethodName(),
  4304. $this->getArgumentsWildcard()
  4305. );
  4306. try {
  4307. $prediction->check($calls, $this->getObjectProphecy(), $this);
  4308. $this->checkedPredictions[] = $prediction;
  4309. } catch (\Exception $e) {
  4310. $this->checkedPredictions[] = $prediction;
  4311. throw $e;
  4312. }
  4313. return $this;
  4314. }
  4315. /**
  4316. * Checks call prediction.
  4317. *
  4318. * @see Prophecy\Prediction\CallPrediction
  4319. *
  4320. * @return $this
  4321. */
  4322. public function shouldHaveBeenCalled()
  4323. {
  4324. return $this->shouldHave(new Prediction\CallPrediction);
  4325. }
  4326. /**
  4327. * Checks no calls prediction.
  4328. *
  4329. * @see Prophecy\Prediction\NoCallsPrediction
  4330. *
  4331. * @return $this
  4332. */
  4333. public function shouldNotHaveBeenCalled()
  4334. {
  4335. return $this->shouldHave(new Prediction\NoCallsPrediction);
  4336. }
  4337. /**
  4338. * Checks no calls prediction.
  4339. *
  4340. * @see Prophecy\Prediction\NoCallsPrediction
  4341. * @deprecated
  4342. *
  4343. * @return $this
  4344. */
  4345. public function shouldNotBeenCalled()
  4346. {
  4347. return $this->shouldNotHaveBeenCalled();
  4348. }
  4349. /**
  4350. * Checks call times prediction.
  4351. *
  4352. * @see Prophecy\Prediction\CallTimesPrediction
  4353. *
  4354. * @param int $count
  4355. *
  4356. * @return $this
  4357. */
  4358. public function shouldHaveBeenCalledTimes($count)
  4359. {
  4360. return $this->shouldHave(new Prediction\CallTimesPrediction($count));
  4361. }
  4362. /**
  4363. * Checks currently registered [with should(...)] prediction.
  4364. */
  4365. public function checkPrediction()
  4366. {
  4367. if (null === $this->prediction) {
  4368. return;
  4369. }
  4370. $this->shouldHave($this->prediction);
  4371. }
  4372. /**
  4373. * Returns currently registered promise.
  4374. *
  4375. * @return null|Promise\PromiseInterface
  4376. */
  4377. public function getPromise()
  4378. {
  4379. return $this->promise;
  4380. }
  4381. /**
  4382. * Returns currently registered prediction.
  4383. *
  4384. * @return null|Prediction\PredictionInterface
  4385. */
  4386. public function getPrediction()
  4387. {
  4388. return $this->prediction;
  4389. }
  4390. /**
  4391. * Returns predictions that were checked on this object.
  4392. *
  4393. * @return Prediction\PredictionInterface[]
  4394. */
  4395. public function getCheckedPredictions()
  4396. {
  4397. return $this->checkedPredictions;
  4398. }
  4399. /**
  4400. * Returns object prophecy this method prophecy is tied to.
  4401. *
  4402. * @return ObjectProphecy
  4403. */
  4404. public function getObjectProphecy()
  4405. {
  4406. return $this->objectProphecy;
  4407. }
  4408. /**
  4409. * Returns method name.
  4410. *
  4411. * @return string
  4412. */
  4413. public function getMethodName()
  4414. {
  4415. return $this->methodName;
  4416. }
  4417. /**
  4418. * Returns arguments wildcard.
  4419. *
  4420. * @return Argument\ArgumentsWildcard
  4421. */
  4422. public function getArgumentsWildcard()
  4423. {
  4424. return $this->argumentsWildcard;
  4425. }
  4426. private function bindToObjectProphecy()
  4427. {
  4428. if ($this->bound) {
  4429. return;
  4430. }
  4431. $this->getObjectProphecy()->addMethodProphecy($this);
  4432. $this->bound = true;
  4433. }
  4434. }
  4435. <?php
  4436. /*
  4437. * This file is part of the Prophecy.
  4438. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4439. * Marcello Duarte <marcello.duarte@gmail.com>
  4440. *
  4441. * For the full copyright and license information, please view the LICENSE
  4442. * file that was distributed with this source code.
  4443. */
  4444. namespace Prophecy\Comparator;
  4445. use SebastianBergmann\Comparator\Comparator;
  4446. use SebastianBergmann\Comparator\ComparisonFailure;
  4447. /**
  4448. * Closure comparator.
  4449. *
  4450. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  4451. */
  4452. final class ClosureComparator extends Comparator
  4453. {
  4454. public function accepts($expected, $actual)
  4455. {
  4456. return is_object($expected) && $expected instanceof \Closure
  4457. && is_object($actual) && $actual instanceof \Closure;
  4458. }
  4459. public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
  4460. {
  4461. throw new ComparisonFailure(
  4462. $expected,
  4463. $actual,
  4464. // we don't need a diff
  4465. '',
  4466. '',
  4467. false,
  4468. 'all closures are born different'
  4469. );
  4470. }
  4471. }
  4472. <?php
  4473. /*
  4474. * This file is part of the Prophecy.
  4475. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4476. * Marcello Duarte <marcello.duarte@gmail.com>
  4477. *
  4478. * For the full copyright and license information, please view the LICENSE
  4479. * file that was distributed with this source code.
  4480. */
  4481. namespace Prophecy\Comparator;
  4482. use SebastianBergmann\Comparator\Factory as BaseFactory;
  4483. /**
  4484. * Prophecy comparator factory.
  4485. *
  4486. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  4487. */
  4488. final class Factory extends BaseFactory
  4489. {
  4490. /**
  4491. * @var Factory
  4492. */
  4493. private static $instance;
  4494. public function __construct()
  4495. {
  4496. parent::__construct();
  4497. $this->register(new ClosureComparator());
  4498. }
  4499. /**
  4500. * @return Factory
  4501. */
  4502. public static function getInstance()
  4503. {
  4504. if (self::$instance === null) {
  4505. self::$instance = new Factory;
  4506. }
  4507. return self::$instance;
  4508. }
  4509. }
  4510. <?php
  4511. /*
  4512. * This file is part of the Prophecy.
  4513. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4514. * Marcello Duarte <marcello.duarte@gmail.com>
  4515. *
  4516. * For the full copyright and license information, please view the LICENSE
  4517. * file that was distributed with this source code.
  4518. */
  4519. namespace Prophecy;
  4520. use Prophecy\Argument\Token;
  4521. /**
  4522. * Argument tokens shortcuts.
  4523. *
  4524. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  4525. */
  4526. class Argument
  4527. {
  4528. /**
  4529. * Checks that argument is exact value or object.
  4530. *
  4531. * @param mixed $value
  4532. *
  4533. * @return Token\ExactValueToken
  4534. */
  4535. public static function exact($value)
  4536. {
  4537. return new Token\ExactValueToken($value);
  4538. }
  4539. /**
  4540. * Checks that argument is of specific type or instance of specific class.
  4541. *
  4542. * @param string $type Type name (`integer`, `string`) or full class name
  4543. *
  4544. * @return Token\TypeToken
  4545. */
  4546. public static function type($type)
  4547. {
  4548. return new Token\TypeToken($type);
  4549. }
  4550. /**
  4551. * Checks that argument object has specific state.
  4552. *
  4553. * @param string $methodName
  4554. * @param mixed $value
  4555. *
  4556. * @return Token\ObjectStateToken
  4557. */
  4558. public static function which($methodName, $value)
  4559. {
  4560. return new Token\ObjectStateToken($methodName, $value);
  4561. }
  4562. /**
  4563. * Checks that argument matches provided callback.
  4564. *
  4565. * @param callable $callback
  4566. *
  4567. * @return Token\CallbackToken
  4568. */
  4569. public static function that($callback)
  4570. {
  4571. return new Token\CallbackToken($callback);
  4572. }
  4573. /**
  4574. * Matches any single value.
  4575. *
  4576. * @return Token\AnyValueToken
  4577. */
  4578. public static function any()
  4579. {
  4580. return new Token\AnyValueToken;
  4581. }
  4582. /**
  4583. * Matches all values to the rest of the signature.
  4584. *
  4585. * @return Token\AnyValuesToken
  4586. */
  4587. public static function cetera()
  4588. {
  4589. return new Token\AnyValuesToken;
  4590. }
  4591. /**
  4592. * Checks that argument matches all tokens
  4593. *
  4594. * @param mixed ... a list of tokens
  4595. *
  4596. * @return Token\LogicalAndToken
  4597. */
  4598. public static function allOf()
  4599. {
  4600. return new Token\LogicalAndToken(func_get_args());
  4601. }
  4602. /**
  4603. * Checks that argument array or countable object has exact number of elements.
  4604. *
  4605. * @param integer $value array elements count
  4606. *
  4607. * @return Token\ArrayCountToken
  4608. */
  4609. public static function size($value)
  4610. {
  4611. return new Token\ArrayCountToken($value);
  4612. }
  4613. /**
  4614. * Checks that argument array contains (key, value) pair
  4615. *
  4616. * @param mixed $key exact value or token
  4617. * @param mixed $value exact value or token
  4618. *
  4619. * @return Token\ArrayEntryToken
  4620. */
  4621. public static function withEntry($key, $value)
  4622. {
  4623. return new Token\ArrayEntryToken($key, $value);
  4624. }
  4625. /**
  4626. * Checks that arguments array entries all match value
  4627. *
  4628. * @param mixed $value
  4629. *
  4630. * @return Token\ArrayEveryEntryToken
  4631. */
  4632. public static function withEveryEntry($value)
  4633. {
  4634. return new Token\ArrayEveryEntryToken($value);
  4635. }
  4636. /**
  4637. * Checks that argument array contains value
  4638. *
  4639. * @param mixed $value
  4640. *
  4641. * @return Token\ArrayEntryToken
  4642. */
  4643. public static function containing($value)
  4644. {
  4645. return new Token\ArrayEntryToken(self::any(), $value);
  4646. }
  4647. /**
  4648. * Checks that argument array has key
  4649. *
  4650. * @param mixed $key exact value or token
  4651. *
  4652. * @return Token\ArrayEntryToken
  4653. */
  4654. public static function withKey($key)
  4655. {
  4656. return new Token\ArrayEntryToken($key, self::any());
  4657. }
  4658. /**
  4659. * Checks that argument does not match the value|token.
  4660. *
  4661. * @param mixed $value either exact value or argument token
  4662. *
  4663. * @return Token\LogicalNotToken
  4664. */
  4665. public static function not($value)
  4666. {
  4667. return new Token\LogicalNotToken($value);
  4668. }
  4669. /**
  4670. * @param string $value
  4671. *
  4672. * @return Token\StringContainsToken
  4673. */
  4674. public static function containingString($value)
  4675. {
  4676. return new Token\StringContainsToken($value);
  4677. }
  4678. /**
  4679. * Checks that argument is identical value.
  4680. *
  4681. * @param mixed $value
  4682. *
  4683. * @return Token\IdenticalValueToken
  4684. */
  4685. public static function is($value)
  4686. {
  4687. return new Token\IdenticalValueToken($value);
  4688. }
  4689. }
  4690. <?php
  4691. /*
  4692. * This file is part of the Prophecy.
  4693. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4694. * Marcello Duarte <marcello.duarte@gmail.com>
  4695. *
  4696. * For the full copyright and license information, please view the LICENSE
  4697. * file that was distributed with this source code.
  4698. */
  4699. namespace Prophecy;
  4700. use Prophecy\Doubler\Doubler;
  4701. use Prophecy\Doubler\LazyDouble;
  4702. use Prophecy\Doubler\ClassPatch;
  4703. use Prophecy\Prophecy\ObjectProphecy;
  4704. use Prophecy\Prophecy\RevealerInterface;
  4705. use Prophecy\Prophecy\Revealer;
  4706. use Prophecy\Call\CallCenter;
  4707. use Prophecy\Util\StringUtil;
  4708. use Prophecy\Exception\Prediction\PredictionException;
  4709. use Prophecy\Exception\Prediction\AggregateException;
  4710. /**
  4711. * Prophet creates prophecies.
  4712. *
  4713. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  4714. */
  4715. class Prophet
  4716. {
  4717. private $doubler;
  4718. private $revealer;
  4719. private $util;
  4720. /**
  4721. * @var ObjectProphecy[]
  4722. */
  4723. private $prophecies = array();
  4724. /**
  4725. * Initializes Prophet.
  4726. *
  4727. * @param null|Doubler $doubler
  4728. * @param null|RevealerInterface $revealer
  4729. * @param null|StringUtil $util
  4730. */
  4731. public function __construct(Doubler $doubler = null, RevealerInterface $revealer = null,
  4732. StringUtil $util = null)
  4733. {
  4734. if (null === $doubler) {
  4735. $doubler = new Doubler;
  4736. $doubler->registerClassPatch(new ClassPatch\SplFileInfoPatch);
  4737. $doubler->registerClassPatch(new ClassPatch\TraversablePatch);
  4738. $doubler->registerClassPatch(new ClassPatch\DisableConstructorPatch);
  4739. $doubler->registerClassPatch(new ClassPatch\ProphecySubjectPatch);
  4740. $doubler->registerClassPatch(new ClassPatch\ReflectionClassNewInstancePatch);
  4741. $doubler->registerClassPatch(new ClassPatch\HhvmExceptionPatch());
  4742. $doubler->registerClassPatch(new ClassPatch\MagicCallPatch);
  4743. $doubler->registerClassPatch(new ClassPatch\KeywordPatch);
  4744. }
  4745. $this->doubler = $doubler;
  4746. $this->revealer = $revealer ?: new Revealer;
  4747. $this->util = $util ?: new StringUtil;
  4748. }
  4749. /**
  4750. * Creates new object prophecy.
  4751. *
  4752. * @param null|string $classOrInterface Class or interface name
  4753. *
  4754. * @return ObjectProphecy
  4755. */
  4756. public function prophesize($classOrInterface = null)
  4757. {
  4758. $this->prophecies[] = $prophecy = new ObjectProphecy(
  4759. new LazyDouble($this->doubler),
  4760. new CallCenter($this->util),
  4761. $this->revealer
  4762. );
  4763. if ($classOrInterface && class_exists($classOrInterface)) {
  4764. return $prophecy->willExtend($classOrInterface);
  4765. }
  4766. if ($classOrInterface && interface_exists($classOrInterface)) {
  4767. return $prophecy->willImplement($classOrInterface);
  4768. }
  4769. return $prophecy;
  4770. }
  4771. /**
  4772. * Returns all created object prophecies.
  4773. *
  4774. * @return ObjectProphecy[]
  4775. */
  4776. public function getProphecies()
  4777. {
  4778. return $this->prophecies;
  4779. }
  4780. /**
  4781. * Returns Doubler instance assigned to this Prophet.
  4782. *
  4783. * @return Doubler
  4784. */
  4785. public function getDoubler()
  4786. {
  4787. return $this->doubler;
  4788. }
  4789. /**
  4790. * Checks all predictions defined by prophecies of this Prophet.
  4791. *
  4792. * @throws Exception\Prediction\AggregateException If any prediction fails
  4793. */
  4794. public function checkPredictions()
  4795. {
  4796. $exception = new AggregateException("Some predictions failed:\n");
  4797. foreach ($this->prophecies as $prophecy) {
  4798. try {
  4799. $prophecy->checkProphecyMethodsPredictions();
  4800. } catch (PredictionException $e) {
  4801. $exception->append($e);
  4802. }
  4803. }
  4804. if (count($exception->getExceptions())) {
  4805. throw $exception;
  4806. }
  4807. }
  4808. }
  4809. <?php
  4810. /*
  4811. * This file is part of the Prophecy.
  4812. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4813. * Marcello Duarte <marcello.duarte@gmail.com>
  4814. *
  4815. * For the full copyright and license information, please view the LICENSE
  4816. * file that was distributed with this source code.
  4817. */
  4818. namespace Prophecy\Exception;
  4819. /**
  4820. * Core Prophecy exception interface.
  4821. * All Prophecy exceptions implement it.
  4822. *
  4823. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  4824. */
  4825. interface Exception
  4826. {
  4827. /**
  4828. * @return string
  4829. */
  4830. public function getMessage();
  4831. }
  4832. <?php
  4833. /*
  4834. * This file is part of the Prophecy.
  4835. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4836. * Marcello Duarte <marcello.duarte@gmail.com>
  4837. *
  4838. * For the full copyright and license information, please view the LICENSE
  4839. * file that was distributed with this source code.
  4840. */
  4841. namespace Prophecy\Exception\Prophecy;
  4842. use Prophecy\Prophecy\ObjectProphecy;
  4843. class ObjectProphecyException extends \RuntimeException implements ProphecyException
  4844. {
  4845. private $objectProphecy;
  4846. public function __construct($message, ObjectProphecy $objectProphecy)
  4847. {
  4848. parent::__construct($message);
  4849. $this->objectProphecy = $objectProphecy;
  4850. }
  4851. /**
  4852. * @return ObjectProphecy
  4853. */
  4854. public function getObjectProphecy()
  4855. {
  4856. return $this->objectProphecy;
  4857. }
  4858. }
  4859. <?php
  4860. /*
  4861. * This file is part of the Prophecy.
  4862. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4863. * Marcello Duarte <marcello.duarte@gmail.com>
  4864. *
  4865. * For the full copyright and license information, please view the LICENSE
  4866. * file that was distributed with this source code.
  4867. */
  4868. namespace Prophecy\Exception\Prophecy;
  4869. use Prophecy\Exception\Exception;
  4870. interface ProphecyException extends Exception
  4871. {
  4872. }
  4873. <?php
  4874. /*
  4875. * This file is part of the Prophecy.
  4876. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4877. * Marcello Duarte <marcello.duarte@gmail.com>
  4878. *
  4879. * For the full copyright and license information, please view the LICENSE
  4880. * file that was distributed with this source code.
  4881. */
  4882. namespace Prophecy\Exception\Prophecy;
  4883. use Prophecy\Prophecy\MethodProphecy;
  4884. class MethodProphecyException extends ObjectProphecyException
  4885. {
  4886. private $methodProphecy;
  4887. public function __construct($message, MethodProphecy $methodProphecy)
  4888. {
  4889. parent::__construct($message, $methodProphecy->getObjectProphecy());
  4890. $this->methodProphecy = $methodProphecy;
  4891. }
  4892. /**
  4893. * @return MethodProphecy
  4894. */
  4895. public function getMethodProphecy()
  4896. {
  4897. return $this->methodProphecy;
  4898. }
  4899. }
  4900. <?php
  4901. /*
  4902. * This file is part of the Prophecy.
  4903. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4904. * Marcello Duarte <marcello.duarte@gmail.com>
  4905. *
  4906. * For the full copyright and license information, please view the LICENSE
  4907. * file that was distributed with this source code.
  4908. */
  4909. namespace Prophecy\Exception\Doubler;
  4910. class InterfaceNotFoundException extends ClassNotFoundException
  4911. {
  4912. public function getInterfaceName()
  4913. {
  4914. return $this->getClassname();
  4915. }
  4916. }
  4917. <?php
  4918. /*
  4919. * This file is part of the Prophecy.
  4920. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4921. * Marcello Duarte <marcello.duarte@gmail.com>
  4922. *
  4923. * For the full copyright and license information, please view the LICENSE
  4924. * file that was distributed with this source code.
  4925. */
  4926. namespace Prophecy\Exception\Doubler;
  4927. use ReflectionClass;
  4928. class ClassMirrorException extends \RuntimeException implements DoublerException
  4929. {
  4930. private $class;
  4931. public function __construct($message, ReflectionClass $class)
  4932. {
  4933. parent::__construct($message);
  4934. $this->class = $class;
  4935. }
  4936. public function getReflectedClass()
  4937. {
  4938. return $this->class;
  4939. }
  4940. }
  4941. <?php
  4942. /*
  4943. * This file is part of the Prophecy.
  4944. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4945. * Marcello Duarte <marcello.duarte@gmail.com>
  4946. *
  4947. * For the full copyright and license information, please view the LICENSE
  4948. * file that was distributed with this source code.
  4949. */
  4950. namespace Prophecy\Exception\Doubler;
  4951. use RuntimeException;
  4952. class DoubleException extends RuntimeException implements DoublerException
  4953. {
  4954. }
  4955. <?php
  4956. /*
  4957. * This file is part of the Prophecy.
  4958. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4959. * Marcello Duarte <marcello.duarte@gmail.com>
  4960. *
  4961. * For the full copyright and license information, please view the LICENSE
  4962. * file that was distributed with this source code.
  4963. */
  4964. namespace Prophecy\Exception\Doubler;
  4965. use Prophecy\Exception\Exception;
  4966. interface DoublerException extends Exception
  4967. {
  4968. }
  4969. <?php
  4970. /*
  4971. * This file is part of the Prophecy.
  4972. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  4973. * Marcello Duarte <marcello.duarte@gmail.com>
  4974. *
  4975. * For the full copyright and license information, please view the LICENSE
  4976. * file that was distributed with this source code.
  4977. */
  4978. namespace Prophecy\Exception\Doubler;
  4979. class MethodNotFoundException extends DoubleException
  4980. {
  4981. /**
  4982. * @var string
  4983. */
  4984. private $classname;
  4985. /**
  4986. * @var string
  4987. */
  4988. private $methodName;
  4989. /**
  4990. * @var array
  4991. */
  4992. private $arguments;
  4993. /**
  4994. * @param string $message
  4995. * @param string $classname
  4996. * @param string $methodName
  4997. * @param null|Argument\ArgumentsWildcard|array $arguments
  4998. */
  4999. public function __construct($message, $classname, $methodName, $arguments = null)
  5000. {
  5001. parent::__construct($message);
  5002. $this->classname = $classname;
  5003. $this->methodName = $methodName;
  5004. $this->arguments = $arguments;
  5005. }
  5006. public function getClassname()
  5007. {
  5008. return $this->classname;
  5009. }
  5010. public function getMethodName()
  5011. {
  5012. return $this->methodName;
  5013. }
  5014. public function getArguments()
  5015. {
  5016. return $this->arguments;
  5017. }
  5018. }
  5019. <?php
  5020. /*
  5021. * This file is part of the Prophecy.
  5022. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5023. * Marcello Duarte <marcello.duarte@gmail.com>
  5024. *
  5025. * For the full copyright and license information, please view the LICENSE
  5026. * file that was distributed with this source code.
  5027. */
  5028. namespace Prophecy\Exception\Doubler;
  5029. class ReturnByReferenceException extends DoubleException
  5030. {
  5031. private $classname;
  5032. private $methodName;
  5033. /**
  5034. * @param string $message
  5035. * @param string $classname
  5036. * @param string $methodName
  5037. */
  5038. public function __construct($message, $classname, $methodName)
  5039. {
  5040. parent::__construct($message);
  5041. $this->classname = $classname;
  5042. $this->methodName = $methodName;
  5043. }
  5044. public function getClassname()
  5045. {
  5046. return $this->classname;
  5047. }
  5048. public function getMethodName()
  5049. {
  5050. return $this->methodName;
  5051. }
  5052. }
  5053. <?php
  5054. /*
  5055. * This file is part of the Prophecy.
  5056. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5057. * Marcello Duarte <marcello.duarte@gmail.com>
  5058. *
  5059. * For the full copyright and license information, please view the LICENSE
  5060. * file that was distributed with this source code.
  5061. */
  5062. namespace Prophecy\Exception\Doubler;
  5063. use Prophecy\Doubler\Generator\Node\ClassNode;
  5064. class ClassCreatorException extends \RuntimeException implements DoublerException
  5065. {
  5066. private $node;
  5067. public function __construct($message, ClassNode $node)
  5068. {
  5069. parent::__construct($message);
  5070. $this->node = $node;
  5071. }
  5072. public function getClassNode()
  5073. {
  5074. return $this->node;
  5075. }
  5076. }
  5077. <?php
  5078. /*
  5079. * This file is part of the Prophecy.
  5080. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5081. * Marcello Duarte <marcello.duarte@gmail.com>
  5082. *
  5083. * For the full copyright and license information, please view the LICENSE
  5084. * file that was distributed with this source code.
  5085. */
  5086. namespace Prophecy\Exception\Doubler;
  5087. class ClassNotFoundException extends DoubleException
  5088. {
  5089. private $classname;
  5090. /**
  5091. * @param string $message
  5092. * @param string $classname
  5093. */
  5094. public function __construct($message, $classname)
  5095. {
  5096. parent::__construct($message);
  5097. $this->classname = $classname;
  5098. }
  5099. public function getClassname()
  5100. {
  5101. return $this->classname;
  5102. }
  5103. }
  5104. <?php
  5105. /*
  5106. * This file is part of the Prophecy.
  5107. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5108. * Marcello Duarte <marcello.duarte@gmail.com>
  5109. *
  5110. * For the full copyright and license information, please view the LICENSE
  5111. * file that was distributed with this source code.
  5112. */
  5113. namespace Prophecy\Exception\Prediction;
  5114. use Prophecy\Prophecy\MethodProphecy;
  5115. use Prophecy\Exception\Prophecy\MethodProphecyException;
  5116. class UnexpectedCallsException extends MethodProphecyException implements PredictionException
  5117. {
  5118. private $calls = array();
  5119. public function __construct($message, MethodProphecy $methodProphecy, array $calls)
  5120. {
  5121. parent::__construct($message, $methodProphecy);
  5122. $this->calls = $calls;
  5123. }
  5124. public function getCalls()
  5125. {
  5126. return $this->calls;
  5127. }
  5128. }
  5129. <?php
  5130. /*
  5131. * This file is part of the Prophecy.
  5132. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5133. * Marcello Duarte <marcello.duarte@gmail.com>
  5134. *
  5135. * For the full copyright and license information, please view the LICENSE
  5136. * file that was distributed with this source code.
  5137. */
  5138. namespace Prophecy\Exception\Prediction;
  5139. use Prophecy\Exception\Exception;
  5140. interface PredictionException extends Exception
  5141. {
  5142. }
  5143. <?php
  5144. /*
  5145. * This file is part of the Prophecy.
  5146. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5147. * Marcello Duarte <marcello.duarte@gmail.com>
  5148. *
  5149. * For the full copyright and license information, please view the LICENSE
  5150. * file that was distributed with this source code.
  5151. */
  5152. namespace Prophecy\Exception\Prediction;
  5153. use RuntimeException;
  5154. /**
  5155. * Basic failed prediction exception.
  5156. * Use it for custom prediction failures.
  5157. *
  5158. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5159. */
  5160. class FailedPredictionException extends RuntimeException implements PredictionException
  5161. {
  5162. }
  5163. <?php
  5164. /*
  5165. * This file is part of the Prophecy.
  5166. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5167. * Marcello Duarte <marcello.duarte@gmail.com>
  5168. *
  5169. * For the full copyright and license information, please view the LICENSE
  5170. * file that was distributed with this source code.
  5171. */
  5172. namespace Prophecy\Exception\Prediction;
  5173. use Prophecy\Exception\Prophecy\MethodProphecyException;
  5174. class NoCallsException extends MethodProphecyException implements PredictionException
  5175. {
  5176. }
  5177. <?php
  5178. /*
  5179. * This file is part of the Prophecy.
  5180. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5181. * Marcello Duarte <marcello.duarte@gmail.com>
  5182. *
  5183. * For the full copyright and license information, please view the LICENSE
  5184. * file that was distributed with this source code.
  5185. */
  5186. namespace Prophecy\Exception\Prediction;
  5187. use Prophecy\Prophecy\ObjectProphecy;
  5188. class AggregateException extends \RuntimeException implements PredictionException
  5189. {
  5190. private $exceptions = array();
  5191. private $objectProphecy;
  5192. public function append(PredictionException $exception)
  5193. {
  5194. $message = $exception->getMessage();
  5195. $message = ' '.strtr($message, array("\n" => "\n "))."\n";
  5196. $this->message = rtrim($this->message.$message);
  5197. $this->exceptions[] = $exception;
  5198. }
  5199. /**
  5200. * @return PredictionException[]
  5201. */
  5202. public function getExceptions()
  5203. {
  5204. return $this->exceptions;
  5205. }
  5206. public function setObjectProphecy(ObjectProphecy $objectProphecy)
  5207. {
  5208. $this->objectProphecy = $objectProphecy;
  5209. }
  5210. /**
  5211. * @return ObjectProphecy
  5212. */
  5213. public function getObjectProphecy()
  5214. {
  5215. return $this->objectProphecy;
  5216. }
  5217. }
  5218. <?php
  5219. /*
  5220. * This file is part of the Prophecy.
  5221. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5222. * Marcello Duarte <marcello.duarte@gmail.com>
  5223. *
  5224. * For the full copyright and license information, please view the LICENSE
  5225. * file that was distributed with this source code.
  5226. */
  5227. namespace Prophecy\Exception\Prediction;
  5228. use Prophecy\Prophecy\MethodProphecy;
  5229. class UnexpectedCallsCountException extends UnexpectedCallsException
  5230. {
  5231. private $expectedCount;
  5232. public function __construct($message, MethodProphecy $methodProphecy, $count, array $calls)
  5233. {
  5234. parent::__construct($message, $methodProphecy, $calls);
  5235. $this->expectedCount = intval($count);
  5236. }
  5237. public function getExpectedCount()
  5238. {
  5239. return $this->expectedCount;
  5240. }
  5241. }
  5242. <?php
  5243. /*
  5244. * This file is part of the Prophecy.
  5245. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5246. * Marcello Duarte <marcello.duarte@gmail.com>
  5247. *
  5248. * For the full copyright and license information, please view the LICENSE
  5249. * file that was distributed with this source code.
  5250. */
  5251. namespace Prophecy\Exception\Call;
  5252. use Prophecy\Exception\Prophecy\ObjectProphecyException;
  5253. use Prophecy\Prophecy\ObjectProphecy;
  5254. class UnexpectedCallException extends ObjectProphecyException
  5255. {
  5256. private $methodName;
  5257. private $arguments;
  5258. public function __construct($message, ObjectProphecy $objectProphecy,
  5259. $methodName, array $arguments)
  5260. {
  5261. parent::__construct($message, $objectProphecy);
  5262. $this->methodName = $methodName;
  5263. $this->arguments = $arguments;
  5264. }
  5265. public function getMethodName()
  5266. {
  5267. return $this->methodName;
  5268. }
  5269. public function getArguments()
  5270. {
  5271. return $this->arguments;
  5272. }
  5273. }
  5274. <?php
  5275. /*
  5276. * This file is part of the Prophecy.
  5277. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5278. * Marcello Duarte <marcello.duarte@gmail.com>
  5279. *
  5280. * For the full copyright and license information, please view the LICENSE
  5281. * file that was distributed with this source code.
  5282. */
  5283. namespace Prophecy\Exception;
  5284. class InvalidArgumentException extends \InvalidArgumentException implements Exception
  5285. {
  5286. }
  5287. <?php
  5288. /*
  5289. * This file is part of the Prophecy.
  5290. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5291. * Marcello Duarte <marcello.duarte@gmail.com>
  5292. *
  5293. * For the full copyright and license information, please view the LICENSE
  5294. * file that was distributed with this source code.
  5295. */
  5296. namespace Prophecy\Doubler;
  5297. use ReflectionClass;
  5298. /**
  5299. * Cached class doubler.
  5300. * Prevents mirroring/creation of the same structure twice.
  5301. *
  5302. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5303. */
  5304. class CachedDoubler extends Doubler
  5305. {
  5306. private $classes = array();
  5307. /**
  5308. * {@inheritdoc}
  5309. */
  5310. public function registerClassPatch(ClassPatch\ClassPatchInterface $patch)
  5311. {
  5312. $this->classes[] = array();
  5313. parent::registerClassPatch($patch);
  5314. }
  5315. /**
  5316. * {@inheritdoc}
  5317. */
  5318. protected function createDoubleClass(ReflectionClass $class = null, array $interfaces)
  5319. {
  5320. $classId = $this->generateClassId($class, $interfaces);
  5321. if (isset($this->classes[$classId])) {
  5322. return $this->classes[$classId];
  5323. }
  5324. return $this->classes[$classId] = parent::createDoubleClass($class, $interfaces);
  5325. }
  5326. /**
  5327. * @param ReflectionClass $class
  5328. * @param ReflectionClass[] $interfaces
  5329. *
  5330. * @return string
  5331. */
  5332. private function generateClassId(ReflectionClass $class = null, array $interfaces)
  5333. {
  5334. $parts = array();
  5335. if (null !== $class) {
  5336. $parts[] = $class->getName();
  5337. }
  5338. foreach ($interfaces as $interface) {
  5339. $parts[] = $interface->getName();
  5340. }
  5341. sort($parts);
  5342. return md5(implode('', $parts));
  5343. }
  5344. }
  5345. <?php
  5346. /*
  5347. * This file is part of the Prophecy.
  5348. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5349. * Marcello Duarte <marcello.duarte@gmail.com>
  5350. *
  5351. * For the full copyright and license information, please view the LICENSE
  5352. * file that was distributed with this source code.
  5353. */
  5354. namespace Prophecy\Doubler;
  5355. /**
  5356. * Core double interface.
  5357. * All doubled classes will implement this one.
  5358. *
  5359. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5360. */
  5361. interface DoubleInterface
  5362. {
  5363. }
  5364. <?php
  5365. /*
  5366. * This file is part of the Prophecy.
  5367. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5368. * Marcello Duarte <marcello.duarte@gmail.com>
  5369. *
  5370. * For the full copyright and license information, please view the LICENSE
  5371. * file that was distributed with this source code.
  5372. */
  5373. namespace Prophecy\Doubler;
  5374. use Doctrine\Instantiator\Instantiator;
  5375. use Prophecy\Doubler\ClassPatch\ClassPatchInterface;
  5376. use Prophecy\Doubler\Generator\ClassMirror;
  5377. use Prophecy\Doubler\Generator\ClassCreator;
  5378. use Prophecy\Exception\InvalidArgumentException;
  5379. use ReflectionClass;
  5380. /**
  5381. * Cached class doubler.
  5382. * Prevents mirroring/creation of the same structure twice.
  5383. *
  5384. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5385. */
  5386. class Doubler
  5387. {
  5388. private $mirror;
  5389. private $creator;
  5390. private $namer;
  5391. /**
  5392. * @var ClassPatchInterface[]
  5393. */
  5394. private $patches = array();
  5395. /**
  5396. * @var \Doctrine\Instantiator\Instantiator
  5397. */
  5398. private $instantiator;
  5399. /**
  5400. * Initializes doubler.
  5401. *
  5402. * @param ClassMirror $mirror
  5403. * @param ClassCreator $creator
  5404. * @param NameGenerator $namer
  5405. */
  5406. public function __construct(ClassMirror $mirror = null, ClassCreator $creator = null,
  5407. NameGenerator $namer = null)
  5408. {
  5409. $this->mirror = $mirror ?: new ClassMirror;
  5410. $this->creator = $creator ?: new ClassCreator;
  5411. $this->namer = $namer ?: new NameGenerator;
  5412. }
  5413. /**
  5414. * Returns list of registered class patches.
  5415. *
  5416. * @return ClassPatchInterface[]
  5417. */
  5418. public function getClassPatches()
  5419. {
  5420. return $this->patches;
  5421. }
  5422. /**
  5423. * Registers new class patch.
  5424. *
  5425. * @param ClassPatchInterface $patch
  5426. */
  5427. public function registerClassPatch(ClassPatchInterface $patch)
  5428. {
  5429. $this->patches[] = $patch;
  5430. @usort($this->patches, function (ClassPatchInterface $patch1, ClassPatchInterface $patch2) {
  5431. return $patch2->getPriority() - $patch1->getPriority();
  5432. });
  5433. }
  5434. /**
  5435. * Creates double from specific class or/and list of interfaces.
  5436. *
  5437. * @param ReflectionClass $class
  5438. * @param ReflectionClass[] $interfaces Array of ReflectionClass instances
  5439. * @param array $args Constructor arguments
  5440. *
  5441. * @return DoubleInterface
  5442. *
  5443. * @throws \Prophecy\Exception\InvalidArgumentException
  5444. */
  5445. public function double(ReflectionClass $class = null, array $interfaces, array $args = null)
  5446. {
  5447. foreach ($interfaces as $interface) {
  5448. if (!$interface instanceof ReflectionClass) {
  5449. throw new InvalidArgumentException(sprintf(
  5450. "[ReflectionClass \$interface1 [, ReflectionClass \$interface2]] array expected as\n".
  5451. "a second argument to `Doubler::double(...)`, but got %s.",
  5452. is_object($interface) ? get_class($interface).' class' : gettype($interface)
  5453. ));
  5454. }
  5455. }
  5456. $classname = $this->createDoubleClass($class, $interfaces);
  5457. $reflection = new ReflectionClass($classname);
  5458. if (null !== $args) {
  5459. return $reflection->newInstanceArgs($args);
  5460. }
  5461. if ((null === $constructor = $reflection->getConstructor())
  5462. || ($constructor->isPublic() && !$constructor->isFinal())) {
  5463. return $reflection->newInstance();
  5464. }
  5465. if (!$this->instantiator) {
  5466. $this->instantiator = new Instantiator();
  5467. }
  5468. return $this->instantiator->instantiate($classname);
  5469. }
  5470. /**
  5471. * Creates double class and returns its FQN.
  5472. *
  5473. * @param ReflectionClass $class
  5474. * @param ReflectionClass[] $interfaces
  5475. *
  5476. * @return string
  5477. */
  5478. protected function createDoubleClass(ReflectionClass $class = null, array $interfaces)
  5479. {
  5480. $name = $this->namer->name($class, $interfaces);
  5481. $node = $this->mirror->reflect($class, $interfaces);
  5482. foreach ($this->patches as $patch) {
  5483. if ($patch->supports($node)) {
  5484. $patch->apply($node);
  5485. }
  5486. }
  5487. $this->creator->create($name, $node);
  5488. return $name;
  5489. }
  5490. }
  5491. <?php
  5492. /*
  5493. * This file is part of the Prophecy.
  5494. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5495. * Marcello Duarte <marcello.duarte@gmail.com>
  5496. *
  5497. * For the full copyright and license information, please view the LICENSE
  5498. * file that was distributed with this source code.
  5499. */
  5500. namespace Prophecy\Doubler\Generator;
  5501. /**
  5502. * Class code creator.
  5503. * Generates PHP code for specific class node tree.
  5504. *
  5505. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5506. */
  5507. class ClassCodeGenerator
  5508. {
  5509. /**
  5510. * Generates PHP code for class node.
  5511. *
  5512. * @param string $classname
  5513. * @param Node\ClassNode $class
  5514. *
  5515. * @return string
  5516. */
  5517. public function generate($classname, Node\ClassNode $class)
  5518. {
  5519. $parts = explode('\\', $classname);
  5520. $classname = array_pop($parts);
  5521. $namespace = implode('\\', $parts);
  5522. $code = sprintf("class %s extends \%s implements %s {\n",
  5523. $classname, $class->getParentClass(), implode(', ',
  5524. array_map(function ($interface) {return '\\'.$interface;}, $class->getInterfaces())
  5525. )
  5526. );
  5527. foreach ($class->getProperties() as $name => $visibility) {
  5528. $code .= sprintf("%s \$%s;\n", $visibility, $name);
  5529. }
  5530. $code .= "\n";
  5531. foreach ($class->getMethods() as $method) {
  5532. $code .= $this->generateMethod($method)."\n";
  5533. }
  5534. $code .= "\n}";
  5535. return sprintf("namespace %s {\n%s\n}", $namespace, $code);
  5536. }
  5537. private function generateMethod(Node\MethodNode $method)
  5538. {
  5539. $php = sprintf("%s %s function %s%s(%s) {\n",
  5540. $method->getVisibility(),
  5541. $method->isStatic() ? 'static' : '',
  5542. $method->returnsReference() ? '&':'',
  5543. $method->getName(),
  5544. implode(', ', $this->generateArguments($method->getArguments()))
  5545. );
  5546. $php .= $method->getCode()."\n";
  5547. return $php.'}';
  5548. }
  5549. private function generateArguments(array $arguments)
  5550. {
  5551. return array_map(function (Node\ArgumentNode $argument) {
  5552. $php = '';
  5553. if ($hint = $argument->getTypeHint()) {
  5554. if ('array' === $hint || 'callable' === $hint) {
  5555. $php .= $hint;
  5556. } else {
  5557. $php .= '\\'.$hint;
  5558. }
  5559. }
  5560. $php .= ' '.($argument->isPassedByReference() ? '&' : '').'$'.$argument->getName();
  5561. if ($argument->isOptional()) {
  5562. $php .= ' = '.var_export($argument->getDefault(), true);
  5563. }
  5564. return $php;
  5565. }, $arguments);
  5566. }
  5567. }
  5568. <?php
  5569. /*
  5570. * This file is part of the Prophecy.
  5571. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5572. * Marcello Duarte <marcello.duarte@gmail.com>
  5573. *
  5574. * For the full copyright and license information, please view the LICENSE
  5575. * file that was distributed with this source code.
  5576. */
  5577. namespace Prophecy\Doubler\Generator;
  5578. use Prophecy\Exception\Doubler\ClassCreatorException;
  5579. /**
  5580. * Class creator.
  5581. * Creates specific class in current environment.
  5582. *
  5583. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5584. */
  5585. class ClassCreator
  5586. {
  5587. private $generator;
  5588. /**
  5589. * Initializes creator.
  5590. *
  5591. * @param ClassCodeGenerator $generator
  5592. */
  5593. public function __construct(ClassCodeGenerator $generator = null)
  5594. {
  5595. $this->generator = $generator ?: new ClassCodeGenerator;
  5596. }
  5597. /**
  5598. * Creates class.
  5599. *
  5600. * @param string $classname
  5601. * @param Node\ClassNode $class
  5602. *
  5603. * @return mixed
  5604. *
  5605. * @throws \Prophecy\Exception\Doubler\ClassCreatorException
  5606. */
  5607. public function create($classname, Node\ClassNode $class)
  5608. {
  5609. $code = $this->generator->generate($classname, $class);
  5610. $return = eval($code);
  5611. if (!class_exists($classname, false)) {
  5612. if (count($class->getInterfaces())) {
  5613. throw new ClassCreatorException(sprintf(
  5614. 'Could not double `%s` and implement interfaces: [%s].',
  5615. $class->getParentClass(), implode(', ', $class->getInterfaces())
  5616. ), $class);
  5617. }
  5618. throw new ClassCreatorException(
  5619. sprintf('Could not double `%s`.', $class->getParentClass()),
  5620. $class
  5621. );
  5622. }
  5623. return $return;
  5624. }
  5625. }
  5626. <?php
  5627. /*
  5628. * This file is part of the Prophecy.
  5629. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5630. * Marcello Duarte <marcello.duarte@gmail.com>
  5631. *
  5632. * For the full copyright and license information, please view the LICENSE
  5633. * file that was distributed with this source code.
  5634. */
  5635. namespace Prophecy\Doubler\Generator;
  5636. /**
  5637. * Reflection interface.
  5638. * All reflected classes implement this interface.
  5639. *
  5640. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5641. */
  5642. interface ReflectionInterface
  5643. {
  5644. }
  5645. <?php
  5646. /*
  5647. * This file is part of the Prophecy.
  5648. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5649. * Marcello Duarte <marcello.duarte@gmail.com>
  5650. *
  5651. * For the full copyright and license information, please view the LICENSE
  5652. * file that was distributed with this source code.
  5653. */
  5654. namespace Prophecy\Doubler\Generator;
  5655. use Prophecy\Exception\InvalidArgumentException;
  5656. use Prophecy\Exception\Doubler\ClassMirrorException;
  5657. use ReflectionClass;
  5658. use ReflectionMethod;
  5659. use ReflectionParameter;
  5660. /**
  5661. * Class mirror.
  5662. * Core doubler class. Mirrors specific class and/or interfaces into class node tree.
  5663. *
  5664. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5665. */
  5666. class ClassMirror
  5667. {
  5668. private static $reflectableMethods = array(
  5669. '__construct',
  5670. '__destruct',
  5671. '__sleep',
  5672. '__wakeup',
  5673. '__toString',
  5674. '__call',
  5675. );
  5676. /**
  5677. * Reflects provided arguments into class node.
  5678. *
  5679. * @param ReflectionClass $class
  5680. * @param ReflectionClass[] $interfaces
  5681. *
  5682. * @return Node\ClassNode
  5683. *
  5684. * @throws \Prophecy\Exception\InvalidArgumentException
  5685. */
  5686. public function reflect(ReflectionClass $class = null, array $interfaces)
  5687. {
  5688. $node = new Node\ClassNode;
  5689. if (null !== $class) {
  5690. if (true === $class->isInterface()) {
  5691. throw new InvalidArgumentException(sprintf(
  5692. "Could not reflect %s as a class, because it\n".
  5693. "is interface - use the second argument instead.",
  5694. $class->getName()
  5695. ));
  5696. }
  5697. $this->reflectClassToNode($class, $node);
  5698. }
  5699. foreach ($interfaces as $interface) {
  5700. if (!$interface instanceof ReflectionClass) {
  5701. throw new InvalidArgumentException(sprintf(
  5702. "[ReflectionClass \$interface1 [, ReflectionClass \$interface2]] array expected as\n".
  5703. "a second argument to `ClassMirror::reflect(...)`, but got %s.",
  5704. is_object($interface) ? get_class($interface).' class' : gettype($interface)
  5705. ));
  5706. }
  5707. if (false === $interface->isInterface()) {
  5708. throw new InvalidArgumentException(sprintf(
  5709. "Could not reflect %s as an interface, because it\n".
  5710. "is class - use the first argument instead.",
  5711. $interface->getName()
  5712. ));
  5713. }
  5714. $this->reflectInterfaceToNode($interface, $node);
  5715. }
  5716. $node->addInterface('Prophecy\Doubler\Generator\ReflectionInterface');
  5717. return $node;
  5718. }
  5719. private function reflectClassToNode(ReflectionClass $class, Node\ClassNode $node)
  5720. {
  5721. if (true === $class->isFinal()) {
  5722. throw new ClassMirrorException(sprintf(
  5723. 'Could not reflect class %s as it is marked final.', $class->getName()
  5724. ), $class);
  5725. }
  5726. $node->setParentClass($class->getName());
  5727. foreach ($class->getMethods(ReflectionMethod::IS_ABSTRACT) as $method) {
  5728. if (false === $method->isProtected()) {
  5729. continue;
  5730. }
  5731. $this->reflectMethodToNode($method, $node);
  5732. }
  5733. foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
  5734. if (0 === strpos($method->getName(), '_')
  5735. && !in_array($method->getName(), self::$reflectableMethods)) {
  5736. continue;
  5737. }
  5738. if (true === $method->isFinal()) {
  5739. continue;
  5740. }
  5741. $this->reflectMethodToNode($method, $node);
  5742. }
  5743. }
  5744. private function reflectInterfaceToNode(ReflectionClass $interface, Node\ClassNode $node)
  5745. {
  5746. $node->addInterface($interface->getName());
  5747. foreach ($interface->getMethods() as $method) {
  5748. $this->reflectMethodToNode($method, $node);
  5749. }
  5750. }
  5751. private function reflectMethodToNode(ReflectionMethod $method, Node\ClassNode $classNode)
  5752. {
  5753. $node = new Node\MethodNode($method->getName());
  5754. if (true === $method->isProtected()) {
  5755. $node->setVisibility('protected');
  5756. }
  5757. if (true === $method->isStatic()) {
  5758. $node->setStatic();
  5759. }
  5760. if (true === $method->returnsReference()) {
  5761. $node->setReturnsReference();
  5762. }
  5763. if (is_array($params = $method->getParameters()) && count($params)) {
  5764. foreach ($params as $param) {
  5765. $this->reflectArgumentToNode($param, $node);
  5766. }
  5767. }
  5768. $classNode->addMethod($node);
  5769. }
  5770. private function reflectArgumentToNode(ReflectionParameter $parameter, Node\MethodNode $methodNode)
  5771. {
  5772. $name = $parameter->getName() == '...' ? '__dot_dot_dot__' : $parameter->getName();
  5773. $node = new Node\ArgumentNode($name);
  5774. $typeHint = $this->getTypeHint($parameter);
  5775. $node->setTypeHint($typeHint);
  5776. if (true === $parameter->isDefaultValueAvailable()) {
  5777. $node->setDefault($parameter->getDefaultValue());
  5778. } elseif (true === $parameter->isOptional()
  5779. || (true === $parameter->allowsNull() && $typeHint)) {
  5780. $node->setDefault(null);
  5781. }
  5782. if (true === $parameter->isPassedByReference()) {
  5783. $node->setAsPassedByReference();
  5784. }
  5785. $methodNode->addArgument($node);
  5786. }
  5787. private function getTypeHint(ReflectionParameter $parameter)
  5788. {
  5789. if (null !== $className = $this->getParameterClassName($parameter)) {
  5790. return $className;
  5791. }
  5792. if (true === $parameter->isArray()) {
  5793. return 'array';
  5794. }
  5795. if (version_compare(PHP_VERSION, '5.4', '>=') && true === $parameter->isCallable()) {
  5796. return 'callable';
  5797. }
  5798. return null;
  5799. }
  5800. private function getParameterClassName(ReflectionParameter $parameter)
  5801. {
  5802. try {
  5803. return $parameter->getClass() ? $parameter->getClass()->getName() : null;
  5804. } catch (\ReflectionException $e) {
  5805. preg_match('/\[\s\<\w+?>\s([\w,\\\]+)/s', $parameter, $matches);
  5806. return isset($matches[1]) ? $matches[1] : null;
  5807. }
  5808. }
  5809. }
  5810. <?php
  5811. /*
  5812. * This file is part of the Prophecy.
  5813. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5814. * Marcello Duarte <marcello.duarte@gmail.com>
  5815. *
  5816. * For the full copyright and license information, please view the LICENSE
  5817. * file that was distributed with this source code.
  5818. */
  5819. namespace Prophecy\Doubler\Generator\Node;
  5820. /**
  5821. * Argument node.
  5822. *
  5823. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5824. */
  5825. class ArgumentNode
  5826. {
  5827. private $name;
  5828. private $typeHint;
  5829. private $default;
  5830. private $optional = false;
  5831. private $byReference = false;
  5832. /**
  5833. * @param string $name
  5834. */
  5835. public function __construct($name)
  5836. {
  5837. $this->name = $name;
  5838. }
  5839. public function getName()
  5840. {
  5841. return $this->name;
  5842. }
  5843. public function getTypeHint()
  5844. {
  5845. return $this->typeHint;
  5846. }
  5847. public function setTypeHint($typeHint = null)
  5848. {
  5849. $this->typeHint = $typeHint;
  5850. }
  5851. public function getDefault()
  5852. {
  5853. return $this->default;
  5854. }
  5855. public function setDefault($default = null)
  5856. {
  5857. $this->optional = true;
  5858. $this->default = $default;
  5859. }
  5860. public function isOptional()
  5861. {
  5862. return $this->optional;
  5863. }
  5864. public function setAsPassedByReference($byReference = true)
  5865. {
  5866. $this->byReference = $byReference;
  5867. }
  5868. public function isPassedByReference()
  5869. {
  5870. return $this->byReference;
  5871. }
  5872. }
  5873. <?php
  5874. /*
  5875. * This file is part of the Prophecy.
  5876. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5877. * Marcello Duarte <marcello.duarte@gmail.com>
  5878. *
  5879. * For the full copyright and license information, please view the LICENSE
  5880. * file that was distributed with this source code.
  5881. */
  5882. namespace Prophecy\Doubler\Generator\Node;
  5883. use Prophecy\Exception\InvalidArgumentException;
  5884. /**
  5885. * Method node.
  5886. *
  5887. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5888. */
  5889. class MethodNode
  5890. {
  5891. private $name;
  5892. private $code;
  5893. private $visibility = 'public';
  5894. private $static = false;
  5895. private $returnsReference = false;
  5896. /**
  5897. * @var ArgumentNode[]
  5898. */
  5899. private $arguments = array();
  5900. /**
  5901. * @param string $name
  5902. * @param string $code
  5903. */
  5904. public function __construct($name, $code = null)
  5905. {
  5906. $this->name = $name;
  5907. $this->code = $code;
  5908. }
  5909. public function getVisibility()
  5910. {
  5911. return $this->visibility;
  5912. }
  5913. /**
  5914. * @param string $visibility
  5915. */
  5916. public function setVisibility($visibility)
  5917. {
  5918. $visibility = strtolower($visibility);
  5919. if (!in_array($visibility, array('public', 'private', 'protected'))) {
  5920. throw new InvalidArgumentException(sprintf(
  5921. '`%s` method visibility is not supported.', $visibility
  5922. ));
  5923. }
  5924. $this->visibility = $visibility;
  5925. }
  5926. public function isStatic()
  5927. {
  5928. return $this->static;
  5929. }
  5930. public function setStatic($static = true)
  5931. {
  5932. $this->static = (bool) $static;
  5933. }
  5934. public function returnsReference()
  5935. {
  5936. return $this->returnsReference;
  5937. }
  5938. public function setReturnsReference()
  5939. {
  5940. $this->returnsReference = true;
  5941. }
  5942. public function getName()
  5943. {
  5944. return $this->name;
  5945. }
  5946. public function addArgument(ArgumentNode $argument)
  5947. {
  5948. $this->arguments[] = $argument;
  5949. }
  5950. /**
  5951. * @return ArgumentNode[]
  5952. */
  5953. public function getArguments()
  5954. {
  5955. return $this->arguments;
  5956. }
  5957. /**
  5958. * @param string $code
  5959. */
  5960. public function setCode($code)
  5961. {
  5962. $this->code = $code;
  5963. }
  5964. public function getCode()
  5965. {
  5966. if ($this->returnsReference)
  5967. {
  5968. return "throw new \Prophecy\Exception\Doubler\ReturnByReferenceException('Returning by reference not supported', get_class(\$this), '{$this->name}');";
  5969. }
  5970. return (string) $this->code;
  5971. }
  5972. public function useParentCode()
  5973. {
  5974. $this->code = sprintf(
  5975. 'return parent::%s(%s);', $this->getName(), implode(', ',
  5976. array_map(function (ArgumentNode $arg) { return '$'.$arg->getName(); }, $this->arguments)
  5977. )
  5978. );
  5979. }
  5980. }
  5981. <?php
  5982. /*
  5983. * This file is part of the Prophecy.
  5984. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5985. * Marcello Duarte <marcello.duarte@gmail.com>
  5986. *
  5987. * For the full copyright and license information, please view the LICENSE
  5988. * file that was distributed with this source code.
  5989. */
  5990. namespace Prophecy\Doubler\Generator\Node;
  5991. use Prophecy\Exception\InvalidArgumentException;
  5992. /**
  5993. * Class node.
  5994. *
  5995. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  5996. */
  5997. class ClassNode
  5998. {
  5999. private $parentClass = 'stdClass';
  6000. private $interfaces = array();
  6001. private $properties = array();
  6002. /**
  6003. * @var MethodNode[]
  6004. */
  6005. private $methods = array();
  6006. public function getParentClass()
  6007. {
  6008. return $this->parentClass;
  6009. }
  6010. /**
  6011. * @param string $class
  6012. */
  6013. public function setParentClass($class)
  6014. {
  6015. $this->parentClass = $class ?: 'stdClass';
  6016. }
  6017. /**
  6018. * @return string[]
  6019. */
  6020. public function getInterfaces()
  6021. {
  6022. return $this->interfaces;
  6023. }
  6024. /**
  6025. * @param string $interface
  6026. */
  6027. public function addInterface($interface)
  6028. {
  6029. if ($this->hasInterface($interface)) {
  6030. return;
  6031. }
  6032. array_unshift($this->interfaces, $interface);
  6033. }
  6034. /**
  6035. * @param string $interface
  6036. *
  6037. * @return bool
  6038. */
  6039. public function hasInterface($interface)
  6040. {
  6041. return in_array($interface, $this->interfaces);
  6042. }
  6043. public function getProperties()
  6044. {
  6045. return $this->properties;
  6046. }
  6047. public function addProperty($name, $visibility = 'public')
  6048. {
  6049. $visibility = strtolower($visibility);
  6050. if (!in_array($visibility, array('public', 'private', 'protected'))) {
  6051. throw new InvalidArgumentException(sprintf(
  6052. '`%s` property visibility is not supported.', $visibility
  6053. ));
  6054. }
  6055. $this->properties[$name] = $visibility;
  6056. }
  6057. /**
  6058. * @return MethodNode[]
  6059. */
  6060. public function getMethods()
  6061. {
  6062. return $this->methods;
  6063. }
  6064. public function addMethod(MethodNode $method)
  6065. {
  6066. $this->methods[$method->getName()] = $method;
  6067. }
  6068. public function removeMethod($name)
  6069. {
  6070. unset($this->methods[$name]);
  6071. }
  6072. /**
  6073. * @param string $name
  6074. *
  6075. * @return MethodNode|null
  6076. */
  6077. public function getMethod($name)
  6078. {
  6079. return $this->hasMethod($name) ? $this->methods[$name] : null;
  6080. }
  6081. /**
  6082. * @param string $name
  6083. *
  6084. * @return bool
  6085. */
  6086. public function hasMethod($name)
  6087. {
  6088. return isset($this->methods[$name]);
  6089. }
  6090. }
  6091. <?php
  6092. /*
  6093. * This file is part of the Prophecy.
  6094. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6095. * Marcello Duarte <marcello.duarte@gmail.com>
  6096. *
  6097. * For the full copyright and license information, please view the LICENSE
  6098. * file that was distributed with this source code.
  6099. */
  6100. namespace Prophecy\Doubler;
  6101. use Prophecy\Exception\Doubler\DoubleException;
  6102. use Prophecy\Exception\Doubler\ClassNotFoundException;
  6103. use Prophecy\Exception\Doubler\InterfaceNotFoundException;
  6104. use ReflectionClass;
  6105. /**
  6106. * Lazy double.
  6107. * Gives simple interface to describe double before creating it.
  6108. *
  6109. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6110. */
  6111. class LazyDouble
  6112. {
  6113. private $doubler;
  6114. private $class;
  6115. private $interfaces = array();
  6116. private $arguments = null;
  6117. private $double;
  6118. /**
  6119. * Initializes lazy double.
  6120. *
  6121. * @param Doubler $doubler
  6122. */
  6123. public function __construct(Doubler $doubler)
  6124. {
  6125. $this->doubler = $doubler;
  6126. }
  6127. /**
  6128. * Tells doubler to use specific class as parent one for double.
  6129. *
  6130. * @param string|ReflectionClass $class
  6131. *
  6132. * @throws \Prophecy\Exception\Doubler\ClassNotFoundException
  6133. * @throws \Prophecy\Exception\Doubler\DoubleException
  6134. */
  6135. public function setParentClass($class)
  6136. {
  6137. if (null !== $this->double) {
  6138. throw new DoubleException('Can not extend class with already instantiated double.');
  6139. }
  6140. if (!$class instanceof ReflectionClass) {
  6141. if (!class_exists($class)) {
  6142. throw new ClassNotFoundException(sprintf('Class %s not found.', $class), $class);
  6143. }
  6144. $class = new ReflectionClass($class);
  6145. }
  6146. $this->class = $class;
  6147. }
  6148. /**
  6149. * Tells doubler to implement specific interface with double.
  6150. *
  6151. * @param string|ReflectionClass $interface
  6152. *
  6153. * @throws \Prophecy\Exception\Doubler\InterfaceNotFoundException
  6154. * @throws \Prophecy\Exception\Doubler\DoubleException
  6155. */
  6156. public function addInterface($interface)
  6157. {
  6158. if (null !== $this->double) {
  6159. throw new DoubleException(
  6160. 'Can not implement interface with already instantiated double.'
  6161. );
  6162. }
  6163. if (!$interface instanceof ReflectionClass) {
  6164. if (!interface_exists($interface)) {
  6165. throw new InterfaceNotFoundException(
  6166. sprintf('Interface %s not found.', $interface),
  6167. $interface
  6168. );
  6169. }
  6170. $interface = new ReflectionClass($interface);
  6171. }
  6172. $this->interfaces[] = $interface;
  6173. }
  6174. /**
  6175. * Sets constructor arguments.
  6176. *
  6177. * @param array $arguments
  6178. */
  6179. public function setArguments(array $arguments = null)
  6180. {
  6181. $this->arguments = $arguments;
  6182. }
  6183. /**
  6184. * Creates double instance or returns already created one.
  6185. *
  6186. * @return DoubleInterface
  6187. */
  6188. public function getInstance()
  6189. {
  6190. if (null === $this->double) {
  6191. if (null !== $this->arguments) {
  6192. return $this->double = $this->doubler->double(
  6193. $this->class, $this->interfaces, $this->arguments
  6194. );
  6195. }
  6196. $this->double = $this->doubler->double($this->class, $this->interfaces);
  6197. }
  6198. return $this->double;
  6199. }
  6200. }
  6201. <?php
  6202. /*
  6203. * This file is part of the Prophecy.
  6204. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6205. * Marcello Duarte <marcello.duarte@gmail.com>
  6206. *
  6207. * For the full copyright and license information, please view the LICENSE
  6208. * file that was distributed with this source code.
  6209. */
  6210. namespace Prophecy\Doubler\ClassPatch;
  6211. use Prophecy\Doubler\Generator\Node\ClassNode;
  6212. /**
  6213. * Remove method functionality from the double which will clash with php keywords.
  6214. *
  6215. * @author Milan Magudia <milan@magudia.com>
  6216. */
  6217. class KeywordPatch implements ClassPatchInterface
  6218. {
  6219. /**
  6220. * Support any class
  6221. *
  6222. * @param ClassNode $node
  6223. *
  6224. * @return boolean
  6225. */
  6226. public function supports(ClassNode $node)
  6227. {
  6228. return true;
  6229. }
  6230. /**
  6231. * Remove methods that clash with php keywords
  6232. *
  6233. * @param ClassNode $node
  6234. */
  6235. public function apply(ClassNode $node)
  6236. {
  6237. $methodNames = array_keys($node->getMethods());
  6238. $methodsToRemove = array_intersect($methodNames, $this->getKeywords());
  6239. foreach ($methodsToRemove as $methodName) {
  6240. $node->removeMethod($methodName);
  6241. }
  6242. }
  6243. /**
  6244. * Returns patch priority, which determines when patch will be applied.
  6245. *
  6246. * @return int Priority number (higher - earlier)
  6247. */
  6248. public function getPriority() {
  6249. return 49;
  6250. }
  6251. /**
  6252. * Returns array of php keywords.
  6253. *
  6254. * @return array
  6255. */
  6256. private function getKeywords() {
  6257. return array(
  6258. '__halt_compiler',
  6259. 'abstract',
  6260. 'and',
  6261. 'array',
  6262. 'as',
  6263. 'break',
  6264. 'callable',
  6265. 'case',
  6266. 'catch',
  6267. 'class',
  6268. 'clone',
  6269. 'const',
  6270. 'continue',
  6271. 'declare',
  6272. 'default',
  6273. 'die',
  6274. 'do',
  6275. 'echo',
  6276. 'else',
  6277. 'elseif',
  6278. 'empty',
  6279. 'enddeclare',
  6280. 'endfor',
  6281. 'endforeach',
  6282. 'endif',
  6283. 'endswitch',
  6284. 'endwhile',
  6285. 'eval',
  6286. 'exit',
  6287. 'extends',
  6288. 'final',
  6289. 'finally',
  6290. 'for',
  6291. 'foreach',
  6292. 'function',
  6293. 'global',
  6294. 'goto',
  6295. 'if',
  6296. 'implements',
  6297. 'include',
  6298. 'include_once',
  6299. 'instanceof',
  6300. 'insteadof',
  6301. 'interface',
  6302. 'isset',
  6303. 'list',
  6304. 'namespace',
  6305. 'new',
  6306. 'or',
  6307. 'print',
  6308. 'private',
  6309. 'protected',
  6310. 'public',
  6311. 'require',
  6312. 'require_once',
  6313. 'return',
  6314. 'static',
  6315. 'switch',
  6316. 'throw',
  6317. 'trait',
  6318. 'try',
  6319. 'unset',
  6320. 'use',
  6321. 'var',
  6322. 'while',
  6323. 'xor',
  6324. 'yield',
  6325. );
  6326. }
  6327. }
  6328. <?php
  6329. /*
  6330. * This file is part of the Prophecy.
  6331. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6332. * Marcello Duarte <marcello.duarte@gmail.com>
  6333. *
  6334. * For the full copyright and license information, please view the LICENSE
  6335. * file that was distributed with this source code.
  6336. */
  6337. namespace Prophecy\Doubler\ClassPatch;
  6338. use Prophecy\Doubler\Generator\Node\ClassNode;
  6339. use Prophecy\Doubler\Generator\Node\MethodNode;
  6340. use Prophecy\Doubler\Generator\Node\ArgumentNode;
  6341. /**
  6342. * Add Prophecy functionality to the double.
  6343. * This is a core class patch for Prophecy.
  6344. *
  6345. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6346. */
  6347. class ProphecySubjectPatch implements ClassPatchInterface
  6348. {
  6349. /**
  6350. * Always returns true.
  6351. *
  6352. * @param ClassNode $node
  6353. *
  6354. * @return bool
  6355. */
  6356. public function supports(ClassNode $node)
  6357. {
  6358. return true;
  6359. }
  6360. /**
  6361. * Apply Prophecy functionality to class node.
  6362. *
  6363. * @param ClassNode $node
  6364. */
  6365. public function apply(ClassNode $node)
  6366. {
  6367. $node->addInterface('Prophecy\Prophecy\ProphecySubjectInterface');
  6368. $node->addProperty('objectProphecy', 'private');
  6369. foreach ($node->getMethods() as $name => $method) {
  6370. if ('__construct' === strtolower($name)) {
  6371. continue;
  6372. }
  6373. $method->setCode(
  6374. 'return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());'
  6375. );
  6376. }
  6377. $prophecySetter = new MethodNode('setProphecy');
  6378. $prophecyArgument = new ArgumentNode('prophecy');
  6379. $prophecyArgument->setTypeHint('Prophecy\Prophecy\ProphecyInterface');
  6380. $prophecySetter->addArgument($prophecyArgument);
  6381. $prophecySetter->setCode('$this->objectProphecy = $prophecy;');
  6382. $prophecyGetter = new MethodNode('getProphecy');
  6383. $prophecyGetter->setCode('return $this->objectProphecy;');
  6384. if ($node->hasMethod('__call')) {
  6385. $__call = $node->getMethod('__call');
  6386. } else {
  6387. $__call = new MethodNode('__call');
  6388. $__call->addArgument(new ArgumentNode('name'));
  6389. $__call->addArgument(new ArgumentNode('arguments'));
  6390. $node->addMethod($__call);
  6391. }
  6392. $__call->setCode(<<<PHP
  6393. throw new \Prophecy\Exception\Doubler\MethodNotFoundException(
  6394. sprintf('Method `%s::%s()` not found.', get_class(\$this), func_get_arg(0)),
  6395. \$this->getProphecy(), func_get_arg(0)
  6396. );
  6397. PHP
  6398. );
  6399. $node->addMethod($prophecySetter);
  6400. $node->addMethod($prophecyGetter);
  6401. }
  6402. /**
  6403. * Returns patch priority, which determines when patch will be applied.
  6404. *
  6405. * @return int Priority number (higher - earlier)
  6406. */
  6407. public function getPriority()
  6408. {
  6409. return 0;
  6410. }
  6411. }
  6412. <?php
  6413. /*
  6414. * This file is part of the Prophecy.
  6415. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6416. * Marcello Duarte <marcello.duarte@gmail.com>
  6417. *
  6418. * For the full copyright and license information, please view the LICENSE
  6419. * file that was distributed with this source code.
  6420. */
  6421. namespace Prophecy\Doubler\ClassPatch;
  6422. use phpDocumentor\Reflection\DocBlock;
  6423. use Prophecy\Doubler\Generator\Node\ClassNode;
  6424. use Prophecy\Doubler\Generator\Node\MethodNode;
  6425. /**
  6426. * Discover Magical API using "@method" PHPDoc format.
  6427. *
  6428. * @author Thomas Tourlourat <thomas@tourlourat.com>
  6429. */
  6430. class MagicCallPatch implements ClassPatchInterface
  6431. {
  6432. /**
  6433. * Support any class
  6434. *
  6435. * @param ClassNode $node
  6436. *
  6437. * @return boolean
  6438. */
  6439. public function supports(ClassNode $node)
  6440. {
  6441. return true;
  6442. }
  6443. /**
  6444. * Discover Magical API
  6445. *
  6446. * @param ClassNode $node
  6447. */
  6448. public function apply(ClassNode $node)
  6449. {
  6450. $parentClass = $node->getParentClass();
  6451. $reflectionClass = new \ReflectionClass($parentClass);
  6452. $phpdoc = new DocBlock($reflectionClass->getDocComment());
  6453. $tagList = $phpdoc->getTagsByName('method');
  6454. foreach($tagList as $tag) {
  6455. $methodName = $tag->getMethodName();
  6456. if (!$reflectionClass->hasMethod($methodName)) {
  6457. $methodNode = new MethodNode($tag->getMethodName());
  6458. $methodNode->setStatic($tag->isStatic());
  6459. $node->addMethod($methodNode);
  6460. }
  6461. }
  6462. }
  6463. /**
  6464. * Returns patch priority, which determines when patch will be applied.
  6465. *
  6466. * @return integer Priority number (higher - earlier)
  6467. */
  6468. public function getPriority()
  6469. {
  6470. return 50;
  6471. }
  6472. }
  6473. <?php
  6474. /*
  6475. * This file is part of the Prophecy.
  6476. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6477. * Marcello Duarte <marcello.duarte@gmail.com>
  6478. *
  6479. * For the full copyright and license information, please view the LICENSE
  6480. * file that was distributed with this source code.
  6481. */
  6482. namespace Prophecy\Doubler\ClassPatch;
  6483. use Prophecy\Doubler\Generator\Node\ClassNode;
  6484. use Prophecy\Doubler\Generator\Node\MethodNode;
  6485. /**
  6486. * Traversable interface patch.
  6487. * Forces classes that implement interfaces, that extend Traversable to also implement Iterator.
  6488. *
  6489. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6490. */
  6491. class TraversablePatch implements ClassPatchInterface
  6492. {
  6493. /**
  6494. * Supports nodetree, that implement Traversable, but not Iterator or IteratorAggregate.
  6495. *
  6496. * @param ClassNode $node
  6497. *
  6498. * @return bool
  6499. */
  6500. public function supports(ClassNode $node)
  6501. {
  6502. if (in_array('Iterator', $node->getInterfaces())) {
  6503. return false;
  6504. }
  6505. if (in_array('IteratorAggregate', $node->getInterfaces())) {
  6506. return false;
  6507. }
  6508. foreach ($node->getInterfaces() as $interface) {
  6509. if ('Traversable' !== $interface && !is_subclass_of($interface, 'Traversable')) {
  6510. continue;
  6511. }
  6512. if ('Iterator' === $interface || is_subclass_of($interface, 'Iterator')) {
  6513. continue;
  6514. }
  6515. if ('IteratorAggregate' === $interface || is_subclass_of($interface, 'IteratorAggregate')) {
  6516. continue;
  6517. }
  6518. return true;
  6519. }
  6520. return false;
  6521. }
  6522. /**
  6523. * Forces class to implement Iterator interface.
  6524. *
  6525. * @param ClassNode $node
  6526. */
  6527. public function apply(ClassNode $node)
  6528. {
  6529. $node->addInterface('Iterator');
  6530. $node->addMethod(new MethodNode('current'));
  6531. $node->addMethod(new MethodNode('key'));
  6532. $node->addMethod(new MethodNode('next'));
  6533. $node->addMethod(new MethodNode('rewind'));
  6534. $node->addMethod(new MethodNode('valid'));
  6535. }
  6536. /**
  6537. * Returns patch priority, which determines when patch will be applied.
  6538. *
  6539. * @return int Priority number (higher - earlier)
  6540. */
  6541. public function getPriority()
  6542. {
  6543. return 100;
  6544. }
  6545. }
  6546. <?php
  6547. /*
  6548. * This file is part of the Prophecy.
  6549. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6550. * Marcello Duarte <marcello.duarte@gmail.com>
  6551. *
  6552. * For the full copyright and license information, please view the LICENSE
  6553. * file that was distributed with this source code.
  6554. */
  6555. namespace Prophecy\Doubler\ClassPatch;
  6556. use Prophecy\Doubler\Generator\Node\ClassNode;
  6557. use Prophecy\Doubler\Generator\Node\MethodNode;
  6558. /**
  6559. * SplFileInfo patch.
  6560. * Makes SplFileInfo and derivative classes usable with Prophecy.
  6561. *
  6562. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6563. */
  6564. class SplFileInfoPatch implements ClassPatchInterface
  6565. {
  6566. /**
  6567. * Supports everything that extends SplFileInfo.
  6568. *
  6569. * @param ClassNode $node
  6570. *
  6571. * @return bool
  6572. */
  6573. public function supports(ClassNode $node)
  6574. {
  6575. if (null === $node->getParentClass()) {
  6576. return false;
  6577. }
  6578. return 'SplFileInfo' === $node->getParentClass()
  6579. || is_subclass_of($node->getParentClass(), 'SplFileInfo')
  6580. ;
  6581. }
  6582. /**
  6583. * Updated constructor code to call parent one with dummy file argument.
  6584. *
  6585. * @param ClassNode $node
  6586. */
  6587. public function apply(ClassNode $node)
  6588. {
  6589. if ($node->hasMethod('__construct')) {
  6590. $constructor = $node->getMethod('__construct');
  6591. } else {
  6592. $constructor = new MethodNode('__construct');
  6593. $node->addMethod($constructor);
  6594. }
  6595. if ($this->nodeIsDirectoryIterator($node)) {
  6596. $constructor->setCode('return parent::__construct("' . __DIR__ . '");');
  6597. return;
  6598. }
  6599. $constructor->useParentCode();
  6600. }
  6601. /**
  6602. * Returns patch priority, which determines when patch will be applied.
  6603. *
  6604. * @return int Priority number (higher - earlier)
  6605. */
  6606. public function getPriority()
  6607. {
  6608. return 50;
  6609. }
  6610. /**
  6611. * @param ClassNode $node
  6612. * @return boolean
  6613. */
  6614. private function nodeIsDirectoryIterator(ClassNode $node)
  6615. {
  6616. $parent = $node->getParentClass();
  6617. return 'DirectoryIterator' === $parent
  6618. || is_subclass_of($parent, 'DirectoryIterator');
  6619. }
  6620. }
  6621. <?php
  6622. /*
  6623. * This file is part of the Prophecy.
  6624. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6625. * Marcello Duarte <marcello.duarte@gmail.com>
  6626. *
  6627. * For the full copyright and license information, please view the LICENSE
  6628. * file that was distributed with this source code.
  6629. */
  6630. namespace Prophecy\Doubler\ClassPatch;
  6631. use Prophecy\Doubler\Generator\Node\ClassNode;
  6632. use Prophecy\Doubler\Generator\Node\MethodNode;
  6633. /**
  6634. * Disable constructor.
  6635. * Makes all constructor arguments optional.
  6636. *
  6637. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6638. */
  6639. class DisableConstructorPatch implements ClassPatchInterface
  6640. {
  6641. /**
  6642. * Checks if class has `__construct` method.
  6643. *
  6644. * @param ClassNode $node
  6645. *
  6646. * @return bool
  6647. */
  6648. public function supports(ClassNode $node)
  6649. {
  6650. return true;
  6651. }
  6652. /**
  6653. * Makes all class constructor arguments optional.
  6654. *
  6655. * @param ClassNode $node
  6656. */
  6657. public function apply(ClassNode $node)
  6658. {
  6659. if (!$node->hasMethod('__construct')) {
  6660. $node->addMethod(new MethodNode('__construct', ''));
  6661. return;
  6662. }
  6663. $constructor = $node->getMethod('__construct');
  6664. foreach ($constructor->getArguments() as $argument) {
  6665. $argument->setDefault(null);
  6666. }
  6667. $constructor->setCode(<<<PHP
  6668. if (0 < func_num_args()) {
  6669. call_user_func_array(array('parent', '__construct'), func_get_args());
  6670. }
  6671. PHP
  6672. );
  6673. }
  6674. /**
  6675. * Returns patch priority, which determines when patch will be applied.
  6676. *
  6677. * @return int Priority number (higher - earlier)
  6678. */
  6679. public function getPriority()
  6680. {
  6681. return 100;
  6682. }
  6683. }
  6684. <?php
  6685. /*
  6686. * This file is part of the Prophecy.
  6687. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6688. * Marcello Duarte <marcello.duarte@gmail.com>
  6689. *
  6690. * For the full copyright and license information, please view the LICENSE
  6691. * file that was distributed with this source code.
  6692. */
  6693. namespace Prophecy\Doubler\ClassPatch;
  6694. use Prophecy\Doubler\Generator\Node\ClassNode;
  6695. /**
  6696. * Exception patch for HHVM to remove the stubs from special methods
  6697. *
  6698. * @author Christophe Coevoet <stof@notk.org>
  6699. */
  6700. class HhvmExceptionPatch implements ClassPatchInterface
  6701. {
  6702. /**
  6703. * Supports exceptions on HHVM.
  6704. *
  6705. * @param ClassNode $node
  6706. *
  6707. * @return bool
  6708. */
  6709. public function supports(ClassNode $node)
  6710. {
  6711. if (!defined('HHVM_VERSION')) {
  6712. return false;
  6713. }
  6714. return 'Exception' === $node->getParentClass() || is_subclass_of($node->getParentClass(), 'Exception');
  6715. }
  6716. /**
  6717. * Removes special exception static methods from the doubled methods.
  6718. *
  6719. * @param ClassNode $node
  6720. *
  6721. * @return void
  6722. */
  6723. public function apply(ClassNode $node)
  6724. {
  6725. if ($node->hasMethod('setTraceOptions')) {
  6726. $node->getMethod('setTraceOptions')->useParentCode();
  6727. }
  6728. if ($node->hasMethod('getTraceOptions')) {
  6729. $node->getMethod('getTraceOptions')->useParentCode();
  6730. }
  6731. }
  6732. /**
  6733. * {@inheritdoc}
  6734. */
  6735. public function getPriority()
  6736. {
  6737. return -50;
  6738. }
  6739. }
  6740. <?php
  6741. /*
  6742. * This file is part of the Prophecy.
  6743. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6744. * Marcello Duarte <marcello.duarte@gmail.com>
  6745. *
  6746. * For the full copyright and license information, please view the LICENSE
  6747. * file that was distributed with this source code.
  6748. */
  6749. namespace Prophecy\Doubler\ClassPatch;
  6750. use Prophecy\Doubler\Generator\Node\ClassNode;
  6751. /**
  6752. * ReflectionClass::newInstance patch.
  6753. * Makes first argument of newInstance optional, since it works but signature is misleading
  6754. *
  6755. * @author Florian Klein <florian.klein@free.fr>
  6756. */
  6757. class ReflectionClassNewInstancePatch implements ClassPatchInterface
  6758. {
  6759. /**
  6760. * Supports ReflectionClass
  6761. *
  6762. * @param ClassNode $node
  6763. *
  6764. * @return bool
  6765. */
  6766. public function supports(ClassNode $node)
  6767. {
  6768. return 'ReflectionClass' === $node->getParentClass();
  6769. }
  6770. /**
  6771. * Updates newInstance's first argument to make it optional
  6772. *
  6773. * @param ClassNode $node
  6774. */
  6775. public function apply(ClassNode $node)
  6776. {
  6777. foreach ($node->getMethod('newInstance')->getArguments() as $argument) {
  6778. $argument->setDefault(null);
  6779. }
  6780. }
  6781. /**
  6782. * Returns patch priority, which determines when patch will be applied.
  6783. *
  6784. * @return int Priority number (higher = earlier)
  6785. */
  6786. public function getPriority()
  6787. {
  6788. return 50;
  6789. }
  6790. }
  6791. <?php
  6792. /*
  6793. * This file is part of the Prophecy.
  6794. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6795. * Marcello Duarte <marcello.duarte@gmail.com>
  6796. *
  6797. * For the full copyright and license information, please view the LICENSE
  6798. * file that was distributed with this source code.
  6799. */
  6800. namespace Prophecy\Doubler\ClassPatch;
  6801. use Prophecy\Doubler\Generator\Node\ClassNode;
  6802. /**
  6803. * Class patch interface.
  6804. * Class patches extend doubles functionality or help
  6805. * Prophecy to avoid some internal PHP bugs.
  6806. *
  6807. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6808. */
  6809. interface ClassPatchInterface
  6810. {
  6811. /**
  6812. * Checks if patch supports specific class node.
  6813. *
  6814. * @param ClassNode $node
  6815. *
  6816. * @return bool
  6817. */
  6818. public function supports(ClassNode $node);
  6819. /**
  6820. * Applies patch to the specific class node.
  6821. *
  6822. * @param ClassNode $node
  6823. * @return void
  6824. */
  6825. public function apply(ClassNode $node);
  6826. /**
  6827. * Returns patch priority, which determines when patch will be applied.
  6828. *
  6829. * @return int Priority number (higher - earlier)
  6830. */
  6831. public function getPriority();
  6832. }
  6833. <?php
  6834. /*
  6835. * This file is part of the Prophecy.
  6836. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6837. * Marcello Duarte <marcello.duarte@gmail.com>
  6838. *
  6839. * For the full copyright and license information, please view the LICENSE
  6840. * file that was distributed with this source code.
  6841. */
  6842. namespace Prophecy\Doubler;
  6843. use ReflectionClass;
  6844. /**
  6845. * Name generator.
  6846. * Generates classname for double.
  6847. *
  6848. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6849. */
  6850. class NameGenerator
  6851. {
  6852. private static $counter = 1;
  6853. /**
  6854. * Generates name.
  6855. *
  6856. * @param ReflectionClass $class
  6857. * @param ReflectionClass[] $interfaces
  6858. *
  6859. * @return string
  6860. */
  6861. public function name(ReflectionClass $class = null, array $interfaces)
  6862. {
  6863. $parts = array();
  6864. if (null !== $class) {
  6865. $parts[] = $class->getName();
  6866. } else {
  6867. foreach ($interfaces as $interface) {
  6868. $parts[] = $interface->getShortName();
  6869. }
  6870. }
  6871. if (!count($parts)) {
  6872. $parts[] = 'stdClass';
  6873. }
  6874. return sprintf('Double\%s\P%d', implode('\\', $parts), self::$counter++);
  6875. }
  6876. }
  6877. <?php
  6878. /*
  6879. * This file is part of the Prophecy.
  6880. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6881. * Marcello Duarte <marcello.duarte@gmail.com>
  6882. *
  6883. * For the full copyright and license information, please view the LICENSE
  6884. * file that was distributed with this source code.
  6885. */
  6886. namespace Prophecy\Prediction;
  6887. use Prophecy\Call\Call;
  6888. use Prophecy\Prophecy\ObjectProphecy;
  6889. use Prophecy\Prophecy\MethodProphecy;
  6890. use Prophecy\Argument\ArgumentsWildcard;
  6891. use Prophecy\Argument\Token\AnyValuesToken;
  6892. use Prophecy\Util\StringUtil;
  6893. use Prophecy\Exception\Prediction\UnexpectedCallsCountException;
  6894. /**
  6895. * Prediction interface.
  6896. * Predictions are logical test blocks, tied to `should...` keyword.
  6897. *
  6898. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6899. */
  6900. class CallTimesPrediction implements PredictionInterface
  6901. {
  6902. private $times;
  6903. private $util;
  6904. /**
  6905. * Initializes prediction.
  6906. *
  6907. * @param int $times
  6908. * @param StringUtil $util
  6909. */
  6910. public function __construct($times, StringUtil $util = null)
  6911. {
  6912. $this->times = intval($times);
  6913. $this->util = $util ?: new StringUtil;
  6914. }
  6915. /**
  6916. * Tests that there was exact amount of calls made.
  6917. *
  6918. * @param Call[] $calls
  6919. * @param ObjectProphecy $object
  6920. * @param MethodProphecy $method
  6921. *
  6922. * @throws \Prophecy\Exception\Prediction\UnexpectedCallsCountException
  6923. */
  6924. public function check(array $calls, ObjectProphecy $object, MethodProphecy $method)
  6925. {
  6926. if ($this->times == count($calls)) {
  6927. return;
  6928. }
  6929. $methodCalls = $object->findProphecyMethodCalls(
  6930. $method->getMethodName(),
  6931. new ArgumentsWildcard(array(new AnyValuesToken))
  6932. );
  6933. if (count($calls)) {
  6934. $message = sprintf(
  6935. "Expected exactly %d calls that match:\n".
  6936. " %s->%s(%s)\n".
  6937. "but %d were made:\n%s",
  6938. $this->times,
  6939. get_class($object->reveal()),
  6940. $method->getMethodName(),
  6941. $method->getArgumentsWildcard(),
  6942. count($calls),
  6943. $this->util->stringifyCalls($calls)
  6944. );
  6945. } elseif (count($methodCalls)) {
  6946. $message = sprintf(
  6947. "Expected exactly %d calls that match:\n".
  6948. " %s->%s(%s)\n".
  6949. "but none were made.\n".
  6950. "Recorded `%s(...)` calls:\n%s",
  6951. $this->times,
  6952. get_class($object->reveal()),
  6953. $method->getMethodName(),
  6954. $method->getArgumentsWildcard(),
  6955. $method->getMethodName(),
  6956. $this->util->stringifyCalls($methodCalls)
  6957. );
  6958. } else {
  6959. $message = sprintf(
  6960. "Expected exactly %d calls that match:\n".
  6961. " %s->%s(%s)\n".
  6962. "but none were made.",
  6963. $this->times,
  6964. get_class($object->reveal()),
  6965. $method->getMethodName(),
  6966. $method->getArgumentsWildcard()
  6967. );
  6968. }
  6969. throw new UnexpectedCallsCountException($message, $method, $this->times, $calls);
  6970. }
  6971. }
  6972. <?php
  6973. /*
  6974. * This file is part of the Prophecy.
  6975. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  6976. * Marcello Duarte <marcello.duarte@gmail.com>
  6977. *
  6978. * For the full copyright and license information, please view the LICENSE
  6979. * file that was distributed with this source code.
  6980. */
  6981. namespace Prophecy\Prediction;
  6982. use Prophecy\Call\Call;
  6983. use Prophecy\Prophecy\ObjectProphecy;
  6984. use Prophecy\Prophecy\MethodProphecy;
  6985. use Prophecy\Util\StringUtil;
  6986. use Prophecy\Exception\Prediction\UnexpectedCallsException;
  6987. /**
  6988. * No calls prediction.
  6989. *
  6990. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  6991. */
  6992. class NoCallsPrediction implements PredictionInterface
  6993. {
  6994. private $util;
  6995. /**
  6996. * Initializes prediction.
  6997. *
  6998. * @param null|StringUtil $util
  6999. */
  7000. public function __construct(StringUtil $util = null)
  7001. {
  7002. $this->util = $util ?: new StringUtil;
  7003. }
  7004. /**
  7005. * Tests that there were no calls made.
  7006. *
  7007. * @param Call[] $calls
  7008. * @param ObjectProphecy $object
  7009. * @param MethodProphecy $method
  7010. *
  7011. * @throws \Prophecy\Exception\Prediction\UnexpectedCallsException
  7012. */
  7013. public function check(array $calls, ObjectProphecy $object, MethodProphecy $method)
  7014. {
  7015. if (!count($calls)) {
  7016. return;
  7017. }
  7018. $verb = count($calls) === 1 ? 'was' : 'were';
  7019. throw new UnexpectedCallsException(sprintf(
  7020. "No calls expected that match:\n".
  7021. " %s->%s(%s)\n".
  7022. "but %d %s made:\n%s",
  7023. get_class($object->reveal()),
  7024. $method->getMethodName(),
  7025. $method->getArgumentsWildcard(),
  7026. count($calls),
  7027. $verb,
  7028. $this->util->stringifyCalls($calls)
  7029. ), $method, $calls);
  7030. }
  7031. }
  7032. <?php
  7033. /*
  7034. * This file is part of the Prophecy.
  7035. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7036. * Marcello Duarte <marcello.duarte@gmail.com>
  7037. *
  7038. * For the full copyright and license information, please view the LICENSE
  7039. * file that was distributed with this source code.
  7040. */
  7041. namespace Prophecy\Prediction;
  7042. use Prophecy\Call\Call;
  7043. use Prophecy\Prophecy\ObjectProphecy;
  7044. use Prophecy\Prophecy\MethodProphecy;
  7045. /**
  7046. * Prediction interface.
  7047. * Predictions are logical test blocks, tied to `should...` keyword.
  7048. *
  7049. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7050. */
  7051. interface PredictionInterface
  7052. {
  7053. /**
  7054. * Tests that double fulfilled prediction.
  7055. *
  7056. * @param Call[] $calls
  7057. * @param ObjectProphecy $object
  7058. * @param MethodProphecy $method
  7059. *
  7060. * @throws object
  7061. * @return void
  7062. */
  7063. public function check(array $calls, ObjectProphecy $object, MethodProphecy $method);
  7064. }
  7065. <?php
  7066. /*
  7067. * This file is part of the Prophecy.
  7068. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7069. * Marcello Duarte <marcello.duarte@gmail.com>
  7070. *
  7071. * For the full copyright and license information, please view the LICENSE
  7072. * file that was distributed with this source code.
  7073. */
  7074. namespace Prophecy\Prediction;
  7075. use Prophecy\Call\Call;
  7076. use Prophecy\Prophecy\ObjectProphecy;
  7077. use Prophecy\Prophecy\MethodProphecy;
  7078. use Prophecy\Exception\InvalidArgumentException;
  7079. use Closure;
  7080. /**
  7081. * Callback prediction.
  7082. *
  7083. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7084. */
  7085. class CallbackPrediction implements PredictionInterface
  7086. {
  7087. private $callback;
  7088. /**
  7089. * Initializes callback prediction.
  7090. *
  7091. * @param callable $callback Custom callback
  7092. *
  7093. * @throws \Prophecy\Exception\InvalidArgumentException
  7094. */
  7095. public function __construct($callback)
  7096. {
  7097. if (!is_callable($callback)) {
  7098. throw new InvalidArgumentException(sprintf(
  7099. 'Callable expected as an argument to CallbackPrediction, but got %s.',
  7100. gettype($callback)
  7101. ));
  7102. }
  7103. $this->callback = $callback;
  7104. }
  7105. /**
  7106. * Executes preset callback.
  7107. *
  7108. * @param Call[] $calls
  7109. * @param ObjectProphecy $object
  7110. * @param MethodProphecy $method
  7111. */
  7112. public function check(array $calls, ObjectProphecy $object, MethodProphecy $method)
  7113. {
  7114. $callback = $this->callback;
  7115. if ($callback instanceof Closure && method_exists('Closure', 'bind')) {
  7116. $callback = Closure::bind($callback, $object);
  7117. }
  7118. call_user_func($callback, $calls, $object, $method);
  7119. }
  7120. }
  7121. <?php
  7122. /*
  7123. * This file is part of the Prophecy.
  7124. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7125. * Marcello Duarte <marcello.duarte@gmail.com>
  7126. *
  7127. * For the full copyright and license information, please view the LICENSE
  7128. * file that was distributed with this source code.
  7129. */
  7130. namespace Prophecy\Prediction;
  7131. use Prophecy\Call\Call;
  7132. use Prophecy\Prophecy\ObjectProphecy;
  7133. use Prophecy\Prophecy\MethodProphecy;
  7134. use Prophecy\Argument\ArgumentsWildcard;
  7135. use Prophecy\Argument\Token\AnyValuesToken;
  7136. use Prophecy\Util\StringUtil;
  7137. use Prophecy\Exception\Prediction\NoCallsException;
  7138. /**
  7139. * Call prediction.
  7140. *
  7141. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7142. */
  7143. class CallPrediction implements PredictionInterface
  7144. {
  7145. private $util;
  7146. /**
  7147. * Initializes prediction.
  7148. *
  7149. * @param StringUtil $util
  7150. */
  7151. public function __construct(StringUtil $util = null)
  7152. {
  7153. $this->util = $util ?: new StringUtil;
  7154. }
  7155. /**
  7156. * Tests that there was at least one call.
  7157. *
  7158. * @param Call[] $calls
  7159. * @param ObjectProphecy $object
  7160. * @param MethodProphecy $method
  7161. *
  7162. * @throws \Prophecy\Exception\Prediction\NoCallsException
  7163. */
  7164. public function check(array $calls, ObjectProphecy $object, MethodProphecy $method)
  7165. {
  7166. if (count($calls)) {
  7167. return;
  7168. }
  7169. $methodCalls = $object->findProphecyMethodCalls(
  7170. $method->getMethodName(),
  7171. new ArgumentsWildcard(array(new AnyValuesToken))
  7172. );
  7173. if (count($methodCalls)) {
  7174. throw new NoCallsException(sprintf(
  7175. "No calls have been made that match:\n".
  7176. " %s->%s(%s)\n".
  7177. "but expected at least one.\n".
  7178. "Recorded `%s(...)` calls:\n%s",
  7179. get_class($object->reveal()),
  7180. $method->getMethodName(),
  7181. $method->getArgumentsWildcard(),
  7182. $method->getMethodName(),
  7183. $this->util->stringifyCalls($methodCalls)
  7184. ), $method);
  7185. }
  7186. throw new NoCallsException(sprintf(
  7187. "No calls have been made that match:\n".
  7188. " %s->%s(%s)\n".
  7189. "but expected at least one.",
  7190. get_class($object->reveal()),
  7191. $method->getMethodName(),
  7192. $method->getArgumentsWildcard()
  7193. ), $method);
  7194. }
  7195. }
  7196. <?php
  7197. /*
  7198. * This file is part of the Prophecy.
  7199. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7200. * Marcello Duarte <marcello.duarte@gmail.com>
  7201. *
  7202. * For the full copyright and license information, please view the LICENSE
  7203. * file that was distributed with this source code.
  7204. */
  7205. namespace Prophecy\Call;
  7206. use Exception;
  7207. /**
  7208. * Call object.
  7209. *
  7210. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7211. */
  7212. class Call
  7213. {
  7214. private $methodName;
  7215. private $arguments;
  7216. private $returnValue;
  7217. private $exception;
  7218. private $file;
  7219. private $line;
  7220. /**
  7221. * Initializes call.
  7222. *
  7223. * @param string $methodName
  7224. * @param array $arguments
  7225. * @param mixed $returnValue
  7226. * @param Exception $exception
  7227. * @param null|string $file
  7228. * @param null|int $line
  7229. */
  7230. public function __construct($methodName, array $arguments, $returnValue,
  7231. Exception $exception = null, $file, $line)
  7232. {
  7233. $this->methodName = $methodName;
  7234. $this->arguments = $arguments;
  7235. $this->returnValue = $returnValue;
  7236. $this->exception = $exception;
  7237. if ($file) {
  7238. $this->file = $file;
  7239. $this->line = intval($line);
  7240. }
  7241. }
  7242. /**
  7243. * Returns called method name.
  7244. *
  7245. * @return string
  7246. */
  7247. public function getMethodName()
  7248. {
  7249. return $this->methodName;
  7250. }
  7251. /**
  7252. * Returns called method arguments.
  7253. *
  7254. * @return array
  7255. */
  7256. public function getArguments()
  7257. {
  7258. return $this->arguments;
  7259. }
  7260. /**
  7261. * Returns called method return value.
  7262. *
  7263. * @return null|mixed
  7264. */
  7265. public function getReturnValue()
  7266. {
  7267. return $this->returnValue;
  7268. }
  7269. /**
  7270. * Returns exception that call thrown.
  7271. *
  7272. * @return null|Exception
  7273. */
  7274. public function getException()
  7275. {
  7276. return $this->exception;
  7277. }
  7278. /**
  7279. * Returns callee filename.
  7280. *
  7281. * @return string
  7282. */
  7283. public function getFile()
  7284. {
  7285. return $this->file;
  7286. }
  7287. /**
  7288. * Returns callee line number.
  7289. *
  7290. * @return int
  7291. */
  7292. public function getLine()
  7293. {
  7294. return $this->line;
  7295. }
  7296. /**
  7297. * Returns short notation for callee place.
  7298. *
  7299. * @return string
  7300. */
  7301. public function getCallPlace()
  7302. {
  7303. if (null === $this->file) {
  7304. return 'unknown';
  7305. }
  7306. return sprintf('%s:%d', $this->file, $this->line);
  7307. }
  7308. }
  7309. <?php
  7310. /*
  7311. * This file is part of the Prophecy.
  7312. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7313. * Marcello Duarte <marcello.duarte@gmail.com>
  7314. *
  7315. * For the full copyright and license information, please view the LICENSE
  7316. * file that was distributed with this source code.
  7317. */
  7318. namespace Prophecy\Call;
  7319. use Prophecy\Prophecy\MethodProphecy;
  7320. use Prophecy\Prophecy\ObjectProphecy;
  7321. use Prophecy\Argument\ArgumentsWildcard;
  7322. use Prophecy\Util\StringUtil;
  7323. use Prophecy\Exception\Call\UnexpectedCallException;
  7324. /**
  7325. * Calls receiver & manager.
  7326. *
  7327. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7328. */
  7329. class CallCenter
  7330. {
  7331. private $util;
  7332. /**
  7333. * @var Call[]
  7334. */
  7335. private $recordedCalls = array();
  7336. /**
  7337. * Initializes call center.
  7338. *
  7339. * @param StringUtil $util
  7340. */
  7341. public function __construct(StringUtil $util = null)
  7342. {
  7343. $this->util = $util ?: new StringUtil;
  7344. }
  7345. /**
  7346. * Makes and records specific method call for object prophecy.
  7347. *
  7348. * @param ObjectProphecy $prophecy
  7349. * @param string $methodName
  7350. * @param array $arguments
  7351. *
  7352. * @return mixed Returns null if no promise for prophecy found or promise return value.
  7353. *
  7354. * @throws \Prophecy\Exception\Call\UnexpectedCallException If no appropriate method prophecy found
  7355. */
  7356. public function makeCall(ObjectProphecy $prophecy, $methodName, array $arguments)
  7357. {
  7358. $backtrace = debug_backtrace();
  7359. $file = $line = null;
  7360. if (isset($backtrace[2]) && isset($backtrace[2]['file'])) {
  7361. $file = $backtrace[2]['file'];
  7362. $line = $backtrace[2]['line'];
  7363. }
  7364. // If no method prophecies defined, then it's a dummy, so we'll just return null
  7365. if ('__destruct' === $methodName || 0 == count($prophecy->getMethodProphecies())) {
  7366. $this->recordedCalls[] = new Call($methodName, $arguments, null, null, $file, $line);
  7367. return null;
  7368. }
  7369. // There are method prophecies, so it's a fake/stub. Searching prophecy for this call
  7370. $matches = array();
  7371. foreach ($prophecy->getMethodProphecies($methodName) as $methodProphecy) {
  7372. if (0 < $score = $methodProphecy->getArgumentsWildcard()->scoreArguments($arguments)) {
  7373. $matches[] = array($score, $methodProphecy);
  7374. }
  7375. }
  7376. // If fake/stub doesn't have method prophecy for this call - throw exception
  7377. if (!count($matches)) {
  7378. throw $this->createUnexpectedCallException($prophecy, $methodName, $arguments);
  7379. }
  7380. // Sort matches by their score value
  7381. @usort($matches, function ($match1, $match2) { return $match2[0] - $match1[0]; });
  7382. // If Highest rated method prophecy has a promise - execute it or return null instead
  7383. $returnValue = null;
  7384. $exception = null;
  7385. if ($promise = $matches[0][1]->getPromise()) {
  7386. try {
  7387. $returnValue = $promise->execute($arguments, $prophecy, $matches[0][1]);
  7388. } catch (\Exception $e) {
  7389. $exception = $e;
  7390. }
  7391. }
  7392. $this->recordedCalls[] = new Call(
  7393. $methodName, $arguments, $returnValue, $exception, $file, $line
  7394. );
  7395. if (null !== $exception) {
  7396. throw $exception;
  7397. }
  7398. return $returnValue;
  7399. }
  7400. /**
  7401. * Searches for calls by method name & arguments wildcard.
  7402. *
  7403. * @param string $methodName
  7404. * @param ArgumentsWildcard $wildcard
  7405. *
  7406. * @return Call[]
  7407. */
  7408. public function findCalls($methodName, ArgumentsWildcard $wildcard)
  7409. {
  7410. return array_values(
  7411. array_filter($this->recordedCalls, function (Call $call) use ($methodName, $wildcard) {
  7412. return $methodName === $call->getMethodName()
  7413. && 0 < $wildcard->scoreArguments($call->getArguments())
  7414. ;
  7415. })
  7416. );
  7417. }
  7418. private function createUnexpectedCallException(ObjectProphecy $prophecy, $methodName,
  7419. array $arguments)
  7420. {
  7421. $classname = get_class($prophecy->reveal());
  7422. $argstring = implode(', ', array_map(array($this->util, 'stringify'), $arguments));
  7423. $expected = implode("\n", array_map(function (MethodProphecy $methodProphecy) {
  7424. return sprintf(' - %s(%s)',
  7425. $methodProphecy->getMethodName(),
  7426. $methodProphecy->getArgumentsWildcard()
  7427. );
  7428. }, call_user_func_array('array_merge', $prophecy->getMethodProphecies())));
  7429. return new UnexpectedCallException(
  7430. sprintf(
  7431. "Method call:\n".
  7432. " - %s(%s)\n".
  7433. "on %s was not expected, expected calls were:\n%s",
  7434. $methodName, $argstring, $classname, $expected
  7435. ),
  7436. $prophecy, $methodName, $arguments
  7437. );
  7438. }
  7439. }
  7440. <?php
  7441. /*
  7442. * This file is part of the Prophecy.
  7443. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7444. * Marcello Duarte <marcello.duarte@gmail.com>
  7445. *
  7446. * For the full copyright and license information, please view the LICENSE
  7447. * file that was distributed with this source code.
  7448. */
  7449. namespace Prophecy\Promise;
  7450. use Doctrine\Instantiator\Instantiator;
  7451. use Prophecy\Prophecy\ObjectProphecy;
  7452. use Prophecy\Prophecy\MethodProphecy;
  7453. use Prophecy\Exception\InvalidArgumentException;
  7454. use ReflectionClass;
  7455. /**
  7456. * Throw promise.
  7457. *
  7458. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7459. */
  7460. class ThrowPromise implements PromiseInterface
  7461. {
  7462. private $exception;
  7463. /**
  7464. * @var \Doctrine\Instantiator\Instantiator
  7465. */
  7466. private $instantiator;
  7467. /**
  7468. * Initializes promise.
  7469. *
  7470. * @param string|\Exception $exception Exception class name or instance
  7471. *
  7472. * @throws \Prophecy\Exception\InvalidArgumentException
  7473. */
  7474. public function __construct($exception)
  7475. {
  7476. if (is_string($exception)) {
  7477. if (!class_exists($exception)
  7478. && 'Exception' !== $exception
  7479. && !is_subclass_of($exception, 'Exception')) {
  7480. throw new InvalidArgumentException(sprintf(
  7481. 'Exception class or instance expected as argument to ThrowPromise, but got %s.',
  7482. gettype($exception)
  7483. ));
  7484. }
  7485. } elseif (!$exception instanceof \Exception) {
  7486. throw new InvalidArgumentException(sprintf(
  7487. 'Exception class or instance expected as argument to ThrowPromise, but got %s.',
  7488. gettype($exception)
  7489. ));
  7490. }
  7491. $this->exception = $exception;
  7492. }
  7493. /**
  7494. * Throws predefined exception.
  7495. *
  7496. * @param array $args
  7497. * @param ObjectProphecy $object
  7498. * @param MethodProphecy $method
  7499. *
  7500. * @throws object
  7501. */
  7502. public function execute(array $args, ObjectProphecy $object, MethodProphecy $method)
  7503. {
  7504. if (is_string($this->exception)) {
  7505. $classname = $this->exception;
  7506. $reflection = new ReflectionClass($classname);
  7507. $constructor = $reflection->getConstructor();
  7508. if ($constructor->isPublic() && 0 == $constructor->getNumberOfRequiredParameters()) {
  7509. throw $reflection->newInstance();
  7510. }
  7511. if (!$this->instantiator) {
  7512. $this->instantiator = new Instantiator();
  7513. }
  7514. throw $this->instantiator->instantiate($classname);
  7515. }
  7516. throw $this->exception;
  7517. }
  7518. }
  7519. <?php
  7520. /*
  7521. * This file is part of the Prophecy.
  7522. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7523. * Marcello Duarte <marcello.duarte@gmail.com>
  7524. *
  7525. * For the full copyright and license information, please view the LICENSE
  7526. * file that was distributed with this source code.
  7527. */
  7528. namespace Prophecy\Promise;
  7529. use Prophecy\Exception\InvalidArgumentException;
  7530. use Prophecy\Prophecy\ObjectProphecy;
  7531. use Prophecy\Prophecy\MethodProphecy;
  7532. /**
  7533. * Return argument promise.
  7534. *
  7535. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7536. */
  7537. class ReturnArgumentPromise implements PromiseInterface
  7538. {
  7539. /**
  7540. * @var int
  7541. */
  7542. private $index;
  7543. /**
  7544. * Initializes callback promise.
  7545. *
  7546. * @param int $index The zero-indexed number of the argument to return
  7547. *
  7548. * @throws \Prophecy\Exception\InvalidArgumentException
  7549. */
  7550. public function __construct($index = 0)
  7551. {
  7552. if (!is_int($index) || $index < 0) {
  7553. throw new InvalidArgumentException(
  7554. 'Zero-based index expected as argument to ReturnArgumentPromise, but got %s.',
  7555. $index
  7556. );
  7557. }
  7558. $this->index = $index;
  7559. }
  7560. /**
  7561. * Returns nth argument if has one, null otherwise.
  7562. *
  7563. * @param array $args
  7564. * @param ObjectProphecy $object
  7565. * @param MethodProphecy $method
  7566. *
  7567. * @return null|mixed
  7568. */
  7569. public function execute(array $args, ObjectProphecy $object, MethodProphecy $method)
  7570. {
  7571. return count($args) > $this->index ? $args[$this->index] : null;
  7572. }
  7573. }
  7574. <?php
  7575. /*
  7576. * This file is part of the Prophecy.
  7577. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7578. * Marcello Duarte <marcello.duarte@gmail.com>
  7579. *
  7580. * For the full copyright and license information, please view the LICENSE
  7581. * file that was distributed with this source code.
  7582. */
  7583. namespace Prophecy\Promise;
  7584. use Prophecy\Prophecy\ObjectProphecy;
  7585. use Prophecy\Prophecy\MethodProphecy;
  7586. /**
  7587. * Return promise.
  7588. *
  7589. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7590. */
  7591. class ReturnPromise implements PromiseInterface
  7592. {
  7593. private $returnValues = array();
  7594. /**
  7595. * Initializes promise.
  7596. *
  7597. * @param array $returnValues Array of values
  7598. */
  7599. public function __construct(array $returnValues)
  7600. {
  7601. $this->returnValues = $returnValues;
  7602. }
  7603. /**
  7604. * Returns saved values one by one until last one, then continuously returns last value.
  7605. *
  7606. * @param array $args
  7607. * @param ObjectProphecy $object
  7608. * @param MethodProphecy $method
  7609. *
  7610. * @return mixed
  7611. */
  7612. public function execute(array $args, ObjectProphecy $object, MethodProphecy $method)
  7613. {
  7614. $value = array_shift($this->returnValues);
  7615. if (!count($this->returnValues)) {
  7616. $this->returnValues[] = $value;
  7617. }
  7618. return $value;
  7619. }
  7620. }
  7621. <?php
  7622. /*
  7623. * This file is part of the Prophecy.
  7624. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7625. * Marcello Duarte <marcello.duarte@gmail.com>
  7626. *
  7627. * For the full copyright and license information, please view the LICENSE
  7628. * file that was distributed with this source code.
  7629. */
  7630. namespace Prophecy\Promise;
  7631. use Prophecy\Prophecy\ObjectProphecy;
  7632. use Prophecy\Prophecy\MethodProphecy;
  7633. use Prophecy\Exception\InvalidArgumentException;
  7634. use Closure;
  7635. /**
  7636. * Callback promise.
  7637. *
  7638. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7639. */
  7640. class CallbackPromise implements PromiseInterface
  7641. {
  7642. private $callback;
  7643. /**
  7644. * Initializes callback promise.
  7645. *
  7646. * @param callable $callback Custom callback
  7647. *
  7648. * @throws \Prophecy\Exception\InvalidArgumentException
  7649. */
  7650. public function __construct($callback)
  7651. {
  7652. if (!is_callable($callback)) {
  7653. throw new InvalidArgumentException(sprintf(
  7654. 'Callable expected as an argument to CallbackPromise, but got %s.',
  7655. gettype($callback)
  7656. ));
  7657. }
  7658. $this->callback = $callback;
  7659. }
  7660. /**
  7661. * Evaluates promise callback.
  7662. *
  7663. * @param array $args
  7664. * @param ObjectProphecy $object
  7665. * @param MethodProphecy $method
  7666. *
  7667. * @return mixed
  7668. */
  7669. public function execute(array $args, ObjectProphecy $object, MethodProphecy $method)
  7670. {
  7671. $callback = $this->callback;
  7672. if ($callback instanceof Closure && method_exists('Closure', 'bind')) {
  7673. $callback = Closure::bind($callback, $object);
  7674. }
  7675. return call_user_func($callback, $args, $object, $method);
  7676. }
  7677. }
  7678. <?php
  7679. /*
  7680. * This file is part of the Prophecy.
  7681. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7682. * Marcello Duarte <marcello.duarte@gmail.com>
  7683. *
  7684. * For the full copyright and license information, please view the LICENSE
  7685. * file that was distributed with this source code.
  7686. */
  7687. namespace Prophecy\Promise;
  7688. use Prophecy\Prophecy\ObjectProphecy;
  7689. use Prophecy\Prophecy\MethodProphecy;
  7690. /**
  7691. * Promise interface.
  7692. * Promises are logical blocks, tied to `will...` keyword.
  7693. *
  7694. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7695. */
  7696. interface PromiseInterface
  7697. {
  7698. /**
  7699. * Evaluates promise.
  7700. *
  7701. * @param array $args
  7702. * @param ObjectProphecy $object
  7703. * @param MethodProphecy $method
  7704. *
  7705. * @return mixed
  7706. */
  7707. public function execute(array $args, ObjectProphecy $object, MethodProphecy $method);
  7708. }
  7709. <?php
  7710. /*
  7711. * This file is part of the Prophecy.
  7712. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7713. * Marcello Duarte <marcello.duarte@gmail.com>
  7714. *
  7715. * For the full copyright and license information, please view the LICENSE
  7716. * file that was distributed with this source code.
  7717. */
  7718. namespace Prophecy\Argument;
  7719. /**
  7720. * Arguments wildcarding.
  7721. *
  7722. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7723. */
  7724. class ArgumentsWildcard
  7725. {
  7726. /**
  7727. * @var Token\TokenInterface[]
  7728. */
  7729. private $tokens = array();
  7730. private $string;
  7731. /**
  7732. * Initializes wildcard.
  7733. *
  7734. * @param array $arguments Array of argument tokens or values
  7735. */
  7736. public function __construct(array $arguments)
  7737. {
  7738. foreach ($arguments as $argument) {
  7739. if (!$argument instanceof Token\TokenInterface) {
  7740. $argument = new Token\ExactValueToken($argument);
  7741. }
  7742. $this->tokens[] = $argument;
  7743. }
  7744. }
  7745. /**
  7746. * Calculates wildcard match score for provided arguments.
  7747. *
  7748. * @param array $arguments
  7749. *
  7750. * @return false|int False OR integer score (higher - better)
  7751. */
  7752. public function scoreArguments(array $arguments)
  7753. {
  7754. if (0 == count($arguments) && 0 == count($this->tokens)) {
  7755. return 1;
  7756. }
  7757. $arguments = array_values($arguments);
  7758. $totalScore = 0;
  7759. foreach ($this->tokens as $i => $token) {
  7760. $argument = isset($arguments[$i]) ? $arguments[$i] : null;
  7761. if (1 >= $score = $token->scoreArgument($argument)) {
  7762. return false;
  7763. }
  7764. $totalScore += $score;
  7765. if (true === $token->isLast()) {
  7766. return $totalScore;
  7767. }
  7768. }
  7769. if (count($arguments) > count($this->tokens)) {
  7770. return false;
  7771. }
  7772. return $totalScore;
  7773. }
  7774. /**
  7775. * Returns string representation for wildcard.
  7776. *
  7777. * @return string
  7778. */
  7779. public function __toString()
  7780. {
  7781. if (null === $this->string) {
  7782. $this->string = implode(', ', array_map(function ($token) {
  7783. return (string) $token;
  7784. }, $this->tokens));
  7785. }
  7786. return $this->string;
  7787. }
  7788. /**
  7789. * @return array
  7790. */
  7791. public function getTokens()
  7792. {
  7793. return $this->tokens;
  7794. }
  7795. }
  7796. <?php
  7797. /*
  7798. * This file is part of the Prophecy.
  7799. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7800. * Marcello Duarte <marcello.duarte@gmail.com>
  7801. *
  7802. * For the full copyright and license information, please view the LICENSE
  7803. * file that was distributed with this source code.
  7804. */
  7805. namespace Prophecy\Argument\Token;
  7806. /**
  7807. * Any single value token.
  7808. *
  7809. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7810. */
  7811. class AnyValueToken implements TokenInterface
  7812. {
  7813. /**
  7814. * Always scores 3 for any argument.
  7815. *
  7816. * @param $argument
  7817. *
  7818. * @return int
  7819. */
  7820. public function scoreArgument($argument)
  7821. {
  7822. return 3;
  7823. }
  7824. /**
  7825. * Returns false.
  7826. *
  7827. * @return bool
  7828. */
  7829. public function isLast()
  7830. {
  7831. return false;
  7832. }
  7833. /**
  7834. * Returns string representation for token.
  7835. *
  7836. * @return string
  7837. */
  7838. public function __toString()
  7839. {
  7840. return '*';
  7841. }
  7842. }
  7843. <?php
  7844. /*
  7845. * This file is part of the Prophecy.
  7846. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7847. * Marcello Duarte <marcello.duarte@gmail.com>
  7848. *
  7849. * For the full copyright and license information, please view the LICENSE
  7850. * file that was distributed with this source code.
  7851. */
  7852. namespace Prophecy\Argument\Token;
  7853. /**
  7854. * Array every entry token.
  7855. *
  7856. * @author Adrien Brault <adrien.brault@gmail.com>
  7857. */
  7858. class ArrayEveryEntryToken implements TokenInterface
  7859. {
  7860. /**
  7861. * @var TokenInterface
  7862. */
  7863. private $value;
  7864. /**
  7865. * @param mixed $value exact value or token
  7866. */
  7867. public function __construct($value)
  7868. {
  7869. if (!$value instanceof TokenInterface) {
  7870. $value = new ExactValueToken($value);
  7871. }
  7872. $this->value = $value;
  7873. }
  7874. /**
  7875. * {@inheritdoc}
  7876. */
  7877. public function scoreArgument($argument)
  7878. {
  7879. if (!$argument instanceof \Traversable && !is_array($argument)) {
  7880. return false;
  7881. }
  7882. $scores = array();
  7883. foreach ($argument as $key => $argumentEntry) {
  7884. $scores[] = $this->value->scoreArgument($argumentEntry);
  7885. }
  7886. if (empty($scores) || in_array(false, $scores, true)) {
  7887. return false;
  7888. }
  7889. return array_sum($scores) / count($scores);
  7890. }
  7891. /**
  7892. * {@inheritdoc}
  7893. */
  7894. public function isLast()
  7895. {
  7896. return false;
  7897. }
  7898. /**
  7899. * {@inheritdoc}
  7900. */
  7901. public function __toString()
  7902. {
  7903. return sprintf('[%s, ..., %s]', $this->value, $this->value);
  7904. }
  7905. /**
  7906. * @return TokenInterface
  7907. */
  7908. public function getValue()
  7909. {
  7910. return $this->value;
  7911. }
  7912. }
  7913. <?php
  7914. /*
  7915. * This file is part of the Prophecy.
  7916. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7917. * Marcello Duarte <marcello.duarte@gmail.com>
  7918. *
  7919. * For the full copyright and license information, please view the LICENSE
  7920. * file that was distributed with this source code.
  7921. */
  7922. namespace Prophecy\Argument\Token;
  7923. /**
  7924. * Logical AND token.
  7925. *
  7926. * @author Boris Mikhaylov <kaguxmail@gmail.com>
  7927. */
  7928. class LogicalAndToken implements TokenInterface
  7929. {
  7930. private $tokens = array();
  7931. /**
  7932. * @param array $arguments exact values or tokens
  7933. */
  7934. public function __construct(array $arguments)
  7935. {
  7936. foreach ($arguments as $argument) {
  7937. if (!$argument instanceof TokenInterface) {
  7938. $argument = new ExactValueToken($argument);
  7939. }
  7940. $this->tokens[] = $argument;
  7941. }
  7942. }
  7943. /**
  7944. * Scores maximum score from scores returned by tokens for this argument if all of them score.
  7945. *
  7946. * @param $argument
  7947. *
  7948. * @return bool|int
  7949. */
  7950. public function scoreArgument($argument)
  7951. {
  7952. if (0 === count($this->tokens)) {
  7953. return false;
  7954. }
  7955. $maxScore = 0;
  7956. foreach ($this->tokens as $token) {
  7957. $score = $token->scoreArgument($argument);
  7958. if (false === $score) {
  7959. return false;
  7960. }
  7961. $maxScore = max($score, $maxScore);
  7962. }
  7963. return $maxScore;
  7964. }
  7965. /**
  7966. * Returns false.
  7967. *
  7968. * @return boolean
  7969. */
  7970. public function isLast()
  7971. {
  7972. return false;
  7973. }
  7974. /**
  7975. * Returns string representation for token.
  7976. *
  7977. * @return string
  7978. */
  7979. public function __toString()
  7980. {
  7981. return sprintf('bool(%s)', implode(' AND ', $this->tokens));
  7982. }
  7983. }
  7984. <?php
  7985. /*
  7986. * This file is part of the Prophecy.
  7987. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  7988. * Marcello Duarte <marcello.duarte@gmail.com>
  7989. *
  7990. * For the full copyright and license information, please view the LICENSE
  7991. * file that was distributed with this source code.
  7992. */
  7993. namespace Prophecy\Argument\Token;
  7994. /**
  7995. * Argument token interface.
  7996. *
  7997. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  7998. */
  7999. interface TokenInterface
  8000. {
  8001. /**
  8002. * Calculates token match score for provided argument.
  8003. *
  8004. * @param $argument
  8005. *
  8006. * @return bool|int
  8007. */
  8008. public function scoreArgument($argument);
  8009. /**
  8010. * Returns true if this token prevents check of other tokens (is last one).
  8011. *
  8012. * @return bool|int
  8013. */
  8014. public function isLast();
  8015. /**
  8016. * Returns string representation for token.
  8017. *
  8018. * @return string
  8019. */
  8020. public function __toString();
  8021. }
  8022. <?php
  8023. /*
  8024. * This file is part of the Prophecy.
  8025. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8026. * Marcello Duarte <marcello.duarte@gmail.com>
  8027. *
  8028. * For the full copyright and license information, please view the LICENSE
  8029. * file that was distributed with this source code.
  8030. */
  8031. namespace Prophecy\Argument\Token;
  8032. use Prophecy\Exception\InvalidArgumentException;
  8033. /**
  8034. * Array entry token.
  8035. *
  8036. * @author Boris Mikhaylov <kaguxmail@gmail.com>
  8037. */
  8038. class ArrayEntryToken implements TokenInterface
  8039. {
  8040. /** @var \Prophecy\Argument\Token\TokenInterface */
  8041. private $key;
  8042. /** @var \Prophecy\Argument\Token\TokenInterface */
  8043. private $value;
  8044. /**
  8045. * @param mixed $key exact value or token
  8046. * @param mixed $value exact value or token
  8047. */
  8048. public function __construct($key, $value)
  8049. {
  8050. $this->key = $this->wrapIntoExactValueToken($key);
  8051. $this->value = $this->wrapIntoExactValueToken($value);
  8052. }
  8053. /**
  8054. * Scores half of combined scores from key and value tokens for same entry. Capped at 8.
  8055. * If argument implements \ArrayAccess without \Traversable, then key token is restricted to ExactValueToken.
  8056. *
  8057. * @param array|\ArrayAccess|\Traversable $argument
  8058. *
  8059. * @throws \Prophecy\Exception\InvalidArgumentException
  8060. * @return bool|int
  8061. */
  8062. public function scoreArgument($argument)
  8063. {
  8064. if ($argument instanceof \Traversable) {
  8065. $argument = iterator_to_array($argument);
  8066. }
  8067. if ($argument instanceof \ArrayAccess) {
  8068. $argument = $this->convertArrayAccessToEntry($argument);
  8069. }
  8070. if (!is_array($argument) || empty($argument)) {
  8071. return false;
  8072. }
  8073. $keyScores = array_map(array($this->key,'scoreArgument'), array_keys($argument));
  8074. $valueScores = array_map(array($this->value,'scoreArgument'), $argument);
  8075. $scoreEntry = function ($value, $key) {
  8076. return $value && $key ? min(8, ($key + $value) / 2) : false;
  8077. };
  8078. return max(array_map($scoreEntry, $valueScores, $keyScores));
  8079. }
  8080. /**
  8081. * Returns false.
  8082. *
  8083. * @return boolean
  8084. */
  8085. public function isLast()
  8086. {
  8087. return false;
  8088. }
  8089. /**
  8090. * Returns string representation for token.
  8091. *
  8092. * @return string
  8093. */
  8094. public function __toString()
  8095. {
  8096. return sprintf('[..., %s => %s, ...]', $this->key, $this->value);
  8097. }
  8098. /**
  8099. * Returns key
  8100. *
  8101. * @return TokenInterface
  8102. */
  8103. public function getKey()
  8104. {
  8105. return $this->key;
  8106. }
  8107. /**
  8108. * Returns value
  8109. *
  8110. * @return TokenInterface
  8111. */
  8112. public function getValue()
  8113. {
  8114. return $this->value;
  8115. }
  8116. /**
  8117. * Wraps non token $value into ExactValueToken
  8118. *
  8119. * @param $value
  8120. * @return TokenInterface
  8121. */
  8122. private function wrapIntoExactValueToken($value)
  8123. {
  8124. return $value instanceof TokenInterface ? $value : new ExactValueToken($value);
  8125. }
  8126. /**
  8127. * Converts instance of \ArrayAccess to key => value array entry
  8128. *
  8129. * @param \ArrayAccess $object
  8130. *
  8131. * @return array|null
  8132. * @throws \Prophecy\Exception\InvalidArgumentException
  8133. */
  8134. private function convertArrayAccessToEntry(\ArrayAccess $object)
  8135. {
  8136. if (!$this->key instanceof ExactValueToken) {
  8137. throw new InvalidArgumentException(sprintf(
  8138. 'You can only use exact value tokens to match key of ArrayAccess object'.PHP_EOL.
  8139. 'But you used `%s`.',
  8140. $this->key
  8141. ));
  8142. }
  8143. $key = $this->key->getValue();
  8144. return $object->offsetExists($key) ? array($key => $object[$key]) : array();
  8145. }
  8146. }
  8147. <?php
  8148. /*
  8149. * This file is part of the Prophecy.
  8150. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8151. * Marcello Duarte <marcello.duarte@gmail.com>
  8152. *
  8153. * For the full copyright and license information, please view the LICENSE
  8154. * file that was distributed with this source code.
  8155. */
  8156. namespace Prophecy\Argument\Token;
  8157. /**
  8158. * Array elements count token.
  8159. *
  8160. * @author Boris Mikhaylov <kaguxmail@gmail.com>
  8161. */
  8162. class ArrayCountToken implements TokenInterface
  8163. {
  8164. private $count;
  8165. /**
  8166. * @param integer $value
  8167. */
  8168. public function __construct($value)
  8169. {
  8170. $this->count = $value;
  8171. }
  8172. /**
  8173. * Scores 6 when argument has preset number of elements.
  8174. *
  8175. * @param $argument
  8176. *
  8177. * @return bool|int
  8178. */
  8179. public function scoreArgument($argument)
  8180. {
  8181. return $this->isCountable($argument) && $this->hasProperCount($argument) ? 6 : false;
  8182. }
  8183. /**
  8184. * Returns false.
  8185. *
  8186. * @return boolean
  8187. */
  8188. public function isLast()
  8189. {
  8190. return false;
  8191. }
  8192. /**
  8193. * Returns string representation for token.
  8194. *
  8195. * @return string
  8196. */
  8197. public function __toString()
  8198. {
  8199. return sprintf('count(%s)', $this->count);
  8200. }
  8201. /**
  8202. * Returns true if object is either array or instance of \Countable
  8203. *
  8204. * @param $argument
  8205. * @return bool
  8206. */
  8207. private function isCountable($argument)
  8208. {
  8209. return (is_array($argument) || $argument instanceof \Countable);
  8210. }
  8211. /**
  8212. * Returns true if $argument has expected number of elements
  8213. *
  8214. * @param array|\Countable $argument
  8215. *
  8216. * @return bool
  8217. */
  8218. private function hasProperCount($argument)
  8219. {
  8220. return $this->count === count($argument);
  8221. }
  8222. }
  8223. <?php
  8224. /*
  8225. * This file is part of the Prophecy.
  8226. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8227. * Marcello Duarte <marcello.duarte@gmail.com>
  8228. *
  8229. * For the full copyright and license information, please view the LICENSE
  8230. * file that was distributed with this source code.
  8231. */
  8232. namespace Prophecy\Argument\Token;
  8233. /**
  8234. * Any values token.
  8235. *
  8236. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  8237. */
  8238. class AnyValuesToken implements TokenInterface
  8239. {
  8240. /**
  8241. * Always scores 2 for any argument.
  8242. *
  8243. * @param $argument
  8244. *
  8245. * @return int
  8246. */
  8247. public function scoreArgument($argument)
  8248. {
  8249. return 2;
  8250. }
  8251. /**
  8252. * Returns true to stop wildcard from processing other tokens.
  8253. *
  8254. * @return bool
  8255. */
  8256. public function isLast()
  8257. {
  8258. return true;
  8259. }
  8260. /**
  8261. * Returns string representation for token.
  8262. *
  8263. * @return string
  8264. */
  8265. public function __toString()
  8266. {
  8267. return '* [, ...]';
  8268. }
  8269. }
  8270. <?php
  8271. /*
  8272. * This file is part of the Prophecy.
  8273. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8274. * Marcello Duarte <marcello.duarte@gmail.com>
  8275. *
  8276. * For the full copyright and license information, please view the LICENSE
  8277. * file that was distributed with this source code.
  8278. */
  8279. namespace Prophecy\Argument\Token;
  8280. /**
  8281. * String contains token.
  8282. *
  8283. * @author Peter Mitchell <pete@peterjmit.com>
  8284. */
  8285. class StringContainsToken implements TokenInterface
  8286. {
  8287. private $value;
  8288. /**
  8289. * Initializes token.
  8290. *
  8291. * @param string $value
  8292. */
  8293. public function __construct($value)
  8294. {
  8295. $this->value = $value;
  8296. }
  8297. public function scoreArgument($argument)
  8298. {
  8299. return strpos($argument, $this->value) !== false ? 6 : false;
  8300. }
  8301. /**
  8302. * Returns preset value against which token checks arguments.
  8303. *
  8304. * @return mixed
  8305. */
  8306. public function getValue()
  8307. {
  8308. return $this->value;
  8309. }
  8310. /**
  8311. * Returns false.
  8312. *
  8313. * @return bool
  8314. */
  8315. public function isLast()
  8316. {
  8317. return false;
  8318. }
  8319. /**
  8320. * Returns string representation for token.
  8321. *
  8322. * @return string
  8323. */
  8324. public function __toString()
  8325. {
  8326. return sprintf('contains("%s")', $this->value);
  8327. }
  8328. }
  8329. <?php
  8330. /*
  8331. * This file is part of the Prophecy.
  8332. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8333. * Marcello Duarte <marcello.duarte@gmail.com>
  8334. *
  8335. * For the full copyright and license information, please view the LICENSE
  8336. * file that was distributed with this source code.
  8337. */
  8338. namespace Prophecy\Argument\Token;
  8339. use SebastianBergmann\Comparator\ComparisonFailure;
  8340. use Prophecy\Comparator\Factory as ComparatorFactory;
  8341. use Prophecy\Util\StringUtil;
  8342. /**
  8343. * Exact value token.
  8344. *
  8345. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  8346. */
  8347. class ExactValueToken implements TokenInterface
  8348. {
  8349. private $value;
  8350. private $string;
  8351. private $util;
  8352. private $comparatorFactory;
  8353. /**
  8354. * Initializes token.
  8355. *
  8356. * @param mixed $value
  8357. * @param StringUtil $util
  8358. * @param ComparatorFactory $comparatorFactory
  8359. */
  8360. public function __construct($value, StringUtil $util = null, ComparatorFactory $comparatorFactory = null)
  8361. {
  8362. $this->value = $value;
  8363. $this->util = $util ?: new StringUtil();
  8364. $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance();
  8365. }
  8366. /**
  8367. * Scores 10 if argument matches preset value.
  8368. *
  8369. * @param $argument
  8370. *
  8371. * @return bool|int
  8372. */
  8373. public function scoreArgument($argument)
  8374. {
  8375. if (is_object($argument) && is_object($this->value)) {
  8376. $comparator = $this->comparatorFactory->getComparatorFor(
  8377. $argument, $this->value
  8378. );
  8379. try {
  8380. $comparator->assertEquals($argument, $this->value);
  8381. return 10;
  8382. } catch (ComparisonFailure $failure) {}
  8383. }
  8384. // If either one is an object it should be castable to a string
  8385. if (is_object($argument) xor is_object($this->value)) {
  8386. if (is_object($argument) && !method_exists($argument, '__toString')) {
  8387. return false;
  8388. }
  8389. if (is_object($this->value) && !method_exists($this->value, '__toString')) {
  8390. return false;
  8391. }
  8392. } elseif (is_numeric($argument) && is_numeric($this->value)) {
  8393. // noop
  8394. } elseif (gettype($argument) !== gettype($this->value)) {
  8395. return false;
  8396. }
  8397. return $argument == $this->value ? 10 : false;
  8398. }
  8399. /**
  8400. * Returns preset value against which token checks arguments.
  8401. *
  8402. * @return mixed
  8403. */
  8404. public function getValue()
  8405. {
  8406. return $this->value;
  8407. }
  8408. /**
  8409. * Returns false.
  8410. *
  8411. * @return bool
  8412. */
  8413. public function isLast()
  8414. {
  8415. return false;
  8416. }
  8417. /**
  8418. * Returns string representation for token.
  8419. *
  8420. * @return string
  8421. */
  8422. public function __toString()
  8423. {
  8424. if (null === $this->string) {
  8425. $this->string = sprintf('exact(%s)', $this->util->stringify($this->value));
  8426. }
  8427. return $this->string;
  8428. }
  8429. }
  8430. <?php
  8431. /*
  8432. * This file is part of the Prophecy.
  8433. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8434. * Marcello Duarte <marcello.duarte@gmail.com>
  8435. *
  8436. * For the full copyright and license information, please view the LICENSE
  8437. * file that was distributed with this source code.
  8438. */
  8439. namespace Prophecy\Argument\Token;
  8440. use SebastianBergmann\Comparator\ComparisonFailure;
  8441. use Prophecy\Comparator\Factory as ComparatorFactory;
  8442. use Prophecy\Util\StringUtil;
  8443. /**
  8444. * Object state-checker token.
  8445. *
  8446. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  8447. */
  8448. class ObjectStateToken implements TokenInterface
  8449. {
  8450. private $name;
  8451. private $value;
  8452. private $util;
  8453. private $comparatorFactory;
  8454. /**
  8455. * Initializes token.
  8456. *
  8457. * @param string $methodName
  8458. * @param mixed $value Expected return value
  8459. * @param null|StringUtil $util
  8460. * @param ComparatorFactory $comparatorFactory
  8461. */
  8462. public function __construct(
  8463. $methodName,
  8464. $value,
  8465. StringUtil $util = null,
  8466. ComparatorFactory $comparatorFactory = null
  8467. ) {
  8468. $this->name = $methodName;
  8469. $this->value = $value;
  8470. $this->util = $util ?: new StringUtil;
  8471. $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance();
  8472. }
  8473. /**
  8474. * Scores 8 if argument is an object, which method returns expected value.
  8475. *
  8476. * @param mixed $argument
  8477. *
  8478. * @return bool|int
  8479. */
  8480. public function scoreArgument($argument)
  8481. {
  8482. if (is_object($argument) && method_exists($argument, $this->name)) {
  8483. $actual = call_user_func(array($argument, $this->name));
  8484. $comparator = $this->comparatorFactory->getComparatorFor(
  8485. $actual, $this->value
  8486. );
  8487. try {
  8488. $comparator->assertEquals($actual, $this->value);
  8489. return 8;
  8490. } catch (ComparisonFailure $failure) {
  8491. return false;
  8492. }
  8493. }
  8494. if (is_object($argument) && property_exists($argument, $this->name)) {
  8495. return $argument->{$this->name} === $this->value ? 8 : false;
  8496. }
  8497. return false;
  8498. }
  8499. /**
  8500. * Returns false.
  8501. *
  8502. * @return bool
  8503. */
  8504. public function isLast()
  8505. {
  8506. return false;
  8507. }
  8508. /**
  8509. * Returns string representation for token.
  8510. *
  8511. * @return string
  8512. */
  8513. public function __toString()
  8514. {
  8515. return sprintf('state(%s(), %s)',
  8516. $this->name,
  8517. $this->util->stringify($this->value)
  8518. );
  8519. }
  8520. }
  8521. <?php
  8522. /*
  8523. * This file is part of the Prophecy.
  8524. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8525. * Marcello Duarte <marcello.duarte@gmail.com>
  8526. *
  8527. * For the full copyright and license information, please view the LICENSE
  8528. * file that was distributed with this source code.
  8529. */
  8530. namespace Prophecy\Argument\Token;
  8531. use Prophecy\Exception\InvalidArgumentException;
  8532. /**
  8533. * Callback-verified token.
  8534. *
  8535. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  8536. */
  8537. class CallbackToken implements TokenInterface
  8538. {
  8539. private $callback;
  8540. /**
  8541. * Initializes token.
  8542. *
  8543. * @param callable $callback
  8544. *
  8545. * @throws \Prophecy\Exception\InvalidArgumentException
  8546. */
  8547. public function __construct($callback)
  8548. {
  8549. if (!is_callable($callback)) {
  8550. throw new InvalidArgumentException(sprintf(
  8551. 'Callable expected as an argument to CallbackToken, but got %s.',
  8552. gettype($callback)
  8553. ));
  8554. }
  8555. $this->callback = $callback;
  8556. }
  8557. /**
  8558. * Scores 7 if callback returns true, false otherwise.
  8559. *
  8560. * @param $argument
  8561. *
  8562. * @return bool|int
  8563. */
  8564. public function scoreArgument($argument)
  8565. {
  8566. return call_user_func($this->callback, $argument) ? 7 : false;
  8567. }
  8568. /**
  8569. * Returns false.
  8570. *
  8571. * @return bool
  8572. */
  8573. public function isLast()
  8574. {
  8575. return false;
  8576. }
  8577. /**
  8578. * Returns string representation for token.
  8579. *
  8580. * @return string
  8581. */
  8582. public function __toString()
  8583. {
  8584. return 'callback()';
  8585. }
  8586. }
  8587. <?php
  8588. /*
  8589. * This file is part of the Prophecy.
  8590. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8591. * Marcello Duarte <marcello.duarte@gmail.com>
  8592. *
  8593. * For the full copyright and license information, please view the LICENSE
  8594. * file that was distributed with this source code.
  8595. */
  8596. namespace Prophecy\Argument\Token;
  8597. use Prophecy\Util\StringUtil;
  8598. /**
  8599. * Identical value token.
  8600. *
  8601. * @author Florian Voutzinos <florian@voutzinos.com>
  8602. */
  8603. class IdenticalValueToken implements TokenInterface
  8604. {
  8605. private $value;
  8606. private $string;
  8607. private $util;
  8608. /**
  8609. * Initializes token.
  8610. *
  8611. * @param mixed $value
  8612. * @param StringUtil $util
  8613. */
  8614. public function __construct($value, StringUtil $util = null)
  8615. {
  8616. $this->value = $value;
  8617. $this->util = $util ?: new StringUtil();
  8618. }
  8619. /**
  8620. * Scores 11 if argument matches preset value.
  8621. *
  8622. * @param $argument
  8623. *
  8624. * @return bool|int
  8625. */
  8626. public function scoreArgument($argument)
  8627. {
  8628. return $argument === $this->value ? 11 : false;
  8629. }
  8630. /**
  8631. * Returns false.
  8632. *
  8633. * @return bool
  8634. */
  8635. public function isLast()
  8636. {
  8637. return false;
  8638. }
  8639. /**
  8640. * Returns string representation for token.
  8641. *
  8642. * @return string
  8643. */
  8644. public function __toString()
  8645. {
  8646. if (null === $this->string) {
  8647. $this->string = sprintf('identical(%s)', $this->util->stringify($this->value));
  8648. }
  8649. return $this->string;
  8650. }
  8651. }
  8652. <?php
  8653. /*
  8654. * This file is part of the Prophecy.
  8655. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8656. * Marcello Duarte <marcello.duarte@gmail.com>
  8657. *
  8658. * For the full copyright and license information, please view the LICENSE
  8659. * file that was distributed with this source code.
  8660. */
  8661. namespace Prophecy\Argument\Token;
  8662. /**
  8663. * Logical NOT token.
  8664. *
  8665. * @author Boris Mikhaylov <kaguxmail@gmail.com>
  8666. */
  8667. class LogicalNotToken implements TokenInterface
  8668. {
  8669. /** @var \Prophecy\Argument\Token\TokenInterface */
  8670. private $token;
  8671. /**
  8672. * @param mixed $value exact value or token
  8673. */
  8674. public function __construct($value)
  8675. {
  8676. $this->token = $value instanceof TokenInterface? $value : new ExactValueToken($value);
  8677. }
  8678. /**
  8679. * Scores 4 when preset token does not match the argument.
  8680. *
  8681. * @param $argument
  8682. *
  8683. * @return bool|int
  8684. */
  8685. public function scoreArgument($argument)
  8686. {
  8687. return false === $this->token->scoreArgument($argument) ? 4 : false;
  8688. }
  8689. /**
  8690. * Returns true if preset token is last.
  8691. *
  8692. * @return bool|int
  8693. */
  8694. public function isLast()
  8695. {
  8696. return $this->token->isLast();
  8697. }
  8698. /**
  8699. * Returns originating token.
  8700. *
  8701. * @return TokenInterface
  8702. */
  8703. public function getOriginatingToken()
  8704. {
  8705. return $this->token;
  8706. }
  8707. /**
  8708. * Returns string representation for token.
  8709. *
  8710. * @return string
  8711. */
  8712. public function __toString()
  8713. {
  8714. return sprintf('not(%s)', $this->token);
  8715. }
  8716. }
  8717. <?php
  8718. /*
  8719. * This file is part of the Prophecy.
  8720. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8721. * Marcello Duarte <marcello.duarte@gmail.com>
  8722. *
  8723. * For the full copyright and license information, please view the LICENSE
  8724. * file that was distributed with this source code.
  8725. */
  8726. namespace Prophecy\Argument\Token;
  8727. use Prophecy\Exception\InvalidArgumentException;
  8728. /**
  8729. * Value type token.
  8730. *
  8731. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  8732. */
  8733. class TypeToken implements TokenInterface
  8734. {
  8735. private $type;
  8736. /**
  8737. * @param string $type
  8738. */
  8739. public function __construct($type)
  8740. {
  8741. $checker = "is_{$type}";
  8742. if (!function_exists($checker) && !interface_exists($type) && !class_exists($type)) {
  8743. throw new InvalidArgumentException(sprintf(
  8744. 'Type or class name expected as an argument to TypeToken, but got %s.', $type
  8745. ));
  8746. }
  8747. $this->type = $type;
  8748. }
  8749. /**
  8750. * Scores 5 if argument has the same type this token was constructed with.
  8751. *
  8752. * @param $argument
  8753. *
  8754. * @return bool|int
  8755. */
  8756. public function scoreArgument($argument)
  8757. {
  8758. $checker = "is_{$this->type}";
  8759. if (function_exists($checker)) {
  8760. return call_user_func($checker, $argument) ? 5 : false;
  8761. }
  8762. return $argument instanceof $this->type ? 5 : false;
  8763. }
  8764. /**
  8765. * Returns false.
  8766. *
  8767. * @return bool
  8768. */
  8769. public function isLast()
  8770. {
  8771. return false;
  8772. }
  8773. /**
  8774. * Returns string representation for token.
  8775. *
  8776. * @return string
  8777. */
  8778. public function __toString()
  8779. {
  8780. return sprintf('type(%s)', $this->type);
  8781. }
  8782. }
  8783. <?php
  8784. namespace Prophecy\Util;
  8785. use Prophecy\Prophecy\ProphecyInterface;
  8786. use SplObjectStorage;
  8787. /*
  8788. * This file is part of the Prophecy.
  8789. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8790. * Marcello Duarte <marcello.duarte@gmail.com>
  8791. *
  8792. * For the full copyright and license information, please view the LICENSE
  8793. * file that was distributed with this source code.
  8794. */
  8795. /**
  8796. * Exporting utility.
  8797. *
  8798. * This class is derived from the PHPUnit testing framework.
  8799. *
  8800. * @author Sebastiaan Stok <s.stok@rollerscapes.net
  8801. * @author Sebastian Bergmann <sebastian@phpunit.de>
  8802. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License>
  8803. */
  8804. class ExportUtil
  8805. {
  8806. /**
  8807. * Exports a value into a string.
  8808. *
  8809. * The output of this method is similar to the output of print_r(), but
  8810. * improved in various aspects:
  8811. *
  8812. * - NULL is rendered as "null" (instead of "")
  8813. * - true is rendered as "true" (instead of "1")
  8814. * - FALSE is rendered as "false" (instead of "")
  8815. * - Strings are always quoted with single quotes
  8816. * - Carriage returns and newlines are normalized to \n
  8817. * - Recursion and repeated rendering is treated properly
  8818. *
  8819. * @param mixed $value The value to export
  8820. * @param integer $indentation The indentation level of the 2nd+ line
  8821. *
  8822. * @return string
  8823. */
  8824. public static function export($value, $indentation = 0)
  8825. {
  8826. return static::recursiveExport($value, $indentation);
  8827. }
  8828. /**
  8829. * Converts an object to an array containing all of its private, protected
  8830. * and public properties.
  8831. *
  8832. * @param object $object
  8833. *
  8834. * @return array
  8835. */
  8836. public static function toArray($object)
  8837. {
  8838. $array = array();
  8839. foreach ((array) $object as $key => $value) {
  8840. // properties are transformed to keys in the following way:
  8841. // private $property => "\0Classname\0property"
  8842. // protected $property => "\0*\0property"
  8843. // public $property => "property"
  8844. if (preg_match('/^\0.+\0(.+)$/', $key, $matches)) {
  8845. $key = $matches[1];
  8846. }
  8847. $array[$key] = $value;
  8848. }
  8849. // Some internal classes like SplObjectStorage don't work with the
  8850. // above (fast) mechanism nor with reflection
  8851. // Format the output similarly to print_r() in this case
  8852. if ($object instanceof SplObjectStorage) {
  8853. foreach ($object as $key => $value) {
  8854. $array[spl_object_hash($value)] = array(
  8855. 'obj' => $value,
  8856. 'inf' => $object->getInfo(),
  8857. );
  8858. }
  8859. }
  8860. return $array;
  8861. }
  8862. /**
  8863. * Recursive implementation of export.
  8864. *
  8865. * @param mixed $value The value to export
  8866. * @param integer $indentation The indentation level of the 2nd+ line
  8867. * @param array $processedObjects Contains all objects that were already
  8868. * rendered
  8869. *
  8870. * @return string
  8871. */
  8872. protected static function recursiveExport($value, $indentation, &$processedObjects = array())
  8873. {
  8874. if ($value === null) {
  8875. return 'null';
  8876. }
  8877. if ($value === true) {
  8878. return 'true';
  8879. }
  8880. if ($value === false) {
  8881. return 'false';
  8882. }
  8883. if (is_string($value)) {
  8884. // Match for most non printable chars somewhat taking multibyte chars into account
  8885. if (preg_match('/[^\x09-\x0d\x20-\xff]/', $value)) {
  8886. return 'Binary String: 0x' . bin2hex($value);
  8887. }
  8888. return "'" . str_replace(array("\r\n", "\n\r", "\r"), array("\n", "\n", "\n"), $value) . "'";
  8889. }
  8890. $origValue = $value;
  8891. if (is_object($value)) {
  8892. if ($value instanceof ProphecyInterface) {
  8893. return sprintf('%s Object (*Prophecy*)', get_class($value));
  8894. } elseif (in_array($value, $processedObjects, true)) {
  8895. return sprintf('%s Object (*RECURSION*)', get_class($value));
  8896. }
  8897. $processedObjects[] = $value;
  8898. // Convert object to array
  8899. $value = self::toArray($value);
  8900. }
  8901. if (is_array($value)) {
  8902. $whitespace = str_repeat(' ', $indentation);
  8903. // There seems to be no other way to check arrays for recursion
  8904. // http://www.php.net/manual/en/language.types.array.php#73936
  8905. preg_match_all('/\n \[(\w+)\] => Array\s+\*RECURSION\*/', print_r($value, true), $matches);
  8906. $recursiveKeys = array_unique($matches[1]);
  8907. // Convert to valid array keys
  8908. // Numeric integer strings are automatically converted to integers
  8909. // by PHP
  8910. foreach ($recursiveKeys as $key => $recursiveKey) {
  8911. if ((string) (integer) $recursiveKey === $recursiveKey) {
  8912. $recursiveKeys[$key] = (integer) $recursiveKey;
  8913. }
  8914. }
  8915. $content = '';
  8916. foreach ($value as $key => $val) {
  8917. if (in_array($key, $recursiveKeys, true)) {
  8918. $val = 'Array (*RECURSION*)';
  8919. } else {
  8920. $val = self::recursiveExport($val, $indentation + 1, $processedObjects);
  8921. }
  8922. $content .= $whitespace . ' ' . self::export($key) . ' => ' . $val . "\n";
  8923. }
  8924. if (strlen($content) > 0) {
  8925. $content = "\n" . $content . $whitespace;
  8926. }
  8927. return sprintf(
  8928. "%s (%s)",
  8929. is_object($origValue) ? sprintf('%s:%s', get_class($origValue), spl_object_hash($origValue)) . ' Object' : 'Array', $content
  8930. );
  8931. }
  8932. if (is_double($value) && (double)(integer) $value === $value) {
  8933. return $value . '.0';
  8934. }
  8935. return (string) $value;
  8936. }
  8937. }
  8938. <?php
  8939. /*
  8940. * This file is part of the Prophecy.
  8941. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  8942. * Marcello Duarte <marcello.duarte@gmail.com>
  8943. *
  8944. * For the full copyright and license information, please view the LICENSE
  8945. * file that was distributed with this source code.
  8946. */
  8947. namespace Prophecy\Util;
  8948. use Prophecy\Call\Call;
  8949. /**
  8950. * String utility.
  8951. *
  8952. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  8953. */
  8954. class StringUtil
  8955. {
  8956. /**
  8957. * Stringifies any provided value.
  8958. *
  8959. * @param mixed $value
  8960. * @param boolean $exportObject
  8961. *
  8962. * @return string
  8963. */
  8964. public function stringify($value, $exportObject = true)
  8965. {
  8966. if (is_array($value)) {
  8967. if (range(0, count($value) - 1) === array_keys($value)) {
  8968. return '['.implode(', ', array_map(array($this, __FUNCTION__), $value)).']';
  8969. }
  8970. $stringify = array($this, __FUNCTION__);
  8971. return '['.implode(', ', array_map(function ($item, $key) use ($stringify) {
  8972. return (is_integer($key) ? $key : '"'.$key.'"').
  8973. ' => '.call_user_func($stringify, $item);
  8974. }, $value, array_keys($value))).']';
  8975. }
  8976. if (is_resource($value)) {
  8977. return get_resource_type($value).':'.$value;
  8978. }
  8979. if (is_object($value)) {
  8980. return $exportObject ? ExportUtil::export($value) : sprintf('%s:%s', get_class($value), spl_object_hash($value));
  8981. }
  8982. if (true === $value || false === $value) {
  8983. return $value ? 'true' : 'false';
  8984. }
  8985. if (is_string($value)) {
  8986. $str = sprintf('"%s"', str_replace("\n", '\\n', $value));
  8987. if (50 <= strlen($str)) {
  8988. return substr($str, 0, 50).'"...';
  8989. }
  8990. return $str;
  8991. }
  8992. if (null === $value) {
  8993. return 'null';
  8994. }
  8995. return (string) $value;
  8996. }
  8997. /**
  8998. * Stringifies provided array of calls.
  8999. *
  9000. * @param Call[] $calls Array of Call instances
  9001. *
  9002. * @return string
  9003. */
  9004. public function stringifyCalls(array $calls)
  9005. {
  9006. $self = $this;
  9007. return implode(PHP_EOL, array_map(function (Call $call) use ($self) {
  9008. return sprintf(' - %s(%s) @ %s',
  9009. $call->getMethodName(),
  9010. implode(', ', array_map(array($self, 'stringify'), $call->getArguments())),
  9011. str_replace(GETCWD().DIRECTORY_SEPARATOR, '', $call->getCallPlace())
  9012. );
  9013. }, $calls));
  9014. }
  9015. }
  9016. Exporter
  9017. Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  9018. All rights reserved.
  9019. Redistribution and use in source and binary forms, with or without
  9020. modification, are permitted provided that the following conditions
  9021. are met:
  9022. * Redistributions of source code must retain the above copyright
  9023. notice, this list of conditions and the following disclaimer.
  9024. * Redistributions in binary form must reproduce the above copyright
  9025. notice, this list of conditions and the following disclaimer in
  9026. the documentation and/or other materials provided with the
  9027. distribution.
  9028. * Neither the name of Sebastian Bergmann nor the names of his
  9029. contributors may be used to endorse or promote products derived
  9030. from this software without specific prior written permission.
  9031. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  9032. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  9033. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  9034. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  9035. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  9036. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  9037. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  9038. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  9039. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  9040. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  9041. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  9042. POSSIBILITY OF SUCH DAMAGE.
  9043. <?php
  9044. /*
  9045. * This file is part of the Exporter package.
  9046. *
  9047. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  9048. *
  9049. * For the full copyright and license information, please view the LICENSE
  9050. * file that was distributed with this source code.
  9051. */
  9052. namespace SebastianBergmann\Exporter;
  9053. use SebastianBergmann\RecursionContext\Context;
  9054. /**
  9055. * A nifty utility for visualizing PHP variables.
  9056. *
  9057. * <code>
  9058. * <?php
  9059. * use SebastianBergmann\Exporter\Exporter;
  9060. *
  9061. * $exporter = new Exporter;
  9062. * print $exporter->export(new Exception);
  9063. * </code>
  9064. *
  9065. * @package Exporter
  9066. * @author Sebastian Bergmann <sebastian@phpunit.de>
  9067. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  9068. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  9069. * @link https://github.com/sebastianbergmann/exporter
  9070. */
  9071. class Exporter
  9072. {
  9073. /**
  9074. * Exports a value as a string
  9075. *
  9076. * The output of this method is similar to the output of print_r(), but
  9077. * improved in various aspects:
  9078. *
  9079. * - NULL is rendered as "null" (instead of "")
  9080. * - TRUE is rendered as "true" (instead of "1")
  9081. * - FALSE is rendered as "false" (instead of "")
  9082. * - Strings are always quoted with single quotes
  9083. * - Carriage returns and newlines are normalized to \n
  9084. * - Recursion and repeated rendering is treated properly
  9085. *
  9086. * @param mixed $value
  9087. * @param integer $indentation The indentation level of the 2nd+ line
  9088. * @return string
  9089. */
  9090. public function export($value, $indentation = 0)
  9091. {
  9092. return $this->recursiveExport($value, $indentation);
  9093. }
  9094. /**
  9095. * @param mixed $data
  9096. * @param Context $context
  9097. * @return string
  9098. */
  9099. public function shortenedRecursiveExport(&$data, Context $context = null)
  9100. {
  9101. $result = array();
  9102. $exporter = new Exporter();
  9103. if (!$context) {
  9104. $context = new Context;
  9105. }
  9106. $context->add($data);
  9107. foreach ($data as $key => $value) {
  9108. if (is_array($value)) {
  9109. if ($context->contains($data[$key]) !== false) {
  9110. $result[] = '*RECURSION*';
  9111. }
  9112. else {
  9113. $result[] = sprintf(
  9114. 'array(%s)',
  9115. $this->shortenedRecursiveExport($data[$key], $context)
  9116. );
  9117. }
  9118. }
  9119. else {
  9120. $result[] = $exporter->shortenedExport($value);
  9121. }
  9122. }
  9123. return join(', ', $result);
  9124. }
  9125. /**
  9126. * Exports a value into a single-line string
  9127. *
  9128. * The output of this method is similar to the output of
  9129. * SebastianBergmann\Exporter\Exporter::export. This method guarantees
  9130. * thought that the result contains now newlines.
  9131. *
  9132. * Newlines are replaced by the visible string '\n'. Contents of arrays
  9133. * and objects (if any) are replaced by '...'.
  9134. *
  9135. * @param mixed $value
  9136. * @return string
  9137. * @see SebastianBergmann\Exporter\Exporter::export
  9138. */
  9139. public function shortenedExport($value)
  9140. {
  9141. if (is_string($value)) {
  9142. $string = $this->export($value);
  9143. if (strlen($string) > 40) {
  9144. $string = substr($string, 0, 30) . '...' . substr($string, -7);
  9145. }
  9146. return str_replace("\n", '\n', $string);
  9147. }
  9148. if (is_object($value)) {
  9149. return sprintf(
  9150. '%s Object (%s)',
  9151. get_class($value),
  9152. count($this->toArray($value)) > 0 ? '...' : ''
  9153. );
  9154. }
  9155. if (is_array($value)) {
  9156. return sprintf(
  9157. 'Array (%s)',
  9158. count($value) > 0 ? '...' : ''
  9159. );
  9160. }
  9161. return $this->export($value);
  9162. }
  9163. /**
  9164. * Converts an object to an array containing all of its private, protected
  9165. * and public properties.
  9166. *
  9167. * @param mixed $value
  9168. * @return array
  9169. */
  9170. public function toArray($value)
  9171. {
  9172. if (!is_object($value)) {
  9173. return (array)$value;
  9174. }
  9175. $array = array();
  9176. foreach ((array)$value as $key => $val) {
  9177. // properties are transformed to keys in the following way:
  9178. // private $property => "\0Classname\0property"
  9179. // protected $property => "\0*\0property"
  9180. // public $property => "property"
  9181. if (preg_match('/^\0.+\0(.+)$/', $key, $matches)) {
  9182. $key = $matches[1];
  9183. }
  9184. // See https://github.com/php/php-src/commit/5721132
  9185. if ($key === "\0gcdata") {
  9186. continue;
  9187. }
  9188. $array[$key] = $val;
  9189. }
  9190. // Some internal classes like SplObjectStorage don't work with the
  9191. // above (fast) mechanism nor with reflection in Zend.
  9192. // Format the output similarly to print_r() in this case
  9193. if ($value instanceof \SplObjectStorage) {
  9194. // However, the fast method does work in HHVM, and exposes the
  9195. // internal implementation. Hide it again.
  9196. if (property_exists('\SplObjectStorage', '__storage')) {
  9197. unset($array['__storage']);
  9198. } elseif (property_exists('\SplObjectStorage', 'storage')) {
  9199. unset($array['storage']);
  9200. }
  9201. if (property_exists('\SplObjectStorage', '__key')) {
  9202. unset($array['__key']);
  9203. }
  9204. foreach ($value as $key => $val) {
  9205. $array[spl_object_hash($val)] = array(
  9206. 'obj' => $val,
  9207. 'inf' => $value->getInfo(),
  9208. );
  9209. }
  9210. }
  9211. return $array;
  9212. }
  9213. /**
  9214. * Recursive implementation of export
  9215. *
  9216. * @param mixed $value The value to export
  9217. * @param integer $indentation The indentation level of the 2nd+ line
  9218. * @param \SebastianBergmann\RecursionContext\Context $processed Previously processed objects
  9219. * @return string
  9220. * @see SebastianBergmann\Exporter\Exporter::export
  9221. */
  9222. protected function recursiveExport(&$value, $indentation, $processed = null)
  9223. {
  9224. if ($value === null) {
  9225. return 'null';
  9226. }
  9227. if ($value === true) {
  9228. return 'true';
  9229. }
  9230. if ($value === false) {
  9231. return 'false';
  9232. }
  9233. if (is_float($value) && floatval(intval($value)) === $value) {
  9234. return "$value.0";
  9235. }
  9236. if (is_resource($value)) {
  9237. return sprintf(
  9238. 'resource(%d) of type (%s)',
  9239. $value,
  9240. get_resource_type($value)
  9241. );
  9242. }
  9243. if (is_string($value)) {
  9244. // Match for most non printable chars somewhat taking multibyte chars into account
  9245. if (preg_match('/[^\x09-\x0d\x20-\xff]/', $value)) {
  9246. return 'Binary String: 0x' . bin2hex($value);
  9247. }
  9248. return "'" .
  9249. str_replace(array("\r\n", "\n\r", "\r"), array("\n", "\n", "\n"), $value) .
  9250. "'";
  9251. }
  9252. $whitespace = str_repeat(' ', 4 * $indentation);
  9253. if (!$processed) {
  9254. $processed = new Context;
  9255. }
  9256. if (is_array($value)) {
  9257. if (($key = $processed->contains($value)) !== false) {
  9258. return 'Array &' . $key;
  9259. }
  9260. $key = $processed->add($value);
  9261. $values = '';
  9262. if (count($value) > 0) {
  9263. foreach ($value as $k => $v) {
  9264. $values .= sprintf(
  9265. '%s %s => %s' . "\n",
  9266. $whitespace,
  9267. $this->recursiveExport($k, $indentation),
  9268. $this->recursiveExport($value[$k], $indentation + 1, $processed)
  9269. );
  9270. }
  9271. $values = "\n" . $values . $whitespace;
  9272. }
  9273. return sprintf('Array &%s (%s)', $key, $values);
  9274. }
  9275. if (is_object($value)) {
  9276. $class = get_class($value);
  9277. if ($hash = $processed->contains($value)) {
  9278. return sprintf('%s Object &%s', $class, $hash);
  9279. }
  9280. $hash = $processed->add($value);
  9281. $values = '';
  9282. $array = $this->toArray($value);
  9283. if (count($array) > 0) {
  9284. foreach ($array as $k => $v) {
  9285. $values .= sprintf(
  9286. '%s %s => %s' . "\n",
  9287. $whitespace,
  9288. $this->recursiveExport($k, $indentation),
  9289. $this->recursiveExport($v, $indentation + 1, $processed)
  9290. );
  9291. }
  9292. $values = "\n" . $values . $whitespace;
  9293. }
  9294. return sprintf('%s Object &%s (%s)', $class, $hash, $values);
  9295. }
  9296. return var_export($value, true);
  9297. }
  9298. }
  9299. File_Iterator
  9300. Copyright (c) 2009-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  9301. All rights reserved.
  9302. Redistribution and use in source and binary forms, with or without
  9303. modification, are permitted provided that the following conditions
  9304. are met:
  9305. * Redistributions of source code must retain the above copyright
  9306. notice, this list of conditions and the following disclaimer.
  9307. * Redistributions in binary form must reproduce the above copyright
  9308. notice, this list of conditions and the following disclaimer in
  9309. the documentation and/or other materials provided with the
  9310. distribution.
  9311. * Neither the name of Sebastian Bergmann nor the names of his
  9312. contributors may be used to endorse or promote products derived
  9313. from this software without specific prior written permission.
  9314. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  9315. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  9316. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  9317. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  9318. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  9319. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  9320. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  9321. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  9322. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  9323. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  9324. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  9325. POSSIBILITY OF SUCH DAMAGE.
  9326. <?php
  9327. /*
  9328. * This file is part of the File_Iterator package.
  9329. *
  9330. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  9331. *
  9332. * For the full copyright and license information, please view the LICENSE
  9333. * file that was distributed with this source code.
  9334. */
  9335. /**
  9336. * FilterIterator implementation that filters files based on prefix(es) and/or
  9337. * suffix(es). Hidden files and files from hidden directories are also filtered.
  9338. *
  9339. * @author Sebastian Bergmann <sebastian@phpunit.de>
  9340. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  9341. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  9342. * @version Release: @package_version@
  9343. * @link http://github.com/sebastianbergmann/php-file-iterator/tree
  9344. * @since Class available since Release 1.0.0
  9345. */
  9346. class File_Iterator extends FilterIterator
  9347. {
  9348. const PREFIX = 0;
  9349. const SUFFIX = 1;
  9350. /**
  9351. * @var array
  9352. */
  9353. protected $suffixes = array();
  9354. /**
  9355. * @var array
  9356. */
  9357. protected $prefixes = array();
  9358. /**
  9359. * @var array
  9360. */
  9361. protected $exclude = array();
  9362. /**
  9363. * @var string
  9364. */
  9365. protected $basepath;
  9366. /**
  9367. * @param Iterator $iterator
  9368. * @param array $suffixes
  9369. * @param array $prefixes
  9370. * @param array $exclude
  9371. * @param string $basepath
  9372. */
  9373. public function __construct(Iterator $iterator, array $suffixes = array(), array $prefixes = array(), array $exclude = array(), $basepath = NULL)
  9374. {
  9375. $exclude = array_filter(array_map('realpath', $exclude));
  9376. if ($basepath !== NULL) {
  9377. $basepath = realpath($basepath);
  9378. }
  9379. if ($basepath === FALSE) {
  9380. $basepath = NULL;
  9381. } else {
  9382. foreach ($exclude as &$_exclude) {
  9383. $_exclude = str_replace($basepath, '', $_exclude);
  9384. }
  9385. }
  9386. $this->prefixes = $prefixes;
  9387. $this->suffixes = $suffixes;
  9388. $this->exclude = $exclude;
  9389. $this->basepath = $basepath;
  9390. parent::__construct($iterator);
  9391. }
  9392. /**
  9393. * @return boolean
  9394. */
  9395. public function accept()
  9396. {
  9397. $current = $this->getInnerIterator()->current();
  9398. $filename = $current->getFilename();
  9399. $realpath = $current->getRealPath();
  9400. if ($this->basepath !== NULL) {
  9401. $realpath = str_replace($this->basepath, '', $realpath);
  9402. }
  9403. // Filter files in hidden directories.
  9404. if (preg_match('=/\.[^/]*/=', $realpath)) {
  9405. return FALSE;
  9406. }
  9407. return $this->acceptPath($realpath) &&
  9408. $this->acceptPrefix($filename) &&
  9409. $this->acceptSuffix($filename);
  9410. }
  9411. /**
  9412. * @param string $path
  9413. * @return boolean
  9414. * @since Method available since Release 1.1.0
  9415. */
  9416. protected function acceptPath($path)
  9417. {
  9418. foreach ($this->exclude as $exclude) {
  9419. if (strpos($path, $exclude) === 0) {
  9420. return FALSE;
  9421. }
  9422. }
  9423. return TRUE;
  9424. }
  9425. /**
  9426. * @param string $filename
  9427. * @return boolean
  9428. * @since Method available since Release 1.1.0
  9429. */
  9430. protected function acceptPrefix($filename)
  9431. {
  9432. return $this->acceptSubString($filename, $this->prefixes, self::PREFIX);
  9433. }
  9434. /**
  9435. * @param string $filename
  9436. * @return boolean
  9437. * @since Method available since Release 1.1.0
  9438. */
  9439. protected function acceptSuffix($filename)
  9440. {
  9441. return $this->acceptSubString($filename, $this->suffixes, self::SUFFIX);
  9442. }
  9443. /**
  9444. * @param string $filename
  9445. * @param array $subString
  9446. * @param integer $type
  9447. * @return boolean
  9448. * @since Method available since Release 1.1.0
  9449. */
  9450. protected function acceptSubString($filename, array $subStrings, $type)
  9451. {
  9452. if (empty($subStrings)) {
  9453. return TRUE;
  9454. }
  9455. $matched = FALSE;
  9456. foreach ($subStrings as $string) {
  9457. if (($type == self::PREFIX && strpos($filename, $string) === 0) ||
  9458. ($type == self::SUFFIX &&
  9459. substr($filename, -1 * strlen($string)) == $string)) {
  9460. $matched = TRUE;
  9461. break;
  9462. }
  9463. }
  9464. return $matched;
  9465. }
  9466. }
  9467. <?php
  9468. /*
  9469. * This file is part of the File_Iterator package.
  9470. *
  9471. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  9472. *
  9473. * For the full copyright and license information, please view the LICENSE
  9474. * file that was distributed with this source code.
  9475. */
  9476. /**
  9477. * Façade implementation that uses File_Iterator_Factory to create a
  9478. * File_Iterator that operates on an AppendIterator that contains an
  9479. * RecursiveDirectoryIterator for each given path. The list of unique
  9480. * files is returned as an array.
  9481. *
  9482. * @author Sebastian Bergmann <sebastian@phpunit.de>
  9483. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  9484. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  9485. * @version Release: @package_version@
  9486. * @link http://github.com/sebastianbergmann/php-file-iterator/tree
  9487. * @since Class available since Release 1.3.0
  9488. */
  9489. class File_Iterator_Facade
  9490. {
  9491. /**
  9492. * @param array|string $paths
  9493. * @param array|string $suffixes
  9494. * @param array|string $prefixes
  9495. * @param array $exclude
  9496. * @param boolean $commonPath
  9497. * @return array
  9498. */
  9499. public function getFilesAsArray($paths, $suffixes = '', $prefixes = '', array $exclude = array(), $commonPath = FALSE)
  9500. {
  9501. if (is_string($paths)) {
  9502. $paths = array($paths);
  9503. }
  9504. $factory = new File_Iterator_Factory;
  9505. $iterator = $factory->getFileIterator(
  9506. $paths, $suffixes, $prefixes, $exclude
  9507. );
  9508. $files = array();
  9509. foreach ($iterator as $file) {
  9510. $file = $file->getRealPath();
  9511. if ($file) {
  9512. $files[] = $file;
  9513. }
  9514. }
  9515. foreach ($paths as $path) {
  9516. if (is_file($path)) {
  9517. $files[] = realpath($path);
  9518. }
  9519. }
  9520. $files = array_unique($files);
  9521. sort($files);
  9522. if ($commonPath) {
  9523. return array(
  9524. 'commonPath' => $this->getCommonPath($files),
  9525. 'files' => $files
  9526. );
  9527. } else {
  9528. return $files;
  9529. }
  9530. }
  9531. /**
  9532. * Returns the common path of a set of files.
  9533. *
  9534. * @param array $files
  9535. * @return string
  9536. */
  9537. protected function getCommonPath(array $files)
  9538. {
  9539. $count = count($files);
  9540. if ($count == 0) {
  9541. return '';
  9542. }
  9543. if ($count == 1) {
  9544. return dirname($files[0]) . DIRECTORY_SEPARATOR;
  9545. }
  9546. $_files = array();
  9547. foreach ($files as $file) {
  9548. $_files[] = $_fileParts = explode(DIRECTORY_SEPARATOR, $file);
  9549. if (empty($_fileParts[0])) {
  9550. $_fileParts[0] = DIRECTORY_SEPARATOR;
  9551. }
  9552. }
  9553. $common = '';
  9554. $done = FALSE;
  9555. $j = 0;
  9556. $count--;
  9557. while (!$done) {
  9558. for ($i = 0; $i < $count; $i++) {
  9559. if ($_files[$i][$j] != $_files[$i+1][$j]) {
  9560. $done = TRUE;
  9561. break;
  9562. }
  9563. }
  9564. if (!$done) {
  9565. $common .= $_files[0][$j];
  9566. if ($j > 0) {
  9567. $common .= DIRECTORY_SEPARATOR;
  9568. }
  9569. }
  9570. $j++;
  9571. }
  9572. return DIRECTORY_SEPARATOR . $common;
  9573. }
  9574. }
  9575. <?php
  9576. /*
  9577. * This file is part of the File_Iterator package.
  9578. *
  9579. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  9580. *
  9581. * For the full copyright and license information, please view the LICENSE
  9582. * file that was distributed with this source code.
  9583. */
  9584. /**
  9585. * Factory Method implementation that creates a File_Iterator that operates on
  9586. * an AppendIterator that contains an RecursiveDirectoryIterator for each given
  9587. * path.
  9588. *
  9589. * @author Sebastian Bergmann <sebastian@phpunit.de>
  9590. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  9591. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  9592. * @version Release: @package_version@
  9593. * @link http://github.com/sebastianbergmann/php-file-iterator/tree
  9594. * @since Class available since Release 1.1.0
  9595. */
  9596. class File_Iterator_Factory
  9597. {
  9598. /**
  9599. * @param array|string $paths
  9600. * @param array|string $suffixes
  9601. * @param array|string $prefixes
  9602. * @param array $exclude
  9603. * @return AppendIterator
  9604. */
  9605. public function getFileIterator($paths, $suffixes = '', $prefixes = '', array $exclude = array())
  9606. {
  9607. if (is_string($paths)) {
  9608. $paths = array($paths);
  9609. }
  9610. $paths = $this->getPathsAfterResolvingWildcards($paths);
  9611. $exclude = $this->getPathsAfterResolvingWildcards($exclude);
  9612. if (is_string($prefixes)) {
  9613. if ($prefixes != '') {
  9614. $prefixes = array($prefixes);
  9615. } else {
  9616. $prefixes = array();
  9617. }
  9618. }
  9619. if (is_string($suffixes)) {
  9620. if ($suffixes != '') {
  9621. $suffixes = array($suffixes);
  9622. } else {
  9623. $suffixes = array();
  9624. }
  9625. }
  9626. $iterator = new AppendIterator;
  9627. foreach ($paths as $path) {
  9628. if (is_dir($path)) {
  9629. $iterator->append(
  9630. new File_Iterator(
  9631. new RecursiveIteratorIterator(
  9632. new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::FOLLOW_SYMLINKS)
  9633. ),
  9634. $suffixes,
  9635. $prefixes,
  9636. $exclude,
  9637. $path
  9638. )
  9639. );
  9640. }
  9641. }
  9642. return $iterator;
  9643. }
  9644. /**
  9645. * @param array $paths
  9646. * @return array
  9647. */
  9648. protected function getPathsAfterResolvingWildcards(array $paths)
  9649. {
  9650. $_paths = array();
  9651. foreach ($paths as $path) {
  9652. if ($locals = glob($path, GLOB_ONLYDIR)) {
  9653. $_paths = array_merge($_paths, $locals);
  9654. } else {
  9655. $_paths[] = $path;
  9656. }
  9657. }
  9658. return $_paths;
  9659. }
  9660. }
  9661. phpunit/phpunit: 4.7.7
  9662. doctrine/instantiator: 1.0.5
  9663. phpdocumentor/reflection-docblock: 2.0.4
  9664. phpspec/prophecy: v1.4.1
  9665. phpunit/dbunit: 1.4.0
  9666. phpunit/php-code-coverage: 2.1.8
  9667. phpunit/php-file-iterator: 1.4.0
  9668. phpunit/php-invoker: 1.1.4
  9669. phpunit/php-text-template: 1.2.1
  9670. phpunit/php-timer: 1.0.6
  9671. phpunit/php-token-stream: 1.4.3
  9672. phpunit/phpunit-mock-objects: 2.3.5
  9673. phpunit/phpunit-selenium: 1.4.2
  9674. sebastian/comparator: 1.1.1
  9675. sebastian/diff: 1.3.0
  9676. sebastian/environment: 1.2.2
  9677. sebastian/exporter: 1.2.0
  9678. sebastian/global-state: 1.0.0
  9679. sebastian/recursion-context: 1.0.0
  9680. sebastian/version: 1.0.6
  9681. symfony/yaml: v2.7.1
  9682. <?php
  9683. /*
  9684. * This file is part of the Recursion Context package.
  9685. *
  9686. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  9687. *
  9688. * For the full copyright and license information, please view the LICENSE
  9689. * file that was distributed with this source code.
  9690. */
  9691. namespace SebastianBergmann\RecursionContext;
  9692. /**
  9693. * @author Sebastian Bergmann <sebastian@phpunit.de>
  9694. * @author Adam Harvey <aharvey@php.net>
  9695. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  9696. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  9697. * @link https://github.com/sebastianbergmann/recursion-context
  9698. */
  9699. interface Exception
  9700. {
  9701. }
  9702. Recursion Context
  9703. Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  9704. All rights reserved.
  9705. Redistribution and use in source and binary forms, with or without
  9706. modification, are permitted provided that the following conditions
  9707. are met:
  9708. * Redistributions of source code must retain the above copyright
  9709. notice, this list of conditions and the following disclaimer.
  9710. * Redistributions in binary form must reproduce the above copyright
  9711. notice, this list of conditions and the following disclaimer in
  9712. the documentation and/or other materials provided with the
  9713. distribution.
  9714. * Neither the name of Sebastian Bergmann nor the names of his
  9715. contributors may be used to endorse or promote products derived
  9716. from this software without specific prior written permission.
  9717. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  9718. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  9719. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  9720. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  9721. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  9722. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  9723. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  9724. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  9725. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  9726. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  9727. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  9728. POSSIBILITY OF SUCH DAMAGE.
  9729. <?php
  9730. /*
  9731. * This file is part of the Recursion Context package.
  9732. *
  9733. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  9734. *
  9735. * For the full copyright and license information, please view the LICENSE
  9736. * file that was distributed with this source code.
  9737. */
  9738. namespace SebastianBergmann\RecursionContext;
  9739. /**
  9740. * A context containing previously processed arrays and objects
  9741. * when recursively processing a value.
  9742. *
  9743. * @author Sebastian Bergmann <sebastian@phpunit.de>
  9744. * @author Adam Harvey <aharvey@php.net>
  9745. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  9746. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  9747. * @link https://github.com/sebastianbergmann/recursion-context
  9748. */
  9749. final class Context
  9750. {
  9751. /**
  9752. * @var array[]
  9753. */
  9754. private $arrays;
  9755. /**
  9756. * @var \SplObjectStorage
  9757. */
  9758. private $objects;
  9759. /**
  9760. * Initialises the context
  9761. */
  9762. public function __construct()
  9763. {
  9764. $this->arrays = array();
  9765. $this->objects = new \SplObjectStorage;
  9766. }
  9767. /**
  9768. * Adds a value to the context.
  9769. *
  9770. * @param array|object $value The value to add.
  9771. * @return integer|string The ID of the stored value, either as
  9772. * a string or integer.
  9773. * @throws InvalidArgumentException Thrown if $value is not an array or
  9774. * object
  9775. */
  9776. public function add(&$value)
  9777. {
  9778. if (is_array($value)) {
  9779. return $this->addArray($value);
  9780. }
  9781. else if (is_object($value)) {
  9782. return $this->addObject($value);
  9783. }
  9784. throw new InvalidArgumentException(
  9785. 'Only arrays and objects are supported'
  9786. );
  9787. }
  9788. /**
  9789. * Checks if the given value exists within the context.
  9790. *
  9791. * @param array|object $value The value to check.
  9792. * @return integer|string|false The string or integer ID of the stored
  9793. * value if it has already been seen, or
  9794. * false if the value is not stored.
  9795. * @throws InvalidArgumentException Thrown if $value is not an array or
  9796. * object
  9797. */
  9798. public function contains(&$value)
  9799. {
  9800. if (is_array($value)) {
  9801. return $this->containsArray($value);
  9802. }
  9803. else if (is_object($value)) {
  9804. return $this->containsObject($value);
  9805. }
  9806. throw new InvalidArgumentException(
  9807. 'Only arrays and objects are supported'
  9808. );
  9809. }
  9810. /**
  9811. * @param array $array
  9812. * @return bool|int
  9813. */
  9814. private function addArray(array &$array)
  9815. {
  9816. $key = $this->containsArray($array);
  9817. if ($key !== false) {
  9818. return $key;
  9819. }
  9820. $this->arrays[] = &$array;
  9821. return count($this->arrays) - 1;
  9822. }
  9823. /**
  9824. * @param object $object
  9825. * @return string
  9826. */
  9827. private function addObject($object)
  9828. {
  9829. if (!$this->objects->contains($object)) {
  9830. $this->objects->attach($object);
  9831. }
  9832. return spl_object_hash($object);
  9833. }
  9834. /**
  9835. * @param array $array
  9836. * @return integer|false
  9837. */
  9838. private function containsArray(array &$array)
  9839. {
  9840. $keys = array_keys($this->arrays, $array, true);
  9841. $hash = '_Key_' . hash('sha512', microtime(true));
  9842. foreach ($keys as $key) {
  9843. $this->arrays[$key][$hash] = $hash;
  9844. if (isset($array[$hash]) && $array[$hash] === $hash) {
  9845. unset($this->arrays[$key][$hash]);
  9846. return $key;
  9847. }
  9848. unset($this->arrays[$key][$hash]);
  9849. }
  9850. return false;
  9851. }
  9852. /**
  9853. * @param object $value
  9854. * @return string|false
  9855. */
  9856. private function containsObject($value)
  9857. {
  9858. if ($this->objects->contains($value)) {
  9859. return spl_object_hash($value);
  9860. }
  9861. return false;
  9862. }
  9863. }
  9864. <?php
  9865. /*
  9866. * This file is part of the Recursion Context package.
  9867. *
  9868. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  9869. *
  9870. * For the full copyright and license information, please view the LICENSE
  9871. * file that was distributed with this source code.
  9872. */
  9873. namespace SebastianBergmann\RecursionContext;
  9874. /**
  9875. * @author Sebastian Bergmann <sebastian@phpunit.de>
  9876. * @author Adam Harvey <aharvey@php.net>
  9877. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  9878. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  9879. * @link https://github.com/sebastianbergmann/recursion-context
  9880. */
  9881. final class InvalidArgumentException extends \InvalidArgumentException implements Exception
  9882. {
  9883. }
  9884. <?php
  9885. /**
  9886. * PHPUnit
  9887. *
  9888. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  9889. * All rights reserved.
  9890. *
  9891. * Redistribution and use in source and binary forms, with or without
  9892. * modification, are permitted provided that the following conditions
  9893. * are met:
  9894. *
  9895. * * Redistributions of source code must retain the above copyright
  9896. * notice, this list of conditions and the following disclaimer.
  9897. *
  9898. * * Redistributions in binary form must reproduce the above copyright
  9899. * notice, this list of conditions and the following disclaimer in
  9900. * the documentation and/or other materials provided with the
  9901. * distribution.
  9902. *
  9903. * * Neither the name of Sebastian Bergmann nor the names of his
  9904. * contributors may be used to endorse or promote products derived
  9905. * from this software without specific prior written permission.
  9906. *
  9907. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  9908. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  9909. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  9910. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  9911. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  9912. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  9913. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  9914. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  9915. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  9916. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  9917. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  9918. * POSSIBILITY OF SUCH DAMAGE.
  9919. *
  9920. * @package PHPUnit_Selenium
  9921. * @author Sebastian Bergmann <sebastian@phpunit.de>
  9922. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  9923. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  9924. * @link http://www.phpunit.de/
  9925. * @since File available since Release 1.0.0
  9926. */
  9927. /**
  9928. * TestCase class that uses Selenium to provide
  9929. * the functionality required for web testing.
  9930. *
  9931. * @package PHPUnit_Selenium
  9932. * @author Sebastian Bergmann <sebastian@phpunit.de>
  9933. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  9934. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  9935. * @version Release: @package_version@
  9936. * @link http://www.phpunit.de/
  9937. * @since Class available since Release 1.0.0
  9938. *
  9939. * @method unknown addLocationStrategy()
  9940. * @method unknown addLocationStrategyAndWait()
  9941. * @method unknown addScript()
  9942. * @method unknown addScriptAndWait()
  9943. * @method unknown addSelection()
  9944. * @method unknown addSelectionAndWait()
  9945. * @method unknown allowNativeXpath()
  9946. * @method unknown allowNativeXpathAndWait()
  9947. * @method unknown altKeyDown()
  9948. * @method unknown altKeyDownAndWait()
  9949. * @method unknown altKeyUp()
  9950. * @method unknown altKeyUpAndWait()
  9951. * @method unknown answerOnNextPrompt()
  9952. * @method unknown assignId()
  9953. * @method unknown assignIdAndWait()
  9954. * @method unknown assertAlert
  9955. * @method unknown assertAlertNotPresent
  9956. * @method unknown assertAlertPresent
  9957. * @method unknown assertAllButtons
  9958. * @method unknown assertAllFields
  9959. * @method unknown assertAllLinks
  9960. * @method unknown assertAllWindowIds
  9961. * @method unknown assertAllWindowNames
  9962. * @method unknown assertAllWindowTitles
  9963. * @method unknown assertAttribute
  9964. * @method unknown assertAttributeFromAllWindows
  9965. * @method unknown assertBodyText
  9966. * @method unknown assertChecked
  9967. * @method unknown assertConfirmation
  9968. * @method unknown assertConfirmationNotPresent
  9969. * @method unknown assertConfirmationPresent
  9970. * @method unknown assertCookie
  9971. * @method unknown assertCookieByName
  9972. * @method unknown assertCookieNotPresent
  9973. * @method unknown assertCookiePresent
  9974. * @method unknown assertCssCount
  9975. * @method unknown assertCursorPosition
  9976. * @method unknown assertEditable
  9977. * @method unknown assertElementHeight
  9978. * @method unknown assertElementIndex
  9979. * @method unknown assertElementNotPresent
  9980. * @method unknown assertElementPositionLeft
  9981. * @method unknown assertElementPositionTop
  9982. * @method unknown assertElementPresent
  9983. * @method unknown assertElementWidth
  9984. * @method unknown assertEval
  9985. * @method unknown assertExpression
  9986. * @method unknown assertHtmlSource
  9987. * @method unknown assertLocation
  9988. * @method unknown assertLogMessages
  9989. * @method unknown assertMouseSpeed
  9990. * @method unknown assertNotAlert
  9991. * @method unknown assertNotAllButtons
  9992. * @method unknown assertNotAllFields
  9993. * @method unknown assertNotAllLinks
  9994. * @method unknown assertNotAllWindowIds
  9995. * @method unknown assertNotAllWindowNames
  9996. * @method unknown assertNotAllWindowTitles
  9997. * @method unknown assertNotAttribute
  9998. * @method unknown assertNotAttributeFromAllWindows
  9999. * @method unknown assertNotBodyText
  10000. * @method unknown assertNotChecked
  10001. * @method unknown assertNotConfirmation
  10002. * @method unknown assertNotCookie
  10003. * @method unknown assertNotCookieByName
  10004. * @method unknown assertNotCssCount
  10005. * @method unknown assertNotCursorPosition
  10006. * @method unknown assertNotEditable
  10007. * @method unknown assertNotElementHeight
  10008. * @method unknown assertNotElementIndex
  10009. * @method unknown assertNotElementPositionLeft
  10010. * @method unknown assertNotElementPositionTop
  10011. * @method unknown assertNotElementWidth
  10012. * @method unknown assertNotEval
  10013. * @method unknown assertNotExpression
  10014. * @method unknown assertNotHtmlSource
  10015. * @method unknown assertNotLocation
  10016. * @method unknown assertNotLogMessages
  10017. * @method unknown assertNotMouseSpeed
  10018. * @method unknown assertNotOrdered
  10019. * @method unknown assertNotPrompt
  10020. * @method unknown assertNotSelectOptions
  10021. * @method unknown assertNotSelectedId
  10022. * @method unknown assertNotSelectedIds
  10023. * @method unknown assertNotSelectedIndex
  10024. * @method unknown assertNotSelectedIndexes
  10025. * @method unknown assertNotSelectedLabel
  10026. * @method unknown assertNotSelectedLabels
  10027. * @method unknown assertNotSelectedValue
  10028. * @method unknown assertNotSelectedValues
  10029. * @method unknown assertNotSomethingSelected
  10030. * @method unknown assertNotSpeed
  10031. * @method unknown assertNotSpeedAndWait
  10032. * @method unknown assertNotTable
  10033. * @method unknown assertNotText
  10034. * @method unknown assertNotTitle
  10035. * @method unknown assertNotValue
  10036. * @method unknown assertNotVisible
  10037. * @method unknown assertNotWhetherThisFrameMatchFrameExpression
  10038. * @method unknown assertNotWhetherThisWindowMatchWindowExpression
  10039. * @method unknown assertNotXpathCount
  10040. * @method unknown assertOrdered
  10041. * @method unknown assertPrompt
  10042. * @method unknown assertPromptNotPresent
  10043. * @method unknown assertPromptPresent
  10044. * @method unknown assertSelectOptions
  10045. * @method unknown assertSelectedId
  10046. * @method unknown assertSelectedIds
  10047. * @method unknown assertSelectedIndex
  10048. * @method unknown assertSelectedIndexes
  10049. * @method unknown assertSelectedLabel
  10050. * @method unknown assertSelectedLabels
  10051. * @method unknown assertSelectedValue
  10052. * @method unknown assertSelectedValues
  10053. * @method unknown assertSomethingSelected
  10054. * @method unknown assertSpeed
  10055. * @method unknown assertSpeedAndWait
  10056. * @method unknown assertTable
  10057. * @method unknown assertText
  10058. * @method unknown assertTextNotPresent
  10059. * @method unknown assertTextPresent
  10060. * @method unknown assertTitle
  10061. * @method unknown assertValue
  10062. * @method unknown assertVisible
  10063. * @method unknown assertWhetherThisFrameMatchFrameExpression
  10064. * @method unknown assertWhetherThisWindowMatchWindowExpression
  10065. * @method unknown assertXpathCount
  10066. * @method unknown attachFile()
  10067. * @method unknown break()
  10068. * @method unknown captureEntirePageScreenshot()
  10069. * @method unknown captureEntirePageScreenshotAndWait()
  10070. * @method unknown captureEntirePageScreenshotToStringAndWait()
  10071. * @method unknown captureScreenshotAndWait()
  10072. * @method unknown captureScreenshotToStringAndWait()
  10073. * @method unknown check()
  10074. * @method unknown checkAndWait()
  10075. * @method unknown chooseCancelOnNextConfirmation()
  10076. * @method unknown chooseCancelOnNextConfirmationAndWait()
  10077. * @method unknown chooseOkOnNextConfirmation()
  10078. * @method unknown chooseOkOnNextConfirmationAndWait()
  10079. * @method unknown click()
  10080. * @method unknown clickAndWait()
  10081. * @method unknown clickAt()
  10082. * @method unknown clickAtAndWait()
  10083. * @method unknown close()
  10084. * @method unknown contextMenu()
  10085. * @method unknown contextMenuAndWait()
  10086. * @method unknown contextMenuAt()
  10087. * @method unknown contextMenuAtAndWait()
  10088. * @method unknown controlKeyDown()
  10089. * @method unknown controlKeyDownAndWait()
  10090. * @method unknown controlKeyUp()
  10091. * @method unknown controlKeyUpAndWait()
  10092. * @method unknown createCookie()
  10093. * @method unknown createCookieAndWait()
  10094. * @method unknown deleteAllVisibleCookies()
  10095. * @method unknown deleteAllVisibleCookiesAndWait()
  10096. * @method unknown deleteCookie()
  10097. * @method unknown deleteCookieAndWait()
  10098. * @method unknown deselectPopUp()
  10099. * @method unknown deselectPopUpAndWait()
  10100. * @method unknown doubleClick()
  10101. * @method unknown doubleClickAndWait()
  10102. * @method unknown doubleClickAt()
  10103. * @method unknown doubleClickAtAndWait()
  10104. * @method unknown dragAndDrop()
  10105. * @method unknown dragAndDropAndWait()
  10106. * @method unknown dragAndDropToObject()
  10107. * @method unknown dragAndDropToObjectAndWait()
  10108. * @method unknown dragDrop()
  10109. * @method unknown dragDropAndWait()
  10110. * @method unknown echo()
  10111. * @method unknown fireEvent()
  10112. * @method unknown fireEventAndWait()
  10113. * @method unknown focus()
  10114. * @method unknown focusAndWait()
  10115. * @method string getAlert()
  10116. * @method array getAllButtons()
  10117. * @method array getAllFields()
  10118. * @method array getAllLinks()
  10119. * @method array getAllWindowIds()
  10120. * @method array getAllWindowNames()
  10121. * @method array getAllWindowTitles()
  10122. * @method string getAttribute()
  10123. * @method array getAttributeFromAllWindows()
  10124. * @method string getBodyText()
  10125. * @method string getConfirmation()
  10126. * @method string getCookie()
  10127. * @method string getCookieByName()
  10128. * @method integer getCursorPosition()
  10129. * @method integer getElementHeight()
  10130. * @method integer getElementIndex()
  10131. * @method integer getElementPositionLeft()
  10132. * @method integer getElementPositionTop()
  10133. * @method integer getElementWidth()
  10134. * @method string getEval()
  10135. * @method string getExpression()
  10136. * @method string getHtmlSource()
  10137. * @method string getLocation()
  10138. * @method string getLogMessages()
  10139. * @method integer getMouseSpeed()
  10140. * @method string getPrompt()
  10141. * @method array getSelectOptions()
  10142. * @method string getSelectedId()
  10143. * @method array getSelectedIds()
  10144. * @method string getSelectedIndex()
  10145. * @method array getSelectedIndexes()
  10146. * @method string getSelectedLabel()
  10147. * @method array getSelectedLabels()
  10148. * @method string getSelectedValue()
  10149. * @method array getSelectedValues()
  10150. * @method unknown getSpeed()
  10151. * @method unknown getSpeedAndWait()
  10152. * @method string getTable()
  10153. * @method string getText()
  10154. * @method string getTitle()
  10155. * @method string getValue()
  10156. * @method boolean getWhetherThisFrameMatchFrameExpression()
  10157. * @method boolean getWhetherThisWindowMatchWindowExpression()
  10158. * @method integer getXpathCount()
  10159. * @method unknown goBack()
  10160. * @method unknown goBackAndWait()
  10161. * @method unknown highlight()
  10162. * @method unknown highlightAndWait()
  10163. * @method unknown ignoreAttributesWithoutValue()
  10164. * @method unknown ignoreAttributesWithoutValueAndWait()
  10165. * @method boolean isAlertPresent()
  10166. * @method boolean isChecked()
  10167. * @method boolean isConfirmationPresent()
  10168. * @method boolean isCookiePresent()
  10169. * @method boolean isEditable()
  10170. * @method boolean isElementPresent()
  10171. * @method boolean isOrdered()
  10172. * @method boolean isPromptPresent()
  10173. * @method boolean isSomethingSelected()
  10174. * @method boolean isTextPresent()
  10175. * @method boolean isVisible()
  10176. * @method unknown keyDown()
  10177. * @method unknown keyDownAndWait()
  10178. * @method unknown keyDownNative()
  10179. * @method unknown keyDownNativeAndWait()
  10180. * @method unknown keyPress()
  10181. * @method unknown keyPressAndWait()
  10182. * @method unknown keyPressNative()
  10183. * @method unknown keyPressNativeAndWait()
  10184. * @method unknown keyUp()
  10185. * @method unknown keyUpAndWait()
  10186. * @method unknown keyUpNative()
  10187. * @method unknown keyUpNativeAndWait()
  10188. * @method unknown metaKeyDown()
  10189. * @method unknown metaKeyDownAndWait()
  10190. * @method unknown metaKeyUp()
  10191. * @method unknown metaKeyUpAndWait()
  10192. * @method unknown mouseDown()
  10193. * @method unknown mouseDownAndWait()
  10194. * @method unknown mouseDownAt()
  10195. * @method unknown mouseDownAtAndWait()
  10196. * @method unknown mouseMove()
  10197. * @method unknown mouseMoveAndWait()
  10198. * @method unknown mouseMoveAt()
  10199. * @method unknown mouseMoveAtAndWait()
  10200. * @method unknown mouseOut()
  10201. * @method unknown mouseOutAndWait()
  10202. * @method unknown mouseOver()
  10203. * @method unknown mouseOverAndWait()
  10204. * @method unknown mouseUp()
  10205. * @method unknown mouseUpAndWait()
  10206. * @method unknown mouseUpAt()
  10207. * @method unknown mouseUpAtAndWait()
  10208. * @method unknown mouseUpRight()
  10209. * @method unknown mouseUpRightAndWait()
  10210. * @method unknown mouseUpRightAt()
  10211. * @method unknown mouseUpRightAtAndWait()
  10212. * @method unknown open()
  10213. * @method unknown openWindow()
  10214. * @method unknown openWindowAndWait()
  10215. * @method unknown pause()
  10216. * @method unknown refresh()
  10217. * @method unknown refreshAndWait()
  10218. * @method unknown removeAllSelections()
  10219. * @method unknown removeAllSelectionsAndWait()
  10220. * @method unknown removeScript()
  10221. * @method unknown removeScriptAndWait()
  10222. * @method unknown removeSelection()
  10223. * @method unknown removeSelectionAndWait()
  10224. * @method unknown retrieveLastRemoteControlLogs()
  10225. * @method unknown rollup()
  10226. * @method unknown rollupAndWait()
  10227. * @method unknown runScript()
  10228. * @method unknown runScriptAndWait()
  10229. * @method unknown select()
  10230. * @method unknown selectAndWait()
  10231. * @method unknown selectFrame()
  10232. * @method unknown selectPopUp()
  10233. * @method unknown selectPopUpAndWait()
  10234. * @method unknown selectWindow()
  10235. * @method unknown setBrowserLogLevel()
  10236. * @method unknown setBrowserLogLevelAndWait()
  10237. * @method unknown setContext()
  10238. * @method unknown setCursorPosition()
  10239. * @method unknown setCursorPositionAndWait()
  10240. * @method unknown setMouseSpeed()
  10241. * @method unknown setMouseSpeedAndWait()
  10242. * @method unknown setSpeed()
  10243. * @method unknown setSpeedAndWait()
  10244. * @method unknown shiftKeyDown()
  10245. * @method unknown shiftKeyDownAndWait()
  10246. * @method unknown shiftKeyUp()
  10247. * @method unknown shiftKeyUpAndWait()
  10248. * @method unknown shutDownSeleniumServer()
  10249. * @method unknown store()
  10250. * @method unknown submit()
  10251. * @method unknown submitAndWait()
  10252. * @method unknown type()
  10253. * @method unknown typeAndWait()
  10254. * @method unknown typeKeys()
  10255. * @method unknown typeKeysAndWait()
  10256. * @method unknown uncheck()
  10257. * @method unknown uncheckAndWait()
  10258. * @method unknown useXpathLibrary()
  10259. * @method unknown useXpathLibraryAndWait()
  10260. * @method unknown waitForAlert
  10261. * @method unknown waitForAlertNotPresent
  10262. * @method unknown waitForAlertPresent
  10263. * @method unknown waitForAllButtons
  10264. * @method unknown waitForAllFields
  10265. * @method unknown waitForAllLinks
  10266. * @method unknown waitForAllWindowIds
  10267. * @method unknown waitForAllWindowNames
  10268. * @method unknown waitForAllWindowTitles
  10269. * @method unknown waitForAttribute
  10270. * @method unknown waitForAttributeFromAllWindows
  10271. * @method unknown waitForBodyText
  10272. * @method unknown waitForChecked
  10273. * @method unknown waitForCondition()
  10274. * @method unknown waitForConfirmation
  10275. * @method unknown waitForConfirmationNotPresent
  10276. * @method unknown waitForConfirmationPresent
  10277. * @method unknown waitForCookie
  10278. * @method unknown waitForCookieByName
  10279. * @method unknown waitForCookieNotPresent
  10280. * @method unknown waitForCookiePresent
  10281. * @method unknown waitForCssCount
  10282. * @method unknown waitForCursorPosition
  10283. * @method unknown waitForEditable
  10284. * @method unknown waitForElementHeight
  10285. * @method unknown waitForElementIndex
  10286. * @method unknown waitForElementNotPresent
  10287. * @method unknown waitForElementPositionLeft
  10288. * @method unknown waitForElementPositionTop
  10289. * @method unknown waitForElementPresent
  10290. * @method unknown waitForElementWidth
  10291. * @method unknown waitForEval
  10292. * @method unknown waitForExpression
  10293. * @method unknown waitForHtmlSource
  10294. * @method unknown waitForLocation
  10295. * @method unknown waitForLogMessages
  10296. * @method unknown waitForMouseSpeed
  10297. * @method unknown waitForNotAlert
  10298. * @method unknown waitForNotAllButtons
  10299. * @method unknown waitForNotAllFields
  10300. * @method unknown waitForNotAllLinks
  10301. * @method unknown waitForNotAllWindowIds
  10302. * @method unknown waitForNotAllWindowNames
  10303. * @method unknown waitForNotAllWindowTitles
  10304. * @method unknown waitForNotAttribute
  10305. * @method unknown waitForNotAttributeFromAllWindows
  10306. * @method unknown waitForNotBodyText
  10307. * @method unknown waitForNotChecked
  10308. * @method unknown waitForNotConfirmation
  10309. * @method unknown waitForNotCookie
  10310. * @method unknown waitForNotCookieByName
  10311. * @method unknown waitForNotCssCount
  10312. * @method unknown waitForNotCursorPosition
  10313. * @method unknown waitForNotEditable
  10314. * @method unknown waitForNotElementHeight
  10315. * @method unknown waitForNotElementIndex
  10316. * @method unknown waitForNotElementPositionLeft
  10317. * @method unknown waitForNotElementPositionTop
  10318. * @method unknown waitForNotElementWidth
  10319. * @method unknown waitForNotEval
  10320. * @method unknown waitForNotExpression
  10321. * @method unknown waitForNotHtmlSource
  10322. * @method unknown waitForNotLocation
  10323. * @method unknown waitForNotLogMessages
  10324. * @method unknown waitForNotMouseSpeed
  10325. * @method unknown waitForNotOrdered
  10326. * @method unknown waitForNotPrompt
  10327. * @method unknown waitForNotSelectOptions
  10328. * @method unknown waitForNotSelectedId
  10329. * @method unknown waitForNotSelectedIds
  10330. * @method unknown waitForNotSelectedIndex
  10331. * @method unknown waitForNotSelectedIndexes
  10332. * @method unknown waitForNotSelectedLabel
  10333. * @method unknown waitForNotSelectedLabels
  10334. * @method unknown waitForNotSelectedValue
  10335. * @method unknown waitForNotSelectedValues
  10336. * @method unknown waitForNotSomethingSelected
  10337. * @method unknown waitForNotSpeed
  10338. * @method unknown waitForNotSpeedAndWait
  10339. * @method unknown waitForNotTable
  10340. * @method unknown waitForNotText
  10341. * @method unknown waitForNotTitle
  10342. * @method unknown waitForNotValue
  10343. * @method unknown waitForNotVisible
  10344. * @method unknown waitForNotWhetherThisFrameMatchFrameExpression
  10345. * @method unknown waitForNotWhetherThisWindowMatchWindowExpression
  10346. * @method unknown waitForNotXpathCount
  10347. * @method unknown waitForOrdered
  10348. * @method unknown waitForPageToLoad()
  10349. * @method unknown waitForPopUp()
  10350. * @method unknown waitForPrompt
  10351. * @method unknown waitForPromptNotPresent
  10352. * @method unknown waitForPromptPresent
  10353. * @method unknown waitForSelectOptions
  10354. * @method unknown waitForSelectedId
  10355. * @method unknown waitForSelectedIds
  10356. * @method unknown waitForSelectedIndex
  10357. * @method unknown waitForSelectedIndexes
  10358. * @method unknown waitForSelectedLabel
  10359. * @method unknown waitForSelectedLabels
  10360. * @method unknown waitForSelectedValue
  10361. * @method unknown waitForSelectedValues
  10362. * @method unknown waitForSomethingSelected
  10363. * @method unknown waitForSpeed
  10364. * @method unknown waitForSpeedAndWait
  10365. * @method unknown waitForTable
  10366. * @method unknown waitForText
  10367. * @method unknown waitForTextNotPresent
  10368. * @method unknown waitForTextPresent
  10369. * @method unknown waitForTitle
  10370. * @method unknown waitForValue
  10371. * @method unknown waitForVisible
  10372. * @method unknown waitForWhetherThisFrameMatchFrameExpression
  10373. * @method unknown waitForWhetherThisWindowMatchWindowExpression
  10374. * @method unknown waitForXpathCount
  10375. * @method unknown windowFocus()
  10376. * @method unknown windowMaximize()
  10377. */
  10378. abstract class PHPUnit_Extensions_SeleniumTestCase extends PHPUnit_Framework_TestCase
  10379. {
  10380. /**
  10381. * @var array
  10382. */
  10383. public static $browsers = array();
  10384. /**
  10385. * @var string
  10386. */
  10387. protected $browserName;
  10388. /**
  10389. * @var boolean
  10390. */
  10391. protected $collectCodeCoverageInformation = FALSE;
  10392. /**
  10393. * @var string
  10394. */
  10395. protected $coverageScriptUrl = '';
  10396. /**
  10397. * @var PHPUnit_Extensions_SeleniumTestCase_Driver[]
  10398. */
  10399. protected $drivers = array();
  10400. /**
  10401. * @var boolean
  10402. */
  10403. protected $inDefaultAssertions = FALSE;
  10404. /**
  10405. * @var string
  10406. */
  10407. protected $testId;
  10408. /**
  10409. * @var array
  10410. * @access protected
  10411. */
  10412. protected $verificationErrors = array();
  10413. /**
  10414. * @var boolean
  10415. */
  10416. protected $captureScreenshotOnFailure = FALSE;
  10417. /**
  10418. * @var string
  10419. */
  10420. protected $screenshotPath = '';
  10421. /**
  10422. * @var string
  10423. */
  10424. protected $screenshotUrl = '';
  10425. /**
  10426. * @var string
  10427. */
  10428. protected $screenshotBgColor = '';
  10429. /**
  10430. * @var integer the number of seconds to wait before declaring
  10431. * the Selenium server not reachable
  10432. */
  10433. protected $serverConnectionTimeOut = 10;
  10434. /**
  10435. * @var boolean
  10436. */
  10437. private $serverRunning;
  10438. /**
  10439. * @var boolean
  10440. */
  10441. private static $shareSession;
  10442. /**
  10443. * The last sessionId used for running a test.
  10444. * @var string
  10445. */
  10446. private static $sessionId;
  10447. /**
  10448. * @param boolean
  10449. */
  10450. public static function shareSession($shareSession)
  10451. {
  10452. self::$shareSession = $shareSession;
  10453. }
  10454. /**
  10455. * @param string $name
  10456. * @param array $data
  10457. * @param string $dataName
  10458. * @param array $browser
  10459. * @throws InvalidArgumentException
  10460. */
  10461. public function __construct($name = NULL, array $data = array(), $dataName = '', array $browser = array())
  10462. {
  10463. parent::__construct($name, $data, $dataName);
  10464. $this->testId = md5(uniqid(rand(), TRUE));
  10465. $this->getDriver($browser);
  10466. }
  10467. public function setupSpecificBrowser(array $browser)
  10468. {
  10469. $this->getDriver($browser);
  10470. }
  10471. /**
  10472. * Stops any shared session still open at the end of the current
  10473. * PHPUnit process.
  10474. */
  10475. public function __destruct()
  10476. {
  10477. $this->stopSession();
  10478. }
  10479. /**
  10480. * @param string $className
  10481. * @return PHPUnit_Framework_TestSuite
  10482. */
  10483. public static function suite($className)
  10484. {
  10485. return PHPUnit_Extensions_SeleniumTestSuite::fromTestCaseClass($className);
  10486. }
  10487. /**
  10488. * Runs the test case and collects the results in a TestResult object.
  10489. * If no TestResult object is passed a new one will be created.
  10490. *
  10491. * @param PHPUnit_Framework_TestResult $result
  10492. * @return PHPUnit_Framework_TestResult
  10493. * @throws InvalidArgumentException
  10494. */
  10495. public function run(PHPUnit_Framework_TestResult $result = NULL)
  10496. {
  10497. if ($result === NULL) {
  10498. $result = $this->createResult();
  10499. }
  10500. $this->collectCodeCoverageInformation = $result->getCollectCodeCoverageInformation();
  10501. foreach ($this->drivers as $driver) {
  10502. $driver->setCollectCodeCoverageInformation(
  10503. $this->collectCodeCoverageInformation
  10504. );
  10505. }
  10506. parent::run($result);
  10507. if ($this->collectCodeCoverageInformation) {
  10508. $result->getCodeCoverage()->append(
  10509. $this->getCodeCoverage(), $this
  10510. );
  10511. }
  10512. return $result;
  10513. }
  10514. /**
  10515. * @param array $browser
  10516. * @return PHPUnit_Extensions_SeleniumTestCase_Driver
  10517. */
  10518. protected function getDriver(array $browser)
  10519. {
  10520. if (isset($browser['name'])) {
  10521. if (!is_string($browser['name'])) {
  10522. throw new InvalidArgumentException(
  10523. 'Array element "name" is no string.'
  10524. );
  10525. }
  10526. } else {
  10527. $browser['name'] = '';
  10528. }
  10529. if (isset($browser['browser'])) {
  10530. if (!is_string($browser['browser'])) {
  10531. throw new InvalidArgumentException(
  10532. 'Array element "browser" is no string.'
  10533. );
  10534. }
  10535. } else {
  10536. $browser['browser'] = '';
  10537. }
  10538. if (isset($browser['host'])) {
  10539. if (!is_string($browser['host'])) {
  10540. throw new InvalidArgumentException(
  10541. 'Array element "host" is no string.'
  10542. );
  10543. }
  10544. } else {
  10545. $browser['host'] = 'localhost';
  10546. }
  10547. if (isset($browser['port'])) {
  10548. if (!is_int($browser['port'])) {
  10549. throw new InvalidArgumentException(
  10550. 'Array element "port" is no integer.'
  10551. );
  10552. }
  10553. } else {
  10554. $browser['port'] = 4444;
  10555. }
  10556. if (isset($browser['timeout'])) {
  10557. if (!is_int($browser['timeout'])) {
  10558. throw new InvalidArgumentException(
  10559. 'Array element "timeout" is no integer.'
  10560. );
  10561. }
  10562. } else {
  10563. $browser['timeout'] = 30;
  10564. }
  10565. if (isset($browser['httpTimeout'])) {
  10566. if (!is_int($browser['httpTimeout'])) {
  10567. throw new InvalidArgumentException(
  10568. 'Array element "httpTimeout" is no integer.'
  10569. );
  10570. }
  10571. } else {
  10572. $browser['httpTimeout'] = 45;
  10573. }
  10574. $driver = new PHPUnit_Extensions_SeleniumTestCase_Driver;
  10575. $driver->setName($browser['name']);
  10576. $driver->setBrowser($browser['browser']);
  10577. $driver->setHost($browser['host']);
  10578. $driver->setPort($browser['port']);
  10579. $driver->setTimeout($browser['timeout']);
  10580. $driver->setHttpTimeout($browser['httpTimeout']);
  10581. $driver->setTestCase($this);
  10582. $driver->setTestId($this->testId);
  10583. $this->drivers[0] = $driver;
  10584. return $driver;
  10585. }
  10586. public function skipWithNoServerRunning()
  10587. {
  10588. try {
  10589. fsockopen($this->drivers[0]->getHost(), $this->drivers[0]->getPort(), $errno, $errstr, $this->serverConnectionTimeOut);
  10590. $this->serverRunning = TRUE;
  10591. } catch (PHPUnit_Framework_Error_Warning $e) {
  10592. $this->markTestSkipped(
  10593. sprintf(
  10594. 'Could not connect to the Selenium Server on %s:%d.',
  10595. $this->drivers[0]->getHost(),
  10596. $this->drivers[0]->getPort()
  10597. )
  10598. );
  10599. $this->serverRunning = FALSE;
  10600. }
  10601. }
  10602. /**
  10603. * @return string
  10604. */
  10605. protected function prepareTestSession()
  10606. {
  10607. $testCaseClassVars = get_class_vars(get_class($this));
  10608. if ($testCaseClassVars['browsers']) {
  10609. return $this->start();
  10610. }
  10611. if (self::$shareSession && self::$sessionId !== NULL) {
  10612. $this->setSessionId(self::$sessionId);
  10613. $this->selectWindow('null');
  10614. } else {
  10615. self::$sessionId = $this->start();
  10616. }
  10617. return self::$sessionId;
  10618. }
  10619. /**
  10620. * @throws RuntimeException
  10621. */
  10622. protected function runTest()
  10623. {
  10624. $this->skipWithNoServerRunning();
  10625. $this->prepareTestSession();
  10626. if (!is_file($this->getName(FALSE))) {
  10627. $result = parent::runTest();
  10628. } else {
  10629. $this->runSelenese($this->getName(FALSE));
  10630. $result = NULL;
  10631. }
  10632. if (!empty($this->verificationErrors)) {
  10633. $this->fail(implode("\n", $this->verificationErrors));
  10634. }
  10635. if (!self::$shareSession) {
  10636. $this->stopSession();
  10637. }
  10638. return $result;
  10639. }
  10640. private function stopSession()
  10641. {
  10642. try {
  10643. $this->stop();
  10644. } catch (RuntimeException $e) { }
  10645. }
  10646. /**
  10647. * Returns a string representation of the test case.
  10648. *
  10649. * @return string
  10650. */
  10651. public function toString()
  10652. {
  10653. $buffer = parent::toString();
  10654. if (!empty($this->browserName)) {
  10655. $buffer .= ' with browser ' . $this->browserName;
  10656. }
  10657. return $buffer;
  10658. }
  10659. /**
  10660. * Runs a test from a Selenese (HTML) specification.
  10661. *
  10662. * @param string $filename
  10663. */
  10664. public function runSelenese($filename)
  10665. {
  10666. $document = PHPUnit_Util_XML::loadFile($filename, TRUE);
  10667. $xpath = new DOMXPath($document);
  10668. $rows = $xpath->query('body/table/tbody/tr');
  10669. foreach ($rows as $row) {
  10670. $action = NULL;
  10671. $arguments = array();
  10672. $columns = $xpath->query('td', $row);
  10673. foreach ($columns as $column) {
  10674. if ($action === NULL) {
  10675. $action = PHPUnit_Util_XML::nodeToText($column);
  10676. } else {
  10677. $arguments[] = PHPUnit_Util_XML::nodeToText($column);
  10678. }
  10679. }
  10680. if (method_exists($this, $action)) {
  10681. call_user_func_array(array($this, $action), $arguments);
  10682. } else {
  10683. $this->__call($action, $arguments);
  10684. }
  10685. }
  10686. }
  10687. /**
  10688. * Delegate method calls to the driver.
  10689. *
  10690. * @param string $command
  10691. * @param array $arguments
  10692. * @return mixed
  10693. */
  10694. public function __call($command, $arguments)
  10695. {
  10696. $result = call_user_func_array(
  10697. array($this->drivers[0], $command), $arguments
  10698. );
  10699. $this->verificationErrors = array_merge(
  10700. $this->verificationErrors, $this->drivers[0]->getVerificationErrors()
  10701. );
  10702. $this->drivers[0]->clearVerificationErrors();
  10703. return $result;
  10704. }
  10705. /**
  10706. * Asserts that an element's value is equal to a given string.
  10707. *
  10708. * @param string $locator
  10709. * @param string $text
  10710. * @param string $message
  10711. */
  10712. public function assertElementValueEquals($locator, $text, $message = '')
  10713. {
  10714. $this->assertEquals($text, $this->getValue($locator), $message);
  10715. }
  10716. /**
  10717. * Asserts that an element's value is not equal to a given string.
  10718. *
  10719. * @param string $locator
  10720. * @param string $text
  10721. * @param string $message
  10722. */
  10723. public function assertElementValueNotEquals($locator, $text, $message = '')
  10724. {
  10725. $this->assertNotEquals($text, $this->getValue($locator), $message);
  10726. }
  10727. /**
  10728. * Asserts that an element's value contains a given string.
  10729. *
  10730. * @param string $locator
  10731. * @param string $text
  10732. * @param string $message
  10733. */
  10734. public function assertElementValueContains($locator, $text, $message = '')
  10735. {
  10736. $this->assertContains($text, $this->getValue($locator), $message);
  10737. }
  10738. /**
  10739. * Asserts that an element's value does not contain a given string.
  10740. *
  10741. * @param string $locator
  10742. * @param string $text
  10743. * @param string $message
  10744. */
  10745. public function assertElementValueNotContains($locator, $text, $message = '')
  10746. {
  10747. $this->assertNotContains($text, $this->getValue($locator), $message);
  10748. }
  10749. /**
  10750. * Asserts that an element contains a given string.
  10751. *
  10752. * @param string $locator
  10753. * @param string $text
  10754. * @param string $message
  10755. */
  10756. public function assertElementContainsText($locator, $text, $message = '')
  10757. {
  10758. $this->assertContains($text, $this->getText($locator), $message);
  10759. }
  10760. /**
  10761. * Asserts that an element does not contain a given string.
  10762. *
  10763. * @param string $locator
  10764. * @param string $text
  10765. * @param string $message
  10766. */
  10767. public function assertElementNotContainsText($locator, $text, $message = '')
  10768. {
  10769. $this->assertNotContains($text, $this->getText($locator), $message);
  10770. }
  10771. /**
  10772. * Asserts that a select element has a specific option.
  10773. *
  10774. * @param string $selectLocator
  10775. * @param string $option
  10776. * @param string $message
  10777. */
  10778. public function assertSelectHasOption($selectLocator, $option, $message = '')
  10779. {
  10780. $this->assertContains($option, $this->getSelectOptions($selectLocator), $message);
  10781. }
  10782. /**
  10783. * Asserts that a select element does not have a specific option.
  10784. *
  10785. * @param string $selectLocator
  10786. * @param string $option
  10787. * @param string $message
  10788. */
  10789. public function assertSelectNotHasOption($selectLocator, $option, $message = '')
  10790. {
  10791. $this->assertNotContains($option, $this->getSelectOptions($selectLocator), $message);
  10792. }
  10793. /**
  10794. * Asserts that a specific label is selected.
  10795. *
  10796. * @param string $selectLocator
  10797. * @param string $value
  10798. * @param string $message
  10799. */
  10800. public function assertSelected($selectLocator, $option, $message = '')
  10801. {
  10802. if ($message == '') {
  10803. $message = sprintf(
  10804. 'Label "%s" not selected in "%s".',
  10805. $option,
  10806. $selectLocator
  10807. );
  10808. }
  10809. $this->assertEquals(
  10810. $option,
  10811. $this->getSelectedLabel($selectLocator),
  10812. $message
  10813. );
  10814. }
  10815. /**
  10816. * Asserts that a specific label is not selected.
  10817. *
  10818. * @param string $selectLocator
  10819. * @param string $value
  10820. * @param string $message
  10821. */
  10822. public function assertNotSelected($selectLocator, $option, $message = '')
  10823. {
  10824. if ($message == '') {
  10825. $message = sprintf(
  10826. 'Label "%s" selected in "%s".',
  10827. $option,
  10828. $selectLocator
  10829. );
  10830. }
  10831. $this->assertNotEquals(
  10832. $option,
  10833. $this->getSelectedLabel($selectLocator),
  10834. $message
  10835. );
  10836. }
  10837. /**
  10838. * Asserts that a specific value is selected.
  10839. *
  10840. * @param string $selectLocator
  10841. * @param string $value
  10842. * @param string $message
  10843. */
  10844. public function assertIsSelected($selectLocator, $value, $message = '')
  10845. {
  10846. if ($message == '') {
  10847. $message = sprintf(
  10848. 'Value "%s" not selected in "%s".',
  10849. $value,
  10850. $selectLocator
  10851. );
  10852. }
  10853. $this->assertEquals(
  10854. $value, $this->getSelectedValue($selectLocator),
  10855. $message
  10856. );
  10857. }
  10858. /**
  10859. * Asserts that a specific value is not selected.
  10860. *
  10861. * @param string $selectLocator
  10862. * @param string $value
  10863. * @param string $message
  10864. */
  10865. public function assertIsNotSelected($selectLocator, $value, $message = '')
  10866. {
  10867. if ($message == '') {
  10868. $message = sprintf(
  10869. 'Value "%s" selected in "%s".',
  10870. $value,
  10871. $selectLocator
  10872. );
  10873. }
  10874. $this->assertNotEquals(
  10875. $value,
  10876. $this->getSelectedValue($selectLocator),
  10877. $message
  10878. );
  10879. }
  10880. /**
  10881. * Template Method that is called after Selenium actions.
  10882. *
  10883. * @param string $action
  10884. */
  10885. protected function defaultAssertions($action)
  10886. {
  10887. }
  10888. /**
  10889. * @return array
  10890. */
  10891. protected function getCodeCoverage()
  10892. {
  10893. $coverage = new PHPUnit_Extensions_SeleniumCommon_RemoteCoverage(
  10894. $this->coverageScriptUrl,
  10895. $this->testId
  10896. );
  10897. return $coverage->get();
  10898. }
  10899. /**
  10900. * @param string $action
  10901. */
  10902. public function runDefaultAssertions($action)
  10903. {
  10904. if (!$this->inDefaultAssertions) {
  10905. $this->inDefaultAssertions = TRUE;
  10906. $this->defaultAssertions($action);
  10907. $this->inDefaultAssertions = FALSE;
  10908. }
  10909. }
  10910. /**
  10911. * This method is called when a test method did not execute successfully.
  10912. *
  10913. * @param Exception $e
  10914. */
  10915. protected function onNotSuccessfulTest(Exception $e)
  10916. {
  10917. if (!$this->serverRunning) {
  10918. throw $e;
  10919. }
  10920. try {
  10921. $this->restoreSessionStateAfterFailedTest();
  10922. $buffer = '';
  10923. if ($this->captureScreenshotOnFailure) {
  10924. $buffer .= 'Current URL: ' . $this->drivers[0]->getLocation() .
  10925. "\n";
  10926. $screenshotInfo = $this->takeScreenshot();
  10927. if ($screenshotInfo != '') {
  10928. $buffer .= $screenshotInfo;
  10929. }
  10930. }
  10931. $this->stopSession();
  10932. } catch (Exception $another) {
  10933. $buffer = "Issues while capturing the screenshot:\n" . $another->getMessage();
  10934. }
  10935. if ($e instanceof PHPUnit_Framework_ExpectationFailedException
  10936. && is_object($e->getComparisonFailure())) {
  10937. $message = $e->getComparisonFailure()->toString();
  10938. } else {
  10939. $message = $e->getMessage();
  10940. }
  10941. $buffer .= "\n" . $message;
  10942. // gain the screenshot path, lose the stack trace
  10943. if ($this->captureScreenshotOnFailure) {
  10944. throw new PHPUnit_Framework_Error($buffer, $e->getCode(), $e->getFile(), $e->getLine(), $e);
  10945. }
  10946. // yes to stack trace and everything
  10947. if ($e instanceof PHPUnit_Framework_IncompleteTestError
  10948. || $e instanceof PHPUnit_Framework_SkippedTestError
  10949. || $e instanceof PHPUnit_Framework_AssertionFailedError) {
  10950. throw $e;
  10951. }
  10952. // yes to stack trace, only for F tests
  10953. // PHPUnit issue 471 prevents getTrace() from being useful
  10954. throw new PHPUnit_Framework_Error($buffer, $e->getCode(), $e->getFile(), $e->getLine(), $e);
  10955. }
  10956. private function restoreSessionStateAfterFailedTest()
  10957. {
  10958. self::$sessionId = NULL;
  10959. }
  10960. /**
  10961. * Returns correct path to screenshot save path.
  10962. *
  10963. * @return string
  10964. */
  10965. protected function getScreenshotPath()
  10966. {
  10967. $path = $this->screenshotPath;
  10968. if (!in_array(substr($path, strlen($path) -1, 1), array("/","\\"))) {
  10969. $path .= DIRECTORY_SEPARATOR;
  10970. }
  10971. return $path;
  10972. }
  10973. /**
  10974. * Take a screenshot and return information about it.
  10975. * Return an empty string if the screenshotPath and screenshotUrl
  10976. * properties are empty.
  10977. * Issue #88.
  10978. *
  10979. * @access protected
  10980. * @return string
  10981. */
  10982. protected function takeScreenshot()
  10983. {
  10984. if (!empty($this->screenshotPath) &&
  10985. !empty($this->screenshotUrl)) {
  10986. $filename = $this->getScreenshotPath() . $this->testId . '.png';
  10987. $kargs = '';
  10988. if ($this->screenshotBgColor!='') {
  10989. $kargs = 'background=' . $this->screenshotBgColor;
  10990. }
  10991. $this->drivers[0]->captureEntirePageScreenshot($filename, $kargs);
  10992. return 'Screenshot: ' . $this->screenshotUrl . '/' .
  10993. $this->testId . ".png\n";
  10994. } else {
  10995. return '';
  10996. }
  10997. }
  10998. /**
  10999. * Pause support for runSelenese() HTML cases
  11000. * @param $milliseconds
  11001. */
  11002. protected function pause($milliseconds)
  11003. {
  11004. sleep(round($milliseconds/1000));
  11005. }
  11006. }
  11007. <?php
  11008. /**
  11009. * PHPUnit
  11010. *
  11011. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  11012. * All rights reserved.
  11013. *
  11014. * Redistribution and use in source and binary forms, with or without
  11015. * modification, are permitted provided that the following conditions
  11016. * are met:
  11017. *
  11018. * * Redistributions of source code must retain the above copyright
  11019. * notice, this list of conditions and the following disclaimer.
  11020. *
  11021. * * Redistributions in binary form must reproduce the above copyright
  11022. * notice, this list of conditions and the following disclaimer in
  11023. * the documentation and/or other materials provided with the
  11024. * distribution.
  11025. *
  11026. * * Neither the name of Sebastian Bergmann nor the names of his
  11027. * contributors may be used to endorse or promote products derived
  11028. * from this software without specific prior written permission.
  11029. *
  11030. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  11031. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  11032. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  11033. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  11034. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  11035. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  11036. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  11037. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  11038. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  11039. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  11040. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  11041. * POSSIBILITY OF SUCH DAMAGE.
  11042. *
  11043. * @package PHPUnit_Selenium
  11044. * @author Giorgio Sironi <info@giorgiosironi.com>
  11045. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  11046. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  11047. * @link http://www.phpunit.de/
  11048. * @since File available since Release 1.2.2
  11049. */
  11050. /**
  11051. * TestSuite class for Selenium 1 tests
  11052. *
  11053. * @package PHPUnit_Selenium
  11054. * @author Giorgio Sironi <info@giorgiosironi.com>
  11055. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  11056. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  11057. * @version Release: @package_version@
  11058. * @link http://www.phpunit.de/
  11059. * @since Class available since Release 1.2.0
  11060. */
  11061. class PHPUnit_Extensions_SeleniumTestSuite extends PHPUnit_Framework_TestSuite
  11062. {
  11063. /**
  11064. * Overriding the default: Selenium suites are always built from a TestCase class.
  11065. * @var boolean
  11066. */
  11067. protected $testCase = TRUE;
  11068. /**
  11069. * Making the method public.
  11070. */
  11071. public function addTestMethod(ReflectionClass $class, ReflectionMethod $method)
  11072. {
  11073. return parent::addTestMethod($class, $method);
  11074. }
  11075. /**
  11076. * @param string $className extending PHPUnit_Extensions_SeleniumTestCase
  11077. * @return PHPUnit_Extensions_SeleniumTestSuite
  11078. */
  11079. public static function fromTestCaseClass($className)
  11080. {
  11081. $suite = new self();
  11082. $suite->setName($className);
  11083. $class = new ReflectionClass($className);
  11084. $classGroups = PHPUnit_Util_Test::getGroups($className);
  11085. $staticProperties = $class->getStaticProperties();
  11086. if (isset($staticProperties['browsers'])) {
  11087. $browsers = $staticProperties['browsers'];
  11088. } else if (is_callable("{$className}::browsers")) {
  11089. $browsers = $className::browsers();
  11090. } else {
  11091. $browsers = null;
  11092. }
  11093. //BC: renamed seleneseDirectory -> selenesePath
  11094. if (!isset($staticProperties['selenesePath']) && isset($staticProperties['seleneseDirectory'])) {
  11095. $staticProperties['selenesePath'] = $staticProperties['seleneseDirectory'];
  11096. }
  11097. // Create tests from Selenese/HTML files.
  11098. if (isset($staticProperties['selenesePath']) &&
  11099. (is_dir($staticProperties['selenesePath']) || is_file($staticProperties['selenesePath']))) {
  11100. if (is_dir($staticProperties['selenesePath'])) {
  11101. $files = array_merge(
  11102. self::getSeleneseFiles($staticProperties['selenesePath'], '.htm'),
  11103. self::getSeleneseFiles($staticProperties['selenesePath'], '.html')
  11104. );
  11105. } else {
  11106. $files[] = realpath($staticProperties['selenesePath']);
  11107. }
  11108. // Create tests from Selenese/HTML files for multiple browsers.
  11109. if ($browsers) {
  11110. foreach ($browsers as $browser) {
  11111. $browserSuite = PHPUnit_Extensions_SeleniumBrowserSuite::fromClassAndBrowser($className, $browser);
  11112. foreach ($files as $file) {
  11113. self::addGeneratedTestTo($browserSuite,
  11114. new $className($file, array(), '', $browser),
  11115. $classGroups
  11116. );
  11117. }
  11118. $suite->addTest($browserSuite);
  11119. }
  11120. }
  11121. else {
  11122. // Create tests from Selenese/HTML files for single browser.
  11123. foreach ($files as $file) {
  11124. self::addGeneratedTestTo($suite,
  11125. new $className($file),
  11126. $classGroups);
  11127. }
  11128. }
  11129. }
  11130. // Create tests from test methods for multiple browsers.
  11131. if ($browsers) {
  11132. foreach ($browsers as $browser) {
  11133. $browserSuite = PHPUnit_Extensions_SeleniumBrowserSuite::fromClassAndBrowser($className, $browser);
  11134. foreach ($class->getMethods() as $method) {
  11135. $browserSuite->addTestMethod($class, $method);
  11136. }
  11137. $browserSuite->setupSpecificBrowser($browser);
  11138. $suite->addTest($browserSuite);
  11139. }
  11140. }
  11141. else {
  11142. // Create tests from test methods for single browser.
  11143. foreach ($class->getMethods() as $method) {
  11144. $suite->addTestMethod($class, $method);
  11145. }
  11146. }
  11147. return $suite;
  11148. }
  11149. private static function addGeneratedTestTo(PHPUnit_Framework_TestSuite $suite, PHPUnit_Framework_TestCase $test, $classGroups)
  11150. {
  11151. list ($methodName, ) = explode(' ', $test->getName());
  11152. $test->setDependencies(
  11153. PHPUnit_Util_Test::getDependencies(get_class($test), $methodName)
  11154. );
  11155. $suite->addTest($test, $classGroups);
  11156. }
  11157. /**
  11158. * @param string $directory
  11159. * @param string $suffix
  11160. * @return array
  11161. */
  11162. private static function getSeleneseFiles($directory, $suffix)
  11163. {
  11164. $facade = new File_Iterator_Facade;
  11165. return $facade->getFilesAsArray($directory, $suffix);
  11166. }
  11167. }
  11168. <?php
  11169. /**
  11170. * PHPUnit
  11171. *
  11172. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  11173. * All rights reserved.
  11174. *
  11175. * Redistribution and use in source and binary forms, with or without
  11176. * modification, are permitted provided that the following conditions
  11177. * are met:
  11178. *
  11179. * * Redistributions of source code must retain the above copyright
  11180. * notice, this list of conditions and the following disclaimer.
  11181. *
  11182. * * Redistributions in binary form must reproduce the above copyright
  11183. * notice, this list of conditions and the following disclaimer in
  11184. * the documentation and/or other materials provided with the
  11185. * distribution.
  11186. *
  11187. * * Neither the name of Sebastian Bergmann nor the names of his
  11188. * contributors may be used to endorse or promote products derived
  11189. * from this software without specific prior written permission.
  11190. *
  11191. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  11192. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  11193. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  11194. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  11195. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  11196. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  11197. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  11198. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  11199. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  11200. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  11201. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  11202. * POSSIBILITY OF SUCH DAMAGE.
  11203. *
  11204. * @package PHPUnit_Selenium
  11205. * @author Sebastian Bergmann <sebastian@phpunit.de>
  11206. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  11207. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  11208. * @link http://www.phpunit.de/
  11209. * @since File available since Release 1.0.0
  11210. */
  11211. /**
  11212. * Implementation of the Selenium RC client/server protocol.
  11213. *
  11214. * @package PHPUnit_Selenium
  11215. * @author Sebastian Bergmann <sebastian@phpunit.de>
  11216. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  11217. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  11218. * @version Release: @package_version@
  11219. * @link http://www.phpunit.de/
  11220. * @since Class available since Release 1.0.0
  11221. */
  11222. class PHPUnit_Extensions_SeleniumTestCase_Driver
  11223. {
  11224. /**
  11225. * @var PHPUnit_Extensions_SeleniumTestCase
  11226. */
  11227. protected $testCase;
  11228. /**
  11229. * @var string
  11230. */
  11231. protected $testId;
  11232. /**
  11233. * @var string
  11234. */
  11235. protected $name;
  11236. /**
  11237. * @var string
  11238. */
  11239. protected $browser;
  11240. /**
  11241. * @var string
  11242. */
  11243. protected $browserUrl;
  11244. /**
  11245. * @var boolean
  11246. */
  11247. protected $collectCodeCoverageInformation = FALSE;
  11248. /**
  11249. * @var string
  11250. */
  11251. protected $host = 'localhost';
  11252. /**
  11253. * @var integer
  11254. */
  11255. protected $port = 4444;
  11256. /**
  11257. * @var integer
  11258. */
  11259. protected $httpTimeout = 45;
  11260. /**
  11261. * @var integer
  11262. */
  11263. protected $seleniumTimeout = 30;
  11264. /**
  11265. * @var string
  11266. */
  11267. protected $sessionId;
  11268. /**
  11269. * @var integer
  11270. */
  11271. protected $sleep = 0;
  11272. /**
  11273. * @var boolean
  11274. */
  11275. protected $useWaitForPageToLoad = TRUE;
  11276. /**
  11277. * @var boolean
  11278. */
  11279. protected $wait = 5;
  11280. /**
  11281. * @var array
  11282. */
  11283. protected static $autoGeneratedCommands = array();
  11284. /**
  11285. * @var array
  11286. */
  11287. protected $commands = array();
  11288. /**
  11289. * @var array $userCommands A numerical array which holds custom user commands.
  11290. */
  11291. protected $userCommands = array();
  11292. /**
  11293. * @var array
  11294. */
  11295. protected $verificationErrors = array();
  11296. /**
  11297. * @var array
  11298. */
  11299. private $webDriverCapabilities;
  11300. public function __construct()
  11301. {
  11302. if (empty(self::$autoGeneratedCommands)) {
  11303. self::autoGenerateCommands();
  11304. }
  11305. }
  11306. /**
  11307. * Only browserName is supported.
  11308. */
  11309. public function setWebDriverCapabilities(array $capabilities)
  11310. {
  11311. $this->webDriverCapabilities = $capabilities;
  11312. }
  11313. /**
  11314. * @return string
  11315. */
  11316. public function start()
  11317. {
  11318. if ($this->browserUrl == NULL) {
  11319. throw new PHPUnit_Framework_Exception(
  11320. 'setBrowserUrl() needs to be called before start().'
  11321. );
  11322. }
  11323. if ($this->webDriverCapabilities !== NULL) {
  11324. $seleniumServerUrl = PHPUnit_Extensions_Selenium2TestCase_URL::fromHostAndPort($this->host, $this->port);
  11325. $driver = new PHPUnit_Extensions_Selenium2TestCase_Driver($seleniumServerUrl);
  11326. $session = $driver->startSession($this->webDriverCapabilities, new PHPUnit_Extensions_Selenium2TestCase_URL($this->browserUrl));
  11327. $webDriverSessionId = $session->id();
  11328. $this->sessionId = $this->getString(
  11329. 'getNewBrowserSession',
  11330. array($this->browser, $this->browserUrl, '',
  11331. "webdriver.remote.sessionid=$webDriverSessionId")
  11332. );
  11333. $this->doCommand('setTimeout', array($this->seleniumTimeout * 1000));
  11334. }
  11335. if (!isset($this->sessionId)) {
  11336. $this->sessionId = $this->getString(
  11337. 'getNewBrowserSession',
  11338. array($this->browser, $this->browserUrl)
  11339. );
  11340. $this->doCommand('setTimeout', array($this->seleniumTimeout * 1000));
  11341. }
  11342. return $this->sessionId;
  11343. }
  11344. /**
  11345. * @return string
  11346. * @since Method available since Release 1.1.0
  11347. */
  11348. public function getSessionId()
  11349. {
  11350. return $this->sessionId;
  11351. }
  11352. /**
  11353. * @param string
  11354. * @since Method available since Release 1.2.0
  11355. */
  11356. public function setSessionId($sessionId)
  11357. {
  11358. $this->sessionId = $sessionId;
  11359. }
  11360. /**
  11361. */
  11362. public function stop()
  11363. {
  11364. if (!isset($this->sessionId)) {
  11365. return;
  11366. }
  11367. $this->doCommand('testComplete');
  11368. $this->sessionId = NULL;
  11369. }
  11370. /**
  11371. * @param boolean $flag
  11372. * @throws InvalidArgumentException
  11373. */
  11374. public function setCollectCodeCoverageInformation($flag)
  11375. {
  11376. if (!is_bool($flag)) {
  11377. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  11378. }
  11379. $this->collectCodeCoverageInformation = $flag;
  11380. }
  11381. /**
  11382. * @param PHPUnit_Extensions_SeleniumTestCase $testCase
  11383. */
  11384. public function setTestCase(PHPUnit_Extensions_SeleniumTestCase $testCase)
  11385. {
  11386. $this->testCase = $testCase;
  11387. }
  11388. /**
  11389. * @param integer $testId
  11390. */
  11391. public function setTestId($testId)
  11392. {
  11393. $this->testId = $testId;
  11394. }
  11395. /**
  11396. * @return integer $testId
  11397. */
  11398. public function getTestId()
  11399. {
  11400. return $this->testId;
  11401. }
  11402. /**
  11403. * @param string $name
  11404. * @throws InvalidArgumentException
  11405. */
  11406. public function setName($name)
  11407. {
  11408. if (!is_string($name)) {
  11409. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  11410. }
  11411. $this->name = $name;
  11412. }
  11413. /**
  11414. * @return string
  11415. */
  11416. public function getName()
  11417. {
  11418. return $this->name;
  11419. }
  11420. /**
  11421. * @param string $browser
  11422. * @throws InvalidArgumentException
  11423. */
  11424. public function setBrowser($browser)
  11425. {
  11426. if (!is_string($browser)) {
  11427. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  11428. }
  11429. $this->browser = $browser;
  11430. }
  11431. /**
  11432. * @return string
  11433. */
  11434. public function getBrowser()
  11435. {
  11436. return $this->browser;
  11437. }
  11438. /**
  11439. * @param string $browserUrl
  11440. * @throws InvalidArgumentException
  11441. */
  11442. public function setBrowserUrl($browserUrl)
  11443. {
  11444. if (!is_string($browserUrl)) {
  11445. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  11446. }
  11447. $this->browserUrl = $browserUrl;
  11448. }
  11449. /**
  11450. * @param string $host
  11451. * @throws InvalidArgumentException
  11452. */
  11453. public function setHost($host)
  11454. {
  11455. if (!is_string($host)) {
  11456. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  11457. }
  11458. $this->host = $host;
  11459. }
  11460. /**
  11461. * @return string
  11462. * @since Method available since Release 1.1.0
  11463. */
  11464. public function getHost()
  11465. {
  11466. return $this->host;
  11467. }
  11468. /**
  11469. * @param integer $port
  11470. * @throws InvalidArgumentException
  11471. */
  11472. public function setPort($port)
  11473. {
  11474. if (!is_int($port)) {
  11475. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  11476. }
  11477. $this->port = $port;
  11478. }
  11479. /**
  11480. * @return integer
  11481. * @since Method available since Release 1.1.0
  11482. */
  11483. public function getPort()
  11484. {
  11485. return $this->port;
  11486. }
  11487. /**
  11488. * @param integer $timeout for Selenium RC in seconds
  11489. * @throws InvalidArgumentException
  11490. */
  11491. public function setTimeout($timeout)
  11492. {
  11493. if (!is_int($timeout)) {
  11494. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  11495. }
  11496. $this->seleniumTimeout = $timeout;
  11497. }
  11498. /**
  11499. * @param integer $timeout for HTTP connection to Selenium RC in seconds
  11500. * @throws InvalidArgumentException
  11501. */
  11502. public function setHttpTimeout($timeout)
  11503. {
  11504. if (!is_int($timeout)) {
  11505. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  11506. }
  11507. $this->httpTimeout = $timeout;
  11508. }
  11509. /**
  11510. * @param integer $seconds
  11511. * @throws InvalidArgumentException
  11512. */
  11513. public function setSleep($seconds)
  11514. {
  11515. if (!is_int($seconds)) {
  11516. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  11517. }
  11518. $this->sleep = $seconds;
  11519. }
  11520. /**
  11521. * Sets the number of seconds to sleep() after *AndWait commands
  11522. * when setWaitForPageToLoad(FALSE) is used.
  11523. *
  11524. * @param integer $seconds
  11525. * @throws InvalidArgumentException
  11526. */
  11527. public function setWait($seconds)
  11528. {
  11529. if (!is_int($seconds)) {
  11530. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  11531. }
  11532. $this->wait = $seconds;
  11533. }
  11534. /**
  11535. * Sets whether waitForPageToLoad (TRUE) or sleep() (FALSE)
  11536. * is used after *AndWait commands.
  11537. *
  11538. * @param boolean $flag
  11539. * @throws InvalidArgumentException
  11540. */
  11541. public function setWaitForPageToLoad($flag)
  11542. {
  11543. if (!is_bool($flag)) {
  11544. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  11545. }
  11546. $this->useWaitForPageToLoad = $flag;
  11547. }
  11548. /**
  11549. * Sets whether captureScreenshotOnFailure (TRUE) or (FALSE)
  11550. * if true, the takeScreenshot() is triggered in onNotSuccessfulTest().
  11551. *
  11552. * @param boolean $flag
  11553. * @throws InvalidArgumentException
  11554. */
  11555. public function setCaptureScreenshotOnFailure($flag)
  11556. {
  11557. if (!is_bool($flag)) {
  11558. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  11559. }
  11560. $this->captureScreenshotOnFailure = $flag;
  11561. }
  11562. /**
  11563. * @param string $screenshotUrl
  11564. * @throws InvalidArgumentException
  11565. */
  11566. public function setScreenshotUrl($screenshotUrl)
  11567. {
  11568. if (!is_string($screenshotUrl)) {
  11569. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  11570. }
  11571. $this->screenshotUrl = $screenshotUrl;
  11572. }
  11573. /**
  11574. * @param string $screenshotPath
  11575. * @throws InvalidArgumentException
  11576. */
  11577. public function setScreenshotPath($screenshotPath)
  11578. {
  11579. if (!is_string($screenshotPath)) {
  11580. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  11581. }
  11582. $this->screenshotPath = $screenshotPath;
  11583. }
  11584. /**
  11585. * Adds allowed user commands into {@link self::$userCommands}. See
  11586. * {@link self::__call()} (switch/case -> default) for usage.
  11587. *
  11588. * @param string $command A command.
  11589. *
  11590. * @return $this
  11591. * @see self::__call()
  11592. */
  11593. public function addUserCommand($command)
  11594. {
  11595. if (!is_string($command)) {
  11596. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  11597. }
  11598. $this->userCommands[] = $command;
  11599. return $this;
  11600. }
  11601. /**
  11602. * This method implements the Selenium RC protocol.
  11603. *
  11604. * @param string $command
  11605. * @param array $arguments
  11606. * @return mixed
  11607. * @method unknown addLocationStrategy()
  11608. * @method unknown addLocationStrategyAndWait()
  11609. * @method unknown addScript()
  11610. * @method unknown addScriptAndWait()
  11611. * @method unknown addSelection()
  11612. * @method unknown addSelectionAndWait()
  11613. * @method unknown allowNativeXpath()
  11614. * @method unknown allowNativeXpathAndWait()
  11615. * @method unknown altKeyDown()
  11616. * @method unknown altKeyDownAndWait()
  11617. * @method unknown altKeyUp()
  11618. * @method unknown altKeyUpAndWait()
  11619. * @method unknown answerOnNextPrompt()
  11620. * @method unknown assignId()
  11621. * @method unknown assignIdAndWait()
  11622. * @method unknown attachFile()
  11623. * @method unknown break()
  11624. * @method unknown captureEntirePageScreenshot()
  11625. * @method unknown captureEntirePageScreenshotAndWait()
  11626. * @method unknown captureEntirePageScreenshotToStringAndWait()
  11627. * @method unknown captureScreenshotAndWait()
  11628. * @method unknown captureScreenshotToStringAndWait()
  11629. * @method unknown check()
  11630. * @method unknown checkAndWait()
  11631. * @method unknown chooseCancelOnNextConfirmation()
  11632. * @method unknown chooseCancelOnNextConfirmationAndWait()
  11633. * @method unknown chooseOkOnNextConfirmation()
  11634. * @method unknown chooseOkOnNextConfirmationAndWait()
  11635. * @method unknown click()
  11636. * @method unknown clickAndWait()
  11637. * @method unknown clickAt()
  11638. * @method unknown clickAtAndWait()
  11639. * @method unknown close()
  11640. * @method unknown contextMenu()
  11641. * @method unknown contextMenuAndWait()
  11642. * @method unknown contextMenuAt()
  11643. * @method unknown contextMenuAtAndWait()
  11644. * @method unknown controlKeyDown()
  11645. * @method unknown controlKeyDownAndWait()
  11646. * @method unknown controlKeyUp()
  11647. * @method unknown controlKeyUpAndWait()
  11648. * @method unknown createCookie()
  11649. * @method unknown createCookieAndWait()
  11650. * @method unknown deleteAllVisibleCookies()
  11651. * @method unknown deleteAllVisibleCookiesAndWait()
  11652. * @method unknown deleteCookie()
  11653. * @method unknown deleteCookieAndWait()
  11654. * @method unknown deselectPopUp()
  11655. * @method unknown deselectPopUpAndWait()
  11656. * @method unknown doubleClick()
  11657. * @method unknown doubleClickAndWait()
  11658. * @method unknown doubleClickAt()
  11659. * @method unknown doubleClickAtAndWait()
  11660. * @method unknown dragAndDrop()
  11661. * @method unknown dragAndDropAndWait()
  11662. * @method unknown dragAndDropToObject()
  11663. * @method unknown dragAndDropToObjectAndWait()
  11664. * @method unknown dragDrop()
  11665. * @method unknown dragDropAndWait()
  11666. * @method unknown echo()
  11667. * @method unknown fireEvent()
  11668. * @method unknown fireEventAndWait()
  11669. * @method unknown focus()
  11670. * @method unknown focusAndWait()
  11671. * @method string getAlert()
  11672. * @method array getAllButtons()
  11673. * @method array getAllFields()
  11674. * @method array getAllLinks()
  11675. * @method array getAllWindowIds()
  11676. * @method array getAllWindowNames()
  11677. * @method array getAllWindowTitles()
  11678. * @method string getAttribute(string $attributeLocator)
  11679. * @method array getAttributeFromAllWindows(string $attributeName)
  11680. * @method string getBodyText()
  11681. * @method string getConfirmation()
  11682. * @method string getCookie()
  11683. * @method string getCookieByName(string $name)
  11684. * @method integer getCssCount(string $locator)
  11685. * @method integer getCursorPosition(string $locator)
  11686. * @method integer getElementHeight(string $locator)
  11687. * @method integer getElementIndex(string $locator)
  11688. * @method integer getElementPositionLeft(string $locator)
  11689. * @method integer getElementPositionTop(string $locator)
  11690. * @method integer getElementWidth(string $locator)
  11691. * @method string getEval(string $script)
  11692. * @method string getExpression(string $expression)
  11693. * @method string getHtmlSource()
  11694. * @method string getLocation()
  11695. * @method string getLogMessages()
  11696. * @method integer getMouseSpeed()
  11697. * @method string getPrompt()
  11698. * @method array getSelectOptions(string $selectLocator)
  11699. * @method string getSelectedId(string $selectLocator)
  11700. * @method array getSelectedIds(string $selectLocator)
  11701. * @method string getSelectedIndex(string $selectLocator)
  11702. * @method array getSelectedIndexes(string $selectLocator)
  11703. * @method string getSelectedLabel(string $selectLocator)
  11704. * @method array getSelectedLabels(string $selectLocator)
  11705. * @method string getSelectedValue(string $selectLocator)
  11706. * @method array getSelectedValues(string $selectLocator)
  11707. * @method unknown getSpeed()
  11708. * @method unknown getSpeedAndWait()
  11709. * @method string getTable(string $tableCellAddress)
  11710. * @method string getText(string $locator)
  11711. * @method string getTitle()
  11712. * @method string getValue(string $locator)
  11713. * @method boolean getWhetherThisFrameMatchFrameExpression(string $currentFrameString, string $target)
  11714. * @method boolean getWhetherThisWindowMatchWindowExpression(string $currentWindowString, string $target)
  11715. * @method integer getXpathCount(string $xpath)
  11716. * @method unknown goBack()
  11717. * @method unknown goBackAndWait()
  11718. * @method unknown highlight(string $locator)
  11719. * @method unknown highlightAndWait(string $locator)
  11720. * @method unknown ignoreAttributesWithoutValue(string $ignore)
  11721. * @method unknown ignoreAttributesWithoutValueAndWait(string $ignore)
  11722. * @method boolean isAlertPresent()
  11723. * @method boolean isChecked(locator)
  11724. * @method boolean isConfirmationPresent()
  11725. * @method boolean isCookiePresent(string $name)
  11726. * @method boolean isEditable(string $locator)
  11727. * @method boolean isElementPresent(string $locator)
  11728. * @method boolean isOrdered(string $locator1, string $locator2)
  11729. * @method boolean isPromptPresent()
  11730. * @method boolean isSomethingSelected(string $selectLocator)
  11731. * @method boolean isTextPresent(pattern)
  11732. * @method boolean isVisible(locator)
  11733. * @method unknown keyDown()
  11734. * @method unknown keyDownAndWait()
  11735. * @method unknown keyDownNative()
  11736. * @method unknown keyDownNativeAndWait()
  11737. * @method unknown keyPress()
  11738. * @method unknown keyPressAndWait()
  11739. * @method unknown keyPressNative()
  11740. * @method unknown keyPressNativeAndWait()
  11741. * @method unknown keyUp()
  11742. * @method unknown keyUpAndWait()
  11743. * @method unknown keyUpNative()
  11744. * @method unknown keyUpNativeAndWait()
  11745. * @method unknown metaKeyDown()
  11746. * @method unknown metaKeyDownAndWait()
  11747. * @method unknown metaKeyUp()
  11748. * @method unknown metaKeyUpAndWait()
  11749. * @method unknown mouseDown()
  11750. * @method unknown mouseDownAndWait()
  11751. * @method unknown mouseDownAt()
  11752. * @method unknown mouseDownAtAndWait()
  11753. * @method unknown mouseMove()
  11754. * @method unknown mouseMoveAndWait()
  11755. * @method unknown mouseMoveAt()
  11756. * @method unknown mouseMoveAtAndWait()
  11757. * @method unknown mouseOut()
  11758. * @method unknown mouseOutAndWait()
  11759. * @method unknown mouseOver()
  11760. * @method unknown mouseOverAndWait()
  11761. * @method unknown mouseUp()
  11762. * @method unknown mouseUpAndWait()
  11763. * @method unknown mouseUpAt()
  11764. * @method unknown mouseUpAtAndWait()
  11765. * @method unknown mouseUpRight()
  11766. * @method unknown mouseUpRightAndWait()
  11767. * @method unknown mouseUpRightAt()
  11768. * @method unknown mouseUpRightAtAndWait()
  11769. * @method unknown open()
  11770. * @method unknown openWindow()
  11771. * @method unknown openWindowAndWait()
  11772. * @method unknown pause()
  11773. * @method unknown refresh()
  11774. * @method unknown refreshAndWait()
  11775. * @method unknown removeAllSelections()
  11776. * @method unknown removeAllSelectionsAndWait()
  11777. * @method unknown removeScript()
  11778. * @method unknown removeScriptAndWait()
  11779. * @method unknown removeSelection()
  11780. * @method unknown removeSelectionAndWait()
  11781. * @method unknown retrieveLastRemoteControlLogs()
  11782. * @method unknown rollup()
  11783. * @method unknown rollupAndWait()
  11784. * @method unknown runScript()
  11785. * @method unknown runScriptAndWait()
  11786. * @method unknown select()
  11787. * @method unknown selectAndWait()
  11788. * @method unknown selectFrame()
  11789. * @method unknown selectPopUp()
  11790. * @method unknown selectPopUpAndWait()
  11791. * @method unknown selectWindow()
  11792. * @method unknown setBrowserLogLevel()
  11793. * @method unknown setBrowserLogLevelAndWait()
  11794. * @method unknown setContext()
  11795. * @method unknown setCursorPosition()
  11796. * @method unknown setCursorPositionAndWait()
  11797. * @method unknown setMouseSpeed()
  11798. * @method unknown setMouseSpeedAndWait()
  11799. * @method unknown setSpeed()
  11800. * @method unknown setSpeedAndWait()
  11801. * @method unknown shiftKeyDown()
  11802. * @method unknown shiftKeyDownAndWait()
  11803. * @method unknown shiftKeyUp()
  11804. * @method unknown shiftKeyUpAndWait()
  11805. * @method unknown shutDownSeleniumServer()
  11806. * @method unknown store()
  11807. * @method unknown submit()
  11808. * @method unknown submitAndWait()
  11809. * @method unknown type()
  11810. * @method unknown typeAndWait()
  11811. * @method unknown typeKeys()
  11812. * @method unknown typeKeysAndWait()
  11813. * @method unknown uncheck()
  11814. * @method unknown uncheckAndWait()
  11815. * @method unknown useXpathLibrary()
  11816. * @method unknown useXpathLibraryAndWait()
  11817. * @method unknown waitForCondition()
  11818. * @method unknown waitForElementPresent()
  11819. * @method unknown waitForElementNotPresent()
  11820. * @method unknown waitForPageToLoad()
  11821. * @method unknown waitForPopUp()
  11822. * @method unknown windowFocus()
  11823. * @method unknown windowMaximize()
  11824. */
  11825. public function __call($command, $arguments)
  11826. {
  11827. $arguments = $this->preprocessParameters($arguments);
  11828. $wait = FALSE;
  11829. if (substr($command, -7, 7) == 'AndWait') {
  11830. $command = substr($command, 0, -7);
  11831. $wait = TRUE;
  11832. }
  11833. switch ($command) {
  11834. case 'addLocationStrategy':
  11835. case 'addScript':
  11836. case 'addSelection':
  11837. case 'allowNativeXpath':
  11838. case 'altKeyDown':
  11839. case 'altKeyUp':
  11840. case 'answerOnNextPrompt':
  11841. case 'assignId':
  11842. case 'attachFile':
  11843. case 'break':
  11844. case 'captureEntirePageScreenshot':
  11845. case 'captureScreenshot':
  11846. case 'check':
  11847. case 'chooseCancelOnNextConfirmation':
  11848. case 'chooseOkOnNextConfirmation':
  11849. case 'click':
  11850. case 'clickAt':
  11851. case 'close':
  11852. case 'contextMenu':
  11853. case 'contextMenuAt':
  11854. case 'controlKeyDown':
  11855. case 'controlKeyUp':
  11856. case 'createCookie':
  11857. case 'deleteAllVisibleCookies':
  11858. case 'deleteCookie':
  11859. case 'deselectPopUp':
  11860. case 'doubleClick':
  11861. case 'doubleClickAt':
  11862. case 'dragAndDrop':
  11863. case 'dragAndDropToObject':
  11864. case 'dragDrop':
  11865. case 'echo':
  11866. case 'fireEvent':
  11867. case 'focus':
  11868. case 'goBack':
  11869. case 'highlight':
  11870. case 'ignoreAttributesWithoutValue':
  11871. case 'keyDown':
  11872. case 'keyDownNative':
  11873. case 'keyPress':
  11874. case 'keyPressNative':
  11875. case 'keyUp':
  11876. case 'keyUpNative':
  11877. case 'metaKeyDown':
  11878. case 'metaKeyUp':
  11879. case 'mouseDown':
  11880. case 'mouseDownAt':
  11881. case 'mouseMove':
  11882. case 'mouseMoveAt':
  11883. case 'mouseOut':
  11884. case 'mouseOver':
  11885. case 'mouseUp':
  11886. case 'mouseUpAt':
  11887. case 'mouseUpRight':
  11888. case 'mouseUpRightAt':
  11889. case 'open':
  11890. case 'openWindow':
  11891. case 'pause':
  11892. case 'refresh':
  11893. case 'removeAllSelections':
  11894. case 'removeScript':
  11895. case 'removeSelection':
  11896. case 'retrieveLastRemoteControlLogs':
  11897. case 'rollup':
  11898. case 'runScript':
  11899. case 'select':
  11900. case 'selectFrame':
  11901. case 'selectPopUp':
  11902. case 'selectWindow':
  11903. case 'setBrowserLogLevel':
  11904. case 'setContext':
  11905. case 'setCursorPosition':
  11906. case 'setMouseSpeed':
  11907. case 'setSpeed':
  11908. case 'shiftKeyDown':
  11909. case 'shiftKeyUp':
  11910. case 'shutDownSeleniumServer':
  11911. case 'store':
  11912. case 'submit':
  11913. case 'type':
  11914. case 'typeKeys':
  11915. case 'uncheck':
  11916. case 'useXpathLibrary':
  11917. case 'windowFocus':
  11918. case 'windowMaximize':
  11919. case isset(self::$autoGeneratedCommands[$command]): {
  11920. // Pre-Command Actions
  11921. switch ($command) {
  11922. case 'open':
  11923. case 'openWindow': {
  11924. if ($this->collectCodeCoverageInformation) {
  11925. $this->deleteCookie('PHPUNIT_SELENIUM_TEST_ID', 'path=/');
  11926. $this->createCookie(
  11927. 'PHPUNIT_SELENIUM_TEST_ID=' . $this->testId,
  11928. 'path=/'
  11929. );
  11930. }
  11931. }
  11932. break;
  11933. case 'store':
  11934. // store is a synonym of storeExpression
  11935. // and RC only understands storeExpression
  11936. $command = 'storeExpression';
  11937. break;
  11938. }
  11939. if (isset(self::$autoGeneratedCommands[$command]) && self::$autoGeneratedCommands[$command]['functionHelper']) {
  11940. $helperArguments = array($command, $arguments, self::$autoGeneratedCommands[$command]);
  11941. call_user_func_array(array($this, self::$autoGeneratedCommands[$command]['functionHelper']), $helperArguments);
  11942. } else {
  11943. $this->doCommand($command, $arguments);
  11944. }
  11945. // Post-Command Actions
  11946. switch ($command) {
  11947. case 'addLocationStrategy':
  11948. case 'allowNativeXpath':
  11949. case 'assignId':
  11950. case 'captureEntirePageScreenshot':
  11951. case 'captureScreenshot': {
  11952. // intentionally empty
  11953. }
  11954. break;
  11955. default: {
  11956. if ($wait) {
  11957. if ($this->useWaitForPageToLoad) {
  11958. $this->waitForPageToLoad($this->seleniumTimeout * 1000);
  11959. } else {
  11960. sleep($this->wait);
  11961. }
  11962. }
  11963. if ($this->sleep > 0) {
  11964. sleep($this->sleep);
  11965. }
  11966. $this->testCase->runDefaultAssertions($command);
  11967. }
  11968. }
  11969. }
  11970. break;
  11971. case 'getWhetherThisFrameMatchFrameExpression':
  11972. case 'getWhetherThisWindowMatchWindowExpression':
  11973. case 'isAlertPresent':
  11974. case 'isChecked':
  11975. case 'isConfirmationPresent':
  11976. case 'isCookiePresent':
  11977. case 'isEditable':
  11978. case 'isElementPresent':
  11979. case 'isOrdered':
  11980. case 'isPromptPresent':
  11981. case 'isSomethingSelected':
  11982. case 'isTextPresent':
  11983. case 'isVisible': {
  11984. return $this->getBoolean($command, $arguments);
  11985. }
  11986. break;
  11987. case 'getCssCount':
  11988. case 'getCursorPosition':
  11989. case 'getElementHeight':
  11990. case 'getElementIndex':
  11991. case 'getElementPositionLeft':
  11992. case 'getElementPositionTop':
  11993. case 'getElementWidth':
  11994. case 'getMouseSpeed':
  11995. case 'getSpeed':
  11996. case 'getXpathCount': {
  11997. $result = $this->getNumber($command, $arguments);
  11998. if ($wait) {
  11999. $this->waitForPageToLoad($this->seleniumTimeout * 1000);
  12000. }
  12001. return $result;
  12002. }
  12003. break;
  12004. case 'getAlert':
  12005. case 'getAttribute':
  12006. case 'getBodyText':
  12007. case 'getConfirmation':
  12008. case 'getCookie':
  12009. case 'getCookieByName':
  12010. case 'getEval':
  12011. case 'getExpression':
  12012. case 'getHtmlSource':
  12013. case 'getLocation':
  12014. case 'getLogMessages':
  12015. case 'getPrompt':
  12016. case 'getSelectedId':
  12017. case 'getSelectedIndex':
  12018. case 'getSelectedLabel':
  12019. case 'getSelectedValue':
  12020. case 'getTable':
  12021. case 'getText':
  12022. case 'getTitle':
  12023. case 'captureEntirePageScreenshotToString':
  12024. case 'captureScreenshotToString':
  12025. case 'getValue': {
  12026. $result = $this->getString($command, $arguments);
  12027. if ($wait) {
  12028. $this->waitForPageToLoad($this->seleniumTimeout * 1000);
  12029. }
  12030. return $result;
  12031. }
  12032. break;
  12033. case 'getAllButtons':
  12034. case 'getAllFields':
  12035. case 'getAllLinks':
  12036. case 'getAllWindowIds':
  12037. case 'getAllWindowNames':
  12038. case 'getAllWindowTitles':
  12039. case 'getAttributeFromAllWindows':
  12040. case 'getSelectedIds':
  12041. case 'getSelectedIndexes':
  12042. case 'getSelectedLabels':
  12043. case 'getSelectedValues':
  12044. case 'getSelectOptions': {
  12045. $result = $this->getStringArray($command, $arguments);
  12046. if ($wait) {
  12047. $this->waitForPageToLoad($this->seleniumTimeout * 1000);
  12048. }
  12049. return $result;
  12050. }
  12051. break;
  12052. case 'waitForCondition':
  12053. case 'waitForElementPresent':
  12054. case 'waitForElementNotPresent':
  12055. case 'waitForFrameToLoad':
  12056. case 'waitForPopUp': {
  12057. if (count($arguments) == 1) {
  12058. $arguments[] = $this->seleniumTimeout * 1000;
  12059. }
  12060. $this->doCommand($command, $arguments);
  12061. $this->testCase->runDefaultAssertions($command);
  12062. }
  12063. break;
  12064. case 'waitForPageToLoad': {
  12065. if (empty($arguments)) {
  12066. $arguments[] = $this->seleniumTimeout * 1000;
  12067. }
  12068. $this->doCommand($command, $arguments);
  12069. $this->testCase->runDefaultAssertions($command);
  12070. }
  12071. break;
  12072. default: {
  12073. if (!in_array($command, $this->userCommands)) {
  12074. throw new BadMethodCallException(
  12075. "Method $command not defined."
  12076. );
  12077. }
  12078. $this->doCommand($command, $arguments);
  12079. }
  12080. }
  12081. }
  12082. /**
  12083. * Send a command to the Selenium RC server.
  12084. *
  12085. * @param string $command
  12086. * @param array $arguments
  12087. * @param array $namedArguments
  12088. * @return string
  12089. * @author Seth Casana <totallymeat@gmail.org>
  12090. */
  12091. protected function doCommand($command, array $arguments = array(), array $namedArguments = array())
  12092. {
  12093. $url = sprintf(
  12094. 'http://%s:%s/selenium-server/driver/',
  12095. $this->host,
  12096. $this->port
  12097. );
  12098. $numArguments = count($arguments);
  12099. $postData = sprintf('cmd=%s', urlencode($command));
  12100. for ($i = 0; $i < $numArguments; $i++) {
  12101. $argNum = strval($i + 1);
  12102. if ($arguments[$i] == ' ') {
  12103. $postData .= sprintf('&%s=%s', $argNum, urlencode($arguments[$i]));
  12104. } else {
  12105. $postData .= sprintf('&%s=%s', $argNum, urlencode(trim($arguments[$i])));
  12106. }
  12107. }
  12108. foreach ($namedArguments as $key => $value) {
  12109. $postData .= sprintf('&%s=%s', $key, urlencode($value));
  12110. }
  12111. if (isset($this->sessionId)) {
  12112. $postData .= sprintf('&%s=%s', 'sessionId', $this->sessionId);
  12113. }
  12114. $curl = curl_init();
  12115. curl_setopt($curl, CURLOPT_URL, $url);
  12116. curl_setopt($curl, CURLOPT_HEADER, 0);
  12117. curl_setopt($curl, CURLOPT_POST, TRUE);
  12118. curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
  12119. curl_setopt($curl, CURLOPT_HTTPHEADER, array(
  12120. 'Content-Type: application/x-www-form-urlencoded; charset=utf-8'
  12121. ));
  12122. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  12123. curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
  12124. $response = curl_exec($curl);
  12125. $info = curl_getinfo($curl);
  12126. if (!$response) {
  12127. throw new RuntimeException("CURL error while accessing the Selenium Server at '$url': " . curl_error($curl));
  12128. }
  12129. curl_close($curl);
  12130. if (!preg_match('/^OK/', $response)) {
  12131. throw new RuntimeException("Invalid response while accessing the Selenium Server at '$url': " . $response);
  12132. }
  12133. if ($info['http_code'] != 200) {
  12134. throw new RuntimeException(
  12135. 'The response from the Selenium RC server is invalid: ' .
  12136. $response
  12137. );
  12138. }
  12139. return $response;
  12140. }
  12141. protected function preprocessParameters($params)
  12142. {
  12143. foreach ($params as $key => $param ) {
  12144. if (is_string($param) && (strlen($param) > 0)) {
  12145. $params[$key] = $this->getString('getExpression', array($param));
  12146. }
  12147. }
  12148. return $params;
  12149. }
  12150. /**
  12151. * Send a command to the Selenium RC server and treat the result
  12152. * as a boolean.
  12153. *
  12154. * @param string $command
  12155. * @param array $arguments
  12156. * @return boolean
  12157. * @author Shin Ohno <ganchiku@gmail.com>
  12158. * @author Bjoern Schotte <schotte@mayflower.de>
  12159. */
  12160. protected function getBoolean($command, array $arguments)
  12161. {
  12162. $result = $this->getString($command, $arguments);
  12163. switch ($result) {
  12164. case 'true': return TRUE;
  12165. case 'false': return FALSE;
  12166. default: {
  12167. throw new PHPUnit_Framework_Exception(
  12168. 'Result is neither "true" nor "false": ' . PHPUnit_Util_Type::export($result)
  12169. );
  12170. }
  12171. }
  12172. }
  12173. /**
  12174. * Send a command to the Selenium RC server and treat the result
  12175. * as a number.
  12176. *
  12177. * @param string $command
  12178. * @param array $arguments
  12179. * @return numeric
  12180. * @author Shin Ohno <ganchiku@gmail.com>
  12181. * @author Bjoern Schotte <schotte@mayflower.de>
  12182. */
  12183. protected function getNumber($command, array $arguments)
  12184. {
  12185. $result = $this->getString($command, $arguments);
  12186. if (!is_numeric($result)) {
  12187. throw new PHPUnit_Framework_Exception(
  12188. 'Result is not numeric: ' . PHPUnit_Util_Type::export($result)
  12189. );
  12190. }
  12191. return $result;
  12192. }
  12193. /**
  12194. * Send a command to the Selenium RC server and treat the result
  12195. * as a string.
  12196. *
  12197. * @param string $command
  12198. * @param array $arguments
  12199. * @return string
  12200. * @author Shin Ohno <ganchiku@gmail.com>
  12201. * @author Bjoern Schotte <schotte@mayflower.de>
  12202. */
  12203. protected function getString($command, array $arguments)
  12204. {
  12205. try {
  12206. $result = $this->doCommand($command, $arguments);
  12207. }
  12208. catch (RuntimeException $e) {
  12209. throw $e;
  12210. }
  12211. return (strlen($result) > 3) ? substr($result, 3) : '';
  12212. }
  12213. /**
  12214. * Send a command to the Selenium RC server and treat the result
  12215. * as an array of strings.
  12216. *
  12217. * @param string $command
  12218. * @param array $arguments
  12219. * @return array
  12220. * @author Shin Ohno <ganchiku@gmail.com>
  12221. * @author Bjoern Schotte <schotte@mayflower.de>
  12222. */
  12223. protected function getStringArray($command, array $arguments)
  12224. {
  12225. $csv = $this->getString($command, $arguments);
  12226. $token = '';
  12227. $tokens = array();
  12228. $letters = preg_split('//', $csv, -1, PREG_SPLIT_NO_EMPTY);
  12229. $count = count($letters);
  12230. for ($i = 0; $i < $count; $i++) {
  12231. $letter = $letters[$i];
  12232. switch($letter) {
  12233. case '\\': {
  12234. $letter = $letters[++$i];
  12235. $token .= $letter;
  12236. }
  12237. break;
  12238. case ',': {
  12239. $tokens[] = $token;
  12240. $token = '';
  12241. }
  12242. break;
  12243. default: {
  12244. $token .= $letter;
  12245. }
  12246. }
  12247. }
  12248. $tokens[] = $token;
  12249. return $tokens;
  12250. }
  12251. public function getVerificationErrors()
  12252. {
  12253. return $this->verificationErrors;
  12254. }
  12255. public function clearVerificationErrors()
  12256. {
  12257. $this->verificationErrors = array();
  12258. }
  12259. protected function assertCommand($command, $arguments, $info)
  12260. {
  12261. $method = $info['originalMethod'];
  12262. $requiresTarget = $info['requiresTarget'];
  12263. $result = $this->__call($method, $arguments);
  12264. $message = "Failed command: " . $command . "('"
  12265. . (array_key_exists(0, $arguments) ? $arguments[0] . "'" : '')
  12266. . (array_key_exists(1, $arguments) ? ", '" . $arguments[1] . "'" : '')
  12267. . ")";
  12268. if ($info['isBoolean']) {
  12269. if (!isset($info['negative']) || !$info['negative']) {
  12270. PHPUnit_Framework_Assert::assertTrue($result, $message);
  12271. } else {
  12272. PHPUnit_Framework_Assert::assertFalse($result, $message);
  12273. }
  12274. } else {
  12275. if ($requiresTarget === TRUE) {
  12276. $expected = $arguments[1];
  12277. } else {
  12278. $expected = $arguments[0];
  12279. }
  12280. if (strpos($expected, 'exact:') === 0) {
  12281. $expected = substr($expected, strlen('exact:'));
  12282. if (!isset($info['negative']) || !$info['negative']) {
  12283. PHPUnit_Framework_Assert::assertEquals($expected, $result, $message);
  12284. } else {
  12285. PHPUnit_Framework_Assert::assertNotEquals($expected, $result, $message);
  12286. }
  12287. } else {
  12288. $caseInsensitive = FALSE;
  12289. if (strpos($expected, 'regexp:') === 0) {
  12290. $expected = substr($expected, strlen('regexp:'));
  12291. }
  12292. else if (strpos($expected, 'regexpi:') === 0) {
  12293. $expected = substr($expected, strlen('regexpi:'));
  12294. $caseInsensitive = TRUE;
  12295. }
  12296. else {
  12297. if (strpos($expected, 'glob:') === 0) {
  12298. $expected = substr($expected, strlen('glob:'));
  12299. }
  12300. $expected = '^' . str_replace(
  12301. array('*', '?'), array('.*', '.?'), $expected
  12302. ) . '$';
  12303. }
  12304. $expected = '/' . str_replace('/', '\/', $expected) . '/';
  12305. if ($caseInsensitive) {
  12306. $expected .= 'i';
  12307. }
  12308. if (!isset($info['negative']) || !$info['negative']) {
  12309. PHPUnit_Framework_Assert::assertRegExp(
  12310. $expected, $result, $message
  12311. );
  12312. } else {
  12313. PHPUnit_Framework_Assert::assertNotRegExp(
  12314. $expected, $result, $message
  12315. );
  12316. }
  12317. }
  12318. }
  12319. }
  12320. protected function verifyCommand($command, $arguments, $info)
  12321. {
  12322. try {
  12323. $this->assertCommand($command, $arguments, $info);
  12324. }
  12325. catch (PHPUnit_Framework_AssertionFailedError $e) {
  12326. array_push($this->verificationErrors, $e->toString());
  12327. }
  12328. }
  12329. protected function waitForCommand($command, $arguments, $info)
  12330. {
  12331. $lastExceptionMessage = '';
  12332. for ($second = 0; ; $second++) {
  12333. if ($second > $this->httpTimeout) {
  12334. PHPUnit_Framework_Assert::fail(
  12335. "WaitFor timeout. \n"
  12336. . "Last exception message: \n" . $lastExceptionMessage
  12337. );
  12338. }
  12339. try {
  12340. $this->assertCommand($command, $arguments, $info);
  12341. return;
  12342. }
  12343. catch (Exception $e) {
  12344. $lastExceptionMessage = $e->getMessage();
  12345. }
  12346. sleep(1);
  12347. }
  12348. }
  12349. /**
  12350. * Parses the docblock of PHPUnit_Extensions_SeleniumTestCase_Driver::__call
  12351. * for get*(), is*(), assert*(), verify*(), assertNot*(), verifyNot*(),
  12352. * store*(), waitFor*(), and waitForNot*() methods.
  12353. */
  12354. protected static function autoGenerateCommands()
  12355. {
  12356. $method = new ReflectionMethod(__CLASS__, '__call');
  12357. $docComment = $method->getDocComment();
  12358. if (preg_match_all('(@method\s+(\w+)\s+([\w]+)\((.*)\))', $docComment, $matches)) {
  12359. foreach ($matches[2] as $methodKey => $method) {
  12360. if (preg_match('/^(get|is)([A-Z].+)$/', $method, $methodMatches)) {
  12361. $baseName = $methodMatches[2];
  12362. $isBoolean = $methodMatches[1] == 'is';
  12363. $requiresTarget = (strlen($matches[3][$methodKey]) > 0);
  12364. if (preg_match('/^(.*)Present$/', $baseName, $methodMatches)) {
  12365. $notBaseName = $methodMatches[1] . 'NotPresent';
  12366. } else {
  12367. $notBaseName = 'Not' . $baseName;
  12368. }
  12369. self::$autoGeneratedCommands['store' . $baseName] = array(
  12370. 'functionHelper' => FALSE
  12371. );
  12372. self::$autoGeneratedCommands['assert' . $baseName] = array(
  12373. 'originalMethod' => $method,
  12374. 'isBoolean' => $isBoolean,
  12375. 'functionHelper' => 'assertCommand',
  12376. 'requiresTarget' => $requiresTarget
  12377. );
  12378. self::$autoGeneratedCommands['assert' . $notBaseName] = array(
  12379. 'originalMethod' => $method,
  12380. 'isBoolean' => $isBoolean,
  12381. 'negative' => TRUE,
  12382. 'functionHelper' => 'assertCommand',
  12383. 'requiresTarget' => $requiresTarget
  12384. );
  12385. self::$autoGeneratedCommands['verify' . $baseName] = array(
  12386. 'originalMethod' => $method,
  12387. 'isBoolean' => $isBoolean,
  12388. 'functionHelper' => 'verifyCommand',
  12389. 'requiresTarget' => $requiresTarget
  12390. );
  12391. self::$autoGeneratedCommands['verify' . $notBaseName] = array(
  12392. 'originalMethod' => $method,
  12393. 'isBoolean' => $isBoolean,
  12394. 'negative' => TRUE,
  12395. 'functionHelper' => 'verifyCommand',
  12396. 'requiresTarget' => $requiresTarget
  12397. );
  12398. self::$autoGeneratedCommands['waitFor' . $baseName] = array(
  12399. 'originalMethod' => $method,
  12400. 'isBoolean' => $isBoolean,
  12401. 'functionHelper' => 'waitForCommand',
  12402. 'requiresTarget' => $requiresTarget
  12403. );
  12404. self::$autoGeneratedCommands['waitFor' . $notBaseName] = array(
  12405. 'originalMethod' => $method,
  12406. 'isBoolean' => $isBoolean,
  12407. 'negative' => TRUE,
  12408. 'functionHelper' => 'waitForCommand',
  12409. 'requiresTarget' => $requiresTarget
  12410. );
  12411. }
  12412. }
  12413. }
  12414. }
  12415. }
  12416. <?php
  12417. /**
  12418. * PHPUnit
  12419. *
  12420. * Copyright (c) 2010-2011, Sebastian Bergmann <sb@sebastian-bergmann.de>.
  12421. * All rights reserved.
  12422. *
  12423. * Redistribution and use in source and binary forms, with or without
  12424. * modification, are permitted provided that the following conditions
  12425. * are met:
  12426. *
  12427. * * Redistributions of source code must retain the above copyright
  12428. * notice, this list of conditions and the following disclaimer.
  12429. *
  12430. * * Redistributions in binary form must reproduce the above copyright
  12431. * notice, this list of conditions and the following disclaimer in
  12432. * the documentation and/or other materials provided with the
  12433. * distribution.
  12434. *
  12435. * * Neither the name of Sebastian Bergmann nor the names of his
  12436. * contributors may be used to endorse or promote products derived
  12437. * from this software without specific prior written permission.
  12438. *
  12439. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  12440. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12441. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  12442. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  12443. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  12444. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  12445. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  12446. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  12447. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  12448. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  12449. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  12450. * POSSIBILITY OF SUCH DAMAGE.
  12451. *
  12452. * @package PHPUnit_Selenium
  12453. * @author Ivan Kurnosov <zerkms@zerkms.com>
  12454. * @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
  12455. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12456. * @link http://www.phpunit.de/
  12457. * @since File available since Release 1.2.12
  12458. */
  12459. /**
  12460. * Class to hold the special keys Unicode entities
  12461. *
  12462. * @package PHPUnit_Selenium
  12463. * @author Ivan Kurnosov <zerkms@zerkms.com>
  12464. * @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
  12465. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12466. * @version Release: @package_version@
  12467. * @link http://www.phpunit.de/
  12468. * @since Class available since Release 1.3.0
  12469. * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/value
  12470. */
  12471. class PHPUnit_Extensions_Selenium2TestCase_Keys
  12472. {
  12473. const NULL = "\xEE\x80\x80";
  12474. const CANCEL = "\xEE\x80\x81";
  12475. const HELP = "\xEE\x80\x82";
  12476. const BACKSPACE = "\xEE\x80\x83";
  12477. const TAB = "\xEE\x80\x84";
  12478. const CLEAR = "\xEE\x80\x85";
  12479. const RETURN_ = "\xEE\x80\x86";
  12480. const ENTER = "\xEE\x80\x87";
  12481. const SHIFT = "\xEE\x80\x88";
  12482. const CONTROL = "\xEE\x80\x89";
  12483. const ALT = "\xEE\x80\x8A";
  12484. const PAUSE = "\xEE\x80\x8B";
  12485. const ESCAPE = "\xEE\x80\x8C";
  12486. const SPACE = "\xEE\x80\x8D";
  12487. const PAGEUP = "\xEE\x80\x8E";
  12488. const PAGEDOWN = "\xEE\x80\x8F";
  12489. const END = "\xEE\x80\x90";
  12490. const HOME = "\xEE\x80\x91";
  12491. const LEFT = "\xEE\x80\x92";
  12492. const UP = "\xEE\x80\x93";
  12493. const RIGHT = "\xEE\x80\x94";
  12494. const DOWN = "\xEE\x80\x95";
  12495. const INSERT = "\xEE\x80\x96";
  12496. const DELETE = "\xEE\x80\x97";
  12497. const SEMICOLON = "\xEE\x80\x98";
  12498. const EQUALS = "\xEE\x80\x99";
  12499. const NUMPAD0 = "\xEE\x80\x9A";
  12500. const NUMPAD1 = "\xEE\x80\x9B";
  12501. const NUMPAD2 = "\xEE\x80\x9C";
  12502. const NUMPAD3 = "\xEE\x80\x9D";
  12503. const NUMPAD4 = "\xEE\x80\x9E";
  12504. const NUMPAD5 = "\xEE\x80\x9F";
  12505. const NUMPAD6 = "\xEE\x80\xA0";
  12506. const NUMPAD7 = "\xEE\x80\xA1";
  12507. const NUMPAD8 = "\xEE\x80\xA2";
  12508. const NUMPAD9 = "\xEE\x80\xA3";
  12509. const MULTIPLY = "\xEE\x80\xA4";
  12510. const ADD = "\xEE\x80\xA5";
  12511. const SEPARATOR = "\xEE\x80\xA6";
  12512. const SUBTRACT = "\xEE\x80\xA7";
  12513. const DECIMAL = "\xEE\x80\xA8";
  12514. const DIVIDE = "\xEE\x80\xA9";
  12515. const F1 = "\xEE\x80\xB1";
  12516. const F2 = "\xEE\x80\xB2";
  12517. const F3 = "\xEE\x80\xB3";
  12518. const F4 = "\xEE\x80\xB4";
  12519. const F5 = "\xEE\x80\xB5";
  12520. const F6 = "\xEE\x80\xB6";
  12521. const F7 = "\xEE\x80\xB7";
  12522. const F8 = "\xEE\x80\xB8";
  12523. const F9 = "\xEE\x80\xB9";
  12524. const F10 = "\xEE\x80\xBA";
  12525. const F11 = "\xEE\x80\xBB";
  12526. const F12 = "\xEE\x80\xBC";
  12527. const COMMAND = "\xEE\x80\xBD";
  12528. }
  12529. <?php
  12530. /**
  12531. * PHPUnit
  12532. *
  12533. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  12534. * All rights reserved.
  12535. *
  12536. * Redistribution and use in source and binary forms, with or without
  12537. * modification, are permitted provided that the following conditions
  12538. * are met:
  12539. *
  12540. * * Redistributions of source code must retain the above copyright
  12541. * notice, this list of conditions and the following disclaimer.
  12542. *
  12543. * * Redistributions in binary form must reproduce the above copyright
  12544. * notice, this list of conditions and the following disclaimer in
  12545. * the documentation and/or other materials provided with the
  12546. * distribution.
  12547. *
  12548. * * Neither the name of Sebastian Bergmann nor the names of his
  12549. * contributors may be used to endorse or promote products derived
  12550. * from this software without specific prior written permission.
  12551. *
  12552. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  12553. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12554. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  12555. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  12556. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  12557. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  12558. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  12559. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  12560. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  12561. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  12562. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  12563. * POSSIBILITY OF SUCH DAMAGE.
  12564. *
  12565. * @package PHPUnit_Selenium
  12566. * @author Giorgio Sironi <info@giorgiosironi.com>
  12567. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12568. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12569. * @link http://www.phpunit.de/
  12570. * @since File available since Release 1.2.6
  12571. */
  12572. /**
  12573. * Adds a cookie.
  12574. *
  12575. * @package PHPUnit_Selenium
  12576. * @author Giorgio Sironi <info@giorgiosironi.com>
  12577. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12578. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12579. * @version Release: @package_version@
  12580. * @link http://www.phpunit.de/
  12581. * @since Class available since Release 1.2.6
  12582. */
  12583. class PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder
  12584. {
  12585. private $name;
  12586. private $value;
  12587. private $path;
  12588. private $domain;
  12589. private $secure = FALSE;
  12590. private $expiry;
  12591. public function __construct($cookieFacade, $name, $value)
  12592. {
  12593. $this->cookieFacade = $cookieFacade;
  12594. $this->name = $name;
  12595. $this->value = $value;
  12596. }
  12597. /**
  12598. * @param string
  12599. * @return PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder
  12600. */
  12601. public function path($path)
  12602. {
  12603. $this->path = $path;
  12604. return $this;
  12605. }
  12606. /**
  12607. * @param string
  12608. * @return PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder
  12609. */
  12610. public function domain($domain)
  12611. {
  12612. $this->domain = $domain;
  12613. return $this;
  12614. }
  12615. /**
  12616. * @param boolean
  12617. * @return PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder
  12618. */
  12619. public function secure($secure)
  12620. {
  12621. $this->secure = $secure;
  12622. return $this;
  12623. }
  12624. /**
  12625. * @param integer
  12626. * @return PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder
  12627. */
  12628. public function expiry($expiry)
  12629. {
  12630. $this->expiry = $expiry;
  12631. return $this;
  12632. }
  12633. /**
  12634. * @return void
  12635. */
  12636. public function set()
  12637. {
  12638. $cookieData = array(
  12639. 'name' => $this->name,
  12640. 'value' => $this->value,
  12641. 'secure' => $this->secure,
  12642. );
  12643. foreach (array('path', 'domain', 'expiry') as $parameter) {
  12644. if ($this->$parameter !== NULL) {
  12645. $cookieData[$parameter] = $this->$parameter;
  12646. }
  12647. }
  12648. $this->cookieFacade->postCookie($cookieData);
  12649. }
  12650. }
  12651. <?php
  12652. /**
  12653. * PHPUnit
  12654. *
  12655. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  12656. * All rights reserved.
  12657. *
  12658. * Redistribution and use in source and binary forms, with or without
  12659. * modification, are permitted provided that the following conditions
  12660. * are met:
  12661. *
  12662. * * Redistributions of source code must retain the above copyright
  12663. * notice, this list of conditions and the following disclaimer.
  12664. *
  12665. * * Redistributions in binary form must reproduce the above copyright
  12666. * notice, this list of conditions and the following disclaimer in
  12667. * the documentation and/or other materials provided with the
  12668. * distribution.
  12669. *
  12670. * * Neither the name of Sebastian Bergmann nor the names of his
  12671. * contributors may be used to endorse or promote products derived
  12672. * from this software without specific prior written permission.
  12673. *
  12674. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  12675. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12676. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  12677. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  12678. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  12679. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  12680. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  12681. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  12682. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  12683. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  12684. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  12685. * POSSIBILITY OF SUCH DAMAGE.
  12686. *
  12687. * @package PHPUnit_Selenium
  12688. * @author Giorgio Sironi <info@giorgiosironi.com>
  12689. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12690. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12691. * @link http://www.phpunit.de/
  12692. * @since File available since Release 1.2.4
  12693. */
  12694. /**
  12695. * Manages timeouts for the current browser session.
  12696. *
  12697. * @package PHPUnit_Selenium
  12698. * @author Giorgio Sironi <info@giorgiosironi.com>
  12699. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12700. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12701. * @version Release: @package_version@
  12702. * @link http://www.phpunit.de/
  12703. * @since Class available since Release 1.2.4
  12704. * @method implicitWait(int $ms) Sets timeout when searching for elements
  12705. * @method asyncScript(int $ms) Sets timeout for asynchronous scripts executed by Session::executeAsync()
  12706. */
  12707. class PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts
  12708. extends PHPUnit_Extensions_Selenium2TestCase_CommandsHolder
  12709. {
  12710. private $maximumTimeout;
  12711. private $lastImplicitWaitValue = 0;
  12712. public function __construct($driver,
  12713. PHPUnit_Extensions_Selenium2TestCase_URL $url,
  12714. $maximumTimeout)
  12715. {
  12716. parent::__construct($driver, $url);
  12717. $this->maximumTimeout = $maximumTimeout;
  12718. }
  12719. protected function initCommands()
  12720. {
  12721. $self = $this;
  12722. return array(
  12723. 'implicitWait' => function ($milliseconds, $commandUrl) use ($self) {
  12724. $self->check($milliseconds);
  12725. $self->setLastImplicitWaitValue($milliseconds);
  12726. $jsonParameters = array('ms' => $milliseconds);
  12727. return new PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost($jsonParameters, $commandUrl);
  12728. },
  12729. 'asyncScript' => function ($milliseconds, $commandUrl) use ($self) {
  12730. $self->check($milliseconds);
  12731. $jsonParameters = array('ms' => $milliseconds);
  12732. return new PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost($jsonParameters, $commandUrl);
  12733. },
  12734. );
  12735. }
  12736. public function setLastImplicitWaitValue($implicitWait)
  12737. {
  12738. $this->lastImplicitWaitValue = $implicitWait;
  12739. }
  12740. public function getLastImplicitWaitValue()
  12741. {
  12742. return $this->lastImplicitWaitValue;
  12743. }
  12744. public function check($timeout)
  12745. {
  12746. if ($timeout > $this->maximumTimeout) {
  12747. throw new PHPUnit_Extensions_Selenium2TestCase_Exception('There is no use in setting this timeout unless you also call $this->setSeleniumServerRequestsTimeout($seconds) in setUp().');
  12748. }
  12749. }
  12750. }
  12751. <?php
  12752. /**
  12753. * PHPUnit
  12754. *
  12755. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  12756. * All rights reserved.
  12757. *
  12758. * Redistribution and use in source and binary forms, with or without
  12759. * modification, are permitted provided that the following conditions
  12760. * are met:
  12761. *
  12762. * * Redistributions of source code must retain the above copyright
  12763. * notice, this list of conditions and the following disclaimer.
  12764. *
  12765. * * Redistributions in binary form must reproduce the above copyright
  12766. * notice, this list of conditions and the following disclaimer in
  12767. * the documentation and/or other materials provided with the
  12768. * distribution.
  12769. *
  12770. * * Neither the name of Sebastian Bergmann nor the names of his
  12771. * contributors may be used to endorse or promote products derived
  12772. * from this software without specific prior written permission.
  12773. *
  12774. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  12775. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12776. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  12777. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  12778. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  12779. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  12780. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  12781. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  12782. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  12783. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  12784. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  12785. * POSSIBILITY OF SUCH DAMAGE.
  12786. *
  12787. * @package PHPUnit_Selenium
  12788. * @author Giorgio Sironi <info@giorgiosironi.com>
  12789. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12790. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12791. * @link http://www.phpunit.de/
  12792. * @since File available since Release 1.2.6
  12793. */
  12794. /**
  12795. * Manage the local storage HTML 5 database.
  12796. *
  12797. * @package PHPUnit_Selenium
  12798. * @author Giorgio Sironi <info@giorgiosironi.com>
  12799. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12800. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12801. * @version Release: @package_version@
  12802. * @link http://www.phpunit.de/
  12803. * @since Class available since Release 1.2.6
  12804. */
  12805. class PHPUnit_Extensions_Selenium2TestCase_Session_Storage
  12806. {
  12807. private $driver;
  12808. private $url;
  12809. public function __construct(PHPUnit_Extensions_Selenium2TestCase_Driver $driver,
  12810. PHPUnit_Extensions_Selenium2TestCase_URL $url)
  12811. {
  12812. $this->driver = $driver;
  12813. $this->url = $url;
  12814. }
  12815. public function __set($name, $value)
  12816. {
  12817. $this->driver->curl('POST', $this->url, array(
  12818. 'key' => $name,
  12819. 'value' => (string)$value
  12820. ));
  12821. }
  12822. public function __get($name)
  12823. {
  12824. return $this->driver->curl(
  12825. 'GET',
  12826. $this->url->descend('key')->descend($name)
  12827. )->getValue();
  12828. }
  12829. }
  12830. <?php
  12831. /**
  12832. * PHPUnit
  12833. *
  12834. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  12835. * All rights reserved.
  12836. *
  12837. * Redistribution and use in source and binary forms, with or without
  12838. * modification, are permitted provided that the following conditions
  12839. * are met:
  12840. *
  12841. * * Redistributions of source code must retain the above copyright
  12842. * notice, this list of conditions and the following disclaimer.
  12843. *
  12844. * * Redistributions in binary form must reproduce the above copyright
  12845. * notice, this list of conditions and the following disclaimer in
  12846. * the documentation and/or other materials provided with the
  12847. * distribution.
  12848. *
  12849. * * Neither the name of Sebastian Bergmann nor the names of his
  12850. * contributors may be used to endorse or promote products derived
  12851. * from this software without specific prior written permission.
  12852. *
  12853. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  12854. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12855. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  12856. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  12857. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  12858. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  12859. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  12860. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  12861. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  12862. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  12863. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  12864. * POSSIBILITY OF SUCH DAMAGE.
  12865. *
  12866. * @package PHPUnit_Selenium
  12867. * @author Giorgio Sironi <info@giorgiosironi.com>
  12868. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12869. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12870. * @link http://www.phpunit.de/
  12871. * @since File available since Release 1.2.6
  12872. */
  12873. /**
  12874. * Adds and remove cookies.
  12875. *
  12876. * @package PHPUnit_Selenium
  12877. * @author Giorgio Sironi <info@giorgiosironi.com>
  12878. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12879. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12880. * @version Release: @package_version@
  12881. * @link http://www.phpunit.de/
  12882. * @since Class available since Release 1.2.6
  12883. */
  12884. class PHPUnit_Extensions_Selenium2TestCase_Session_Cookie
  12885. {
  12886. private $driver;
  12887. private $url;
  12888. public function __construct(PHPUnit_Extensions_Selenium2TestCase_Driver $driver,
  12889. PHPUnit_Extensions_Selenium2TestCase_URL $url)
  12890. {
  12891. $this->driver = $driver;
  12892. $this->url = $url;
  12893. }
  12894. /**
  12895. * @param string $name
  12896. * @param string $value
  12897. * @return void
  12898. */
  12899. public function add($name, $value)
  12900. {
  12901. return new PHPUnit_Extensions_Selenium2TestCase_Session_Cookie_Builder($this, $name, $value);
  12902. }
  12903. /**
  12904. * @param string $name
  12905. * @return string
  12906. */
  12907. public function get($name)
  12908. {
  12909. $cookies = $this->driver->curl('GET', $this->url)->getValue();
  12910. foreach ($cookies as $cookie) {
  12911. if ($cookie['name'] == $name) {
  12912. return $cookie['value'];
  12913. }
  12914. }
  12915. throw new PHPUnit_Extensions_Selenium2TestCase_Exception("There is no '$name' cookie available on this page.");
  12916. }
  12917. /**
  12918. * @param string $name
  12919. * @return void
  12920. */
  12921. public function remove($name)
  12922. {
  12923. $url = $this->url->descend($name);
  12924. $this->driver->curl('DELETE', $url);
  12925. }
  12926. /**
  12927. * @return void
  12928. */
  12929. public function clear()
  12930. {
  12931. $this->driver->curl('DELETE', $this->url);
  12932. }
  12933. /**
  12934. * @internal
  12935. * @param array $data
  12936. * @return void
  12937. */
  12938. public function postCookie(array $data)
  12939. {
  12940. $this->driver->curl('POST',
  12941. $this->url,
  12942. array(
  12943. 'cookie' => $data
  12944. ));
  12945. }
  12946. }
  12947. <?php
  12948. /**
  12949. * PHPUnit
  12950. *
  12951. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  12952. * All rights reserved.
  12953. *
  12954. * Redistribution and use in source and binary forms, with or without
  12955. * modification, are permitted provided that the following conditions
  12956. * are met:
  12957. *
  12958. * * Redistributions of source code must retain the above copyright
  12959. * notice, this list of conditions and the following disclaimer.
  12960. *
  12961. * * Redistributions in binary form must reproduce the above copyright
  12962. * notice, this list of conditions and the following disclaimer in
  12963. * the documentation and/or other materials provided with the
  12964. * distribution.
  12965. *
  12966. * * Neither the name of Sebastian Bergmann nor the names of his
  12967. * contributors may be used to endorse or promote products derived
  12968. * from this software without specific prior written permission.
  12969. *
  12970. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  12971. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12972. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  12973. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  12974. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  12975. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  12976. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  12977. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  12978. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  12979. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  12980. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  12981. * POSSIBILITY OF SUCH DAMAGE.
  12982. *
  12983. * @package PHPUnit_Selenium
  12984. * @author Giorgio Sironi <info@giorgiosironi.com>
  12985. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12986. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12987. * @link http://www.phpunit.de/
  12988. * @since File available since Release 1.2.6
  12989. */
  12990. /**
  12991. * Indicates an exception during the execution of Selenium 2 commands.
  12992. *
  12993. * @package PHPUnit_Selenium
  12994. * @author Giorgio Sironi <info@giorgiosironi.com>
  12995. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  12996. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  12997. * @version Release: @package_version@
  12998. * @link http://www.phpunit.de/
  12999. * @since Class available since Release 1.2.6
  13000. */
  13001. class PHPUnit_Extensions_Selenium2TestCase_Exception extends RuntimeException
  13002. {
  13003. }
  13004. <?php
  13005. /**
  13006. * PHPUnit
  13007. *
  13008. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13009. * All rights reserved.
  13010. *
  13011. * Redistribution and use in source and binary forms, with or without
  13012. * modification, are permitted provided that the following conditions
  13013. * are met:
  13014. *
  13015. * * Redistributions of source code must retain the above copyright
  13016. * notice, this list of conditions and the following disclaimer.
  13017. *
  13018. * * Redistributions in binary form must reproduce the above copyright
  13019. * notice, this list of conditions and the following disclaimer in
  13020. * the documentation and/or other materials provided with the
  13021. * distribution.
  13022. *
  13023. * * Neither the name of Sebastian Bergmann nor the names of his
  13024. * contributors may be used to endorse or promote products derived
  13025. * from this software without specific prior written permission.
  13026. *
  13027. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13028. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13029. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13030. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13031. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13032. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13033. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13034. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13035. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13036. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13037. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13038. * POSSIBILITY OF SUCH DAMAGE.
  13039. *
  13040. * @package PHPUnit_Selenium
  13041. * @author Giorgio Sironi <info@giorgiosironi.com>
  13042. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13043. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13044. * @link http://www.phpunit.de/
  13045. * @since File available since Release 1.2.4
  13046. */
  13047. /**
  13048. * Object representing elements, or everything that may have subcommands.
  13049. *
  13050. * @package PHPUnit_Selenium
  13051. * @author Giorgio Sironi <info@giorgiosironi.com>
  13052. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13053. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13054. * @version Release: @package_version@
  13055. * @link http://www.phpunit.de/
  13056. * @since Class available since Release 1.2.4
  13057. */
  13058. abstract class PHPUnit_Extensions_Selenium2TestCase_CommandsHolder
  13059. {
  13060. /**
  13061. * @var PHPUnit_Extensions_Selenium2TestCase_Driver
  13062. */
  13063. protected $driver;
  13064. /**
  13065. * @var string the API URL for this element,
  13066. */
  13067. protected $url;
  13068. /**
  13069. * @var array instances of
  13070. * PHPUnit_Extensions_Selenium2TestCase_ElementCommand
  13071. */
  13072. protected $commands;
  13073. public function __construct($driver,
  13074. PHPUnit_Extensions_Selenium2TestCase_URL $url)
  13075. {
  13076. $this->driver = $driver;
  13077. $this->url = $url;
  13078. $this->commands = array();
  13079. foreach ($this->initCommands() as $commandName => $handler) {
  13080. if (is_string($handler)) {
  13081. $this->commands[$commandName] = $this->factoryMethod($handler);
  13082. } else if (is_callable($handler)) {
  13083. $this->commands[$commandName] = $handler;
  13084. } else {
  13085. throw new InvalidArgumentException("Command $commandName is not configured correctly.");
  13086. }
  13087. }
  13088. }
  13089. /**
  13090. * @return array class names, or
  13091. * callables of the form function($parameter, $commandUrl)
  13092. */
  13093. protected abstract function initCommands();
  13094. public function __call($commandName, $arguments)
  13095. {
  13096. $jsonParameters = $this->extractJsonParameters($arguments);
  13097. $response = $this->driver->execute($this->newCommand($commandName, $jsonParameters));
  13098. return $response->getValue();
  13099. }
  13100. protected function postCommand($name, PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria)
  13101. {
  13102. $response = $this->driver->curl('POST',
  13103. $this->url->addCommand($name),
  13104. $criteria->getArrayCopy());
  13105. return $response->getValue();
  13106. }
  13107. /**
  13108. * @params string $commandClass a class name, descending from
  13109. PHPUnit_Extensions_Selenium2TestCase_Command
  13110. * @return callable
  13111. */
  13112. private function factoryMethod($commandClass)
  13113. {
  13114. return function($jsonParameters, $url) use ($commandClass) {
  13115. return new $commandClass($jsonParameters, $url);
  13116. };
  13117. }
  13118. private function extractJsonParameters($arguments)
  13119. {
  13120. $this->checkArguments($arguments);
  13121. if (count($arguments) == 0) {
  13122. return NULL;
  13123. }
  13124. return $arguments[0];
  13125. }
  13126. private function checkArguments($arguments)
  13127. {
  13128. if (count($arguments) > 1) {
  13129. throw new Exception('You cannot call a command with multiple method arguments.');
  13130. }
  13131. }
  13132. /**
  13133. * @param string $commandName The called method name
  13134. * defined as a key in initCommands()
  13135. * @param array $jsonParameters
  13136. * @return PHPUnit_Extensions_Selenium2TestCase_Command
  13137. */
  13138. protected function newCommand($commandName, $jsonParameters)
  13139. {
  13140. if (isset($this->commands[$commandName])) {
  13141. $factoryMethod = $this->commands[$commandName];
  13142. $url = $this->url->addCommand($commandName);
  13143. $command = $factoryMethod($jsonParameters, $url);
  13144. return $command;
  13145. }
  13146. throw new BadMethodCallException("The command '$commandName' is not existent or not supported yet.");
  13147. }
  13148. }
  13149. <?php
  13150. /**
  13151. * PHPUnit
  13152. *
  13153. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13154. * All rights reserved.
  13155. *
  13156. * Redistribution and use in source and binary forms, with or without
  13157. * modification, are permitted provided that the following conditions
  13158. * are met:
  13159. *
  13160. * * Redistributions of source code must retain the above copyright
  13161. * notice, this list of conditions and the following disclaimer.
  13162. *
  13163. * * Redistributions in binary form must reproduce the above copyright
  13164. * notice, this list of conditions and the following disclaimer in
  13165. * the documentation and/or other materials provided with the
  13166. * distribution.
  13167. *
  13168. * * Neither the name of Sebastian Bergmann nor the names of his
  13169. * contributors may be used to endorse or promote products derived
  13170. * from this software without specific prior written permission.
  13171. *
  13172. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13173. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13174. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13175. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13176. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13177. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13178. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13179. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13180. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13181. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13182. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13183. * POSSIBILITY OF SUCH DAMAGE.
  13184. *
  13185. * @package PHPUnit_Selenium
  13186. * @author Giorgio Sironi <info@giorgiosironi.com>
  13187. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13188. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13189. * @link http://www.phpunit.de/
  13190. * @since File available since Release 1.2.8
  13191. */
  13192. /**
  13193. * Base class for implementing commands with special semantics.
  13194. *
  13195. * @package PHPUnit_Selenium
  13196. * @author Giorgio Sironi <info@giorgiosironi.com>
  13197. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13198. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13199. * @version Release: @package_version@
  13200. * @link http://www.phpunit.de/
  13201. * @since Class available since Release 1.2.8
  13202. */
  13203. class PHPUnit_Extensions_Selenium2TestCase_ScreenshotListener implements PHPUnit_Framework_TestListener
  13204. {
  13205. private $directory;
  13206. public function __construct($directory)
  13207. {
  13208. $this->directory = $directory;
  13209. }
  13210. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  13211. {
  13212. $this->storeAScreenshot($test);
  13213. }
  13214. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  13215. {
  13216. $this->storeAScreenshot($test);
  13217. }
  13218. private function storeAScreenshot(PHPUnit_Framework_Test $test)
  13219. {
  13220. if ($test instanceof PHPUnit_Extensions_Selenium2TestCase)
  13221. {
  13222. try {
  13223. $file = $this->directory . '/' . get_class($test) . '__' . $test->getName() . '__' . date('Y-m-d\TH-i-s') . '.png';
  13224. file_put_contents($file, $test->currentScreenshot());
  13225. } catch (Exception $e) {
  13226. $file = $this->directory . '/' . get_class($test) . '__' . $test->getName() . '__' . date('Y-m-d\TH-i-s') . '.txt';
  13227. file_put_contents($file, "Screenshot generation doesn't work." . "\n"
  13228. . $e->getMessage() . "\n"
  13229. . $e->getTraceAsString());
  13230. }
  13231. }
  13232. }
  13233. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) {}
  13234. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) {}
  13235. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time) {}
  13236. public function startTest(PHPUnit_Framework_Test $test) {}
  13237. public function endTest(PHPUnit_Framework_Test $test, $time) {}
  13238. public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {}
  13239. public function endTestSuite(PHPUnit_Framework_TestSuite $suite) {}
  13240. }
  13241. <?php
  13242. /**
  13243. * PHPUnit
  13244. *
  13245. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13246. * All rights reserved.
  13247. *
  13248. * Redistribution and use in source and binary forms, with or without
  13249. * modification, are permitted provided that the following conditions
  13250. * are met:
  13251. *
  13252. * * Redistributions of source code must retain the above copyright
  13253. * notice, this list of conditions and the following disclaimer.
  13254. *
  13255. * * Redistributions in binary form must reproduce the above copyright
  13256. * notice, this list of conditions and the following disclaimer in
  13257. * the documentation and/or other materials provided with the
  13258. * distribution.
  13259. *
  13260. * * Neither the name of Sebastian Bergmann nor the names of his
  13261. * contributors may be used to endorse or promote products derived
  13262. * from this software without specific prior written permission.
  13263. *
  13264. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13265. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13266. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13267. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13268. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13269. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13270. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13271. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13272. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13273. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13274. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13275. * POSSIBILITY OF SUCH DAMAGE.
  13276. *
  13277. * @package PHPUnit_Selenium
  13278. * @author Giorgio Sironi <info@giorgiosironi.com>
  13279. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13280. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13281. * @link http://www.phpunit.de/
  13282. * @since File available since Release 1.2.0
  13283. */
  13284. /**
  13285. * Base class for implementing commands with special semantics.
  13286. *
  13287. * @package PHPUnit_Selenium
  13288. * @author Giorgio Sironi <info@giorgiosironi.com>
  13289. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13290. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13291. * @version Release: @package_version@
  13292. * @link http://www.phpunit.de/
  13293. * @since Class available since Release 1.2.0
  13294. */
  13295. abstract class PHPUnit_Extensions_Selenium2TestCase_Command
  13296. {
  13297. protected $jsonParameters;
  13298. private $commandName;
  13299. /**
  13300. * @param array $jsonParameters null in case of no parameters
  13301. */
  13302. public function __construct($jsonParameters,
  13303. PHPUnit_Extensions_Selenium2TestCase_URL $url)
  13304. {
  13305. if (!is_array($jsonParameters) && $jsonParameters !== NULL) {
  13306. throw new InvalidArgumentException("The JSON parameters must be an array, or a NULL value in case they are not required.");
  13307. }
  13308. $this->jsonParameters = $jsonParameters;
  13309. $this->url = $url;
  13310. }
  13311. public function url()
  13312. {
  13313. return $this->url;
  13314. }
  13315. /**
  13316. * @return string
  13317. */
  13318. abstract public function httpMethod();
  13319. /**
  13320. * @param array $jsonParameters null in case of no parameters
  13321. */
  13322. public function jsonParameters()
  13323. {
  13324. return $this->jsonParameters;
  13325. }
  13326. }
  13327. <?php
  13328. /**
  13329. * PHPUnit
  13330. *
  13331. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13332. * All rights reserved.
  13333. *
  13334. * Redistribution and use in source and binary forms, with or without
  13335. * modification, are permitted provided that the following conditions
  13336. * are met:
  13337. *
  13338. * * Redistributions of source code must retain the above copyright
  13339. * notice, this list of conditions and the following disclaimer.
  13340. *
  13341. * * Redistributions in binary form must reproduce the above copyright
  13342. * notice, this list of conditions and the following disclaimer in
  13343. * the documentation and/or other materials provided with the
  13344. * distribution.
  13345. *
  13346. * * Neither the name of Sebastian Bergmann nor the names of his
  13347. * contributors may be used to endorse or promote products derived
  13348. * from this software without specific prior written permission.
  13349. *
  13350. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13351. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13352. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13353. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13354. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13355. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13356. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13357. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13358. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13359. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13360. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13361. * POSSIBILITY OF SUCH DAMAGE.
  13362. *
  13363. * @package PHPUnit_Selenium
  13364. * @author Giorgio Sironi <info@giorgiosironi.com>
  13365. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13366. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13367. * @link http://www.phpunit.de/
  13368. * @since File available since Release 1.2.5
  13369. */
  13370. /**
  13371. * Gets or sets an attribute of an object.
  13372. *
  13373. * @package PHPUnit_Selenium
  13374. * @author Giorgio Sironi <info@giorgiosironi.com>
  13375. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13376. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13377. * @version Release: @package_version@
  13378. * @link http://www.phpunit.de/
  13379. * @since Class available since Release 1.2.5
  13380. */
  13381. class PHPUnit_Extensions_Selenium2TestCase_StateCommand
  13382. extends PHPUnit_Extensions_Selenium2TestCase_Command
  13383. {
  13384. public function httpMethod()
  13385. {
  13386. if ($this->jsonParameters) {
  13387. return 'POST';
  13388. }
  13389. return 'GET';
  13390. }
  13391. }
  13392. <?php
  13393. /**
  13394. * PHPUnit
  13395. *
  13396. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13397. * All rights reserved.
  13398. *
  13399. * Redistribution and use in source and binary forms, with or without
  13400. * modification, are permitted provided that the following conditions
  13401. * are met:
  13402. *
  13403. * * Redistributions of source code must retain the above copyright
  13404. * notice, this list of conditions and the following disclaimer.
  13405. *
  13406. * * Redistributions in binary form must reproduce the above copyright
  13407. * notice, this list of conditions and the following disclaimer in
  13408. * the documentation and/or other materials provided with the
  13409. * distribution.
  13410. *
  13411. * * Neither the name of Sebastian Bergmann nor the names of his
  13412. * contributors may be used to endorse or promote products derived
  13413. * from this software without specific prior written permission.
  13414. *
  13415. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13416. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13417. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13418. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13419. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13420. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13421. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13422. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13423. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13424. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13425. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13426. * POSSIBILITY OF SUCH DAMAGE.
  13427. *
  13428. * @package PHPUnit_Selenium
  13429. * @author Giorgio Sironi <info@giorgiosironi.com>
  13430. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13431. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13432. * @link http://www.phpunit.de/
  13433. * @since File available since Release 1.2.0
  13434. */
  13435. /**
  13436. * Object representing a DOM element.
  13437. *
  13438. * @package PHPUnit_Selenium
  13439. * @author Giorgio Sironi <info@giorgiosironi.com>
  13440. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13441. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13442. * @version Release: @package_version@
  13443. * @link http://www.phpunit.de/
  13444. * @since Class available since Release 1.2.0
  13445. * @method string attribute($name) Retrieves an element's attribute
  13446. * @method void clear() Empties the content of a form element.
  13447. * @method void click() Clicks on element
  13448. * @method string css($propertyName) Retrieves the value of a CSS property
  13449. * @method bool displayed() Checks an element's visibility
  13450. * @method bool enabled() Checks a form element's state
  13451. * @method bool equals(PHPUnit_Extensions_Selenium2TestCase_Element $another) Checks if the two elements are the same on the page
  13452. * @method array location() Retrieves the element's position in the page: keys 'x' and 'y' in the returned array
  13453. * @method bool selected() Checks the state of an option or other form element
  13454. * @method array size() Retrieves the dimensions of the element: 'width' and 'height' of the returned array
  13455. * @method void submit() Submits a form; can be called on its children
  13456. * @method string text() Get content of ordinary elements
  13457. */
  13458. class PHPUnit_Extensions_Selenium2TestCase_Element
  13459. extends PHPUnit_Extensions_Selenium2TestCase_Element_Accessor
  13460. {
  13461. /**
  13462. * @return \self
  13463. * @throws InvalidArgumentException
  13464. */
  13465. public static function fromResponseValue(
  13466. array $value,
  13467. PHPUnit_Extensions_Selenium2TestCase_URL $parentFolder,
  13468. PHPUnit_Extensions_Selenium2TestCase_Driver $driver)
  13469. {
  13470. if (!isset($value['ELEMENT'])) {
  13471. throw new InvalidArgumentException('Element not found.');
  13472. }
  13473. $url = $parentFolder->descend($value['ELEMENT']);
  13474. return new self($driver, $url);
  13475. }
  13476. /**
  13477. * @return integer
  13478. */
  13479. public function getId()
  13480. {
  13481. return $this->url->lastSegment();
  13482. }
  13483. /**
  13484. * @return array class names
  13485. */
  13486. protected function initCommands()
  13487. {
  13488. return array(
  13489. 'attribute' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Attribute',
  13490. 'clear' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  13491. 'click' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Click',
  13492. 'css' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Css',
  13493. 'displayed' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
  13494. 'enabled' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
  13495. 'equals' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Equals',
  13496. 'location' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
  13497. 'name' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
  13498. 'selected' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
  13499. 'size' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
  13500. 'submit' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  13501. 'text' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
  13502. 'value' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Value',
  13503. 'tap' => $this->touchCommandFactoryMethod('touch/click'),
  13504. 'scroll' => $this->touchCommandFactoryMethod('touch/scroll'),
  13505. 'doubletap' => $this->touchCommandFactoryMethod('touch/doubleclick'),
  13506. 'longtap' => $this->touchCommandFactoryMethod('touch/longclick'),
  13507. 'flick' => $this->touchCommandFactoryMethod('touch/flick')
  13508. );
  13509. }
  13510. protected function getSessionUrl()
  13511. {
  13512. return $this->url->ascend()->ascend();
  13513. }
  13514. private function touchCommandFactoryMethod($urlSegment)
  13515. {
  13516. $url = $this->getSessionUrl()->addCommand($urlSegment);
  13517. $self = $this;
  13518. return function ($jsonParameters, $commandUrl) use ($url, $self) {
  13519. if ((is_array($jsonParameters) &&
  13520. !isset($jsonParameters['element'])) ||
  13521. is_null($jsonParameters)) {
  13522. $jsonParameters['element'] = $self->getId();
  13523. }
  13524. return new PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost($jsonParameters, $url);
  13525. };
  13526. }
  13527. /**
  13528. * Retrieves the tag name
  13529. * @return string
  13530. */
  13531. public function name()
  13532. {
  13533. return strtolower(parent::name());
  13534. }
  13535. /**
  13536. * Generates an array that is structured as the WebDriver Object of the JSONWireProtocoll
  13537. *
  13538. * @return array
  13539. */
  13540. public function toWebDriverObject()
  13541. {
  13542. return array('ELEMENT' => (string)$this->getId());
  13543. }
  13544. /**
  13545. * Get or set value of form elements. If the element already has a value, the set one will be appended to it.
  13546. * Created **ONLY** for keeping backward compatibility, since in selenium v2.42.0 it was removed
  13547. * The currently recommended solution is to use `$element->attribute('value')`
  13548. * @see https://code.google.com/p/selenium/source/detail?r=953007b48e83f90450f3e41b11ec31e2928f1605
  13549. * @see https://code.google.com/p/selenium/source/browse/java/CHANGELOG
  13550. *
  13551. * @param string $newValue
  13552. * @return null|string
  13553. */
  13554. public function value($newValue = NULL)
  13555. {
  13556. if ($newValue !== NULL) {
  13557. return parent::value($newValue);
  13558. }
  13559. return $this->attribute('value');
  13560. }
  13561. }
  13562. <?php
  13563. /**
  13564. * PHPUnit
  13565. *
  13566. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13567. * All rights reserved.
  13568. *
  13569. * Redistribution and use in source and binary forms, with or without
  13570. * modification, are permitted provided that the following conditions
  13571. * are met:
  13572. *
  13573. * * Redistributions of source code must retain the above copyright
  13574. * notice, this list of conditions and the following disclaimer.
  13575. *
  13576. * * Redistributions in binary form must reproduce the above copyright
  13577. * notice, this list of conditions and the following disclaimer in
  13578. * the documentation and/or other materials provided with the
  13579. * distribution.
  13580. *
  13581. * * Neither the name of Sebastian Bergmann nor the names of his
  13582. * contributors may be used to endorse or promote products derived
  13583. * from this software without specific prior written permission.
  13584. *
  13585. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13586. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13587. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13588. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13589. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13590. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13591. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13592. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13593. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13594. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13595. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13596. * POSSIBILITY OF SUCH DAMAGE.
  13597. *
  13598. * @package PHPUnit_Selenium
  13599. * @author Giorgio Sironi <info@giorgiosironi.com>
  13600. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13601. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13602. * @link http://www.phpunit.de/
  13603. * @since File available since Release 1.2.0
  13604. */
  13605. /**
  13606. * Object representing an HTTP response from the Selenium Server.
  13607. *
  13608. * @package PHPUnit_Selenium
  13609. * @author Giorgio Sironi <info@giorgiosironi.com>
  13610. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13611. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13612. * @version Release: @package_version@
  13613. * @link http://www.phpunit.de/
  13614. * @since Class available since Release 1.2.0
  13615. */
  13616. class PHPUnit_Extensions_Selenium2TestCase_Response
  13617. {
  13618. /**
  13619. * @var array decoded response
  13620. */
  13621. private $jsonResponse;
  13622. /**
  13623. * @var array CURL info for the response.
  13624. */
  13625. private $info;
  13626. public function __construct($jsonResponse, $info)
  13627. {
  13628. $this->jsonResponse = $jsonResponse;
  13629. $this->info = $info;
  13630. }
  13631. public function getValue()
  13632. {
  13633. if (isset($this->jsonResponse['value'])) {
  13634. return $this->jsonResponse['value'];
  13635. }
  13636. }
  13637. /**
  13638. * @return PHPUnit_Extensions_Selenium2TestCase_URL
  13639. */
  13640. public function getURL()
  13641. {
  13642. $url = $this->info['url'];
  13643. $sessionId = $this->jsonResponse['sessionId'];
  13644. // if url doesn't have sessionId included - append it manually
  13645. // this change was performed in selenium v2.34
  13646. // @see https://code.google.com/p/selenium/issues/detail?id=6089
  13647. // @see https://github.com/sebastianbergmann/phpunit-selenium/issues/265
  13648. if (strpos($url, $sessionId) === FALSE) {
  13649. $url .= '/' . $sessionId;
  13650. }
  13651. return new PHPUnit_Extensions_Selenium2TestCase_URL($url);
  13652. }
  13653. }
  13654. <?php
  13655. /**
  13656. * PHPUnit
  13657. *
  13658. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13659. * All rights reserved.
  13660. *
  13661. * Redistribution and use in source and binary forms, with or without
  13662. * modification, are permitted provided that the following conditions
  13663. * are met:
  13664. *
  13665. * * Redistributions of source code must retain the above copyright
  13666. * notice, this list of conditions and the following disclaimer.
  13667. *
  13668. * * Redistributions in binary form must reproduce the above copyright
  13669. * notice, this list of conditions and the following disclaimer in
  13670. * the documentation and/or other materials provided with the
  13671. * distribution.
  13672. *
  13673. * * Neither the name of Sebastian Bergmann nor the names of his
  13674. * contributors may be used to endorse or promote products derived
  13675. * from this software without specific prior written permission.
  13676. *
  13677. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13678. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13679. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13680. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13681. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13682. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13683. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13684. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13685. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13686. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13687. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13688. * POSSIBILITY OF SUCH DAMAGE.
  13689. *
  13690. * @package PHPUnit_Selenium
  13691. * @author Giorgio Sironi <info@giorgiosironi.com>
  13692. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13693. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13694. * @link http://www.phpunit.de/
  13695. * @since File available since Release 1.2.9
  13696. */
  13697. /**
  13698. * @package PHPUnit_Selenium
  13699. * @author Giorgio Sironi <info@giorgiosironi.com>
  13700. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13701. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13702. * @version Release: @package_version@
  13703. * @link http://www.phpunit.de/
  13704. * @since Class available since Release 1.2.8
  13705. */
  13706. class PHPUnit_Extensions_Selenium2TestCase_NoSeleniumException
  13707. extends PHPUnit_Extensions_Selenium2TestCase_Exception
  13708. {
  13709. }
  13710. <?php
  13711. /**
  13712. * PHPUnit
  13713. *
  13714. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13715. * All rights reserved.
  13716. *
  13717. * Redistribution and use in source and binary forms, with or without
  13718. * modification, are permitted provided that the following conditions
  13719. * are met:
  13720. *
  13721. * * Redistributions of source code must retain the above copyright
  13722. * notice, this list of conditions and the following disclaimer.
  13723. *
  13724. * * Redistributions in binary form must reproduce the above copyright
  13725. * notice, this list of conditions and the following disclaimer in
  13726. * the documentation and/or other materials provided with the
  13727. * distribution.
  13728. *
  13729. * * Neither the name of Sebastian Bergmann nor the names of his
  13730. * contributors may be used to endorse or promote products derived
  13731. * from this software without specific prior written permission.
  13732. *
  13733. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13734. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13735. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13736. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13737. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13738. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13739. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13740. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13741. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13742. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13743. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13744. * POSSIBILITY OF SUCH DAMAGE.
  13745. *
  13746. * @package PHPUnit_Selenium
  13747. * @author Giorgio Sironi <info@giorgiosironi.com>
  13748. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13749. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13750. * @link http://www.phpunit.de/
  13751. * @since File available since Release 1.2.6
  13752. */
  13753. /**
  13754. * Keeps a Session object shared between test runs to save time.
  13755. *
  13756. * @package PHPUnit_Selenium
  13757. * @author Giorgio Sironi <info@giorgiosironi.com>
  13758. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13759. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13760. * @version Release: @package_version@
  13761. * @link http://www.phpunit.de/
  13762. * @since Class available since Release 1.2.6
  13763. */
  13764. class PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Shared
  13765. implements PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
  13766. {
  13767. private $original;
  13768. private $session;
  13769. private $mainWindow;
  13770. private $lastTestWasNotSuccessful = FALSE;
  13771. public function __construct(PHPUnit_Extensions_Selenium2TestCase_SessionStrategy $originalStrategy)
  13772. {
  13773. $this->original = $originalStrategy;
  13774. }
  13775. public function session(array $parameters)
  13776. {
  13777. if ($this->lastTestWasNotSuccessful) {
  13778. if ($this->session !== NULL) {
  13779. $this->session->stop();
  13780. $this->session = NULL;
  13781. }
  13782. $this->lastTestWasNotSuccessful = FALSE;
  13783. }
  13784. if ($this->session === NULL) {
  13785. $this->session = $this->original->session($parameters);
  13786. $this->mainWindow = $this->session->windowHandle();
  13787. } else {
  13788. $this->session->window($this->mainWindow);
  13789. }
  13790. return $this->session;
  13791. }
  13792. public function notSuccessfulTest()
  13793. {
  13794. $this->lastTestWasNotSuccessful = TRUE;
  13795. }
  13796. public function endOfTest(PHPUnit_Extensions_Selenium2TestCase_Session $session = NULL)
  13797. {
  13798. }
  13799. }
  13800. <?php
  13801. /**
  13802. * PHPUnit
  13803. *
  13804. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13805. * All rights reserved.
  13806. *
  13807. * Redistribution and use in source and binary forms, with or without
  13808. * modification, are permitted provided that the following conditions
  13809. * are met:
  13810. *
  13811. * * Redistributions of source code must retain the above copyright
  13812. * notice, this list of conditions and the following disclaimer.
  13813. *
  13814. * * Redistributions in binary form must reproduce the above copyright
  13815. * notice, this list of conditions and the following disclaimer in
  13816. * the documentation and/or other materials provided with the
  13817. * distribution.
  13818. *
  13819. * * Neither the name of Sebastian Bergmann nor the names of his
  13820. * contributors may be used to endorse or promote products derived
  13821. * from this software without specific prior written permission.
  13822. *
  13823. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13824. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13825. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13826. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13827. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13828. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13829. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13830. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13831. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13832. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13833. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13834. * POSSIBILITY OF SUCH DAMAGE.
  13835. *
  13836. * @package PHPUnit_Selenium
  13837. * @author Giorgio Sironi <info@giorgiosironi.com>
  13838. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13839. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13840. * @link http://www.phpunit.de/
  13841. * @since File available since Release 1.2.6
  13842. */
  13843. /**
  13844. * Produces a new Session object shared for each test.
  13845. *
  13846. * @package PHPUnit_Selenium
  13847. * @author Giorgio Sironi <info@giorgiosironi.com>
  13848. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13849. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13850. * @version Release: @package_version@
  13851. * @link http://www.phpunit.de/
  13852. * @since Class available since Release 1.2.6
  13853. */
  13854. class PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Isolated
  13855. implements PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
  13856. {
  13857. public function session(array $parameters)
  13858. {
  13859. $seleniumServerUrl = PHPUnit_Extensions_Selenium2TestCase_URL::fromHostAndPort($parameters['host'], $parameters['port']);
  13860. $driver = new PHPUnit_Extensions_Selenium2TestCase_Driver($seleniumServerUrl, $parameters['seleniumServerRequestsTimeout']);
  13861. $capabilities = array_merge($parameters['desiredCapabilities'],
  13862. array(
  13863. 'browserName' => $parameters['browserName']
  13864. ));
  13865. $session = $driver->startSession($capabilities, $parameters['browserUrl']);
  13866. return $session;
  13867. }
  13868. public function notSuccessfulTest()
  13869. {
  13870. }
  13871. public function endOfTest(PHPUnit_Extensions_Selenium2TestCase_Session $session = NULL)
  13872. {
  13873. if ($session !== NULL) {
  13874. $session->stop();
  13875. }
  13876. }
  13877. }
  13878. <?php
  13879. /**
  13880. * PHPUnit
  13881. *
  13882. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13883. * All rights reserved.
  13884. *
  13885. * Redistribution and use in source and binary forms, with or without
  13886. * modification, are permitted provided that the following conditions
  13887. * are met:
  13888. *
  13889. * * Redistributions of source code must retain the above copyright
  13890. * notice, this list of conditions and the following disclaimer.
  13891. *
  13892. * * Redistributions in binary form must reproduce the above copyright
  13893. * notice, this list of conditions and the following disclaimer in
  13894. * the documentation and/or other materials provided with the
  13895. * distribution.
  13896. *
  13897. * * Neither the name of Sebastian Bergmann nor the names of his
  13898. * contributors may be used to endorse or promote products derived
  13899. * from this software without specific prior written permission.
  13900. *
  13901. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13902. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13903. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13904. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13905. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13906. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13907. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13908. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13909. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13910. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13911. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13912. * POSSIBILITY OF SUCH DAMAGE.
  13913. *
  13914. * @package PHPUnit_Selenium
  13915. * @author Giorgio Sironi <info@giorgiosironi.com>
  13916. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13917. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13918. * @link http://www.phpunit.de/
  13919. * @since File available since Release 1.2.0
  13920. */
  13921. /**
  13922. * Clicks ok on an alert popup.
  13923. *
  13924. * @package PHPUnit_Selenium
  13925. * @author Giorgio Sironi <info@giorgiosironi.com>
  13926. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13927. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13928. * @version Release: @package_version@
  13929. * @link http://www.phpunit.de/
  13930. * @since Class available since Release 1.2.0
  13931. */
  13932. class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Click
  13933. extends PHPUnit_Extensions_Selenium2TestCase_Command
  13934. {
  13935. public function httpMethod()
  13936. {
  13937. return 'POST';
  13938. }
  13939. }
  13940. <?php
  13941. /**
  13942. * PHPUnit
  13943. *
  13944. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  13945. * All rights reserved.
  13946. *
  13947. * Redistribution and use in source and binary forms, with or without
  13948. * modification, are permitted provided that the following conditions
  13949. * are met:
  13950. *
  13951. * * Redistributions of source code must retain the above copyright
  13952. * notice, this list of conditions and the following disclaimer.
  13953. *
  13954. * * Redistributions in binary form must reproduce the above copyright
  13955. * notice, this list of conditions and the following disclaimer in
  13956. * the documentation and/or other materials provided with the
  13957. * distribution.
  13958. *
  13959. * * Neither the name of Sebastian Bergmann nor the names of his
  13960. * contributors may be used to endorse or promote products derived
  13961. * from this software without specific prior written permission.
  13962. *
  13963. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  13964. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  13965. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  13966. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  13967. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  13968. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  13969. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  13970. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  13971. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  13972. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  13973. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  13974. * POSSIBILITY OF SUCH DAMAGE.
  13975. *
  13976. * @package PHPUnit_Selenium
  13977. * @author Giorgio Sironi <info@giorgiosironi.com>
  13978. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13979. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13980. * @link http://www.phpunit.de/
  13981. * @since File available since Release 1.2.4
  13982. */
  13983. /**
  13984. * Checks equality (same element on the page) with another DOM element.
  13985. *
  13986. * @package PHPUnit_Selenium
  13987. * @author Giorgio Sironi <info@giorgiosironi.com>
  13988. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  13989. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  13990. * @version Release: @package_version@
  13991. * @link http://www.phpunit.de/
  13992. * @since Class available since Release 1.2.4
  13993. */
  13994. class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Equals
  13995. extends PHPUnit_Extensions_Selenium2TestCase_Command
  13996. {
  13997. /**
  13998. * @param array $parameter
  13999. */
  14000. public function __construct($parameter,
  14001. PHPUnit_Extensions_Selenium2TestCase_URL $equalsResourceBaseUrl)
  14002. {
  14003. $this->jsonParameters = array();
  14004. if (!($parameter instanceof PHPUnit_Extensions_Selenium2TestCase_Element)) {
  14005. throw new InvalidArgumentException("Elements can only test equality with other Element instances.");
  14006. }
  14007. $this->url = $equalsResourceBaseUrl->descend($parameter->getId());
  14008. }
  14009. public function httpMethod()
  14010. {
  14011. return 'GET';
  14012. }
  14013. }
  14014. <?php
  14015. /**
  14016. * PHPUnit
  14017. *
  14018. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14019. * All rights reserved.
  14020. *
  14021. * Redistribution and use in source and binary forms, with or without
  14022. * modification, are permitted provided that the following conditions
  14023. * are met:
  14024. *
  14025. * * Redistributions of source code must retain the above copyright
  14026. * notice, this list of conditions and the following disclaimer.
  14027. *
  14028. * * Redistributions in binary form must reproduce the above copyright
  14029. * notice, this list of conditions and the following disclaimer in
  14030. * the documentation and/or other materials provided with the
  14031. * distribution.
  14032. *
  14033. * * Neither the name of Sebastian Bergmann nor the names of his
  14034. * contributors may be used to endorse or promote products derived
  14035. * from this software without specific prior written permission.
  14036. *
  14037. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14038. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14039. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14040. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14041. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14042. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14043. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14044. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14045. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14046. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14047. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14048. * POSSIBILITY OF SUCH DAMAGE.
  14049. *
  14050. * @package PHPUnit_Selenium
  14051. * @author Giorgio Sironi <info@giorgiosironi.com>
  14052. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14053. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14054. * @link http://www.phpunit.de/
  14055. * @since File available since Release 1.2.0
  14056. */
  14057. /**
  14058. * Class for implementing commands that just return a value
  14059. * (obtained with GET).
  14060. *
  14061. * @package PHPUnit_Selenium
  14062. * @author Giorgio Sironi <info@giorgiosironi.com>
  14063. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14064. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14065. * @version Release: @package_version@
  14066. * @link http://www.phpunit.de/
  14067. * @since Class available since Release 1.2.0
  14068. */
  14069. class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor
  14070. extends PHPUnit_Extensions_Selenium2TestCase_Command
  14071. {
  14072. public function httpMethod()
  14073. {
  14074. return 'GET';
  14075. }
  14076. }
  14077. <?php
  14078. /**
  14079. * PHPUnit
  14080. *
  14081. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14082. * All rights reserved.
  14083. *
  14084. * Redistribution and use in source and binary forms, with or without
  14085. * modification, are permitted provided that the following conditions
  14086. * are met:
  14087. *
  14088. * * Redistributions of source code must retain the above copyright
  14089. * notice, this list of conditions and the following disclaimer.
  14090. *
  14091. * * Redistributions in binary form must reproduce the above copyright
  14092. * notice, this list of conditions and the following disclaimer in
  14093. * the documentation and/or other materials provided with the
  14094. * distribution.
  14095. *
  14096. * * Neither the name of Sebastian Bergmann nor the names of his
  14097. * contributors may be used to endorse or promote products derived
  14098. * from this software without specific prior written permission.
  14099. *
  14100. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14101. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14102. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14103. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14104. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14105. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14106. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14107. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14108. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14109. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14110. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14111. * POSSIBILITY OF SUCH DAMAGE.
  14112. *
  14113. * @package PHPUnit_Selenium
  14114. * @author Giorgio Sironi <info@giorgiosironi.com>
  14115. * @copyright 2012 Sebastian Bergmann <sebastian@phpunit.de>
  14116. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14117. * @link http://www.phpunit.de/
  14118. * @since File available since Release 1.2.4
  14119. */
  14120. /**
  14121. * Class for implementing commands that just accomplishes an action (via POST).
  14122. *
  14123. * @package PHPUnit_Selenium
  14124. * @author Giorgio Sironi <info@giorgiosironi.com>
  14125. * @copyright 2012 Sebastian Bergmann <sebastian@phpunit.de>
  14126. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14127. * @version Release: @package_version@
  14128. * @link http://www.phpunit.de/
  14129. * @since Class available since Release 1.2.4
  14130. */
  14131. class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost
  14132. extends PHPUnit_Extensions_Selenium2TestCase_Command
  14133. {
  14134. public function httpMethod()
  14135. {
  14136. return 'POST';
  14137. }
  14138. }
  14139. <?php
  14140. /**
  14141. * PHPUnit
  14142. *
  14143. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14144. * All rights reserved.
  14145. *
  14146. * Redistribution and use in source and binary forms, with or without
  14147. * modification, are permitted provided that the following conditions
  14148. * are met:
  14149. *
  14150. * * Redistributions of source code must retain the above copyright
  14151. * notice, this list of conditions and the following disclaimer.
  14152. *
  14153. * * Redistributions in binary form must reproduce the above copyright
  14154. * notice, this list of conditions and the following disclaimer in
  14155. * the documentation and/or other materials provided with the
  14156. * distribution.
  14157. *
  14158. * * Neither the name of Sebastian Bergmann nor the names of his
  14159. * contributors may be used to endorse or promote products derived
  14160. * from this software without specific prior written permission.
  14161. *
  14162. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14163. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14164. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14165. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14166. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14167. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14168. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14169. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14170. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14171. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14172. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14173. * POSSIBILITY OF SUCH DAMAGE.
  14174. *
  14175. * @package PHPUnit_Selenium
  14176. * @author Giorgio Sironi <info@giorgiosironi.com>
  14177. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14178. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14179. * @link http://www.phpunit.de/
  14180. * @since File available since Release 1.2.0
  14181. */
  14182. /**
  14183. * Get and set the element's value attribute.
  14184. *
  14185. * @package PHPUnit_Selenium
  14186. * @author Giorgio Sironi <info@giorgiosironi.com>
  14187. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14188. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14189. * @version Release: @package_version@
  14190. * @link http://www.phpunit.de/
  14191. * @since Class available since Release 1.2.0
  14192. */
  14193. class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Value
  14194. extends PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Keys
  14195. {
  14196. public function httpMethod()
  14197. {
  14198. if ($this->jsonParameters) {
  14199. return 'POST';
  14200. }
  14201. throw new BadMethodCallException("JSON Wire Protocol only supports POST to /value now. To get the value of an element GET /attribute/:naem should be used and this object should never be involved.");
  14202. }
  14203. }
  14204. <?php
  14205. /**
  14206. * PHPUnit
  14207. *
  14208. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14209. * All rights reserved.
  14210. *
  14211. * Redistribution and use in source and binary forms, with or without
  14212. * modification, are permitted provided that the following conditions
  14213. * are met:
  14214. *
  14215. * * Redistributions of source code must retain the above copyright
  14216. * notice, this list of conditions and the following disclaimer.
  14217. *
  14218. * * Redistributions in binary form must reproduce the above copyright
  14219. * notice, this list of conditions and the following disclaimer in
  14220. * the documentation and/or other materials provided with the
  14221. * distribution.
  14222. *
  14223. * * Neither the name of Sebastian Bergmann nor the names of his
  14224. * contributors may be used to endorse or promote products derived
  14225. * from this software without specific prior written permission.
  14226. *
  14227. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14228. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14229. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14230. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14231. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14232. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14233. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14234. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14235. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14236. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14237. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14238. * POSSIBILITY OF SUCH DAMAGE.
  14239. *
  14240. * @package PHPUnit_Selenium
  14241. * @author Giorgio Sironi <info@giorgiosironi.com>
  14242. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14243. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14244. * @link http://www.phpunit.de/
  14245. * @since File available since Release 1.2.4
  14246. */
  14247. /**
  14248. * Retrieves an attribute of a DOM element.
  14249. *
  14250. * @package PHPUnit_Selenium
  14251. * @author Giorgio Sironi <info@giorgiosironi.com>
  14252. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14253. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14254. * @version Release: @package_version@
  14255. * @link http://www.phpunit.de/
  14256. * @since Class available since Release 1.2.4
  14257. */
  14258. class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Attribute
  14259. extends PHPUnit_Extensions_Selenium2TestCase_Command
  14260. {
  14261. /**
  14262. * @param array $parameter
  14263. */
  14264. public function __construct($parameter,
  14265. PHPUnit_Extensions_Selenium2TestCase_URL $attributeResourceBaseUrl)
  14266. {
  14267. $this->jsonParameters = array();
  14268. $this->url = $attributeResourceBaseUrl->descend($parameter);
  14269. }
  14270. public function httpMethod()
  14271. {
  14272. return 'GET';
  14273. }
  14274. }
  14275. <?php
  14276. /**
  14277. * PHPUnit
  14278. *
  14279. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14280. * All rights reserved.
  14281. *
  14282. * Redistribution and use in source and binary forms, with or without
  14283. * modification, are permitted provided that the following conditions
  14284. * are met:
  14285. *
  14286. * * Redistributions of source code must retain the above copyright
  14287. * notice, this list of conditions and the following disclaimer.
  14288. *
  14289. * * Redistributions in binary form must reproduce the above copyright
  14290. * notice, this list of conditions and the following disclaimer in
  14291. * the documentation and/or other materials provided with the
  14292. * distribution.
  14293. *
  14294. * * Neither the name of Sebastian Bergmann nor the names of his
  14295. * contributors may be used to endorse or promote products derived
  14296. * from this software without specific prior written permission.
  14297. *
  14298. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14299. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14300. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14301. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14302. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14303. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14304. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14305. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14306. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14307. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14308. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14309. * POSSIBILITY OF SUCH DAMAGE.
  14310. *
  14311. * @package PHPUnit_Selenium
  14312. * @author Giorgio Sironi <info@giorgiosironi.com>
  14313. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14314. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14315. * @link http://www.phpunit.de/
  14316. * @since File available since Release 1.2.4
  14317. */
  14318. /**
  14319. * Retrieves the value of a CSS property.
  14320. *
  14321. * @package PHPUnit_Selenium
  14322. * @author Giorgio Sironi <info@giorgiosironi.com>
  14323. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14324. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14325. * @version Release: @package_version@
  14326. * @link http://www.phpunit.de/
  14327. * @since Class available since Release 1.2.4
  14328. */
  14329. class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Css
  14330. extends PHPUnit_Extensions_Selenium2TestCase_Command
  14331. {
  14332. /**
  14333. * @param array $propertyName
  14334. */
  14335. public function __construct($propertyName,
  14336. PHPUnit_Extensions_Selenium2TestCase_URL $cssResourceBaseUrl)
  14337. {
  14338. $this->jsonParameters = array();
  14339. $this->url = $cssResourceBaseUrl->descend($propertyName);
  14340. }
  14341. public function httpMethod()
  14342. {
  14343. return 'GET';
  14344. }
  14345. }
  14346. <?php
  14347. /**
  14348. * PHPUnit
  14349. *
  14350. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14351. * All rights reserved.
  14352. *
  14353. * Redistribution and use in source and binary forms, with or without
  14354. * modification, are permitted provided that the following conditions
  14355. * are met:
  14356. *
  14357. * * Redistributions of source code must retain the above copyright
  14358. * notice, this list of conditions and the following disclaimer.
  14359. *
  14360. * * Redistributions in binary form must reproduce the above copyright
  14361. * notice, this list of conditions and the following disclaimer in
  14362. * the documentation and/or other materials provided with the
  14363. * distribution.
  14364. *
  14365. * * Neither the name of Sebastian Bergmann nor the names of his
  14366. * contributors may be used to endorse or promote products derived
  14367. * from this software without specific prior written permission.
  14368. *
  14369. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14370. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14371. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14372. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14373. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14374. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14375. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14376. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14377. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14378. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14379. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14380. * POSSIBILITY OF SUCH DAMAGE.
  14381. *
  14382. * @package PHPUnit_Selenium
  14383. * @author Giorgio Sironi <info@giorgiosironi.com>
  14384. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14385. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14386. * @link http://www.phpunit.de/
  14387. * @since File available since Release 1.2.0
  14388. */
  14389. /**
  14390. * Conditions for selecting a DOM element.
  14391. *
  14392. * @package PHPUnit_Selenium
  14393. * @author Giorgio Sironi <info@giorgiosironi.com>
  14394. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14395. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14396. * @version Release: @package_version@
  14397. * @link http://www.phpunit.de/
  14398. * @since Class available since Release 1.2.0
  14399. * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element
  14400. */
  14401. class PHPUnit_Extensions_Selenium2TestCase_ElementCriteria extends ArrayObject
  14402. {
  14403. public function __construct($strategy)
  14404. {
  14405. $this['using'] = $strategy;
  14406. }
  14407. /**
  14408. * @return PHPUnit_Extensions_Selenium2TestCase_ElementCriteria
  14409. */
  14410. public function value($searchTarget)
  14411. {
  14412. $this['value'] = $searchTarget;
  14413. return $this;
  14414. }
  14415. }
  14416. <?php
  14417. /**
  14418. * PHPUnit
  14419. *
  14420. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14421. * All rights reserved.
  14422. *
  14423. * Redistribution and use in source and binary forms, with or without
  14424. * modification, are permitted provided that the following conditions
  14425. * are met:
  14426. *
  14427. * * Redistributions of source code must retain the above copyright
  14428. * notice, this list of conditions and the following disclaimer.
  14429. *
  14430. * * Redistributions in binary form must reproduce the above copyright
  14431. * notice, this list of conditions and the following disclaimer in
  14432. * the documentation and/or other materials provided with the
  14433. * distribution.
  14434. *
  14435. * * Neither the name of Sebastian Bergmann nor the names of his
  14436. * contributors may be used to endorse or promote products derived
  14437. * from this software without specific prior written permission.
  14438. *
  14439. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14440. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14441. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14442. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14443. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14444. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14445. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14446. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14447. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14448. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14449. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14450. * POSSIBILITY OF SUCH DAMAGE.
  14451. *
  14452. * @package PHPUnit_Selenium
  14453. * @author Giorgio Sironi <info@giorgiosironi.com>
  14454. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14455. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14456. * @link http://www.phpunit.de/
  14457. * @since File available since Release 1.2.5
  14458. */
  14459. /**
  14460. * Object representing a browser window.
  14461. *
  14462. * @package PHPUnit_Selenium
  14463. * @author Giorgio Sironi <info@giorgiosironi.com>
  14464. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14465. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14466. * @version Release: @package_version@
  14467. * @link http://www.phpunit.de/
  14468. * @since Class available since Release 1.2.5
  14469. * @method array size(array $size = null) Window size as array('width' => $x, 'height' => $y)
  14470. * @method array position(array $position = null) Window position as array('x' => $x, 'y' => $y)
  14471. * @method array maximize() Maximize window
  14472. */
  14473. class PHPUnit_Extensions_Selenium2TestCase_Window extends PHPUnit_Extensions_Selenium2TestCase_CommandsHolder
  14474. {
  14475. /**
  14476. * @return array class names
  14477. */
  14478. protected function initCommands()
  14479. {
  14480. return array(
  14481. 'size' => 'PHPUnit_Extensions_Selenium2TestCase_StateCommand',
  14482. 'position' => 'PHPUnit_Extensions_Selenium2TestCase_StateCommand',
  14483. 'maximize' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  14484. );
  14485. }
  14486. }
  14487. <?php
  14488. /**
  14489. * PHPUnit
  14490. *
  14491. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14492. * All rights reserved.
  14493. *
  14494. * Redistribution and use in source and binary forms, with or without
  14495. * modification, are permitted provided that the following conditions
  14496. * are met:
  14497. *
  14498. * * Redistributions of source code must retain the above copyright
  14499. * notice, this list of conditions and the following disclaimer.
  14500. *
  14501. * * Redistributions in binary form must reproduce the above copyright
  14502. * notice, this list of conditions and the following disclaimer in
  14503. * the documentation and/or other materials provided with the
  14504. * distribution.
  14505. *
  14506. * * Neither the name of Sebastian Bergmann nor the names of his
  14507. * contributors may be used to endorse or promote products derived
  14508. * from this software without specific prior written permission.
  14509. *
  14510. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14511. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14512. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14513. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14514. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14515. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14516. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14517. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14518. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14519. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14520. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14521. * POSSIBILITY OF SUCH DAMAGE.
  14522. *
  14523. * @package PHPUnit_Selenium
  14524. * @author Giorgio Sironi <info@giorgiosironi.com>
  14525. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14526. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14527. * @link http://www.phpunit.de/
  14528. * @since File available since Release 1.2.0
  14529. */
  14530. /**
  14531. * Driver for creating browser session with Selenium 2 (WebDriver API).
  14532. *
  14533. * @package PHPUnit_Selenium
  14534. * @author Giorgio Sironi <info@giorgiosironi.com>
  14535. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14536. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14537. * @version Release: @package_version@
  14538. * @link http://www.phpunit.de/
  14539. * @since Class available since Release 1.2.0
  14540. */
  14541. class PHPUnit_Extensions_Selenium2TestCase_Driver
  14542. {
  14543. private $seleniumServerUrl;
  14544. private $seleniumServerRequestsTimeout;
  14545. public function __construct(PHPUnit_Extensions_Selenium2TestCase_URL $seleniumServerUrl, $timeout = 60)
  14546. {
  14547. $this->seleniumServerUrl = $seleniumServerUrl;
  14548. $this->seleniumServerRequestsTimeout = $timeout;
  14549. }
  14550. public function startSession(array $desiredCapabilities, PHPUnit_Extensions_Selenium2TestCase_URL $browserUrl)
  14551. {
  14552. $sessionCreation = $this->seleniumServerUrl->descend("/wd/hub/session");
  14553. $response = $this->curl('POST', $sessionCreation, array(
  14554. 'desiredCapabilities' => $desiredCapabilities
  14555. ));
  14556. $sessionPrefix = $response->getURL();
  14557. $timeouts = new PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts(
  14558. $this,
  14559. $sessionPrefix->descend('timeouts'),
  14560. $this->seleniumServerRequestsTimeout * 1000
  14561. );
  14562. return new PHPUnit_Extensions_Selenium2TestCase_Session(
  14563. $this,
  14564. $sessionPrefix,
  14565. $browserUrl,
  14566. $timeouts
  14567. );
  14568. }
  14569. /**
  14570. * Performs an HTTP request to the Selenium 2 server.
  14571. *
  14572. * @param string $method 'GET'|'POST'|'DELETE'|...
  14573. * @param string $url
  14574. * @param array $params JSON parameters for POST requests
  14575. */
  14576. public function curl($http_method,
  14577. PHPUnit_Extensions_Selenium2TestCase_URL $url,
  14578. $params = NULL)
  14579. {
  14580. $curl = curl_init($url->getValue());
  14581. curl_setopt($curl, CURLOPT_TIMEOUT, $this->seleniumServerRequestsTimeout);
  14582. curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
  14583. curl_setopt($curl,
  14584. CURLOPT_HTTPHEADER,
  14585. array(
  14586. 'Content-type: application/json;charset=UTF-8',
  14587. 'Accept: application/json;charset=UTF-8'
  14588. ));
  14589. if ($http_method === 'POST') {
  14590. curl_setopt($curl, CURLOPT_POST, TRUE);
  14591. if ($params && is_array($params)) {
  14592. curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params));
  14593. } else {
  14594. curl_setopt($curl, CURLOPT_POSTFIELDS, '');
  14595. }
  14596. curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
  14597. } else if ($http_method == 'DELETE') {
  14598. curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
  14599. }
  14600. $rawResponse = trim(curl_exec($curl));
  14601. if (curl_errno($curl)) {
  14602. throw new PHPUnit_Extensions_Selenium2TestCase_NoSeleniumException(
  14603. 'Error connection[' . curl_errno($curl) . '] to ' .
  14604. $url->getValue() . ': ' . curl_error($curl)
  14605. );
  14606. }
  14607. $info = curl_getinfo($curl);
  14608. if ($info['http_code'] == 0) {
  14609. throw new PHPUnit_Extensions_Selenium2TestCase_NoSeleniumException();
  14610. }
  14611. if ($info['http_code'] == 404) {
  14612. throw new BadMethodCallException("The command $url is not recognized by the server.");
  14613. }
  14614. curl_close($curl);
  14615. $content = json_decode($rawResponse, TRUE);
  14616. if ($info['http_code'] == 500) {
  14617. $message = '';
  14618. if (isset($content['value']['message'])) {
  14619. $message .= $content['value']['message'];
  14620. } else {
  14621. $message .= "Internal server error while executing $http_method request at $url. Response: " . var_export($content, TRUE);
  14622. }
  14623. if (isset($content['value']['class'])) {
  14624. $message .= PHP_EOL . $content['value']['class'];
  14625. }
  14626. throw new PHPUnit_Extensions_Selenium2TestCase_WebDriverException($message, isset($content['status']) ? $content['status'] : 13);
  14627. }
  14628. return new PHPUnit_Extensions_Selenium2TestCase_Response($content, $info);
  14629. }
  14630. public function execute(PHPUnit_Extensions_Selenium2TestCase_Command $command)
  14631. {
  14632. return $this->curl($command->httpMethod(),
  14633. $command->url(),
  14634. $command->jsonParameters());
  14635. }
  14636. }
  14637. <?php
  14638. /**
  14639. * PHPUnit
  14640. *
  14641. * Copyright (c) 2010-2011, Sebastian Bergmann <sb@sebastian-bergmann.de>.
  14642. * All rights reserved.
  14643. *
  14644. * Redistribution and use in source and binary forms, with or without
  14645. * modification, are permitted provided that the following conditions
  14646. * are met:
  14647. *
  14648. * * Redistributions of source code must retain the above copyright
  14649. * notice, this list of conditions and the following disclaimer.
  14650. *
  14651. * * Redistributions in binary form must reproduce the above copyright
  14652. * notice, this list of conditions and the following disclaimer in
  14653. * the documentation and/or other materials provided with the
  14654. * distribution.
  14655. *
  14656. * * Neither the name of Sebastian Bergmann nor the names of his
  14657. * contributors may be used to endorse or promote products derived
  14658. * from this software without specific prior written permission.
  14659. *
  14660. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14661. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14662. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14663. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14664. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14665. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14666. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14667. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14668. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14669. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14670. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14671. * POSSIBILITY OF SUCH DAMAGE.
  14672. *
  14673. * @package PHPUnit_Selenium
  14674. * @author Ivan Kurnosov <zerkms@zerkms.com>
  14675. * @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
  14676. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14677. * @link http://www.phpunit.de/
  14678. * @since File available since Release 1.2.12
  14679. */
  14680. /**
  14681. * The WaitUntil implementation, inspired by Java and .NET clients
  14682. *
  14683. * @package PHPUnit_Selenium
  14684. * @author Ivan Kurnosov <zerkms@zerkms.com>
  14685. * @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
  14686. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14687. * @version Release: @package_version@
  14688. * @link http://www.phpunit.de/
  14689. * @since Class available since Release 1.2.12
  14690. * @see http://selenium.googlecode.com/svn/trunk/dotnet/src/WebDriver.Support/UI/WebDriverWait.cs
  14691. * @see http://selenium.googlecode.com/svn/trunk/java/client/src/org/openqa/selenium/support/ui/FluentWait.java
  14692. */
  14693. class PHPUnit_Extensions_Selenium2TestCase_WaitUntil
  14694. {
  14695. /**
  14696. * PHPUnit Test Case instance
  14697. *
  14698. * @var PHPUnit_Extensions_Selenium2TestCase
  14699. */
  14700. private $_testCase;
  14701. /**
  14702. * Default timeout, ms
  14703. *
  14704. * @var int
  14705. */
  14706. private $_defaultTimeout = 0;
  14707. /**
  14708. * The sleep interval between iterations, ms
  14709. *
  14710. * @var int
  14711. */
  14712. private $_defaultSleepInterval = 500;
  14713. /**
  14714. * @param PHPUnit_Extensions_Selenium2TestCase $testCase
  14715. */
  14716. public function __construct(PHPUnit_Extensions_Selenium2TestCase $testCase)
  14717. {
  14718. $this->_testCase = $testCase;
  14719. }
  14720. /**
  14721. * @param $callback Callback to run until it returns not null or timeout occurs
  14722. * @param null $timeout
  14723. * @return mixed
  14724. * @throws PHPUnit_Extensions_Selenium2TestCase_Exception
  14725. * @throws PHPUnit_Extensions_Selenium2TestCase_WebDriverException
  14726. */
  14727. public function run($callback, $timeout = NULL)
  14728. {
  14729. if (!is_callable($callback)) {
  14730. throw new PHPUnit_Extensions_Selenium2TestCase_Exception('The valid callback is expected');
  14731. }
  14732. // if there was an implicit timeout specified - remember it and temporarily turn it off
  14733. $implicitWait = $this->_testCase->timeouts()->getLastImplicitWaitValue();
  14734. if ($implicitWait) {
  14735. $this->_testCase->timeouts()->implicitWait(0);
  14736. }
  14737. if (is_null($timeout)) {
  14738. $timeout = $this->_defaultTimeout;
  14739. }
  14740. $timeout /= 1000;
  14741. $endTime = microtime(TRUE) + $timeout;
  14742. $lastException = NULL;
  14743. while (TRUE) {
  14744. try {
  14745. $result = call_user_func($callback, $this->_testCase);
  14746. if (!is_null($result)) {
  14747. if ($implicitWait) {
  14748. $this->_testCase->timeouts()->implicitWait($implicitWait);
  14749. }
  14750. return $result;
  14751. }
  14752. } catch(Exception $e) {
  14753. $lastException = $e;
  14754. }
  14755. if (microtime(TRUE) > $endTime) {
  14756. if ($implicitWait) {
  14757. $this->_testCase->timeouts()->implicitWait($implicitWait);
  14758. }
  14759. $message = "Timed out after {$timeout} second" . ($timeout != 1 ? 's' : '');
  14760. throw new PHPUnit_Extensions_Selenium2TestCase_WebDriverException($message,
  14761. PHPUnit_Extensions_Selenium2TestCase_WebDriverException::Timeout, $lastException);
  14762. }
  14763. usleep($this->_defaultSleepInterval * 1000);
  14764. }
  14765. }
  14766. }
  14767. <?php
  14768. /**
  14769. * PHPUnit
  14770. *
  14771. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14772. * All rights reserved.
  14773. *
  14774. * Redistribution and use in source and binary forms, with or without
  14775. * modification, are permitted provided that the following conditions
  14776. * are met:
  14777. *
  14778. * * Redistributions of source code must retain the above copyright
  14779. * notice, this list of conditions and the following disclaimer.
  14780. *
  14781. * * Redistributions in binary form must reproduce the above copyright
  14782. * notice, this list of conditions and the following disclaimer in
  14783. * the documentation and/or other materials provided with the
  14784. * distribution.
  14785. *
  14786. * * Neither the name of Sebastian Bergmann nor the names of his
  14787. * contributors may be used to endorse or promote products derived
  14788. * from this software without specific prior written permission.
  14789. *
  14790. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14791. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14792. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14793. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14794. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14795. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14796. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14797. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14798. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14799. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14800. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14801. * POSSIBILITY OF SUCH DAMAGE.
  14802. *
  14803. * @package PHPUnit_Selenium
  14804. * @author Christian Becker <chris@beckr.org>
  14805. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14806. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14807. * @link http://www.phpunit.de/
  14808. * @since
  14809. */
  14810. /**
  14811. * Indicates an exception as a result of a non-sucessful WebDriver response status code.
  14812. *
  14813. * @package PHPUnit_Selenium
  14814. * @author Christian Becker <chris@beckr.org>
  14815. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14816. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14817. * @version Release: @package_version@
  14818. * @link http://www.phpunit.de/
  14819. * @since
  14820. */
  14821. class PHPUnit_Extensions_Selenium2TestCase_WebDriverException extends PHPUnit_Extensions_Selenium2TestCase_Exception
  14822. {
  14823. /* @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes */
  14824. const Success = 0;
  14825. const NoSuchDriver = 6;
  14826. const NoSuchElement = 7;
  14827. const NoSuchFrame = 8;
  14828. const UnknownCommand = 9;
  14829. const StaleElementReference = 10;
  14830. const ElementNotVisible = 11;
  14831. const InvalidElementState = 12;
  14832. const UnknownError = 13;
  14833. const ElementIsNotSelectable = 15;
  14834. const JavaScriptError = 17;
  14835. const XPathLookupError = 19;
  14836. const Timeout = 21;
  14837. const NoSuchWindow = 23;
  14838. const InvalidCookieDomain = 24;
  14839. const UnableToSetCookie = 25;
  14840. const UnexpectedAlertOpen = 26;
  14841. const NoAlertOpenError = 27;
  14842. const ScriptTimeout = 28;
  14843. const InvalidElementCoordinates = 29;
  14844. const IMENotAvailable = 30;
  14845. const IMEEngineActivationFailed = 31;
  14846. const InvalidSelector = 32;
  14847. const SessionNotCreatedException = 33;
  14848. const MoveTargetOutOfBounds = 34;
  14849. }<?php
  14850. /**
  14851. * PHPUnit
  14852. *
  14853. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14854. * All rights reserved.
  14855. *
  14856. * Redistribution and use in source and binary forms, with or without
  14857. * modification, are permitted provided that the following conditions
  14858. * are met:
  14859. *
  14860. * * Redistributions of source code must retain the above copyright
  14861. * notice, this list of conditions and the following disclaimer.
  14862. *
  14863. * * Redistributions in binary form must reproduce the above copyright
  14864. * notice, this list of conditions and the following disclaimer in
  14865. * the documentation and/or other materials provided with the
  14866. * distribution.
  14867. *
  14868. * * Neither the name of Sebastian Bergmann nor the names of his
  14869. * contributors may be used to endorse or promote products derived
  14870. * from this software without specific prior written permission.
  14871. *
  14872. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14873. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14874. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14875. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14876. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14877. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14878. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14879. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14880. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14881. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14882. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14883. * POSSIBILITY OF SUCH DAMAGE.
  14884. *
  14885. * @package PHPUnit_Selenium
  14886. * @author Christian Soronellas <csoronellas@emagister.com>
  14887. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14888. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14889. * @link http://www.phpunit.de/
  14890. * @since File available since Release 1.2.0
  14891. */
  14892. /**
  14893. * Gets or sets the current URL of the window.
  14894. *
  14895. * @package PHPUnit_Selenium
  14896. * @author Christian Soronellas <csoronellas@emagister.com>
  14897. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14898. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14899. * @version Release: @package_version@
  14900. * @link http://www.phpunit.de/
  14901. * @since Class available since Release 1.2.0
  14902. */
  14903. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Keys
  14904. extends PHPUnit_Extensions_Selenium2TestCase_Command
  14905. {
  14906. public function __construct($jsonParameters,
  14907. PHPUnit_Extensions_Selenium2TestCase_URL $url)
  14908. {
  14909. if ($jsonParameters === NULL) {
  14910. parent::__construct(NULL, $url);
  14911. } else {
  14912. $jsonParameters = $this->keysForText($jsonParameters);
  14913. parent::__construct($jsonParameters, $url);
  14914. }
  14915. }
  14916. /**
  14917. * @return string
  14918. */
  14919. public function httpMethod()
  14920. {
  14921. return 'POST';
  14922. }
  14923. /**
  14924. * Given a string returns an array of the characters that compose the string
  14925. *
  14926. * @param string $text
  14927. * @throws InvalidArgumentException
  14928. * @return array
  14929. */
  14930. public function keysForText($text)
  14931. {
  14932. if (is_scalar($text)) {
  14933. return array('value' => preg_split('//u', (string) $text, -1, PREG_SPLIT_NO_EMPTY));
  14934. }
  14935. if (is_array($text)) {
  14936. return $text;
  14937. }
  14938. throw new InvalidArgumentException('The "text" argument should be a string or an array of special characters!');
  14939. }
  14940. }
  14941. <?php
  14942. /**
  14943. * PHPUnit
  14944. *
  14945. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  14946. * All rights reserved.
  14947. *
  14948. * Redistribution and use in source and binary forms, with or without
  14949. * modification, are permitted provided that the following conditions
  14950. * are met:
  14951. *
  14952. * * Redistributions of source code must retain the above copyright
  14953. * notice, this list of conditions and the following disclaimer.
  14954. *
  14955. * * Redistributions in binary form must reproduce the above copyright
  14956. * notice, this list of conditions and the following disclaimer in
  14957. * the documentation and/or other materials provided with the
  14958. * distribution.
  14959. *
  14960. * * Neither the name of Sebastian Bergmann nor the names of his
  14961. * contributors may be used to endorse or promote products derived
  14962. * from this software without specific prior written permission.
  14963. *
  14964. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  14965. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  14966. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  14967. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  14968. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  14969. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  14970. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  14971. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  14972. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  14973. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  14974. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  14975. * POSSIBILITY OF SUCH DAMAGE.
  14976. *
  14977. * @package PHPUnit_Selenium
  14978. * @author Giorgio Sironi <info@giorgiosironi.com>
  14979. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14980. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14981. * @link http://www.phpunit.de/
  14982. * @since File available since Release 1.2.13
  14983. */
  14984. /**
  14985. * Sends session click command for emulating LEFT, MIDDLE or RIGHT mouse buttons
  14986. *
  14987. * @package PHPUnit_Selenium
  14988. * @author Ivan Kurnosov <zerkms@zerkms.com>
  14989. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  14990. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  14991. * @version Release: @package_version@
  14992. * @link http://www.phpunit.de/
  14993. * @since Class available since Release 1.2.13
  14994. */
  14995. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Click
  14996. extends PHPUnit_Extensions_Selenium2TestCase_Command
  14997. {
  14998. const LEFT = 0;
  14999. const MIDDLE = 1;
  15000. const RIGHT = 2;
  15001. public function __construct($argument, PHPUnit_Extensions_Selenium2TestCase_URL $url)
  15002. {
  15003. if (is_null($argument)) {
  15004. $jsonParameters = NULL;
  15005. } elseif (!is_scalar($argument) || !in_array($argument, array(
  15006. self::LEFT, self::RIGHT, self::MIDDLE
  15007. ))) {
  15008. throw new BadMethodCallException('Wrong parameter for click(): expecting 0, 1 or 2.');
  15009. } else {
  15010. $jsonParameters = array('button' => $argument);
  15011. }
  15012. parent::__construct($jsonParameters, $url);
  15013. }
  15014. public function httpMethod()
  15015. {
  15016. return 'POST';
  15017. }
  15018. }
  15019. <?php
  15020. /**
  15021. * PHPUnit
  15022. *
  15023. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15024. * All rights reserved.
  15025. *
  15026. * Redistribution and use in source and binary forms, with or without
  15027. * modification, are permitted provided that the following conditions
  15028. * are met:
  15029. *
  15030. * * Redistributions of source code must retain the above copyright
  15031. * notice, this list of conditions and the following disclaimer.
  15032. *
  15033. * * Redistributions in binary form must reproduce the above copyright
  15034. * notice, this list of conditions and the following disclaimer in
  15035. * the documentation and/or other materials provided with the
  15036. * distribution.
  15037. *
  15038. * * Neither the name of Sebastian Bergmann nor the names of his
  15039. * contributors may be used to endorse or promote products derived
  15040. * from this software without specific prior written permission.
  15041. *
  15042. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15043. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15044. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15045. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15046. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15047. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15048. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15049. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15050. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15051. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15052. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15053. * POSSIBILITY OF SUCH DAMAGE.
  15054. *
  15055. * @package PHPUnit_Selenium
  15056. * @author Jonathan Lipps <jlipps@gmail.com>
  15057. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15058. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15059. * @link http://www.phpunit.de/
  15060. * @since File available since Release 1.2.0
  15061. */
  15062. /**
  15063. * Gets or posts an attribute from/to the session (title, alert text, etc.)
  15064. *
  15065. * @package PHPUnit_Selenium
  15066. * @author Jonathan Lipps <jlipps@gmail.com>
  15067. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15068. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15069. * @version Release: @package_version@
  15070. * @link http://www.phpunit.de/
  15071. * @since Class available since Release 1.2.9
  15072. */
  15073. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Location
  15074. extends PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAttribute
  15075. {
  15076. public function __construct($location, $commandUrl)
  15077. {
  15078. if ($location !== NULL) {
  15079. $jsonParameters = array('location' => $location);
  15080. } else {
  15081. $jsonParameters = NULL;
  15082. }
  15083. parent::__construct($jsonParameters, $commandUrl);
  15084. }
  15085. public function httpMethod()
  15086. {
  15087. if ($this->jsonParameters) {
  15088. return 'POST';
  15089. }
  15090. return 'GET';
  15091. }
  15092. }
  15093. <?php
  15094. /**
  15095. * PHPUnit
  15096. *
  15097. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15098. * All rights reserved.
  15099. *
  15100. * Redistribution and use in source and binary forms, with or without
  15101. * modification, are permitted provided that the following conditions
  15102. * are met:
  15103. *
  15104. * * Redistributions of source code must retain the above copyright
  15105. * notice, this list of conditions and the following disclaimer.
  15106. *
  15107. * * Redistributions in binary form must reproduce the above copyright
  15108. * notice, this list of conditions and the following disclaimer in
  15109. * the documentation and/or other materials provided with the
  15110. * distribution.
  15111. *
  15112. * * Neither the name of Sebastian Bergmann nor the names of his
  15113. * contributors may be used to endorse or promote products derived
  15114. * from this software without specific prior written permission.
  15115. *
  15116. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15117. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15118. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15119. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15120. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15121. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15122. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15123. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15124. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15125. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15126. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15127. * POSSIBILITY OF SUCH DAMAGE.
  15128. *
  15129. * @package PHPUnit_Selenium
  15130. * @author Giorgio Sironi <info@giorgiosironi.com>
  15131. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15132. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15133. * @link http://www.phpunit.de/
  15134. * @since File available since Release 1.2.0
  15135. */
  15136. /**
  15137. * Gets an attribute from the session (title, alert text, etc.)
  15138. *
  15139. * @package PHPUnit_Selenium
  15140. * @author Giorgio Sironi <info@giorgiosironi.com>
  15141. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15142. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15143. * @version Release: @package_version@
  15144. * @link http://www.phpunit.de/
  15145. * @since Class available since Release 1.2.0
  15146. */
  15147. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAccessor
  15148. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15149. {
  15150. public function httpMethod()
  15151. {
  15152. return 'GET';
  15153. }
  15154. }
  15155. <?php
  15156. /**
  15157. * PHPUnit
  15158. *
  15159. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15160. * All rights reserved.
  15161. *
  15162. * Redistribution and use in source and binary forms, with or without
  15163. * modification, are permitted provided that the following conditions
  15164. * are met:
  15165. *
  15166. * * Redistributions of source code must retain the above copyright
  15167. * notice, this list of conditions and the following disclaimer.
  15168. *
  15169. * * Redistributions in binary form must reproduce the above copyright
  15170. * notice, this list of conditions and the following disclaimer in
  15171. * the documentation and/or other materials provided with the
  15172. * distribution.
  15173. *
  15174. * * Neither the name of Sebastian Bergmann nor the names of his
  15175. * contributors may be used to endorse or promote products derived
  15176. * from this software without specific prior written permission.
  15177. *
  15178. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15179. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15180. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15181. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15182. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15183. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15184. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15185. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15186. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15187. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15188. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15189. * POSSIBILITY OF SUCH DAMAGE.
  15190. *
  15191. * @package PHPUnit_Selenium
  15192. * @author Giorgio Sironi <info@giorgiosironi.com>
  15193. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15194. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15195. * @link http://www.phpunit.de/
  15196. * @since File available since Release 1.3.2
  15197. */
  15198. /**
  15199. * Sends a file to a RC
  15200. * Returns the FQ path to the transfered file
  15201. *
  15202. * @package PHPUnit_Selenium
  15203. * @author Kevin Ran <heilong24@gmail.com>
  15204. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15205. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15206. * @version Release: @package_version@
  15207. * @link http://www.phpunit.de/
  15208. * @since Class available since Release 1.3.2
  15209. */
  15210. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_File
  15211. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15212. {
  15213. /**
  15214. * @var
  15215. */
  15216. private static $_zipArchive;
  15217. public function __construct($argument, PHPUnit_Extensions_Selenium2TestCase_URL $url)
  15218. {
  15219. if (!is_file($argument)) {
  15220. throw new BadMethodCallException("No such file: {$argument}");
  15221. }
  15222. $zipfile_path = $this->_zipArchiveFile($argument);
  15223. $contents = file_get_contents($zipfile_path);
  15224. if ($contents === false) {
  15225. throw new Exception("Unable to read generated zip file: {$zipfile_path}");
  15226. }
  15227. $file = base64_encode($contents);
  15228. parent::__construct(array('file' => $file), $url);
  15229. unlink($zipfile_path);
  15230. }
  15231. public function httpMethod()
  15232. {
  15233. return 'POST';
  15234. }
  15235. /**
  15236. * Creates a zip archive with the given file
  15237. *
  15238. * @param string $file_path FQ path to file
  15239. * @return string Generated zip file
  15240. */
  15241. protected function _zipArchiveFile( $file_path )
  15242. {
  15243. // file MUST be readable
  15244. if( !is_readable( $file_path ) ) {
  15245. throw new Exception( "Unable to read {$file_path}" );
  15246. } // if !file_data
  15247. $filename_hash = sha1( time() . $file_path );
  15248. $tmp_dir = $this->_getTmpDir();
  15249. $zip_filename = "{$tmp_dir}{$filename_hash}.zip";
  15250. $zip = $this->_getZipArchiver();
  15251. if ($zip->open($zip_filename, ZIPARCHIVE::CREATE) === FALSE) {
  15252. throw new Exception( "Unable to create zip archive: {$zip_filename}" );
  15253. }
  15254. $zip->addFile($file_path, basename($file_path));
  15255. $zip->close();
  15256. return $zip_filename;
  15257. }
  15258. /**
  15259. * Returns a runtime instance of a ZipArchive
  15260. *
  15261. * @return ZipArchive
  15262. */
  15263. protected function _getZipArchiver()
  15264. {
  15265. // create ZipArchive if necessary
  15266. if (!static::$_zipArchive) {
  15267. static::$_zipArchive = new ZipArchive();
  15268. }
  15269. return static::$_zipArchive;
  15270. }
  15271. /**
  15272. * Calls sys_get_temp_dir and ensures that it has a trailing slash
  15273. * ( behavior varies across systems )
  15274. *
  15275. * @return string
  15276. */
  15277. protected function _getTmpDir()
  15278. {
  15279. return rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
  15280. }
  15281. }
  15282. <?php
  15283. /**
  15284. * PHPUnit
  15285. *
  15286. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15287. * All rights reserved.
  15288. *
  15289. * Redistribution and use in source and binary forms, with or without
  15290. * modification, are permitted provided that the following conditions
  15291. * are met:
  15292. *
  15293. * * Redistributions of source code must retain the above copyright
  15294. * notice, this list of conditions and the following disclaimer.
  15295. *
  15296. * * Redistributions in binary form must reproduce the above copyright
  15297. * notice, this list of conditions and the following disclaimer in
  15298. * the documentation and/or other materials provided with the
  15299. * distribution.
  15300. *
  15301. * * Neither the name of Sebastian Bergmann nor the names of his
  15302. * contributors may be used to endorse or promote products derived
  15303. * from this software without specific prior written permission.
  15304. *
  15305. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15306. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15307. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15308. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15309. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15310. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15311. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15312. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15313. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15314. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15315. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15316. * POSSIBILITY OF SUCH DAMAGE.
  15317. *
  15318. * @package PHPUnit_Selenium
  15319. * @author Giorgio Sironi <info@giorgiosironi.com>
  15320. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15321. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15322. * @link http://www.phpunit.de/
  15323. * @since File available since Release 1.2.0
  15324. */
  15325. /**
  15326. * Clicks Ok on an alert popup.
  15327. *
  15328. * @package PHPUnit_Selenium
  15329. * @author Giorgio Sironi <info@giorgiosironi.com>
  15330. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15331. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15332. * @version Release: @package_version@
  15333. * @link http://www.phpunit.de/
  15334. * @since Class available since Release 1.2.0
  15335. */
  15336. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_AcceptAlert
  15337. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15338. {
  15339. public function httpMethod()
  15340. {
  15341. return 'POST';
  15342. }
  15343. }
  15344. <?php
  15345. /**
  15346. * PHPUnit
  15347. *
  15348. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15349. * All rights reserved.
  15350. *
  15351. * Redistribution and use in source and binary forms, with or without
  15352. * modification, are permitted provided that the following conditions
  15353. * are met:
  15354. *
  15355. * * Redistributions of source code must retain the above copyright
  15356. * notice, this list of conditions and the following disclaimer.
  15357. *
  15358. * * Redistributions in binary form must reproduce the above copyright
  15359. * notice, this list of conditions and the following disclaimer in
  15360. * the documentation and/or other materials provided with the
  15361. * distribution.
  15362. *
  15363. * * Neither the name of Sebastian Bergmann nor the names of his
  15364. * contributors may be used to endorse or promote products derived
  15365. * from this software without specific prior written permission.
  15366. *
  15367. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15368. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15369. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15370. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15371. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15372. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15373. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15374. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15375. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15376. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15377. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15378. * POSSIBILITY OF SUCH DAMAGE.
  15379. *
  15380. * @package PHPUnit_Selenium
  15381. * @author Giorgio Sironi <info@giorgiosironi.com>
  15382. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15383. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15384. * @link http://www.phpunit.de/
  15385. * @since File available since Release 1.2.4
  15386. */
  15387. /**
  15388. * Obtains the text of an alert, or types into a prompt.
  15389. *
  15390. * @package PHPUnit_Selenium
  15391. * @author Giorgio Sironi <info@giorgiosironi.com>
  15392. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15393. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15394. * @version Release: @package_version@
  15395. * @link http://www.phpunit.de/
  15396. * @since Class available since Release 1.2.4
  15397. */
  15398. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_AlertText
  15399. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15400. {
  15401. public function __construct($argument, PHPUnit_Extensions_Selenium2TestCase_URL $url)
  15402. {
  15403. if (is_string($argument)) {
  15404. $jsonParameters =array('text' => $argument);
  15405. } else if ($argument == NULL) {
  15406. $jsonParameters = NULL;
  15407. } else {
  15408. throw new BadMethodCallException('Wrong parameters for alertText().');
  15409. }
  15410. parent::__construct($jsonParameters, $url);
  15411. }
  15412. public function httpMethod()
  15413. {
  15414. if ($this->jsonParameters) {
  15415. return 'POST';
  15416. }
  15417. return 'GET';
  15418. }
  15419. }
  15420. <?php
  15421. /**
  15422. * PHPUnit
  15423. *
  15424. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15425. * All rights reserved.
  15426. *
  15427. * Redistribution and use in source and binary forms, with or without
  15428. * modification, are permitted provided that the following conditions
  15429. * are met:
  15430. *
  15431. * * Redistributions of source code must retain the above copyright
  15432. * notice, this list of conditions and the following disclaimer.
  15433. *
  15434. * * Redistributions in binary form must reproduce the above copyright
  15435. * notice, this list of conditions and the following disclaimer in
  15436. * the documentation and/or other materials provided with the
  15437. * distribution.
  15438. *
  15439. * * Neither the name of Sebastian Bergmann nor the names of his
  15440. * contributors may be used to endorse or promote products derived
  15441. * from this software without specific prior written permission.
  15442. *
  15443. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15444. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15445. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15446. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15447. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15448. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15449. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15450. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15451. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15452. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15453. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15454. * POSSIBILITY OF SUCH DAMAGE.
  15455. *
  15456. * @package PHPUnit_Selenium
  15457. * @author Giorgio Sironi <info@giorgiosironi.com>
  15458. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15459. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15460. * @link http://www.phpunit.de/
  15461. * @since File available since Release 1.2.0
  15462. */
  15463. /**
  15464. * Gets or sets the current URL of the window.
  15465. *
  15466. * @package PHPUnit_Selenium
  15467. * @author Giorgio Sironi <info@giorgiosironi.com>
  15468. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15469. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15470. * @version Release: @package_version@
  15471. * @link http://www.phpunit.de/
  15472. * @since Class available since Release 1.2.0
  15473. */
  15474. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Url
  15475. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15476. {
  15477. public function __construct($url, $commandUrl, PHPUnit_Extensions_Selenium2TestCase_URL $baseUrl)
  15478. {
  15479. if ($url !== NULL) {
  15480. $absoluteLocation = $baseUrl->jump($url)->getValue();
  15481. $jsonParameters = array('url' => $absoluteLocation);
  15482. } else {
  15483. $jsonParameters = NULL;
  15484. }
  15485. parent::__construct($jsonParameters, $commandUrl);
  15486. }
  15487. public function httpMethod()
  15488. {
  15489. if ($this->jsonParameters) {
  15490. return 'POST';
  15491. }
  15492. return 'GET';
  15493. }
  15494. }
  15495. <?php
  15496. /**
  15497. * PHPUnit
  15498. *
  15499. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15500. * All rights reserved.
  15501. *
  15502. * Redistribution and use in source and binary forms, with or without
  15503. * modification, are permitted provided that the following conditions
  15504. * are met:
  15505. *
  15506. * * Redistributions of source code must retain the above copyright
  15507. * notice, this list of conditions and the following disclaimer.
  15508. *
  15509. * * Redistributions in binary form must reproduce the above copyright
  15510. * notice, this list of conditions and the following disclaimer in
  15511. * the documentation and/or other materials provided with the
  15512. * distribution.
  15513. *
  15514. * * Neither the name of Sebastian Bergmann nor the names of his
  15515. * contributors may be used to endorse or promote products derived
  15516. * from this software without specific prior written permission.
  15517. *
  15518. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15519. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15520. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15521. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15522. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15523. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15524. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15525. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15526. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15527. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15528. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15529. * POSSIBILITY OF SUCH DAMAGE.
  15530. *
  15531. * @package PHPUnit_Selenium
  15532. * @author Giorgio Sironi <info@giorgiosironi.com>
  15533. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15534. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15535. * @link http://www.phpunit.de/
  15536. * @since File available since Release 1.2.4
  15537. */
  15538. /**
  15539. * Changes the focus to a window.
  15540. *
  15541. * @package PHPUnit_Selenium
  15542. * @author Giorgio Sironi <info@giorgiosironi.com>
  15543. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15544. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15545. * @version Release: @package_version@
  15546. * @link http://www.phpunit.de/
  15547. * @since Class available since Release 1.2.4
  15548. */
  15549. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Window
  15550. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15551. {
  15552. public function __construct($name, $commandUrl)
  15553. {
  15554. $jsonParameters = array('name' => $name);
  15555. parent::__construct($jsonParameters, $commandUrl);
  15556. }
  15557. public function httpMethod()
  15558. {
  15559. return 'POST';
  15560. }
  15561. }
  15562. <?php
  15563. /**
  15564. * PHPUnit
  15565. *
  15566. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15567. * All rights reserved.
  15568. *
  15569. * Redistribution and use in source and binary forms, with or without
  15570. * modification, are permitted provided that the following conditions
  15571. * are met:
  15572. *
  15573. * * Redistributions of source code must retain the above copyright
  15574. * notice, this list of conditions and the following disclaimer.
  15575. *
  15576. * * Redistributions in binary form must reproduce the above copyright
  15577. * notice, this list of conditions and the following disclaimer in
  15578. * the documentation and/or other materials provided with the
  15579. * distribution.
  15580. *
  15581. * * Neither the name of Sebastian Bergmann nor the names of his
  15582. * contributors may be used to endorse or promote products derived
  15583. * from this software without specific prior written permission.
  15584. *
  15585. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15586. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15587. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15588. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15589. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15590. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15591. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15592. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15593. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15594. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15595. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15596. * POSSIBILITY OF SUCH DAMAGE.
  15597. *
  15598. * @package PHPUnit_Selenium
  15599. * @author Jonathan Lipps <jlipps@gmail.com>
  15600. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15601. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15602. * @link http://www.phpunit.de/
  15603. * @since File available since Release 1.2.0
  15604. */
  15605. /**
  15606. * Gets or posts an attribute from/to the session (title, alert text, etc.)
  15607. *
  15608. * @package PHPUnit_Selenium
  15609. * @author Jonathan Lipps <jlipps@gmail.com>
  15610. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15611. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15612. * @version Release: @package_version@
  15613. * @link http://www.phpunit.de/
  15614. * @since Class available since Release 1.2.9
  15615. */
  15616. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAttribute
  15617. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15618. {
  15619. public function httpMethod()
  15620. {
  15621. if ($this->jsonParameters) {
  15622. return 'POST';
  15623. }
  15624. return 'GET';
  15625. }
  15626. }
  15627. <?php
  15628. /**
  15629. * PHPUnit
  15630. *
  15631. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15632. * All rights reserved.
  15633. *
  15634. * Redistribution and use in source and binary forms, with or without
  15635. * modification, are permitted provided that the following conditions
  15636. * are met:
  15637. *
  15638. * * Redistributions of source code must retain the above copyright
  15639. * notice, this list of conditions and the following disclaimer.
  15640. *
  15641. * * Redistributions in binary form must reproduce the above copyright
  15642. * notice, this list of conditions and the following disclaimer in
  15643. * the documentation and/or other materials provided with the
  15644. * distribution.
  15645. *
  15646. * * Neither the name of Sebastian Bergmann nor the names of his
  15647. * contributors may be used to endorse or promote products derived
  15648. * from this software without specific prior written permission.
  15649. *
  15650. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15651. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15652. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15653. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15654. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15655. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15656. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15657. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15658. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15659. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15660. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15661. * POSSIBILITY OF SUCH DAMAGE.
  15662. *
  15663. * @package PHPUnit_Selenium
  15664. * @author Giorgio Sironi <info@giorgiosironi.com>
  15665. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15666. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15667. * @link http://www.phpunit.de/
  15668. * @since File available since Release 1.2.8
  15669. */
  15670. /**
  15671. * Moves the mouse pointer.
  15672. *
  15673. * @author Giorgio Sironi <info@giorgiosironi.com>
  15674. * @package PHPUnit_Selenium
  15675. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15676. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15677. * @version Release: @package_version@
  15678. * @link http://www.phpunit.de/
  15679. * @since Class available since Release 1.2.8
  15680. */
  15681. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_MoveTo
  15682. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15683. {
  15684. public function __construct($element,
  15685. PHPUnit_Extensions_Selenium2TestCase_URL $url)
  15686. {
  15687. if (!is_array($element)) {
  15688. $element = array(
  15689. 'element' => $element,
  15690. );
  15691. }
  15692. $validKeys = array(
  15693. 'element' => NULL,
  15694. 'xoffset' => NULL,
  15695. 'yoffset' => NULL,
  15696. );
  15697. $jsonParameters = array_intersect_key($element, $validKeys);
  15698. if (isset($jsonParameters['element'])) {
  15699. if (!($jsonParameters['element'] instanceof PHPUnit_Extensions_Selenium2TestCase_Element)) {
  15700. throw new PHPUnit_Extensions_Selenium2TestCase_Exception('Only moving over an element is supported. Please pass a PHPUnit_Extensions_Selenium2TestCase_Element instance.');
  15701. }
  15702. $jsonParameters['element'] = $jsonParameters['element']->getId();
  15703. }
  15704. if (isset($jsonParameters['xoffset']) || isset($jsonParameters['yoffset'])) {
  15705. // @see https://github.com/sebastianbergmann/phpunit-selenium/pull/250#issuecomment-21308153
  15706. // @see https://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/moveto
  15707. error_log('Even though this method is a part of the WebDriver Wire protocol it might be not supported by your browser yet');
  15708. }
  15709. parent::__construct($jsonParameters, $url);
  15710. }
  15711. /**
  15712. * @return string
  15713. */
  15714. public function httpMethod()
  15715. {
  15716. return 'POST';
  15717. }
  15718. }
  15719. <?php
  15720. /**
  15721. * PHPUnit
  15722. *
  15723. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15724. * All rights reserved.
  15725. *
  15726. * Redistribution and use in source and binary forms, with or without
  15727. * modification, are permitted provided that the following conditions
  15728. * are met:
  15729. *
  15730. * * Redistributions of source code must retain the above copyright
  15731. * notice, this list of conditions and the following disclaimer.
  15732. *
  15733. * * Redistributions in binary form must reproduce the above copyright
  15734. * notice, this list of conditions and the following disclaimer in
  15735. * the documentation and/or other materials provided with the
  15736. * distribution.
  15737. *
  15738. * * Neither the name of Sebastian Bergmann nor the names of his
  15739. * contributors may be used to endorse or promote products derived
  15740. * from this software without specific prior written permission.
  15741. *
  15742. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15743. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15744. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15745. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15746. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15747. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15748. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15749. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15750. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15751. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15752. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15753. * POSSIBILITY OF SUCH DAMAGE.
  15754. *
  15755. * @package PHPUnit_Selenium
  15756. * @author Jonathan Lipps <jlipps@gmail.com>
  15757. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15758. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15759. * @link http://www.phpunit.de/
  15760. * @since File available since Release 1.2.0
  15761. */
  15762. /**
  15763. * Gets or posts an attribute from/to the session (title, alert text, etc.)
  15764. *
  15765. * @package PHPUnit_Selenium
  15766. * @author Jonathan Lipps <jlipps@gmail.com>
  15767. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15768. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15769. * @version Release: @package_version@
  15770. * @link http://www.phpunit.de/
  15771. * @since Class available since Release 1.2.9
  15772. */
  15773. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Orientation
  15774. extends PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAttribute
  15775. {
  15776. public function __construct($orientation, $commandUrl)
  15777. {
  15778. if ($orientation !== NULL) {
  15779. $jsonParameters = array('orientation' => $orientation);
  15780. } else {
  15781. $jsonParameters = NULL;
  15782. }
  15783. parent::__construct($jsonParameters, $commandUrl);
  15784. }
  15785. public function httpMethod()
  15786. {
  15787. if ($this->jsonParameters) {
  15788. return 'POST';
  15789. }
  15790. return 'GET';
  15791. }
  15792. }
  15793. <?php
  15794. /**
  15795. * PHPUnit
  15796. *
  15797. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15798. * All rights reserved.
  15799. *
  15800. * Redistribution and use in source and binary forms, with or without
  15801. * modification, are permitted provided that the following conditions
  15802. * are met:
  15803. *
  15804. * * Redistributions of source code must retain the above copyright
  15805. * notice, this list of conditions and the following disclaimer.
  15806. *
  15807. * * Redistributions in binary form must reproduce the above copyright
  15808. * notice, this list of conditions and the following disclaimer in
  15809. * the documentation and/or other materials provided with the
  15810. * distribution.
  15811. *
  15812. * * Neither the name of Sebastian Bergmann nor the names of his
  15813. * contributors may be used to endorse or promote products derived
  15814. * from this software without specific prior written permission.
  15815. *
  15816. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15817. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15818. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15819. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15820. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15821. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15822. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15823. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15824. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15825. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15826. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15827. * POSSIBILITY OF SUCH DAMAGE.
  15828. *
  15829. * @package PHPUnit_Selenium
  15830. * @author Andrew Krasichkov <krasichkovandrew@gmail.com>
  15831. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15832. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15833. * @link http://www.phpunit.de/
  15834. * @since File available since Release 1.3.2
  15835. */
  15836. /**
  15837. * Get the log for a given log type. Log buffer is reset after each request.
  15838. *
  15839. * @package PHPUnit_Selenium
  15840. * @author Andrew Krasichkov <krasichkovandrew@gmail.com>
  15841. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15842. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15843. * @version Release: @package_version@
  15844. * @link http://www.phpunit.de/
  15845. * @since Class available since Release 1.3.2
  15846. */
  15847. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Log
  15848. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15849. {
  15850. public function __construct($type, $commandUrl)
  15851. {
  15852. $jsonParameters = array('type' => $type);
  15853. parent::__construct($jsonParameters, $commandUrl);
  15854. }
  15855. public function httpMethod()
  15856. {
  15857. return 'POST';
  15858. }
  15859. }<?php
  15860. /**
  15861. * PHPUnit
  15862. *
  15863. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15864. * All rights reserved.
  15865. *
  15866. * Redistribution and use in source and binary forms, with or without
  15867. * modification, are permitted provided that the following conditions
  15868. * are met:
  15869. *
  15870. * * Redistributions of source code must retain the above copyright
  15871. * notice, this list of conditions and the following disclaimer.
  15872. *
  15873. * * Redistributions in binary form must reproduce the above copyright
  15874. * notice, this list of conditions and the following disclaimer in
  15875. * the documentation and/or other materials provided with the
  15876. * distribution.
  15877. *
  15878. * * Neither the name of Sebastian Bergmann nor the names of his
  15879. * contributors may be used to endorse or promote products derived
  15880. * from this software without specific prior written permission.
  15881. *
  15882. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15883. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15884. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15885. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15886. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15887. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15888. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15889. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15890. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15891. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15892. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15893. * POSSIBILITY OF SUCH DAMAGE.
  15894. *
  15895. * @package PHPUnit_Selenium
  15896. * @author Giorgio Sironi <info@giorgiosironi.com>
  15897. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15898. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15899. * @link http://www.phpunit.de/
  15900. * @since File available since Release
  15901. */
  15902. /**
  15903. * Gets the active element from the session
  15904. *
  15905. * @package PHPUnit_Selenium
  15906. * @author Marcel Erz <marcel.erz@gmail.com>
  15907. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15908. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15909. * @version Release: @package_version@
  15910. * @link http://www.phpunit.de/
  15911. * @since Class available since Release
  15912. */
  15913. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Active
  15914. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15915. {
  15916. public function __construct($jsonParameters, PHPUnit_Extensions_Selenium2TestCase_URL $url)
  15917. {
  15918. $url = $url->addCommand('element')->addCommand('active');
  15919. parent::__construct($jsonParameters, $url);
  15920. }
  15921. public function httpMethod()
  15922. {
  15923. return 'POST';
  15924. }
  15925. }
  15926. <?php
  15927. /**
  15928. * PHPUnit
  15929. *
  15930. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15931. * All rights reserved.
  15932. *
  15933. * Redistribution and use in source and binary forms, with or without
  15934. * modification, are permitted provided that the following conditions
  15935. * are met:
  15936. *
  15937. * * Redistributions of source code must retain the above copyright
  15938. * notice, this list of conditions and the following disclaimer.
  15939. *
  15940. * * Redistributions in binary form must reproduce the above copyright
  15941. * notice, this list of conditions and the following disclaimer in
  15942. * the documentation and/or other materials provided with the
  15943. * distribution.
  15944. *
  15945. * * Neither the name of Sebastian Bergmann nor the names of his
  15946. * contributors may be used to endorse or promote products derived
  15947. * from this software without specific prior written permission.
  15948. *
  15949. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15950. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  15951. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  15952. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  15953. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  15954. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  15955. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  15956. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  15957. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  15958. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  15959. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  15960. * POSSIBILITY OF SUCH DAMAGE.
  15961. *
  15962. * @package PHPUnit_Selenium
  15963. * @author Giorgio Sironi <info@giorgiosironi.com>
  15964. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15965. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15966. * @link http://www.phpunit.de/
  15967. * @since File available since Release 1.2.0
  15968. */
  15969. /**
  15970. * Clicks Cancel on an alert popup.
  15971. *
  15972. * @package PHPUnit_Selenium
  15973. * @author Giorgio Sironi <info@giorgiosironi.com>
  15974. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  15975. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  15976. * @version Release: @package_version@
  15977. * @link http://www.phpunit.de/
  15978. * @since Class available since Release 1.2.0
  15979. */
  15980. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_DismissAlert
  15981. extends PHPUnit_Extensions_Selenium2TestCase_Command
  15982. {
  15983. public function httpMethod()
  15984. {
  15985. return 'POST';
  15986. }
  15987. }
  15988. <?php
  15989. /**
  15990. * PHPUnit
  15991. *
  15992. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  15993. * All rights reserved.
  15994. *
  15995. * Redistribution and use in source and binary forms, with or without
  15996. * modification, are permitted provided that the following conditions
  15997. * are met:
  15998. *
  15999. * * Redistributions of source code must retain the above copyright
  16000. * notice, this list of conditions and the following disclaimer.
  16001. *
  16002. * * Redistributions in binary form must reproduce the above copyright
  16003. * notice, this list of conditions and the following disclaimer in
  16004. * the documentation and/or other materials provided with the
  16005. * distribution.
  16006. *
  16007. * * Neither the name of Sebastian Bergmann nor the names of his
  16008. * contributors may be used to endorse or promote products derived
  16009. * from this software without specific prior written permission.
  16010. *
  16011. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16012. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16013. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  16014. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16015. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16016. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  16017. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16018. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  16019. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  16020. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  16021. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  16022. * POSSIBILITY OF SUCH DAMAGE.
  16023. *
  16024. * @package PHPUnit_Selenium
  16025. * @author Giorgio Sironi <info@giorgiosironi.com>
  16026. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16027. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16028. * @link http://www.phpunit.de/
  16029. * @since File available since Release 1.2.4
  16030. */
  16031. /**
  16032. * Changes the focus to a frame.
  16033. *
  16034. * @package PHPUnit_Selenium
  16035. * @author Giorgio Sironi <info@giorgiosironi.com>
  16036. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16037. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16038. * @version Release: @package_version@
  16039. * @link http://www.phpunit.de/
  16040. * @since Class available since Release 1.2.4
  16041. */
  16042. class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Frame
  16043. extends PHPUnit_Extensions_Selenium2TestCase_Command
  16044. {
  16045. public function __construct($id, $commandUrl)
  16046. {
  16047. $jsonParameters = array(
  16048. 'id' => $this->extractId($id)
  16049. );
  16050. parent::__construct($jsonParameters, $commandUrl);
  16051. }
  16052. /**
  16053. * @param $id
  16054. * @return array
  16055. */
  16056. private function extractId($id)
  16057. {
  16058. if ($this->isElement($id)) { //selenium-element
  16059. return $id->toWebDriverObject();
  16060. }
  16061. //html-id or null
  16062. return $id;
  16063. }
  16064. /**
  16065. * @param $id
  16066. * @return bool
  16067. */
  16068. private function isElement($id)
  16069. {
  16070. return $id instanceof PHPUnit_Extensions_Selenium2TestCase_Element;
  16071. }
  16072. public function httpMethod()
  16073. {
  16074. return 'POST';
  16075. }
  16076. }
  16077. <?php
  16078. /**
  16079. * PHPUnit
  16080. *
  16081. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  16082. * All rights reserved.
  16083. *
  16084. * Redistribution and use in source and binary forms, with or without
  16085. * modification, are permitted provided that the following conditions
  16086. * are met:
  16087. *
  16088. * * Redistributions of source code must retain the above copyright
  16089. * notice, this list of conditions and the following disclaimer.
  16090. *
  16091. * * Redistributions in binary form must reproduce the above copyright
  16092. * notice, this list of conditions and the following disclaimer in
  16093. * the documentation and/or other materials provided with the
  16094. * distribution.
  16095. *
  16096. * * Neither the name of Sebastian Bergmann nor the names of his
  16097. * contributors may be used to endorse or promote products derived
  16098. * from this software without specific prior written permission.
  16099. *
  16100. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16101. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16102. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  16103. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16104. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16105. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  16106. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16107. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  16108. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  16109. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  16110. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  16111. * POSSIBILITY OF SUCH DAMAGE.
  16112. *
  16113. * @package PHPUnit_Selenium
  16114. * @author Giorgio Sironi <info@giorgiosironi.com>
  16115. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16116. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16117. * @link http://www.phpunit.de/
  16118. * @since File available since Release 1.2.0
  16119. */
  16120. /**
  16121. * URL Value Object allowing easy concatenation.
  16122. *
  16123. * @package PHPUnit_Selenium
  16124. * @author Giorgio Sironi <info@giorgiosironi.com>
  16125. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16126. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16127. * @version Release: @package_version@
  16128. * @link http://www.phpunit.de/
  16129. * @since Class available since Release 1.2.0
  16130. */
  16131. final class PHPUnit_Extensions_Selenium2TestCase_URL
  16132. {
  16133. /**
  16134. * @var string
  16135. */
  16136. private $value;
  16137. /**
  16138. * @param string $value
  16139. */
  16140. public function __construct($value)
  16141. {
  16142. $this->value = $value;
  16143. }
  16144. /**
  16145. * @param string $host
  16146. * @param int port
  16147. * @return PHPUnit_Extensions_Selenium2TestCase_URL
  16148. */
  16149. public static function fromHostAndPort($host, $port)
  16150. {
  16151. return new self("http://{$host}:{$port}");
  16152. }
  16153. /**
  16154. * @return string
  16155. */
  16156. public function getValue()
  16157. {
  16158. return $this->value;
  16159. }
  16160. public function __toString()
  16161. {
  16162. return $this->getValue();
  16163. }
  16164. /**
  16165. * @param string $addition
  16166. * @return PHPUnit_Extensions_Selenium2TestCase_URL
  16167. */
  16168. public function descend($addition)
  16169. {
  16170. if ($addition == '') {
  16171. // if we're adding nothing, respect the current url's choice of
  16172. // whether or not to include a trailing slash; prevents inadvertent
  16173. // adding of slashes to urls that can't handle it
  16174. $newValue = $this->value;
  16175. } else {
  16176. $newValue = rtrim($this->value, '/')
  16177. . '/'
  16178. . ltrim($addition, '/');
  16179. }
  16180. return new self($newValue);
  16181. }
  16182. /**
  16183. * @return PHPUnit_Extensions_Selenium2TestCase_URL
  16184. */
  16185. public function ascend()
  16186. {
  16187. $lastSlash = strrpos($this->value, "/");
  16188. $newValue = substr($this->value, 0, $lastSlash);
  16189. return new self($newValue);
  16190. }
  16191. /**
  16192. * @return string
  16193. */
  16194. public function lastSegment()
  16195. {
  16196. $segments = explode('/', $this->value);
  16197. return end($segments);
  16198. }
  16199. /**
  16200. * @param string $command
  16201. * @return PHPUnit_Extensions_Selenium2TestCase_URL
  16202. */
  16203. public function addCommand($command)
  16204. {
  16205. return $this->descend($this->camelCaseToUnderScores($command));
  16206. }
  16207. /**
  16208. * @param string $newUrl
  16209. * @return PHPUnit_Extensions_Selenium2TestCase_URL
  16210. */
  16211. public function jump($newUrl)
  16212. {
  16213. if ($this->isAbsolute($newUrl)) {
  16214. return new self($newUrl);
  16215. } else {
  16216. return $this->descend($newUrl);
  16217. }
  16218. }
  16219. private function camelCaseToUnderScores($string)
  16220. {
  16221. $string = preg_replace('/([A-Z]{1,1})/', ' \1', $string);
  16222. $string = strtolower($string);
  16223. return str_replace(' ', '_', $string);
  16224. }
  16225. private function isAbsolute($urlValue)
  16226. {
  16227. return preg_match('/^(http|https):\/\//', $urlValue) > 0;
  16228. }
  16229. }
  16230. <?php
  16231. /**
  16232. * PHPUnit
  16233. *
  16234. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  16235. * All rights reserved.
  16236. *
  16237. * Redistribution and use in source and binary forms, with or without
  16238. * modification, are permitted provided that the following conditions
  16239. * are met:
  16240. *
  16241. * * Redistributions of source code must retain the above copyright
  16242. * notice, this list of conditions and the following disclaimer.
  16243. *
  16244. * * Redistributions in binary form must reproduce the above copyright
  16245. * notice, this list of conditions and the following disclaimer in
  16246. * the documentation and/or other materials provided with the
  16247. * distribution.
  16248. *
  16249. * * Neither the name of Sebastian Bergmann nor the names of his
  16250. * contributors may be used to endorse or promote products derived
  16251. * from this software without specific prior written permission.
  16252. *
  16253. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16254. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16255. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  16256. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16257. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16258. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  16259. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16260. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  16261. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  16262. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  16263. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  16264. * POSSIBILITY OF SUCH DAMAGE.
  16265. *
  16266. * @package PHPUnit_Selenium
  16267. * @author Giorgio Sironi <info@giorgiosironi.com>
  16268. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16269. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16270. * @link http://www.phpunit.de/
  16271. * @since File available since Release 1.2.6
  16272. */
  16273. /**
  16274. * Specifies how to create Session objects for running tests.
  16275. *
  16276. * @package PHPUnit_Selenium
  16277. * @author Giorgio Sironi <info@giorgiosironi.com>
  16278. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16279. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16280. * @version Release: @package_version@
  16281. * @link http://www.phpunit.de/
  16282. * @since Class available since Release 1.2.6
  16283. */
  16284. interface PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
  16285. {
  16286. /**
  16287. * @param array $parameters 'host' => Selenium Server machine
  16288. 'port' => Selenium Server port
  16289. 'browser' => a browser name
  16290. * 'browserUrl' => base URL to use during the test
  16291. */
  16292. public function session(array $parameters);
  16293. public function notSuccessfulTest();
  16294. public function endOfTest(PHPUnit_Extensions_Selenium2TestCase_Session $session = NULL);
  16295. }
  16296. <?php
  16297. /**
  16298. * PHPUnit
  16299. *
  16300. * Copyright (c) 2010-2011, Sebastian Bergmann <sb@sebastian-bergmann.de>.
  16301. * All rights reserved.
  16302. *
  16303. * Redistribution and use in source and binary forms, with or without
  16304. * modification, are permitted provided that the following conditions
  16305. * are met:
  16306. *
  16307. * * Redistributions of source code must retain the above copyright
  16308. * notice, this list of conditions and the following disclaimer.
  16309. *
  16310. * * Redistributions in binary form must reproduce the above copyright
  16311. * notice, this list of conditions and the following disclaimer in
  16312. * the documentation and/or other materials provided with the
  16313. * distribution.
  16314. *
  16315. * * Neither the name of Sebastian Bergmann nor the names of his
  16316. * contributors may be used to endorse or promote products derived
  16317. * from this software without specific prior written permission.
  16318. *
  16319. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16320. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16321. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  16322. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16323. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16324. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  16325. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16326. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  16327. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  16328. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  16329. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  16330. * POSSIBILITY OF SUCH DAMAGE.
  16331. *
  16332. * @package PHPUnit_Selenium
  16333. * @author Ivan Kurnosov <zerkms@zerkms.com>
  16334. * @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
  16335. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16336. * @link http://www.phpunit.de/
  16337. * @since File available since Release 1.2.12
  16338. */
  16339. /**
  16340. * Class-mapper, that converts requested special key into correspondent Unicode character
  16341. *
  16342. * @package PHPUnit_Selenium
  16343. * @author Ivan Kurnosov <zerkms@zerkms.com>
  16344. * @copyright 2010-2011 Sebastian Bergmann <sb@sebastian-bergmann.de>
  16345. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16346. * @version Release: @package_version@
  16347. * @link http://www.phpunit.de/
  16348. * @since Class available since Release 1.2.12
  16349. * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/value
  16350. */
  16351. class PHPUnit_Extensions_Selenium2TestCase_KeysHolder
  16352. {
  16353. private $_keys = array(
  16354. 'null' => "\xEE\x80\x80",
  16355. 'cancel' => "\xEE\x80\x81",
  16356. 'help' => "\xEE\x80\x82",
  16357. 'backspace' => "\xEE\x80\x83",
  16358. 'tab' => "\xEE\x80\x84",
  16359. 'clear' => "\xEE\x80\x85",
  16360. 'return' => "\xEE\x80\x86",
  16361. 'enter' => "\xEE\x80\x87",
  16362. 'shift' => "\xEE\x80\x88",
  16363. 'control' => "\xEE\x80\x89",
  16364. 'alt' => "\xEE\x80\x8A",
  16365. 'pause' => "\xEE\x80\x8B",
  16366. 'escape' => "\xEE\x80\x8C",
  16367. 'space' => "\xEE\x80\x8D",
  16368. 'pageup' => "\xEE\x80\x8E",
  16369. 'pagedown' => "\xEE\x80\x8F",
  16370. 'end' => "\xEE\x80\x90",
  16371. 'home' => "\xEE\x80\x91",
  16372. 'left' => "\xEE\x80\x92",
  16373. 'up' => "\xEE\x80\x93",
  16374. 'right' => "\xEE\x80\x94",
  16375. 'down' => "\xEE\x80\x95",
  16376. 'insert' => "\xEE\x80\x96",
  16377. 'delete' => "\xEE\x80\x97",
  16378. 'semicolon' => "\xEE\x80\x98",
  16379. 'equals' => "\xEE\x80\x99",
  16380. 'numpad0' => "\xEE\x80\x9A",
  16381. 'numpad1' => "\xEE\x80\x9B",
  16382. 'numpad2' => "\xEE\x80\x9C",
  16383. 'numpad3' => "\xEE\x80\x9D",
  16384. 'numpad4' => "\xEE\x80\x9E",
  16385. 'numpad5' => "\xEE\x80\x9F",
  16386. 'numpad6' => "\xEE\x80\xA0",
  16387. 'numpad7' => "\xEE\x80\xA1",
  16388. 'numpad8' => "\xEE\x80\xA2",
  16389. 'numpad9' => "\xEE\x80\xA3",
  16390. 'multiply' => "\xEE\x80\xA4",
  16391. 'add' => "\xEE\x80\xA5",
  16392. 'separator' => "\xEE\x80\xA6",
  16393. 'subtract' => "\xEE\x80\xA7",
  16394. 'decimal' => "\xEE\x80\xA8",
  16395. 'divide' => "\xEE\x80\xA9",
  16396. 'f1' => "\xEE\x80\xB1",
  16397. 'f2' => "\xEE\x80\xB2",
  16398. 'f3' => "\xEE\x80\xB3",
  16399. 'f4' => "\xEE\x80\xB4",
  16400. 'f5' => "\xEE\x80\xB5",
  16401. 'f6' => "\xEE\x80\xB6",
  16402. 'f7' => "\xEE\x80\xB7",
  16403. 'f8' => "\xEE\x80\xB8",
  16404. 'f9' => "\xEE\x80\xB9",
  16405. 'f10' => "\xEE\x80\xBA",
  16406. 'f11' => "\xEE\x80\xBB",
  16407. 'f12' => "\xEE\x80\xBC",
  16408. 'command' => "\xEE\x80\xBD",
  16409. );
  16410. public function specialKey($name)
  16411. {
  16412. $normalizedName = strtolower($name);
  16413. if (!isset($this->_keys[$normalizedName])) {
  16414. throw new PHPUnit_Extensions_Selenium2TestCase_Exception("There is no special key '$name' defined");
  16415. }
  16416. return $this->_keys[$normalizedName];
  16417. }
  16418. }
  16419. <?php
  16420. /**
  16421. * PHPUnit
  16422. *
  16423. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  16424. * All rights reserved.
  16425. *
  16426. * Redistribution and use in source and binary forms, with or without
  16427. * modification, are permitted provided that the following conditions
  16428. * are met:
  16429. *
  16430. * * Redistributions of source code must retain the above copyright
  16431. * notice, this list of conditions and the following disclaimer.
  16432. *
  16433. * * Redistributions in binary form must reproduce the above copyright
  16434. * notice, this list of conditions and the following disclaimer in
  16435. * the documentation and/or other materials provided with the
  16436. * distribution.
  16437. *
  16438. * * Neither the name of Sebastian Bergmann nor the names of his
  16439. * contributors may be used to endorse or promote products derived
  16440. * from this software without specific prior written permission.
  16441. *
  16442. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16443. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16444. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  16445. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16446. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16447. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  16448. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16449. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  16450. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  16451. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  16452. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  16453. * POSSIBILITY OF SUCH DAMAGE.
  16454. *
  16455. * @package PHPUnit_Selenium
  16456. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16457. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16458. * @link http://www.phpunit.de/
  16459. */
  16460. /**
  16461. * Provides access to /element and /elements commands
  16462. *
  16463. * @package PHPUnit_Selenium
  16464. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16465. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16466. * @version Release: @package_version@
  16467. * @link http://www.phpunit.de/
  16468. */
  16469. abstract class PHPUnit_Extensions_Selenium2TestCase_Element_Accessor
  16470. extends PHPUnit_Extensions_Selenium2TestCase_CommandsHolder
  16471. {
  16472. /**
  16473. * @param string $value e.g. 'container'
  16474. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16475. */
  16476. public function byClassName($value)
  16477. {
  16478. return $this->by('class name', $value);
  16479. }
  16480. /**
  16481. * @param string $value e.g. 'div.container'
  16482. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16483. */
  16484. public function byCssSelector($value)
  16485. {
  16486. return $this->by('css selector', $value);
  16487. }
  16488. /**
  16489. * @param string $value e.g. 'uniqueId'
  16490. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16491. */
  16492. public function byId($value)
  16493. {
  16494. return $this->by('id', $value);
  16495. }
  16496. /**
  16497. * @param string $value e.g. 'Link text'
  16498. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16499. */
  16500. public function byLinkText($value)
  16501. {
  16502. return $this->by('link text', $value);
  16503. }
  16504. /**
  16505. * @param string $value e.g. 'Link te'
  16506. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16507. */
  16508. public function byPartialLinkText($value)
  16509. {
  16510. return $this->by('partial link text', $value);
  16511. }
  16512. /**
  16513. * @param string $value e.g. 'email_address'
  16514. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16515. */
  16516. public function byName($value)
  16517. {
  16518. return $this->by('name', $value);
  16519. }
  16520. /**
  16521. * @param string $value e.g. 'body'
  16522. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16523. */
  16524. public function byTag($value)
  16525. {
  16526. return $this->by('tag name', $value);
  16527. }
  16528. /**
  16529. * @param string $value e.g. '/div[@attribute="value"]'
  16530. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16531. */
  16532. public function byXPath($value)
  16533. {
  16534. return $this->by('xpath', $value);
  16535. }
  16536. /**
  16537. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16538. */
  16539. public function element(PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria)
  16540. {
  16541. $value = $this->postCommand('element', $criteria);
  16542. return PHPUnit_Extensions_Selenium2TestCase_Element::fromResponseValue(
  16543. $value, $this->getSessionUrl()->descend('element'), $this->driver);
  16544. }
  16545. /**
  16546. * @return array instances of PHPUnit_Extensions_Selenium2TestCase_Element
  16547. */
  16548. public function elements(PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria)
  16549. {
  16550. $values = $this->postCommand('elements', $criteria);
  16551. $elements = array();
  16552. foreach ($values as $value) {
  16553. $elements[] =
  16554. PHPUnit_Extensions_Selenium2TestCase_Element::fromResponseValue(
  16555. $value, $this->getSessionUrl()->descend('element'), $this->driver);
  16556. }
  16557. return $elements;
  16558. }
  16559. /**
  16560. * @param string $strategy
  16561. * @return PHPUnit_Extensions_Selenium2TestCase_ElementCriteria
  16562. */
  16563. public function using($strategy)
  16564. {
  16565. return new PHPUnit_Extensions_Selenium2TestCase_ElementCriteria($strategy);
  16566. }
  16567. /**
  16568. * @return PHPUnit_Extensions_Selenium2TestCase_URL
  16569. */
  16570. protected abstract function getSessionUrl();
  16571. /**
  16572. * @param string $strategy supported by JsonWireProtocol element/ command
  16573. * @param string $value
  16574. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  16575. */
  16576. private function by($strategy, $value)
  16577. {
  16578. return $this->element($this->using($strategy)->value($value));
  16579. }
  16580. }
  16581. <?php
  16582. /**
  16583. * PHPUnit
  16584. *
  16585. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  16586. * All rights reserved.
  16587. *
  16588. * Redistribution and use in source and binary forms, with or without
  16589. * modification, are permitted provided that the following conditions
  16590. * are met:
  16591. *
  16592. * * Redistributions of source code must retain the above copyright
  16593. * notice, this list of conditions and the following disclaimer.
  16594. *
  16595. * * Redistributions in binary form must reproduce the above copyright
  16596. * notice, this list of conditions and the following disclaimer in
  16597. * the documentation and/or other materials provided with the
  16598. * distribution.
  16599. *
  16600. * * Neither the name of Sebastian Bergmann nor the names of his
  16601. * contributors may be used to endorse or promote products derived
  16602. * from this software without specific prior written permission.
  16603. *
  16604. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16605. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16606. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  16607. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16608. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16609. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  16610. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16611. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  16612. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  16613. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  16614. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  16615. * POSSIBILITY OF SUCH DAMAGE.
  16616. *
  16617. * @package PHPUnit_Selenium
  16618. * @author Giorgio Sironi <info@giorgiosironi.com>
  16619. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16620. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16621. * @link http://www.phpunit.de/
  16622. * @since File available since Release 1.2.2
  16623. */
  16624. /**
  16625. * Object representing a <select> element.
  16626. *
  16627. * @package PHPUnit_Selenium
  16628. * @author Giorgio Sironi <info@giorgiosironi.com>
  16629. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16630. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16631. * @version Release: @package_version@
  16632. * @link http://www.phpunit.de/
  16633. * @since Class available since Release 1.2.2
  16634. */
  16635. class PHPUnit_Extensions_Selenium2TestCase_Element_Select
  16636. extends PHPUnit_Extensions_Selenium2TestCase_Element
  16637. {
  16638. /**
  16639. * @return PHPUnit_Extensions_Selenium2TestCase_Element_Select
  16640. */
  16641. public static function fromElement(PHPUnit_Extensions_Selenium2TestCase_Element $element)
  16642. {
  16643. return new self($element->driver, $element->url);
  16644. }
  16645. /**
  16646. * @return string
  16647. */
  16648. public function selectedLabel()
  16649. {
  16650. $selectedOption = $this->selectedOption();
  16651. if ($selectedOption === NULL) {
  16652. return '';
  16653. }
  16654. return $selectedOption->text();
  16655. }
  16656. /**
  16657. * @return string
  16658. */
  16659. public function selectedValue()
  16660. {
  16661. $selectedOption = $this->selectedOption();
  16662. if ($selectedOption === NULL) {
  16663. return '';
  16664. }
  16665. return $selectedOption->value();
  16666. }
  16667. /**
  16668. * @return string
  16669. */
  16670. public function selectedId()
  16671. {
  16672. $selectedOption = $this->selectedOption();
  16673. if ($selectedOption === NULL) {
  16674. return '';
  16675. }
  16676. return $selectedOption->attribute('id');
  16677. }
  16678. /**
  16679. * @return array
  16680. */
  16681. public function selectedLabels()
  16682. {
  16683. $labels = array();
  16684. foreach ($this->selectedOptions() as $option) {
  16685. $labels[] = $option->text();
  16686. }
  16687. return $labels;
  16688. }
  16689. /**
  16690. * @return array
  16691. */
  16692. public function selectedValues()
  16693. {
  16694. $values = array();
  16695. foreach ($this->selectedOptions() as $option) {
  16696. $values[] = $option->value();
  16697. }
  16698. return $values;
  16699. }
  16700. /**
  16701. * @return array
  16702. */
  16703. public function selectedIds()
  16704. {
  16705. $id = array();
  16706. foreach ($this->selectedOptions() as $option) {
  16707. $values[] = $option->attribute('id');
  16708. }
  16709. return $id;
  16710. }
  16711. /**
  16712. * @param string $label the text appearing in the option
  16713. * @return void
  16714. */
  16715. public function selectOptionByLabel($label)
  16716. {
  16717. $toSelect = $this->using('xpath')->value(".//option[.='$label']");
  16718. $this->selectOptionByCriteria($toSelect);
  16719. }
  16720. /**
  16721. * @param string $value the value attribute of the option
  16722. * @return void
  16723. */
  16724. public function selectOptionByValue($value)
  16725. {
  16726. $toSelect = $this->using('xpath')->value(".//option[@value='$value']");
  16727. $this->selectOptionByCriteria($toSelect);
  16728. }
  16729. /**
  16730. * @param PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $localCriteria condiotions for selecting an option
  16731. * @return void
  16732. */
  16733. public function selectOptionByCriteria(PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $localCriteria)
  16734. {
  16735. $option = $this->element($localCriteria);
  16736. if (!$option->selected()) {
  16737. $option->click();
  16738. }
  16739. }
  16740. /**
  16741. * @return array
  16742. */
  16743. public function selectOptionValues()
  16744. {
  16745. $options = array();
  16746. foreach ($this->options() as $option) {
  16747. $options[] = $option->value();
  16748. }
  16749. return $options;
  16750. }
  16751. /**
  16752. * @return array
  16753. */
  16754. public function selectOptionLabels()
  16755. {
  16756. $options = array();
  16757. foreach ($this->options() as $option) {
  16758. $options[] = $option->text();
  16759. }
  16760. return $options;
  16761. }
  16762. /***
  16763. * @return array
  16764. */
  16765. private function selectedOptions()
  16766. {
  16767. $options = array();
  16768. foreach ($this->options() as $option) {
  16769. if ($option->selected()) {
  16770. $options[] = $option;
  16771. }
  16772. }
  16773. return $options;
  16774. }
  16775. public function clearSelectedOptions()
  16776. {
  16777. foreach ($this->selectedOptions() as $option) {
  16778. $option->click();
  16779. }
  16780. }
  16781. private function selectedOption()
  16782. {
  16783. foreach ($this->options() as $option) {
  16784. if ($option->selected()) {
  16785. return $option;
  16786. }
  16787. }
  16788. return NULL;
  16789. }
  16790. private function options()
  16791. {
  16792. $onlyTheOptions = $this->using('css selector')->value('option');
  16793. return $this->elements($onlyTheOptions);
  16794. }
  16795. }
  16796. <?php
  16797. /**
  16798. * PHPUnit
  16799. *
  16800. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  16801. * All rights reserved.
  16802. *
  16803. * Redistribution and use in source and binary forms, with or without
  16804. * modification, are permitted provided that the following conditions
  16805. * are met:
  16806. *
  16807. * * Redistributions of source code must retain the above copyright
  16808. * notice, this list of conditions and the following disclaimer.
  16809. *
  16810. * * Redistributions in binary form must reproduce the above copyright
  16811. * notice, this list of conditions and the following disclaimer in
  16812. * the documentation and/or other materials provided with the
  16813. * distribution.
  16814. *
  16815. * * Neither the name of Sebastian Bergmann nor the names of his
  16816. * contributors may be used to endorse or promote products derived
  16817. * from this software without specific prior written permission.
  16818. *
  16819. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16820. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16821. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  16822. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16823. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  16824. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  16825. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  16826. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  16827. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  16828. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  16829. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  16830. * POSSIBILITY OF SUCH DAMAGE.
  16831. *
  16832. * @package PHPUnit_Selenium
  16833. * @author Giorgio Sironi <info@giorgiosironi.com>
  16834. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16835. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16836. * @link http://www.phpunit.de/
  16837. * @since File available since Release 1.2.0
  16838. */
  16839. /**
  16840. * Browser session for Selenium 2: main point of entry for functionality.
  16841. *
  16842. * @package PHPUnit_Selenium
  16843. * @author Giorgio Sironi <info@giorgiosironi.com>
  16844. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  16845. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  16846. * @version Release: @package_version@
  16847. * @link http://www.phpunit.de/
  16848. * @since Class available since Release 1.2.0
  16849. * @method void acceptAlert() Press OK on an alert, or confirms a dialog
  16850. * @method mixed alertText($value = NULL) Gets the alert dialog text, or sets the text for a prompt dialog
  16851. * @method void back()
  16852. * @method void dismissAlert() Press Cancel on an alert, or does not confirm a dialog
  16853. * @method void doubleclick() Double-clicks at the current mouse coordinates (set by moveto).
  16854. * @method string execute(array $javaScriptCode) Injects arbitrary JavaScript in the page and returns the last. See unit tests for usage
  16855. * @method string executeAsync(array $javaScriptCode) Injects arbitrary JavaScript and wait for the callback (last element of arguments) to be called. See unit tests for usage
  16856. * @method void forward()
  16857. * @method void frame(mixed $element) Changes the focus to a frame in the page (by frameCount of type int, htmlId of type string, htmlName of type string or element of type \PHPUnit_Extensions_Selenium2TestCase_Element)
  16858. * @method void moveto(\PHPUnit_Extensions_Selenium2TestCase_Element $element) Move the mouse by an offset of the specificed element.
  16859. * @method void refresh()
  16860. * @method string source() Returns the HTML source of the page
  16861. * @method string title()
  16862. * @method void|string url($url = NULL)
  16863. * @method void window($name) Changes the focus to another window
  16864. * @method string windowHandle() Retrieves the current window handle
  16865. * @method string windowHandles() Retrieves a list of all available window handles
  16866. * @method string keys() Send a sequence of key strokes to the active element.
  16867. * @method string file($file_path) Upload a local file. Returns the fully qualified path to the transferred file.
  16868. * @method array log(string $type) Get the log for a given log type. Log buffer is reset after each request.
  16869. * @method array logTypes() Get available log types.
  16870. */
  16871. class PHPUnit_Extensions_Selenium2TestCase_Session
  16872. extends PHPUnit_Extensions_Selenium2TestCase_Element_Accessor
  16873. {
  16874. /**
  16875. * @var string the base URL for this session,
  16876. * which all relative URLs will refer to
  16877. */
  16878. private $baseUrl;
  16879. /**
  16880. * @var PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts
  16881. */
  16882. private $timeouts;
  16883. /**
  16884. * @var boolean
  16885. */
  16886. private $stopped = FALSE;
  16887. public function __construct($driver,
  16888. PHPUnit_Extensions_Selenium2TestCase_URL $url,
  16889. PHPUnit_Extensions_Selenium2TestCase_URL $baseUrl,
  16890. PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts $timeouts)
  16891. {
  16892. $this->baseUrl = $baseUrl;
  16893. $this->timeouts = $timeouts;
  16894. parent::__construct($driver, $url);
  16895. }
  16896. /**
  16897. * @return string
  16898. */
  16899. public function id()
  16900. {
  16901. return $this->url->lastSegment();
  16902. }
  16903. protected function initCommands()
  16904. {
  16905. $baseUrl = $this->baseUrl;
  16906. return array(
  16907. 'acceptAlert' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_AcceptAlert',
  16908. 'alertText' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_AlertText',
  16909. 'back' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  16910. 'click' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Click',
  16911. 'buttondown' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  16912. 'buttonup' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  16913. 'dismissAlert' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_DismissAlert',
  16914. 'doubleclick' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  16915. 'execute' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  16916. 'executeAsync' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  16917. 'forward' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  16918. 'frame' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Frame',
  16919. 'keys' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Keys',
  16920. 'moveto' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_MoveTo',
  16921. 'refresh' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost',
  16922. 'screenshot' => 'PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor',
  16923. 'source' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAccessor',
  16924. 'title' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAccessor',
  16925. 'log' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Log',
  16926. 'logTypes' => $this->attributeCommandFactoryMethod('log/types'),
  16927. 'url' => function ($jsonParameters, $commandUrl) use ($baseUrl) {
  16928. return new PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Url($jsonParameters, $commandUrl, $baseUrl);
  16929. },
  16930. 'window' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Window',
  16931. 'windowHandle' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAccessor',
  16932. 'windowHandles' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAccessor',
  16933. 'touchDown' => $this->touchCommandFactoryMethod('touch/down'),
  16934. 'touchUp' => $this->touchCommandFactoryMethod('touch/up'),
  16935. 'touchMove' => $this->touchCommandFactoryMethod('touch/move'),
  16936. 'touchScroll' => $this->touchCommandFactoryMethod('touch/scroll'),
  16937. 'flick' => $this->touchCommandFactoryMethod('touch/flick'),
  16938. 'location' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Location',
  16939. 'orientation' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Orientation',
  16940. 'file' => 'PHPUnit_Extensions_Selenium2TestCase_SessionCommand_File'
  16941. );
  16942. }
  16943. private function attributeCommandFactoryMethod($urlSegment)
  16944. {
  16945. $url = $this->url->addCommand($urlSegment);
  16946. return function ($jsonParameters, $commandUrl) use ($url) {
  16947. return new PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAttribute($jsonParameters, $url);
  16948. };
  16949. }
  16950. private function touchCommandFactoryMethod($urlSegment)
  16951. {
  16952. $url = $this->url->addCommand($urlSegment);
  16953. return function ($jsonParameters, $commandUrl) use ($url) {
  16954. return new PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost($jsonParameters, $url);
  16955. };
  16956. }
  16957. public function __destruct()
  16958. {
  16959. $this->stop();
  16960. }
  16961. /**
  16962. * @return PHPUnit_Extensions_Selenium2TestCase_URL
  16963. */
  16964. public function getSessionUrl()
  16965. {
  16966. return $this->url;
  16967. }
  16968. /**
  16969. * Closed the browser.
  16970. * @return void
  16971. */
  16972. public function stop()
  16973. {
  16974. if ($this->stopped) {
  16975. return;
  16976. }
  16977. try {
  16978. $this->driver->curl('DELETE', $this->url);
  16979. } catch (Exception $e) {
  16980. // sessions which aren't closed because of sharing can time out on the server. In no way trying to close them should make a test fail, as it already finished before arriving here.
  16981. "Closing sessions: " . $e->getMessage() . "\n";
  16982. }
  16983. $this->stopped = TRUE;
  16984. if ($this->stopped) {
  16985. return;
  16986. }
  16987. }
  16988. /**
  16989. * @return PHPUnit_Extensions_Selenium2TestCase_Element_Select
  16990. */
  16991. public function select(PHPUnit_Extensions_Selenium2TestCase_Element $element)
  16992. {
  16993. $tag = $element->name();
  16994. if ($tag !== 'select') {
  16995. throw new InvalidArgumentException("The element is not a `select` tag but a `$tag`.");
  16996. }
  16997. return PHPUnit_Extensions_Selenium2TestCase_Element_Select::fromElement($element);
  16998. }
  16999. /**
  17000. * @param array WebElement JSON object
  17001. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  17002. */
  17003. public function elementFromResponseValue($value)
  17004. {
  17005. return PHPUnit_Extensions_Selenium2TestCase_Element::fromResponseValue($value, $this->getSessionUrl()->descend('element'), $this->driver);
  17006. }
  17007. /**
  17008. * @param string $id id attribute, e.g. 'container'
  17009. * @return void
  17010. */
  17011. public function clickOnElement($id)
  17012. {
  17013. return $this->element($this->using('id')->value($id))->click();
  17014. }
  17015. public function timeouts()
  17016. {
  17017. return $this->timeouts;
  17018. }
  17019. /**
  17020. * @return string a BLOB of a PNG file
  17021. */
  17022. public function currentScreenshot()
  17023. {
  17024. return base64_decode($this->screenshot());
  17025. }
  17026. /**
  17027. * @return PHPUnit_Extensions_Selenium2TestCase_Window
  17028. */
  17029. public function currentWindow()
  17030. {
  17031. $url = $this->url->descend('window')->descend(trim($this->windowHandle(), '{}'));
  17032. return new PHPUnit_Extensions_Selenium2TestCase_Window($this->driver, $url);
  17033. }
  17034. public function closeWindow()
  17035. {
  17036. $this->driver->curl('DELETE', $this->url->descend('window'));
  17037. }
  17038. /**
  17039. * Get the element on the page that currently has focus.
  17040. *
  17041. * @return PHPUnit_Extensions_Selenium2TestCase_Element
  17042. */
  17043. public function active()
  17044. {
  17045. $command = new PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Active(null, $this->url);
  17046. $response = $this->driver->execute($command);
  17047. return $this->elementFromResponseValue($response->getValue());
  17048. }
  17049. /**
  17050. * @return PHPUnit_Extensions_Selenium2TestCase_Session_Cookie
  17051. */
  17052. public function cookie()
  17053. {
  17054. $url = $this->url->descend('cookie');
  17055. return new PHPUnit_Extensions_Selenium2TestCase_Session_Cookie($this->driver, $url);
  17056. }
  17057. /**
  17058. * @return PHPUnit_Extensions_Selenium2TestCase_Session_Storage
  17059. */
  17060. public function localStorage()
  17061. {
  17062. $url = $this->url->addCommand('localStorage');
  17063. return new PHPUnit_Extensions_Selenium2TestCase_Session_Storage($this->driver, $url);
  17064. }
  17065. public function landscape()
  17066. {
  17067. $this->orientation('LANDSCAPE');
  17068. }
  17069. public function portrait()
  17070. {
  17071. $this->orientation('PORTRAIT');
  17072. }
  17073. }
  17074. <?php
  17075. /**
  17076. * PHPUnit
  17077. *
  17078. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  17079. * All rights reserved.
  17080. *
  17081. * Redistribution and use in source and binary forms, with or without
  17082. * modification, are permitted provided that the following conditions
  17083. * are met:
  17084. *
  17085. * * Redistributions of source code must retain the above copyright
  17086. * notice, this list of conditions and the following disclaimer.
  17087. *
  17088. * * Redistributions in binary form must reproduce the above copyright
  17089. * notice, this list of conditions and the following disclaimer in
  17090. * the documentation and/or other materials provided with the
  17091. * distribution.
  17092. *
  17093. * * Neither the name of Sebastian Bergmann nor the names of his
  17094. * contributors may be used to endorse or promote products derived
  17095. * from this software without specific prior written permission.
  17096. *
  17097. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17098. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17099. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  17100. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  17101. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  17102. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  17103. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  17104. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  17105. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  17106. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  17107. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  17108. * POSSIBILITY OF SUCH DAMAGE.
  17109. *
  17110. * @package PHPUnit_Selenium
  17111. * @author Sebastian Bergmann <sebastian@phpunit.de>
  17112. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  17113. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  17114. * @link http://www.phpunit.de/
  17115. * @since File available since Release 1.0.0
  17116. */
  17117. // By default the code coverage files are written to the same directory
  17118. // that contains the covered sourcecode files. Use this setting to change
  17119. // the default behaviour and set a specific directory to write the files to.
  17120. // If you change the default setting, please make sure to also configure
  17121. // the same directory in phpunit_coverage.php. Also note that the webserver
  17122. // needs write access to the directory.
  17123. if (!isset($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'])) {
  17124. $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] = FALSE;
  17125. }
  17126. if ( isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) &&
  17127. !isset($_GET['PHPUNIT_SELENIUM_TEST_ID']) &&
  17128. extension_loaded('xdebug')) {
  17129. $GLOBALS['PHPUNIT_FILTERED_FILES'] = array(__FILE__);
  17130. xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
  17131. }
  17132. include ('ExitHandler.php');
  17133. PHPUnit_Extensions_SeleniumCommon_ExitHandler::init();
  17134. <?php
  17135. /**
  17136. * PHPUnit
  17137. *
  17138. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  17139. * All rights reserved.
  17140. *
  17141. * Redistribution and use in source and binary forms, with or without
  17142. * modification, are permitted provided that the following conditions
  17143. * are met:
  17144. *
  17145. * * Redistributions of source code must retain the above copyright
  17146. * notice, this list of conditions and the following disclaimer.
  17147. *
  17148. * * Redistributions in binary form must reproduce the above copyright
  17149. * notice, this list of conditions and the following disclaimer in
  17150. * the documentation and/or other materials provided with the
  17151. * distribution.
  17152. *
  17153. * * Neither the name of Sebastian Bergmann nor the names of his
  17154. * contributors may be used to endorse or promote products derived
  17155. * from this software without specific prior written permission.
  17156. *
  17157. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17158. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17159. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  17160. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  17161. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  17162. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  17163. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  17164. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  17165. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  17166. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  17167. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  17168. * POSSIBILITY OF SUCH DAMAGE.
  17169. *
  17170. * @package PHPUnit_Selenium
  17171. * @author Sebastian Bergmann <sebastian@phpunit.de>
  17172. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  17173. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  17174. * @link http://www.phpunit.de/
  17175. * @since File available since Release 1.0.0
  17176. */
  17177. if ( isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) &&
  17178. !isset($_GET['PHPUNIT_SELENIUM_TEST_ID']) &&
  17179. extension_loaded('xdebug')) {
  17180. $GLOBALS['PHPUNIT_FILTERED_FILES'][] = __FILE__;
  17181. $data = xdebug_get_code_coverage();
  17182. xdebug_stop_code_coverage();
  17183. foreach ($GLOBALS['PHPUNIT_FILTERED_FILES'] as $file) {
  17184. unset($data[$file]);
  17185. }
  17186. if (is_string($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY']) &&
  17187. is_dir($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'])) {
  17188. $file = $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] .
  17189. DIRECTORY_SEPARATOR . md5($_SERVER['SCRIPT_FILENAME']);
  17190. } else {
  17191. $file = $_SERVER['SCRIPT_FILENAME'];
  17192. }
  17193. file_put_contents(
  17194. $name = $file . '.' . md5(uniqid(rand(), TRUE)) . '.' . $_COOKIE['PHPUNIT_SELENIUM_TEST_ID'],
  17195. serialize($data)
  17196. );
  17197. }
  17198. <?php
  17199. class PHPUnit_Extensions_SeleniumCommon_RemoteCoverage
  17200. {
  17201. public function __construct($coverageScriptUrl, $testId)
  17202. {
  17203. $this->coverageScriptUrl = $coverageScriptUrl;
  17204. $this->testId = $testId;
  17205. }
  17206. public function get()
  17207. {
  17208. if (!empty($this->coverageScriptUrl)) {
  17209. $url = sprintf(
  17210. '%s?PHPUNIT_SELENIUM_TEST_ID=%s',
  17211. $this->coverageScriptUrl,
  17212. urlencode($this->testId)
  17213. );
  17214. $buffer = @file_get_contents($url);
  17215. if ($buffer !== FALSE) {
  17216. $coverageData = unserialize($buffer);
  17217. if (is_array($coverageData)) {
  17218. return $this->matchLocalAndRemotePaths($coverageData);
  17219. } else {
  17220. throw new Exception('Empty or invalid code coverage data received from url "' . $url . '"');
  17221. }
  17222. }
  17223. }
  17224. return array();
  17225. }
  17226. /**
  17227. * @param array $coverage
  17228. * @return array
  17229. * @author Mattis Stordalen Flister <mattis@xait.no>
  17230. */
  17231. protected function matchLocalAndRemotePaths(array $coverage)
  17232. {
  17233. $coverageWithLocalPaths = array();
  17234. foreach ($coverage as $originalRemotePath => $data) {
  17235. $remotePath = $originalRemotePath;
  17236. $separator = $this->findDirectorySeparator($remotePath);
  17237. while (!($localpath = stream_resolve_include_path($remotePath)) &&
  17238. strpos($remotePath, $separator) !== FALSE) {
  17239. $remotePath = substr($remotePath, strpos($remotePath, $separator) + 1);
  17240. }
  17241. if ($localpath && md5_file($localpath) == $data['md5']) {
  17242. $coverageWithLocalPaths[$localpath] = $data['coverage'];
  17243. }
  17244. }
  17245. return $coverageWithLocalPaths;
  17246. }
  17247. /**
  17248. * @param string $path
  17249. * @return string
  17250. * @author Mattis Stordalen Flister <mattis@xait.no>
  17251. */
  17252. protected function findDirectorySeparator($path)
  17253. {
  17254. if (strpos($path, '/') !== FALSE) {
  17255. return '/';
  17256. }
  17257. return '\\';
  17258. }
  17259. }
  17260. <?php
  17261. /**
  17262. * If Ececution was stopped by calling exit();
  17263. * php does not append append.php, so no code coverage date is collected
  17264. * We have to add shutdown handler to append this file manualy.
  17265. * @author Arbuzov <info@whitediver.com>
  17266. *
  17267. */
  17268. class PHPUnit_Extensions_SeleniumCommon_ExitHandler
  17269. {
  17270. /**
  17271. * Register handler.
  17272. * If project have own shutdown hanldler user have to add function to handler
  17273. *
  17274. */
  17275. public static function init()
  17276. {
  17277. register_shutdown_function( array( 'PHPUnit_Extensions_SeleniumCommon_ExitHandler', 'handle' ) );
  17278. }
  17279. /**
  17280. * Manual include apendable files
  17281. */
  17282. public static function handle()
  17283. {
  17284. $execFile = ini_get('auto_append_file');
  17285. if ($execFile!=='') {
  17286. include_once ($execFile);
  17287. }
  17288. }
  17289. }
  17290. <?php
  17291. /**
  17292. * PHPUnit
  17293. *
  17294. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  17295. * All rights reserved.
  17296. *
  17297. * Redistribution and use in source and binary forms, with or without
  17298. * modification, are permitted provided that the following conditions
  17299. * are met:
  17300. *
  17301. * * Redistributions of source code must retain the above copyright
  17302. * notice, this list of conditions and the following disclaimer.
  17303. *
  17304. * * Redistributions in binary form must reproduce the above copyright
  17305. * notice, this list of conditions and the following disclaimer in
  17306. * the documentation and/or other materials provided with the
  17307. * distribution.
  17308. *
  17309. * * Neither the name of Sebastian Bergmann nor the names of his
  17310. * contributors may be used to endorse or promote products derived
  17311. * from this software without specific prior written permission.
  17312. *
  17313. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17314. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17315. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  17316. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  17317. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  17318. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  17319. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  17320. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  17321. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  17322. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  17323. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  17324. * POSSIBILITY OF SUCH DAMAGE.
  17325. *
  17326. * @package PHPUnit_Selenium
  17327. * @author Sebastian Bergmann <sebastian@phpunit.de>
  17328. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  17329. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  17330. * @link http://www.phpunit.de/
  17331. * @since File available since Release 1.0.0
  17332. */
  17333. $directory = realpath(__DIR__);
  17334. while ($directory != '/') {
  17335. $autoloadCandidate = $directory . '/vendor/autoload.php';
  17336. if (file_exists($autoloadCandidate)) {
  17337. require_once $autoloadCandidate;
  17338. break;
  17339. }
  17340. $directory = realpath($directory . '/..');
  17341. }
  17342. // Set this to the directory that contains the code coverage files.
  17343. // It defaults to getcwd(). If you have configured a different directory
  17344. // in prepend.php, you need to configure the same directory here.
  17345. $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] = getcwd();
  17346. if (isset($_GET['PHPUNIT_SELENIUM_TEST_ID'])) {
  17347. $facade = new File_Iterator_Facade;
  17348. $files = $facade->getFilesAsArray(
  17349. $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'],
  17350. $_GET['PHPUNIT_SELENIUM_TEST_ID']
  17351. );
  17352. $coverage = array();
  17353. foreach ($files as $file) {
  17354. $data = unserialize(file_get_contents($file));
  17355. unlink($file);
  17356. unset($file);
  17357. $filter = new PHP_CodeCoverage_Filter();
  17358. foreach ($data as $file => $lines) {
  17359. if ($filter->isFile($file)) {
  17360. if (!isset($coverage[$file])) {
  17361. $coverage[$file] = array(
  17362. 'md5' => md5_file($file), 'coverage' => $lines
  17363. );
  17364. } else {
  17365. foreach ($lines as $line => $flag) {
  17366. if (!isset($coverage[$file]['coverage'][$line]) ||
  17367. $flag > $coverage[$file]['coverage'][$line]) {
  17368. $coverage[$file]['coverage'][$line] = $flag;
  17369. }
  17370. }
  17371. }
  17372. }
  17373. }
  17374. }
  17375. print serialize($coverage);
  17376. }
  17377. <?php
  17378. /**
  17379. * PHPUnit
  17380. *
  17381. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  17382. * All rights reserved.
  17383. *
  17384. * Redistribution and use in source and binary forms, with or without
  17385. * modification, are permitted provided that the following conditions
  17386. * are met:
  17387. *
  17388. * * Redistributions of source code must retain the above copyright
  17389. * notice, this list of conditions and the following disclaimer.
  17390. *
  17391. * * Redistributions in binary form must reproduce the above copyright
  17392. * notice, this list of conditions and the following disclaimer in
  17393. * the documentation and/or other materials provided with the
  17394. * distribution.
  17395. *
  17396. * * Neither the name of Sebastian Bergmann nor the names of his
  17397. * contributors may be used to endorse or promote products derived
  17398. * from this software without specific prior written permission.
  17399. *
  17400. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17401. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17402. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  17403. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  17404. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  17405. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  17406. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  17407. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  17408. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  17409. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  17410. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  17411. * POSSIBILITY OF SUCH DAMAGE.
  17412. *
  17413. * @package PHPUnit_Selenium
  17414. * @author Giorgio Sironi <info@giorgiosironi.com>
  17415. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  17416. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  17417. * @link http://www.phpunit.de/
  17418. * @since File available since Release 1.2.6
  17419. */
  17420. /**
  17421. * TestSuite class for a set of tests from a single Testcase Class
  17422. * executed with a particular browser.
  17423. *
  17424. * @package PHPUnit_Selenium
  17425. * @author Giorgio Sironi <info@giorgiosironi.com>
  17426. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  17427. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  17428. * @version Release: @package_version@
  17429. * @link http://www.phpunit.de/
  17430. * @since Class available since Release 1.2.6
  17431. */
  17432. class PHPUnit_Extensions_SeleniumBrowserSuite extends PHPUnit_Framework_TestSuite
  17433. {
  17434. /**
  17435. * Overriding the default: Selenium suites are always built from a TestCase class.
  17436. * @var boolean
  17437. */
  17438. protected $testCase = TRUE;
  17439. public function addTestMethod(ReflectionClass $class, ReflectionMethod $method)
  17440. {
  17441. return parent::addTestMethod($class, $method);
  17442. }
  17443. public static function fromClassAndBrowser($className, array $browser)
  17444. {
  17445. $browserSuite = new self();
  17446. if (isset($browser['browserName'])) {
  17447. $name = $browser['browserName'];
  17448. } else if (isset($browser['name'])) {
  17449. $name = $browser['name'];
  17450. } else {
  17451. $name = $browser['browser'];
  17452. }
  17453. $browserSuite->setName($className . ': ' . $name);
  17454. return $browserSuite;
  17455. }
  17456. public function setupSpecificBrowser(array $browser)
  17457. {
  17458. $this->browserOnAllTests($this, $browser);
  17459. }
  17460. private function browserOnAllTests(PHPUnit_Framework_TestSuite $suite, array $browser)
  17461. {
  17462. foreach ($suite->tests() as $test) {
  17463. if ($test instanceof PHPUnit_Framework_TestSuite) {
  17464. $this->browserOnAllTests($test, $browser);
  17465. } else {
  17466. $test->setupSpecificBrowser($browser);
  17467. }
  17468. }
  17469. }
  17470. }
  17471. <?php
  17472. /**
  17473. * PHPUnit
  17474. *
  17475. * Copyright (c) 2010-2013, Sebastian Bergmann <sebastian@phpunit.de>.
  17476. * All rights reserved.
  17477. *
  17478. * Redistribution and use in source and binary forms, with or without
  17479. * modification, are permitted provided that the following conditions
  17480. * are met:
  17481. *
  17482. * * Redistributions of source code must retain the above copyright
  17483. * notice, this list of conditions and the following disclaimer.
  17484. *
  17485. * * Redistributions in binary form must reproduce the above copyright
  17486. * notice, this list of conditions and the following disclaimer in
  17487. * the documentation and/or other materials provided with the
  17488. * distribution.
  17489. *
  17490. * * Neither the name of Sebastian Bergmann nor the names of his
  17491. * contributors may be used to endorse or promote products derived
  17492. * from this software without specific prior written permission.
  17493. *
  17494. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17495. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17496. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  17497. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  17498. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  17499. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  17500. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  17501. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  17502. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  17503. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  17504. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  17505. * POSSIBILITY OF SUCH DAMAGE.
  17506. *
  17507. * @package PHPUnit_Selenium
  17508. * @author Giorgio Sironi <info@giorgiosironi.com>
  17509. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  17510. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  17511. * @link http://www.phpunit.de/
  17512. * @since File available since Release 1.2.0
  17513. */
  17514. /**
  17515. * TestCase class that uses Selenium 2
  17516. * (WebDriver API and JsonWire protocol) to provide
  17517. * the functionality required for web testing.
  17518. *
  17519. * @package PHPUnit_Selenium
  17520. * @author Giorgio Sironi <info@giorgiosironi.com>
  17521. * @copyright 2010-2013 Sebastian Bergmann <sebastian@phpunit.de>
  17522. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  17523. * @version Release: @package_version@
  17524. * @link http://www.phpunit.de/
  17525. * @since Class available since Release 1.2.0
  17526. * @method void acceptAlert() Press OK on an alert, or confirms a dialog
  17527. * @method mixed alertText() alertText($value = NULL) Gets the alert dialog text, or sets the text for a prompt dialog
  17528. * @method void back()
  17529. * @method \PHPUnit_Extensions_Selenium2TestCase_Element byClassName() byClassName($value)
  17530. * @method \PHPUnit_Extensions_Selenium2TestCase_Element byCssSelector() byCssSelector($value)
  17531. * @method \PHPUnit_Extensions_Selenium2TestCase_Element byId() byId($value)
  17532. * @method \PHPUnit_Extensions_Selenium2TestCase_Element byLinkText() byLinkText($value)
  17533. * @method \PHPUnit_Extensions_Selenium2TestCase_Element byName() byName($value)
  17534. * @method \PHPUnit_Extensions_Selenium2TestCase_Element byTag() byTag($value)
  17535. * @method \PHPUnit_Extensions_Selenium2TestCase_Element byXPath() byXPath($value)
  17536. * @method void click() click(int $button = 0) Click any mouse button (at the coordinates set by the last moveto command).
  17537. * @method void clickOnElement() clickOnElement($id)
  17538. * @method string currentScreenshot() BLOB of the image file
  17539. * @method void dismissAlert() Press Cancel on an alert, or does not confirm a dialog
  17540. * @method void doubleclick() Double clicks (at the coordinates set by the last moveto command).
  17541. * @method \PHPUnit_Extensions_Selenium2TestCase_Element element() element(\PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria) Retrieves an element
  17542. * @method array elements() elements(\PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria) Retrieves an array of Element instances
  17543. * @method string execute() execute($javaScriptCode) Injects arbitrary JavaScript in the page and returns the last
  17544. * @method string executeAsync() executeAsync($javaScriptCode) Injects arbitrary JavaScript and wait for the callback (last element of arguments) to be called
  17545. * @method void forward()
  17546. * @method void frame() frame(mixed $element) Changes the focus to a frame in the page (by frameCount of type int, htmlId of type string, htmlName of type string or element of type \PHPUnit_Extensions_Selenium2TestCase_Element)
  17547. * @method void moveto() moveto(\PHPUnit_Extensions_Selenium2TestCase_Element $element) Move the mouse by an offset of the specificed element.
  17548. * @method void refresh()
  17549. * @method \PHPUnit_Extensions_Selenium2TestCase_Element_Select select() select($element)
  17550. * @method string source() Returns the HTML source of the page
  17551. * @method \PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts timeouts()
  17552. * @method string title()
  17553. * @method void|string url() url($url = NULL)
  17554. * @method PHPUnit_Extensions_Selenium2TestCase_ElementCriteria using() using($strategy) Factory Method for Criteria objects
  17555. * @method void window() window($name) Changes the focus to another window
  17556. * @method string windowHandle() Retrieves the current window handle
  17557. * @method string windowHandles() Retrieves a list of all available window handles
  17558. * @method string keys() Send a sequence of key strokes to the active element.
  17559. * @method string file($file_path) Upload a local file. Returns the fully qualified path to the transferred file.
  17560. * @method array log(string $type) Get the log for a given log type. Log buffer is reset after each request.
  17561. * @method array logTypes() Get available log types.
  17562. * @method void closeWindow() Close the current window.
  17563. * @method void close() Close the current window and clear session data.
  17564. * @method \PHPUnit_Extensions_Selenium2TestCase_Element active() Get the element on the page that currently has focus.
  17565. */
  17566. abstract class PHPUnit_Extensions_Selenium2TestCase extends PHPUnit_Framework_TestCase
  17567. {
  17568. const VERSION = '1.4.2';
  17569. /**
  17570. * @var string override to provide code coverage data from the server
  17571. */
  17572. protected $coverageScriptUrl;
  17573. /**
  17574. * @var PHPUnit_Extensions_Selenium2TestCase_Session
  17575. */
  17576. private $session;
  17577. /**
  17578. * @var array
  17579. */
  17580. private $parameters;
  17581. /**
  17582. * @var PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
  17583. */
  17584. protected static $sessionStrategy;
  17585. /**
  17586. * @var PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
  17587. */
  17588. protected static $browserSessionStrategy;
  17589. /**
  17590. * @var PHPUnit_Extensions_Selenium2TestCase_SessionStrategy
  17591. */
  17592. protected $localSessionStrategy;
  17593. /**
  17594. * @var array
  17595. */
  17596. private static $lastBrowserParams;
  17597. /**
  17598. * @var string
  17599. */
  17600. private $testId;
  17601. /**
  17602. * @var boolean
  17603. */
  17604. private $collectCodeCoverageInformation;
  17605. /**
  17606. * @var PHPUnit_Extensions_Selenium2TestCase_KeysHolder
  17607. */
  17608. private $keysHolder;
  17609. /**
  17610. * @param boolean
  17611. */
  17612. public static function shareSession($shareSession)
  17613. {
  17614. if (!is_bool($shareSession)) {
  17615. throw new InvalidArgumentException("The shared session support can only be switched on or off.");
  17616. }
  17617. if (!$shareSession) {
  17618. self::$sessionStrategy = self::defaultSessionStrategy();
  17619. } else {
  17620. self::$sessionStrategy = new PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Shared(self::defaultSessionStrategy());
  17621. }
  17622. }
  17623. private static function sessionStrategy()
  17624. {
  17625. if (!self::$sessionStrategy) {
  17626. self::$sessionStrategy = self::defaultSessionStrategy();
  17627. }
  17628. return self::$sessionStrategy;
  17629. }
  17630. private static function defaultSessionStrategy()
  17631. {
  17632. return new PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Isolated;
  17633. }
  17634. public function __construct($name = NULL, array $data = array(), $dataName = '')
  17635. {
  17636. parent::__construct($name, $data, $dataName);
  17637. $this->parameters = array(
  17638. 'host' => 'localhost',
  17639. 'port' => 4444,
  17640. 'browser' => NULL,
  17641. 'browserName' => NULL,
  17642. 'desiredCapabilities' => array(),
  17643. 'seleniumServerRequestsTimeout' => 60
  17644. );
  17645. $this->keysHolder = new PHPUnit_Extensions_Selenium2TestCase_KeysHolder();
  17646. }
  17647. public function setupSpecificBrowser($params)
  17648. {
  17649. $this->setUpSessionStrategy($params);
  17650. $params = array_merge($this->parameters, $params);
  17651. $this->setHost($params['host']);
  17652. $this->setPort($params['port']);
  17653. $this->setBrowser($params['browserName']);
  17654. $this->parameters['browser'] = $params['browser'];
  17655. $this->setDesiredCapabilities($params['desiredCapabilities']);
  17656. $this->setSeleniumServerRequestsTimeout(
  17657. $params['seleniumServerRequestsTimeout']);
  17658. }
  17659. protected function setUpSessionStrategy($params)
  17660. {
  17661. // This logic enables us to have a session strategy reused for each
  17662. // item in self::$browsers. We don't want them both to share one
  17663. // and we don't want each test for a specific browser to have a
  17664. // new strategy
  17665. if ($params == self::$lastBrowserParams) {
  17666. // do nothing so we use the same session strategy for this
  17667. // browser
  17668. } elseif (isset($params['sessionStrategy'])) {
  17669. $strat = $params['sessionStrategy'];
  17670. if ($strat != "isolated" && $strat != "shared") {
  17671. throw new InvalidArgumentException("Session strategy must be either 'isolated' or 'shared'");
  17672. } elseif ($strat == "isolated") {
  17673. self::$browserSessionStrategy = new PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Isolated;
  17674. } else {
  17675. self::$browserSessionStrategy = new PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Shared(self::defaultSessionStrategy());
  17676. }
  17677. } else {
  17678. self::$browserSessionStrategy = self::defaultSessionStrategy();
  17679. }
  17680. self::$lastBrowserParams = $params;
  17681. $this->localSessionStrategy = self::$browserSessionStrategy;
  17682. }
  17683. private function getStrategy()
  17684. {
  17685. if ($this->localSessionStrategy) {
  17686. return $this->localSessionStrategy;
  17687. } else {
  17688. return self::sessionStrategy();
  17689. }
  17690. }
  17691. public function prepareSession()
  17692. {
  17693. try {
  17694. if (!$this->session) {
  17695. $this->session = $this->getStrategy()->session($this->parameters);
  17696. }
  17697. } catch (PHPUnit_Extensions_Selenium2TestCase_NoSeleniumException $e) {
  17698. $this->markTestSkipped("The Selenium Server is not active on host {$this->parameters['host']} at port {$this->parameters['port']}.");
  17699. }
  17700. return $this->session;
  17701. }
  17702. public function run(PHPUnit_Framework_TestResult $result = NULL)
  17703. {
  17704. $this->testId = get_class($this) . '__' . $this->getName();
  17705. if ($result === NULL) {
  17706. $result = $this->createResult();
  17707. }
  17708. $this->collectCodeCoverageInformation = $result->getCollectCodeCoverageInformation();
  17709. parent::run($result);
  17710. if ($this->collectCodeCoverageInformation) {
  17711. $coverage = new PHPUnit_Extensions_SeleniumCommon_RemoteCoverage(
  17712. $this->coverageScriptUrl,
  17713. $this->testId
  17714. );
  17715. $result->getCodeCoverage()->append(
  17716. $coverage->get(), $this
  17717. );
  17718. }
  17719. // do not call this before to give the time to the Listeners to run
  17720. $this->getStrategy()->endOfTest($this->session);
  17721. return $result;
  17722. }
  17723. /**
  17724. * @throws RuntimeException
  17725. */
  17726. protected function runTest()
  17727. {
  17728. $this->prepareSession();
  17729. $thrownException = NULL;
  17730. if ($this->collectCodeCoverageInformation) {
  17731. $this->url($this->coverageScriptUrl); // phpunit_coverage.php won't do anything if the cookie isn't set, which is exactly what we want
  17732. $this->session->cookie()->add('PHPUNIT_SELENIUM_TEST_ID', $this->testId)->set();
  17733. }
  17734. try {
  17735. $this->setUpPage();
  17736. $result = parent::runTest();
  17737. if (!empty($this->verificationErrors)) {
  17738. $this->fail(implode("\n", $this->verificationErrors));
  17739. }
  17740. } catch (Exception $e) {
  17741. $thrownException = $e;
  17742. }
  17743. if ($this->collectCodeCoverageInformation) {
  17744. $this->session->cookie()->remove('PHPUNIT_SELENIUM_TEST_ID');
  17745. }
  17746. if (NULL !== $thrownException) {
  17747. throw $thrownException;
  17748. }
  17749. return $result;
  17750. }
  17751. public static function suite($className)
  17752. {
  17753. return PHPUnit_Extensions_SeleniumTestSuite::fromTestCaseClass($className);
  17754. }
  17755. public function onNotSuccessfulTest(Exception $e)
  17756. {
  17757. $this->getStrategy()->notSuccessfulTest();
  17758. parent::onNotSuccessfulTest($e);
  17759. }
  17760. /**
  17761. * Delegate method calls to the Session.
  17762. *
  17763. * @param string $command
  17764. * @param array $arguments
  17765. * @return mixed
  17766. */
  17767. public function __call($command, $arguments)
  17768. {
  17769. if ($this->session === NULL) {
  17770. throw new PHPUnit_Extensions_Selenium2TestCase_Exception("There is currently no active session to execute the '$command' command. You're probably trying to set some option in setUp() with an incorrect setter name. You may consider using setUpPage() instead.");
  17771. }
  17772. $result = call_user_func_array(
  17773. array($this->session, $command), $arguments
  17774. );
  17775. return $result;
  17776. }
  17777. /**
  17778. * @param string $host
  17779. * @throws InvalidArgumentException
  17780. */
  17781. public function setHost($host)
  17782. {
  17783. if (!is_string($host)) {
  17784. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  17785. }
  17786. $this->parameters['host'] = $host;
  17787. }
  17788. public function getHost()
  17789. {
  17790. return $this->parameters['host'];
  17791. }
  17792. /**
  17793. * @param integer $port
  17794. * @throws InvalidArgumentException
  17795. */
  17796. public function setPort($port)
  17797. {
  17798. if (!is_int($port)) {
  17799. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  17800. }
  17801. $this->parameters['port'] = $port;
  17802. }
  17803. public function getPort()
  17804. {
  17805. return $this->parameters['port'];
  17806. }
  17807. /**
  17808. * @param string $browser
  17809. * @throws InvalidArgumentException
  17810. */
  17811. public function setBrowser($browserName)
  17812. {
  17813. if (!is_string($browserName)) {
  17814. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  17815. }
  17816. $this->parameters['browserName'] = $browserName;
  17817. }
  17818. public function getBrowser()
  17819. {
  17820. return $this->parameters['browserName'];
  17821. }
  17822. /**
  17823. * @param string $browserUrl
  17824. * @throws InvalidArgumentException
  17825. */
  17826. public function setBrowserUrl($browserUrl)
  17827. {
  17828. if (!is_string($browserUrl)) {
  17829. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  17830. }
  17831. $this->parameters['browserUrl'] = new PHPUnit_Extensions_Selenium2TestCase_URL($browserUrl);
  17832. }
  17833. public function getBrowserUrl()
  17834. {
  17835. if (isset($this->parameters['browserUrl'])) {
  17836. return $this->parameters['browserUrl'];
  17837. }
  17838. return '';
  17839. }
  17840. /**
  17841. * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol
  17842. */
  17843. public function setDesiredCapabilities(array $capabilities)
  17844. {
  17845. $this->parameters['desiredCapabilities'] = $capabilities;
  17846. }
  17847. public function getDesiredCapabilities()
  17848. {
  17849. return $this->parameters['desiredCapabilities'];
  17850. }
  17851. /**
  17852. * @param int $timeout seconds
  17853. */
  17854. public function setSeleniumServerRequestsTimeout($timeout)
  17855. {
  17856. $this->parameters['seleniumServerRequestsTimeout'] = $timeout;
  17857. }
  17858. public function getSeleniumServerRequestsTimeout()
  17859. {
  17860. return $this->parameters['seleniumServerRequestsTimeout'];
  17861. }
  17862. /**
  17863. * Get test id (generated internally)
  17864. * @return string
  17865. */
  17866. public function getTestId()
  17867. {
  17868. return $this->testId;
  17869. }
  17870. /**
  17871. * Get Selenium2 current session id
  17872. * @return string
  17873. */
  17874. public function getSessionId()
  17875. {
  17876. if ($this->session) {
  17877. return $this->session->id();
  17878. }
  17879. return FALSE;
  17880. }
  17881. /**
  17882. * Wait until callback isn't null or timeout occurs
  17883. *
  17884. * @param $callback
  17885. * @param null $timeout
  17886. * @return mixed
  17887. */
  17888. public function waitUntil($callback, $timeout = NULL)
  17889. {
  17890. $waitUntil = new PHPUnit_Extensions_Selenium2TestCase_WaitUntil($this);
  17891. return $waitUntil->run($callback, $timeout);
  17892. }
  17893. /**
  17894. * Sends a special key
  17895. * Deprecated due to issues with IE webdriver. Use keys() method instead
  17896. * @deprecated
  17897. * @param string $name
  17898. * @throws PHPUnit_Extensions_Selenium2TestCase_Exception
  17899. * @see PHPUnit_Extensions_Selenium2TestCase_KeysHolder
  17900. */
  17901. public function keysSpecial($name)
  17902. {
  17903. $names = explode(',', $name);
  17904. foreach ($names as $key) {
  17905. $this->keys($this->keysHolder->specialKey(trim($key)));
  17906. }
  17907. }
  17908. /**
  17909. * setUp method that is called after the session has been prepared.
  17910. * It is possible to use session-specific commands like url() here.
  17911. */
  17912. public function setUpPage()
  17913. {
  17914. }
  17915. }
  17916. <?php
  17917. /*
  17918. * This file is part of the PHP_CodeCoverage package.
  17919. *
  17920. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  17921. *
  17922. * For the full copyright and license information, please view the LICENSE
  17923. * file that was distributed with this source code.
  17924. */
  17925. /**
  17926. * Utility methods.
  17927. *
  17928. * @since Class available since Release 1.0.0
  17929. */
  17930. class PHP_CodeCoverage_Util
  17931. {
  17932. /**
  17933. * @param float $a
  17934. * @param float $b
  17935. * @return float ($a / $b) * 100
  17936. */
  17937. public static function percent($a, $b, $asString = false, $fixedWidth = false)
  17938. {
  17939. if ($asString && $b == 0) {
  17940. return '';
  17941. }
  17942. if ($b > 0) {
  17943. $percent = ($a / $b) * 100;
  17944. } else {
  17945. $percent = 100;
  17946. }
  17947. if ($asString) {
  17948. if ($fixedWidth) {
  17949. return sprintf('%6.2F%%', $percent);
  17950. }
  17951. return sprintf('%01.2F%%', $percent);
  17952. } else {
  17953. return $percent;
  17954. }
  17955. }
  17956. }
  17957. <?php
  17958. /*
  17959. * This file is part of the PHP_CodeCoverage package.
  17960. *
  17961. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  17962. *
  17963. * For the full copyright and license information, please view the LICENSE
  17964. * file that was distributed with this source code.
  17965. */
  17966. /**
  17967. * Exception class for PHP_CodeCoverage component.
  17968. *
  17969. * @since Class available since Release 1.1.0
  17970. */
  17971. class PHP_CodeCoverage_Exception extends RuntimeException
  17972. {
  17973. }
  17974. <?php
  17975. /*
  17976. * This file is part of the PHP_CodeCoverage package.
  17977. *
  17978. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  17979. *
  17980. * For the full copyright and license information, please view the LICENSE
  17981. * file that was distributed with this source code.
  17982. */
  17983. use SebastianBergmann\Environment\Runtime;
  17984. /**
  17985. * Base class for PHP_CodeCoverage_Report_Node renderers.
  17986. *
  17987. * @since Class available since Release 1.1.0
  17988. */
  17989. abstract class PHP_CodeCoverage_Report_HTML_Renderer
  17990. {
  17991. /**
  17992. * @var string
  17993. */
  17994. protected $templatePath;
  17995. /**
  17996. * @var string
  17997. */
  17998. protected $generator;
  17999. /**
  18000. * @var string
  18001. */
  18002. protected $date;
  18003. /**
  18004. * @var int
  18005. */
  18006. protected $lowUpperBound;
  18007. /**
  18008. * @var int
  18009. */
  18010. protected $highLowerBound;
  18011. /**
  18012. * @var string
  18013. */
  18014. protected $version;
  18015. /**
  18016. * Constructor.
  18017. *
  18018. * @param string $templatePath
  18019. * @param string $generator
  18020. * @param string $date
  18021. * @param int $lowUpperBound
  18022. * @param int $highLowerBound
  18023. */
  18024. public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound)
  18025. {
  18026. $version = new SebastianBergmann\Version('2.1.8', dirname(dirname(dirname(dirname(__DIR__)))));
  18027. $this->templatePath = $templatePath;
  18028. $this->generator = $generator;
  18029. $this->date = $date;
  18030. $this->lowUpperBound = $lowUpperBound;
  18031. $this->highLowerBound = $highLowerBound;
  18032. $this->version = $version->getVersion();
  18033. }
  18034. /**
  18035. * @param Text_Template $template
  18036. * @param array $data
  18037. * @return string
  18038. */
  18039. protected function renderItemTemplate(Text_Template $template, array $data)
  18040. {
  18041. $numSeparator = '&nbsp;/&nbsp;';
  18042. $classesBar = '&nbsp;';
  18043. $classesLevel = 'None';
  18044. $classesNumber = '&nbsp;';
  18045. if (isset($data['numClasses']) && $data['numClasses'] > 0) {
  18046. $classesLevel = $this->getColorLevel($data['testedClassesPercent']);
  18047. $classesNumber = $data['numTestedClasses'] . $numSeparator .
  18048. $data['numClasses'];
  18049. $classesBar = $this->getCoverageBar(
  18050. $data['testedClassesPercent']
  18051. );
  18052. }
  18053. $methodsBar = '&nbsp;';
  18054. $methodsLevel = 'None';
  18055. $methodsNumber = '&nbsp;';
  18056. if ($data['numMethods'] > 0) {
  18057. $methodsLevel = $this->getColorLevel($data['testedMethodsPercent']);
  18058. $methodsNumber = $data['numTestedMethods'] . $numSeparator .
  18059. $data['numMethods'];
  18060. $methodsBar = $this->getCoverageBar(
  18061. $data['testedMethodsPercent']
  18062. );
  18063. }
  18064. $linesBar = '&nbsp;';
  18065. $linesLevel = 'None';
  18066. $linesNumber = '&nbsp;';
  18067. if ($data['numExecutableLines'] > 0) {
  18068. $linesLevel = $this->getColorLevel($data['linesExecutedPercent']);
  18069. $linesNumber = $data['numExecutedLines'] . $numSeparator .
  18070. $data['numExecutableLines'];
  18071. $linesBar = $this->getCoverageBar(
  18072. $data['linesExecutedPercent']
  18073. );
  18074. }
  18075. $template->setVar(
  18076. array(
  18077. 'icon' => isset($data['icon']) ? $data['icon'] : '',
  18078. 'crap' => isset($data['crap']) ? $data['crap'] : '',
  18079. 'name' => $data['name'],
  18080. 'lines_bar' => $linesBar,
  18081. 'lines_executed_percent' => $data['linesExecutedPercentAsString'],
  18082. 'lines_level' => $linesLevel,
  18083. 'lines_number' => $linesNumber,
  18084. 'methods_bar' => $methodsBar,
  18085. 'methods_tested_percent' => $data['testedMethodsPercentAsString'],
  18086. 'methods_level' => $methodsLevel,
  18087. 'methods_number' => $methodsNumber,
  18088. 'classes_bar' => $classesBar,
  18089. 'classes_tested_percent' => isset($data['testedClassesPercentAsString']) ? $data['testedClassesPercentAsString'] : '',
  18090. 'classes_level' => $classesLevel,
  18091. 'classes_number' => $classesNumber
  18092. )
  18093. );
  18094. return $template->render();
  18095. }
  18096. /**
  18097. * @param Text_Template $template
  18098. * @param PHP_CodeCoverage_Report_Node $node
  18099. */
  18100. protected function setCommonTemplateVariables(Text_Template $template, PHP_CodeCoverage_Report_Node $node)
  18101. {
  18102. $runtime = new Runtime;
  18103. $template->setVar(
  18104. array(
  18105. 'id' => $node->getId(),
  18106. 'full_path' => $node->getPath(),
  18107. 'path_to_root' => $this->getPathToRoot($node),
  18108. 'breadcrumbs' => $this->getBreadcrumbs($node),
  18109. 'date' => $this->date,
  18110. 'version' => $this->version,
  18111. 'runtime_name' => $runtime->getName(),
  18112. 'runtime_version' => $runtime->getVersion(),
  18113. 'runtime_link' => $runtime->getVendorUrl(),
  18114. 'generator' => $this->generator,
  18115. 'low_upper_bound' => $this->lowUpperBound,
  18116. 'high_lower_bound' => $this->highLowerBound
  18117. )
  18118. );
  18119. }
  18120. protected function getBreadcrumbs(PHP_CodeCoverage_Report_Node $node)
  18121. {
  18122. $breadcrumbs = '';
  18123. $path = $node->getPathAsArray();
  18124. $pathToRoot = array();
  18125. $max = count($path);
  18126. if ($node instanceof PHP_CodeCoverage_Report_Node_File) {
  18127. $max--;
  18128. }
  18129. for ($i = 0; $i < $max; $i++) {
  18130. $pathToRoot[] = str_repeat('../', $i);
  18131. }
  18132. foreach ($path as $step) {
  18133. if ($step !== $node) {
  18134. $breadcrumbs .= $this->getInactiveBreadcrumb(
  18135. $step,
  18136. array_pop($pathToRoot)
  18137. );
  18138. } else {
  18139. $breadcrumbs .= $this->getActiveBreadcrumb($step);
  18140. }
  18141. }
  18142. return $breadcrumbs;
  18143. }
  18144. protected function getActiveBreadcrumb(PHP_CodeCoverage_Report_Node $node)
  18145. {
  18146. $buffer = sprintf(
  18147. ' <li class="active">%s</li>' . "\n",
  18148. $node->getName()
  18149. );
  18150. if ($node instanceof PHP_CodeCoverage_Report_Node_Directory) {
  18151. $buffer .= ' <li>(<a href="dashboard.html">Dashboard</a>)</li>' . "\n";
  18152. }
  18153. return $buffer;
  18154. }
  18155. protected function getInactiveBreadcrumb(PHP_CodeCoverage_Report_Node $node, $pathToRoot)
  18156. {
  18157. return sprintf(
  18158. ' <li><a href="%sindex.html">%s</a></li>' . "\n",
  18159. $pathToRoot,
  18160. $node->getName()
  18161. );
  18162. }
  18163. protected function getPathToRoot(PHP_CodeCoverage_Report_Node $node)
  18164. {
  18165. $id = $node->getId();
  18166. $depth = substr_count($id, '/');
  18167. if ($id != 'index' &&
  18168. $node instanceof PHP_CodeCoverage_Report_Node_Directory) {
  18169. $depth++;
  18170. }
  18171. return str_repeat('../', $depth);
  18172. }
  18173. protected function getCoverageBar($percent)
  18174. {
  18175. $level = $this->getColorLevel($percent);
  18176. $template = new Text_Template(
  18177. $this->templatePath . 'coverage_bar.html',
  18178. '{{',
  18179. '}}'
  18180. );
  18181. $template->setVar(array('level' => $level, 'percent' => sprintf('%.2F', $percent)));
  18182. return $template->render();
  18183. }
  18184. /**
  18185. * @param int $percent
  18186. * @return string
  18187. */
  18188. protected function getColorLevel($percent)
  18189. {
  18190. if ($percent <= $this->lowUpperBound) {
  18191. return 'danger';
  18192. } elseif ($percent > $this->lowUpperBound &&
  18193. $percent < $this->highLowerBound) {
  18194. return 'warning';
  18195. } else {
  18196. return 'success';
  18197. }
  18198. }
  18199. }
  18200. <?php
  18201. /*
  18202. * This file is part of the PHP_CodeCoverage package.
  18203. *
  18204. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  18205. *
  18206. * For the full copyright and license information, please view the LICENSE
  18207. * file that was distributed with this source code.
  18208. */
  18209. /**
  18210. * Renders the dashboard for a PHP_CodeCoverage_Report_Node_Directory node.
  18211. *
  18212. * @since Class available since Release 1.1.0
  18213. */
  18214. class PHP_CodeCoverage_Report_HTML_Renderer_Dashboard extends PHP_CodeCoverage_Report_HTML_Renderer
  18215. {
  18216. /**
  18217. * @param PHP_CodeCoverage_Report_Node_Directory $node
  18218. * @param string $file
  18219. */
  18220. public function render(PHP_CodeCoverage_Report_Node_Directory $node, $file)
  18221. {
  18222. $classes = $node->getClassesAndTraits();
  18223. $template = new Text_Template(
  18224. $this->templatePath . 'dashboard.html',
  18225. '{{',
  18226. '}}'
  18227. );
  18228. $this->setCommonTemplateVariables($template, $node);
  18229. $baseLink = $node->getId() . '/';
  18230. $complexity = $this->complexity($classes, $baseLink);
  18231. $coverageDistribution = $this->coverageDistribution($classes);
  18232. $insufficientCoverage = $this->insufficientCoverage($classes, $baseLink);
  18233. $projectRisks = $this->projectRisks($classes, $baseLink);
  18234. $template->setVar(
  18235. array(
  18236. 'insufficient_coverage_classes' => $insufficientCoverage['class'],
  18237. 'insufficient_coverage_methods' => $insufficientCoverage['method'],
  18238. 'project_risks_classes' => $projectRisks['class'],
  18239. 'project_risks_methods' => $projectRisks['method'],
  18240. 'complexity_class' => $complexity['class'],
  18241. 'complexity_method' => $complexity['method'],
  18242. 'class_coverage_distribution' => $coverageDistribution['class'],
  18243. 'method_coverage_distribution' => $coverageDistribution['method']
  18244. )
  18245. );
  18246. $template->renderTo($file);
  18247. }
  18248. /**
  18249. * Returns the data for the Class/Method Complexity charts.
  18250. *
  18251. * @param array $classes
  18252. * @param string $baseLink
  18253. * @return array
  18254. */
  18255. protected function complexity(array $classes, $baseLink)
  18256. {
  18257. $result = array('class' => array(), 'method' => array());
  18258. foreach ($classes as $className => $class) {
  18259. foreach ($class['methods'] as $methodName => $method) {
  18260. if ($className != '*') {
  18261. $methodName = $className . '::' . $methodName;
  18262. }
  18263. $result['method'][] = array(
  18264. $method['coverage'],
  18265. $method['ccn'],
  18266. sprintf(
  18267. '<a href="%s">%s</a>',
  18268. str_replace($baseLink, '', $method['link']),
  18269. $methodName
  18270. )
  18271. );
  18272. }
  18273. $result['class'][] = array(
  18274. $class['coverage'],
  18275. $class['ccn'],
  18276. sprintf(
  18277. '<a href="%s">%s</a>',
  18278. str_replace($baseLink, '', $class['link']),
  18279. $className
  18280. )
  18281. );
  18282. }
  18283. return array(
  18284. 'class' => json_encode($result['class']),
  18285. 'method' => json_encode($result['method'])
  18286. );
  18287. }
  18288. /**
  18289. * Returns the data for the Class / Method Coverage Distribution chart.
  18290. *
  18291. * @param array $classes
  18292. * @return array
  18293. */
  18294. protected function coverageDistribution(array $classes)
  18295. {
  18296. $result = array(
  18297. 'class' => array(
  18298. '0%' => 0,
  18299. '0-10%' => 0,
  18300. '10-20%' => 0,
  18301. '20-30%' => 0,
  18302. '30-40%' => 0,
  18303. '40-50%' => 0,
  18304. '50-60%' => 0,
  18305. '60-70%' => 0,
  18306. '70-80%' => 0,
  18307. '80-90%' => 0,
  18308. '90-100%' => 0,
  18309. '100%' => 0
  18310. ),
  18311. 'method' => array(
  18312. '0%' => 0,
  18313. '0-10%' => 0,
  18314. '10-20%' => 0,
  18315. '20-30%' => 0,
  18316. '30-40%' => 0,
  18317. '40-50%' => 0,
  18318. '50-60%' => 0,
  18319. '60-70%' => 0,
  18320. '70-80%' => 0,
  18321. '80-90%' => 0,
  18322. '90-100%' => 0,
  18323. '100%' => 0
  18324. )
  18325. );
  18326. foreach ($classes as $class) {
  18327. foreach ($class['methods'] as $methodName => $method) {
  18328. if ($method['coverage'] == 0) {
  18329. $result['method']['0%']++;
  18330. } elseif ($method['coverage'] == 100) {
  18331. $result['method']['100%']++;
  18332. } else {
  18333. $key = floor($method['coverage'] / 10) * 10;
  18334. $key = $key . '-' . ($key + 10) . '%';
  18335. $result['method'][$key]++;
  18336. }
  18337. }
  18338. if ($class['coverage'] == 0) {
  18339. $result['class']['0%']++;
  18340. } elseif ($class['coverage'] == 100) {
  18341. $result['class']['100%']++;
  18342. } else {
  18343. $key = floor($class['coverage'] / 10) * 10;
  18344. $key = $key . '-' . ($key + 10) . '%';
  18345. $result['class'][$key]++;
  18346. }
  18347. }
  18348. return array(
  18349. 'class' => json_encode(array_values($result['class'])),
  18350. 'method' => json_encode(array_values($result['method']))
  18351. );
  18352. }
  18353. /**
  18354. * Returns the classes / methods with insufficient coverage.
  18355. *
  18356. * @param array $classes
  18357. * @param string $baseLink
  18358. * @return array
  18359. */
  18360. protected function insufficientCoverage(array $classes, $baseLink)
  18361. {
  18362. $leastTestedClasses = array();
  18363. $leastTestedMethods = array();
  18364. $result = array('class' => '', 'method' => '');
  18365. foreach ($classes as $className => $class) {
  18366. foreach ($class['methods'] as $methodName => $method) {
  18367. if ($method['coverage'] < $this->highLowerBound) {
  18368. if ($className != '*') {
  18369. $key = $className . '::' . $methodName;
  18370. } else {
  18371. $key = $methodName;
  18372. }
  18373. $leastTestedMethods[$key] = $method['coverage'];
  18374. }
  18375. }
  18376. if ($class['coverage'] < $this->highLowerBound) {
  18377. $leastTestedClasses[$className] = $class['coverage'];
  18378. }
  18379. }
  18380. asort($leastTestedClasses);
  18381. asort($leastTestedMethods);
  18382. foreach ($leastTestedClasses as $className => $coverage) {
  18383. $result['class'] .= sprintf(
  18384. ' <tr><td><a href="%s">%s</a></td><td class="text-right">%d%%</td></tr>' . "\n",
  18385. str_replace($baseLink, '', $classes[$className]['link']),
  18386. $className,
  18387. $coverage
  18388. );
  18389. }
  18390. foreach ($leastTestedMethods as $methodName => $coverage) {
  18391. list($class, $method) = explode('::', $methodName);
  18392. $result['method'] .= sprintf(
  18393. ' <tr><td><a href="%s"><abbr title="%s">%s</a></a></td><td class="text-right">%d%%</td></tr>' . "\n",
  18394. str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']),
  18395. $methodName,
  18396. $method,
  18397. $coverage
  18398. );
  18399. }
  18400. return $result;
  18401. }
  18402. /**
  18403. * Returns the project risks according to the CRAP index.
  18404. *
  18405. * @param array $classes
  18406. * @param string $baseLink
  18407. * @return array
  18408. */
  18409. protected function projectRisks(array $classes, $baseLink)
  18410. {
  18411. $classRisks = array();
  18412. $methodRisks = array();
  18413. $result = array('class' => '', 'method' => '');
  18414. foreach ($classes as $className => $class) {
  18415. foreach ($class['methods'] as $methodName => $method) {
  18416. if ($method['coverage'] < $this->highLowerBound &&
  18417. $method['ccn'] > 1) {
  18418. if ($className != '*') {
  18419. $key = $className . '::' . $methodName;
  18420. } else {
  18421. $key = $methodName;
  18422. }
  18423. $methodRisks[$key] = $method['crap'];
  18424. }
  18425. }
  18426. if ($class['coverage'] < $this->highLowerBound &&
  18427. $class['ccn'] > count($class['methods'])) {
  18428. $classRisks[$className] = $class['crap'];
  18429. }
  18430. }
  18431. arsort($classRisks);
  18432. arsort($methodRisks);
  18433. foreach ($classRisks as $className => $crap) {
  18434. $result['class'] .= sprintf(
  18435. ' <tr><td><a href="%s">%s</a></td><td class="text-right">%d</td></tr>' . "\n",
  18436. str_replace($baseLink, '', $classes[$className]['link']),
  18437. $className,
  18438. $crap
  18439. );
  18440. }
  18441. foreach ($methodRisks as $methodName => $crap) {
  18442. list($class, $method) = explode('::', $methodName);
  18443. $result['method'] .= sprintf(
  18444. ' <tr><td><a href="%s"><abbr title="%s">%s</abbr></a></td><td class="text-right">%d</td></tr>' . "\n",
  18445. str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']),
  18446. $methodName,
  18447. $method,
  18448. $crap
  18449. );
  18450. }
  18451. return $result;
  18452. }
  18453. protected function getActiveBreadcrumb(PHP_CodeCoverage_Report_Node $node)
  18454. {
  18455. return sprintf(
  18456. ' <li><a href="index.html">%s</a></li>' . "\n" .
  18457. ' <li class="active">(Dashboard)</li>' . "\n",
  18458. $node->getName()
  18459. );
  18460. }
  18461. }
  18462. <?php
  18463. /*
  18464. * This file is part of the PHP_CodeCoverage package.
  18465. *
  18466. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  18467. *
  18468. * For the full copyright and license information, please view the LICENSE
  18469. * file that was distributed with this source code.
  18470. */
  18471. // @codeCoverageIgnoreStart
  18472. if (!defined('T_TRAIT')) {
  18473. define('T_TRAIT', 1001);
  18474. }
  18475. if (!defined('T_INSTEADOF')) {
  18476. define('T_INSTEADOF', 1002);
  18477. }
  18478. if (!defined('T_CALLABLE')) {
  18479. define('T_CALLABLE', 1003);
  18480. }
  18481. if (!defined('T_FINALLY')) {
  18482. define('T_FINALLY', 1004);
  18483. }
  18484. if (!defined('T_YIELD')) {
  18485. define('T_YIELD', 1005);
  18486. }
  18487. // @codeCoverageIgnoreEnd
  18488. /**
  18489. * Renders a PHP_CodeCoverage_Report_Node_File node.
  18490. *
  18491. * @since Class available since Release 1.1.0
  18492. */
  18493. class PHP_CodeCoverage_Report_HTML_Renderer_File extends PHP_CodeCoverage_Report_HTML_Renderer
  18494. {
  18495. /**
  18496. * @var int
  18497. */
  18498. private $htmlspecialcharsFlags;
  18499. /**
  18500. * Constructor.
  18501. *
  18502. * @param string $templatePath
  18503. * @param string $generator
  18504. * @param string $date
  18505. * @param int $lowUpperBound
  18506. * @param int $highLowerBound
  18507. */
  18508. public function __construct($templatePath, $generator, $date, $lowUpperBound, $highLowerBound)
  18509. {
  18510. parent::__construct(
  18511. $templatePath,
  18512. $generator,
  18513. $date,
  18514. $lowUpperBound,
  18515. $highLowerBound
  18516. );
  18517. $this->htmlspecialcharsFlags = ENT_COMPAT;
  18518. if (PHP_VERSION_ID >= 50400 && defined('ENT_SUBSTITUTE')) {
  18519. $this->htmlspecialcharsFlags = $this->htmlspecialcharsFlags | ENT_HTML401 | ENT_SUBSTITUTE;
  18520. }
  18521. }
  18522. /**
  18523. * @param PHP_CodeCoverage_Report_Node_File $node
  18524. * @param string $file
  18525. */
  18526. public function render(PHP_CodeCoverage_Report_Node_File $node, $file)
  18527. {
  18528. $template = new Text_Template($this->templatePath . 'file.html', '{{', '}}');
  18529. $template->setVar(
  18530. array(
  18531. 'items' => $this->renderItems($node),
  18532. 'lines' => $this->renderSource($node)
  18533. )
  18534. );
  18535. $this->setCommonTemplateVariables($template, $node);
  18536. $template->renderTo($file);
  18537. }
  18538. /**
  18539. * @param PHP_CodeCoverage_Report_Node_File $node
  18540. * @return string
  18541. */
  18542. protected function renderItems(PHP_CodeCoverage_Report_Node_File $node)
  18543. {
  18544. $template = new Text_Template($this->templatePath . 'file_item.html', '{{', '}}');
  18545. $methodItemTemplate = new Text_Template(
  18546. $this->templatePath . 'method_item.html',
  18547. '{{',
  18548. '}}'
  18549. );
  18550. $items = $this->renderItemTemplate(
  18551. $template,
  18552. array(
  18553. 'name' => 'Total',
  18554. 'numClasses' => $node->getNumClassesAndTraits(),
  18555. 'numTestedClasses' => $node->getNumTestedClassesAndTraits(),
  18556. 'numMethods' => $node->getNumMethods(),
  18557. 'numTestedMethods' => $node->getNumTestedMethods(),
  18558. 'linesExecutedPercent' => $node->getLineExecutedPercent(false),
  18559. 'linesExecutedPercentAsString' => $node->getLineExecutedPercent(),
  18560. 'numExecutedLines' => $node->getNumExecutedLines(),
  18561. 'numExecutableLines' => $node->getNumExecutableLines(),
  18562. 'testedMethodsPercent' => $node->getTestedMethodsPercent(false),
  18563. 'testedMethodsPercentAsString' => $node->getTestedMethodsPercent(),
  18564. 'testedClassesPercent' => $node->getTestedClassesAndTraitsPercent(false),
  18565. 'testedClassesPercentAsString' => $node->getTestedClassesAndTraitsPercent(),
  18566. 'crap' => '<abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr>'
  18567. )
  18568. );
  18569. $items .= $this->renderFunctionItems(
  18570. $node->getFunctions(),
  18571. $methodItemTemplate
  18572. );
  18573. $items .= $this->renderTraitOrClassItems(
  18574. $node->getTraits(),
  18575. $template,
  18576. $methodItemTemplate
  18577. );
  18578. $items .= $this->renderTraitOrClassItems(
  18579. $node->getClasses(),
  18580. $template,
  18581. $methodItemTemplate
  18582. );
  18583. return $items;
  18584. }
  18585. /**
  18586. * @param array $items
  18587. * @param Text_Template $template
  18588. * @param Text_Template $methodItemTemplate
  18589. * @return string
  18590. */
  18591. protected function renderTraitOrClassItems(array $items, Text_Template $template, Text_Template $methodItemTemplate)
  18592. {
  18593. if (empty($items)) {
  18594. return '';
  18595. }
  18596. $buffer = '';
  18597. foreach ($items as $name => $item) {
  18598. $numMethods = count($item['methods']);
  18599. $numTestedMethods = 0;
  18600. foreach ($item['methods'] as $method) {
  18601. if ($method['executedLines'] == $method['executableLines']) {
  18602. $numTestedMethods++;
  18603. }
  18604. }
  18605. $buffer .= $this->renderItemTemplate(
  18606. $template,
  18607. array(
  18608. 'name' => $name,
  18609. 'numClasses' => 1,
  18610. 'numTestedClasses' => $numTestedMethods == $numMethods ? 1 : 0,
  18611. 'numMethods' => $numMethods,
  18612. 'numTestedMethods' => $numTestedMethods,
  18613. 'linesExecutedPercent' => PHP_CodeCoverage_Util::percent(
  18614. $item['executedLines'],
  18615. $item['executableLines'],
  18616. false
  18617. ),
  18618. 'linesExecutedPercentAsString' => PHP_CodeCoverage_Util::percent(
  18619. $item['executedLines'],
  18620. $item['executableLines'],
  18621. true
  18622. ),
  18623. 'numExecutedLines' => $item['executedLines'],
  18624. 'numExecutableLines' => $item['executableLines'],
  18625. 'testedMethodsPercent' => PHP_CodeCoverage_Util::percent(
  18626. $numTestedMethods,
  18627. $numMethods,
  18628. false
  18629. ),
  18630. 'testedMethodsPercentAsString' => PHP_CodeCoverage_Util::percent(
  18631. $numTestedMethods,
  18632. $numMethods,
  18633. true
  18634. ),
  18635. 'testedClassesPercent' => PHP_CodeCoverage_Util::percent(
  18636. $numTestedMethods == $numMethods ? 1 : 0,
  18637. 1,
  18638. false
  18639. ),
  18640. 'testedClassesPercentAsString' => PHP_CodeCoverage_Util::percent(
  18641. $numTestedMethods == $numMethods ? 1 : 0,
  18642. 1,
  18643. true
  18644. ),
  18645. 'crap' => $item['crap']
  18646. )
  18647. );
  18648. foreach ($item['methods'] as $method) {
  18649. $buffer .= $this->renderFunctionOrMethodItem(
  18650. $methodItemTemplate,
  18651. $method,
  18652. '&nbsp;'
  18653. );
  18654. }
  18655. }
  18656. return $buffer;
  18657. }
  18658. /**
  18659. * @param array $functions
  18660. * @param Text_Template $template
  18661. * @return string
  18662. */
  18663. protected function renderFunctionItems(array $functions, Text_Template $template)
  18664. {
  18665. if (empty($functions)) {
  18666. return '';
  18667. }
  18668. $buffer = '';
  18669. foreach ($functions as $function) {
  18670. $buffer .= $this->renderFunctionOrMethodItem(
  18671. $template,
  18672. $function
  18673. );
  18674. }
  18675. return $buffer;
  18676. }
  18677. /**
  18678. * @param Text_Template $template
  18679. * @return string
  18680. */
  18681. protected function renderFunctionOrMethodItem(Text_Template $template, array $item, $indent = '')
  18682. {
  18683. $numTestedItems = $item['executedLines'] == $item['executableLines'] ? 1 : 0;
  18684. return $this->renderItemTemplate(
  18685. $template,
  18686. array(
  18687. 'name' => sprintf(
  18688. '%s<a href="#%d"><abbr title="%s">%s</abbr></a>',
  18689. $indent,
  18690. $item['startLine'],
  18691. htmlspecialchars($item['signature']),
  18692. isset($item['functionName']) ? $item['functionName'] : $item['methodName']
  18693. ),
  18694. 'numMethods' => 1,
  18695. 'numTestedMethods' => $numTestedItems,
  18696. 'linesExecutedPercent' => PHP_CodeCoverage_Util::percent(
  18697. $item['executedLines'],
  18698. $item['executableLines'],
  18699. false
  18700. ),
  18701. 'linesExecutedPercentAsString' => PHP_CodeCoverage_Util::percent(
  18702. $item['executedLines'],
  18703. $item['executableLines'],
  18704. true
  18705. ),
  18706. 'numExecutedLines' => $item['executedLines'],
  18707. 'numExecutableLines' => $item['executableLines'],
  18708. 'testedMethodsPercent' => PHP_CodeCoverage_Util::percent(
  18709. $numTestedItems,
  18710. 1,
  18711. false
  18712. ),
  18713. 'testedMethodsPercentAsString' => PHP_CodeCoverage_Util::percent(
  18714. $numTestedItems,
  18715. 1,
  18716. true
  18717. ),
  18718. 'crap' => $item['crap']
  18719. )
  18720. );
  18721. }
  18722. /**
  18723. * @param PHP_CodeCoverage_Report_Node_File $node
  18724. * @return string
  18725. */
  18726. protected function renderSource(PHP_CodeCoverage_Report_Node_File $node)
  18727. {
  18728. $coverageData = $node->getCoverageData();
  18729. $testData = $node->getTestData();
  18730. $codeLines = $this->loadFile($node->getPath());
  18731. $lines = '';
  18732. $i = 1;
  18733. foreach ($codeLines as $line) {
  18734. $trClass = '';
  18735. $popoverContent = '';
  18736. $popoverTitle = '';
  18737. if (array_key_exists($i, $coverageData)) {
  18738. $numTests = count($coverageData[$i]);
  18739. if ($coverageData[$i] === null) {
  18740. $trClass = ' class="warning"';
  18741. } elseif ($numTests == 0) {
  18742. $trClass = ' class="danger"';
  18743. } else {
  18744. $lineCss = 'covered-by-large-tests';
  18745. $popoverContent = '<ul>';
  18746. if ($numTests > 1) {
  18747. $popoverTitle = $numTests . ' tests cover line ' . $i;
  18748. } else {
  18749. $popoverTitle = '1 test covers line ' . $i;
  18750. }
  18751. foreach ($coverageData[$i] as $test) {
  18752. if ($lineCss == 'covered-by-large-tests' && $testData[$test]['size'] == 'medium') {
  18753. $lineCss = 'covered-by-medium-tests';
  18754. } elseif ($testData[$test]['size'] == 'small') {
  18755. $lineCss = 'covered-by-small-tests';
  18756. }
  18757. switch ($testData[$test]['status']) {
  18758. case 0:
  18759. switch ($testData[$test]['size']) {
  18760. case 'small':
  18761. $testCSS = ' class="covered-by-small-tests"';
  18762. break;
  18763. case 'medium':
  18764. $testCSS = ' class="covered-by-medium-tests"';
  18765. break;
  18766. default:
  18767. $testCSS = ' class="covered-by-large-tests"';
  18768. break;
  18769. }
  18770. break;
  18771. case 1:
  18772. case 2:
  18773. $testCSS = ' class="warning"';
  18774. break;
  18775. case 3:
  18776. $testCSS = ' class="danger"';
  18777. break;
  18778. case 4:
  18779. $testCSS = ' class="danger"';
  18780. break;
  18781. default:
  18782. $testCSS = '';
  18783. }
  18784. $popoverContent .= sprintf(
  18785. '<li%s>%s</li>',
  18786. $testCSS,
  18787. htmlspecialchars($test)
  18788. );
  18789. }
  18790. $popoverContent .= '</ul>';
  18791. $trClass = ' class="' . $lineCss . ' popin"';
  18792. }
  18793. }
  18794. if (!empty($popoverTitle)) {
  18795. $popover = sprintf(
  18796. ' data-title="%s" data-content="%s" data-placement="bottom" data-html="true"',
  18797. $popoverTitle,
  18798. htmlspecialchars($popoverContent)
  18799. );
  18800. } else {
  18801. $popover = '';
  18802. }
  18803. $lines .= sprintf(
  18804. ' <tr%s%s><td><div align="right"><a name="%d"></a><a href="#%d">%d</a></div></td><td class="codeLine">%s</td></tr>' . "\n",
  18805. $trClass,
  18806. $popover,
  18807. $i,
  18808. $i,
  18809. $i,
  18810. $line
  18811. );
  18812. $i++;
  18813. }
  18814. return $lines;
  18815. }
  18816. /**
  18817. * @param string $file
  18818. * @return array
  18819. */
  18820. protected function loadFile($file)
  18821. {
  18822. $buffer = file_get_contents($file);
  18823. $tokens = token_get_all($buffer);
  18824. $result = array('');
  18825. $i = 0;
  18826. $stringFlag = false;
  18827. $fileEndsWithNewLine = substr($buffer, -1) == "\n";
  18828. unset($buffer);
  18829. foreach ($tokens as $j => $token) {
  18830. if (is_string($token)) {
  18831. if ($token === '"' && $tokens[$j - 1] !== '\\') {
  18832. $result[$i] .= sprintf(
  18833. '<span class="string">%s</span>',
  18834. htmlspecialchars($token)
  18835. );
  18836. $stringFlag = !$stringFlag;
  18837. } else {
  18838. $result[$i] .= sprintf(
  18839. '<span class="keyword">%s</span>',
  18840. htmlspecialchars($token)
  18841. );
  18842. }
  18843. continue;
  18844. }
  18845. list ($token, $value) = $token;
  18846. $value = str_replace(
  18847. array("\t", ' '),
  18848. array('&nbsp;&nbsp;&nbsp;&nbsp;', '&nbsp;'),
  18849. htmlspecialchars($value, $this->htmlspecialcharsFlags)
  18850. );
  18851. if ($value === "\n") {
  18852. $result[++$i] = '';
  18853. } else {
  18854. $lines = explode("\n", $value);
  18855. foreach ($lines as $jj => $line) {
  18856. $line = trim($line);
  18857. if ($line !== '') {
  18858. if ($stringFlag) {
  18859. $colour = 'string';
  18860. } else {
  18861. switch ($token) {
  18862. case T_INLINE_HTML:
  18863. $colour = 'html';
  18864. break;
  18865. case T_COMMENT:
  18866. case T_DOC_COMMENT:
  18867. $colour = 'comment';
  18868. break;
  18869. case T_ABSTRACT:
  18870. case T_ARRAY:
  18871. case T_AS:
  18872. case T_BREAK:
  18873. case T_CALLABLE:
  18874. case T_CASE:
  18875. case T_CATCH:
  18876. case T_CLASS:
  18877. case T_CLONE:
  18878. case T_CONTINUE:
  18879. case T_DEFAULT:
  18880. case T_ECHO:
  18881. case T_ELSE:
  18882. case T_ELSEIF:
  18883. case T_EMPTY:
  18884. case T_ENDDECLARE:
  18885. case T_ENDFOR:
  18886. case T_ENDFOREACH:
  18887. case T_ENDIF:
  18888. case T_ENDSWITCH:
  18889. case T_ENDWHILE:
  18890. case T_EXIT:
  18891. case T_EXTENDS:
  18892. case T_FINAL:
  18893. case T_FINALLY:
  18894. case T_FOREACH:
  18895. case T_FUNCTION:
  18896. case T_GLOBAL:
  18897. case T_IF:
  18898. case T_IMPLEMENTS:
  18899. case T_INCLUDE:
  18900. case T_INCLUDE_ONCE:
  18901. case T_INSTANCEOF:
  18902. case T_INSTEADOF:
  18903. case T_INTERFACE:
  18904. case T_ISSET:
  18905. case T_LOGICAL_AND:
  18906. case T_LOGICAL_OR:
  18907. case T_LOGICAL_XOR:
  18908. case T_NAMESPACE:
  18909. case T_NEW:
  18910. case T_PRIVATE:
  18911. case T_PROTECTED:
  18912. case T_PUBLIC:
  18913. case T_REQUIRE:
  18914. case T_REQUIRE_ONCE:
  18915. case T_RETURN:
  18916. case T_STATIC:
  18917. case T_THROW:
  18918. case T_TRAIT:
  18919. case T_TRY:
  18920. case T_UNSET:
  18921. case T_USE:
  18922. case T_VAR:
  18923. case T_WHILE:
  18924. case T_YIELD:
  18925. $colour = 'keyword';
  18926. break;
  18927. default:
  18928. $colour = 'default';
  18929. }
  18930. }
  18931. $result[$i] .= sprintf(
  18932. '<span class="%s">%s</span>',
  18933. $colour,
  18934. $line
  18935. );
  18936. }
  18937. if (isset($lines[$jj + 1])) {
  18938. $result[++$i] = '';
  18939. }
  18940. }
  18941. }
  18942. }
  18943. if ($fileEndsWithNewLine) {
  18944. unset($result[count($result)-1]);
  18945. }
  18946. return $result;
  18947. }
  18948. }
  18949. <!DOCTYPE html>
  18950. <html lang="en">
  18951. <head>
  18952. <meta charset="UTF-8">
  18953. <title>Dashboard for {{full_path}}</title>
  18954. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  18955. <link href="{{path_to_root}}css/bootstrap.min.css" rel="stylesheet">
  18956. <link href="{{path_to_root}}css/nv.d3.min.css" rel="stylesheet">
  18957. <link href="{{path_to_root}}css/style.css" rel="stylesheet">
  18958. <!--[if lt IE 9]>
  18959. <script src="{{path_to_root}}js/html5shiv.min.js"></script>
  18960. <script src="{{path_to_root}}js/respond.min.js"></script>
  18961. <![endif]-->
  18962. </head>
  18963. <body>
  18964. <header>
  18965. <div class="container">
  18966. <div class="row">
  18967. <div class="col-md-12">
  18968. <ol class="breadcrumb">
  18969. {{breadcrumbs}}
  18970. </ol>
  18971. </div>
  18972. </div>
  18973. </div>
  18974. </header>
  18975. <div class="container">
  18976. <div class="row">
  18977. <div class="col-md-12">
  18978. <h2>Classes</h2>
  18979. </div>
  18980. </div>
  18981. <div class="row">
  18982. <div class="col-md-6">
  18983. <h3>Coverage Distribution</h3>
  18984. <div id="classCoverageDistribution" style="height: 300px;">
  18985. <svg></svg>
  18986. </div>
  18987. </div>
  18988. <div class="col-md-6">
  18989. <h3>Complexity</h3>
  18990. <div id="classComplexity" style="height: 300px;">
  18991. <svg></svg>
  18992. </div>
  18993. </div>
  18994. </div>
  18995. <div class="row">
  18996. <div class="col-md-6">
  18997. <h3>Insufficient Coverage</h3>
  18998. <div class="scrollbox">
  18999. <table class="table">
  19000. <thead>
  19001. <tr>
  19002. <th>Class</th>
  19003. <th class="text-right">Coverage</th>
  19004. </tr>
  19005. </thead>
  19006. <tbody>
  19007. {{insufficient_coverage_classes}}
  19008. </tbody>
  19009. </table>
  19010. </div>
  19011. </div>
  19012. <div class="col-md-6">
  19013. <h3>Project Risks</h3>
  19014. <div class="scrollbox">
  19015. <table class="table">
  19016. <thead>
  19017. <tr>
  19018. <th>Class</th>
  19019. <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
  19020. </tr>
  19021. </thead>
  19022. <tbody>
  19023. {{project_risks_classes}}
  19024. </tbody>
  19025. </table>
  19026. </div>
  19027. </div>
  19028. </div>
  19029. <div class="row">
  19030. <div class="col-md-12">
  19031. <h2>Methods</h2>
  19032. </div>
  19033. </div>
  19034. <div class="row">
  19035. <div class="col-md-6">
  19036. <h3>Coverage Distribution</h3>
  19037. <div id="methodCoverageDistribution" style="height: 300px;">
  19038. <svg></svg>
  19039. </div>
  19040. </div>
  19041. <div class="col-md-6">
  19042. <h3>Complexity</h3>
  19043. <div id="methodComplexity" style="height: 300px;">
  19044. <svg></svg>
  19045. </div>
  19046. </div>
  19047. </div>
  19048. <div class="row">
  19049. <div class="col-md-6">
  19050. <h3>Insufficient Coverage</h3>
  19051. <div class="scrollbox">
  19052. <table class="table">
  19053. <thead>
  19054. <tr>
  19055. <th>Method</th>
  19056. <th class="text-right">Coverage</th>
  19057. </tr>
  19058. </thead>
  19059. <tbody>
  19060. {{insufficient_coverage_methods}}
  19061. </tbody>
  19062. </table>
  19063. </div>
  19064. </div>
  19065. <div class="col-md-6">
  19066. <h3>Project Risks</h3>
  19067. <div class="scrollbox">
  19068. <table class="table">
  19069. <thead>
  19070. <tr>
  19071. <th>Method</th>
  19072. <th class="text-right"><abbr title="Change Risk Anti-Patterns (CRAP) Index">CRAP</abbr></th>
  19073. </tr>
  19074. </thead>
  19075. <tbody>
  19076. {{project_risks_methods}}
  19077. </tbody>
  19078. </table>
  19079. </div>
  19080. </div>
  19081. </div>
  19082. <footer>
  19083. <hr/>
  19084. <p>
  19085. <small>Generated by <a href="http://github.com/sebastianbergmann/php-code-coverage" target="_top">PHP_CodeCoverage {{version}}</a> using <a href="{{runtime_link}}" target="_top">{{runtime_name}} {{runtime_version}}</a>{{generator}} at {{date}}.</small>
  19086. </p>
  19087. </footer>
  19088. </div>
  19089. <script src="{{path_to_root}}js/jquery.min.js" type="text/javascript"></script>
  19090. <script src="{{path_to_root}}js/bootstrap.min.js" type="text/javascript"></script>
  19091. <script src="{{path_to_root}}js/holder.min.js" type="text/javascript"></script>
  19092. <script src="{{path_to_root}}js/d3.min.js" type="text/javascript"></script>
  19093. <script src="{{path_to_root}}js/nv.d3.min.js" type="text/javascript"></script>
  19094. <script type="text/javascript">
  19095. $(document).ready(function() {
  19096. nv.addGraph(function() {
  19097. var chart = nv.models.multiBarChart();
  19098. chart.tooltips(false)
  19099. .showControls(false)
  19100. .showLegend(false)
  19101. .reduceXTicks(false)
  19102. .staggerLabels(true)
  19103. .yAxis.tickFormat(d3.format('d'));
  19104. d3.select('#classCoverageDistribution svg')
  19105. .datum(getCoverageDistributionData({{class_coverage_distribution}}, "Class Coverage"))
  19106. .transition().duration(500).call(chart);
  19107. nv.utils.windowResize(chart.update);
  19108. return chart;
  19109. });
  19110. nv.addGraph(function() {
  19111. var chart = nv.models.multiBarChart();
  19112. chart.tooltips(false)
  19113. .showControls(false)
  19114. .showLegend(false)
  19115. .reduceXTicks(false)
  19116. .staggerLabels(true)
  19117. .yAxis.tickFormat(d3.format('d'));
  19118. d3.select('#methodCoverageDistribution svg')
  19119. .datum(getCoverageDistributionData({{method_coverage_distribution}}, "Method Coverage"))
  19120. .transition().duration(500).call(chart);
  19121. nv.utils.windowResize(chart.update);
  19122. return chart;
  19123. });
  19124. function getCoverageDistributionData(data, label) {
  19125. var labels = [
  19126. '0%',
  19127. '0-10%',
  19128. '10-20%',
  19129. '20-30%',
  19130. '30-40%',
  19131. '40-50%',
  19132. '50-60%',
  19133. '60-70%',
  19134. '70-80%',
  19135. '80-90%',
  19136. '90-100%',
  19137. '100%'
  19138. ];
  19139. var values = [];
  19140. $.each(labels, function(key) {
  19141. values.push({x: labels[key], y: data[key]});
  19142. });
  19143. return [
  19144. {
  19145. key: label,
  19146. values: values,
  19147. color: "#4572A7"
  19148. }
  19149. ];
  19150. }
  19151. nv.addGraph(function() {
  19152. var chart = nv.models.scatterChart()
  19153. .showDistX(true)
  19154. .showDistY(true)
  19155. .showLegend(false)
  19156. .forceX([0, 100]);
  19157. chart.tooltipContent(function(key, y, e, graph) {
  19158. return '<p>' + graph.point.class + '</p>';
  19159. });
  19160. chart.xAxis.axisLabel('Code Coverage (in percent)');
  19161. chart.yAxis.axisLabel('Cyclomatic Complexity');
  19162. d3.select('#classComplexity svg')
  19163. .datum(getComplexityData({{complexity_class}}, 'Class Complexity'))
  19164. .transition()
  19165. .duration(500)
  19166. .call(chart);
  19167. nv.utils.windowResize(chart.update);
  19168. return chart;
  19169. });
  19170. nv.addGraph(function() {
  19171. var chart = nv.models.scatterChart()
  19172. .showDistX(true)
  19173. .showDistY(true)
  19174. .showLegend(false)
  19175. .forceX([0, 100]);
  19176. chart.tooltipContent(function(key, y, e, graph) {
  19177. return '<p>' + graph.point.class + '</p>';
  19178. });
  19179. chart.xAxis.axisLabel('Code Coverage (in percent)');
  19180. chart.yAxis.axisLabel('Method Complexity');
  19181. d3.select('#methodComplexity svg')
  19182. .datum(getComplexityData({{complexity_method}}, 'Method Complexity'))
  19183. .transition()
  19184. .duration(500)
  19185. .call(chart);
  19186. nv.utils.windowResize(chart.update);
  19187. return chart;
  19188. });
  19189. function getComplexityData(data, label) {
  19190. var values = [];
  19191. $.each(data, function(key) {
  19192. var value = Math.round(data[key][0]*100) / 100;
  19193. values.push({
  19194. x: value,
  19195. y: data[key][1],
  19196. class: data[key][2],
  19197. size: 0.05,
  19198. shape: 'diamond'
  19199. });
  19200. });
  19201. return [
  19202. {
  19203. key: label,
  19204. values: values,
  19205. color: "#4572A7"
  19206. }
  19207. ];
  19208. }
  19209. });
  19210. </script>
  19211. </body>
  19212. </html>
  19213. <!DOCTYPE html>
  19214. <html lang="en">
  19215. <head>
  19216. <meta charset="UTF-8">
  19217. <title>Code Coverage for {{full_path}}</title>
  19218. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  19219. <link href="{{path_to_root}}css/bootstrap.min.css" rel="stylesheet">
  19220. <link href="{{path_to_root}}css/style.css" rel="stylesheet">
  19221. <!--[if lt IE 9]>
  19222. <script src="{{path_to_root}}js/html5shiv.min.js"></script>
  19223. <script src="{{path_to_root}}js/respond.min.js"></script>
  19224. <![endif]-->
  19225. </head>
  19226. <body>
  19227. <header>
  19228. <div class="container">
  19229. <div class="row">
  19230. <div class="col-md-12">
  19231. <ol class="breadcrumb">
  19232. {{breadcrumbs}}
  19233. </ol>
  19234. </div>
  19235. </div>
  19236. </div>
  19237. </header>
  19238. <div class="container">
  19239. <table class="table table-bordered">
  19240. <thead>
  19241. <tr>
  19242. <td>&nbsp;</td>
  19243. <td colspan="9"><div align="center"><strong>Code Coverage</strong></div></td>
  19244. </tr>
  19245. <tr>
  19246. <td>&nbsp;</td>
  19247. <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
  19248. <td colspan="3"><div align="center"><strong>Functions and Methods</strong></div></td>
  19249. <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
  19250. </tr>
  19251. </thead>
  19252. <tbody>
  19253. {{items}}
  19254. </tbody>
  19255. </table>
  19256. <footer>
  19257. <hr/>
  19258. <h4>Legend</h4>
  19259. <p>
  19260. <span class="danger"><strong>Low</strong>: 0% to {{low_upper_bound}}%</span>
  19261. <span class="warning"><strong>Medium</strong>: {{low_upper_bound}}% to {{high_lower_bound}}%</span>
  19262. <span class="success"><strong>High</strong>: {{high_lower_bound}}% to 100%</span>
  19263. </p>
  19264. <p>
  19265. <small>Generated by <a href="http://github.com/sebastianbergmann/php-code-coverage" target="_top">PHP_CodeCoverage {{version}}</a> using <a href="{{runtime_link}}" target="_top">{{runtime_name}} {{runtime_version}}</a>{{generator}} at {{date}}.</small>
  19266. </p>
  19267. </footer>
  19268. </div>
  19269. <script src="{{path_to_root}}js/jquery.min.js" type="text/javascript"></script>
  19270. <script src="{{path_to_root}}js/bootstrap.min.js" type="text/javascript"></script>
  19271. <script src="{{path_to_root}}js/holder.min.js" type="text/javascript"></script>
  19272. </body>
  19273. </html>
  19274. <div class="progress">
  19275. <div class="progress-bar progress-bar-{{level}}" role="progressbar" aria-valuenow="{{percent}}" aria-valuemin="0" aria-valuemax="100" style="width: {{percent}}%">
  19276. <span class="sr-only">{{percent}}% covered ({{level}})</span>
  19277. </div>
  19278. </div>
  19279. /*!
  19280. * Bootstrap v3.3.4 (http://getbootstrap.com)
  19281. * Copyright 2011-2015 Twitter, Inc.
  19282. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  19283. */
  19284. if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.4",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.4",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.4",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.4",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.4",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27|32)/.test(b.which)&&!/input|textarea/i.test(b.target.tagName)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g&&27!=b.which||g&&27==b.which)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(b.target);38==b.which&&j>0&&j--,40==b.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="menu"]',g.prototype.keydown).on("keydown.bs.dropdown.data-api",'[role="listbox"]',g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.4",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in").attr("aria-hidden",!1),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a('<div class="modal-backdrop '+e+'" />').appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.init("tooltip",a,b)};c.VERSION="3.3.4",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport),this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c&&c.$tip&&c.$tip.is(":visible")?void(c.hoverState="in"):(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.options.container?a(this.options.container):this.$element.parent(),p=this.getPosition(o);h="bottom"==h&&k.bottom+m>p.bottom?"top":"top"==h&&k.top-m<p.top?"bottom":"right"==h&&k.right+l>p.width?"left":"left"==h&&k.left-l<p.left?"right":h,f.removeClass(n).addClass(h)}var q=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(q,h);var r=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",r).emulateTransitionEnd(c.TRANSITION_DURATION):r()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top=b.top+g,b.left=b.left+h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type)})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.4",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.4",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.4",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){
  19285. var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.4",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a(document.body).height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function r(n){return null===n?0/0:+n}function u(n){return!isNaN(n)}function i(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function c(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function l(){this._=Object.create(null)}function s(n){return(n+="")===pa||n[0]===va?va+n:n}function f(n){return(n+="")[0]===va?n.slice(1):n}function h(n){return s(n)in this._}function g(n){return(n=s(n))in this._&&delete this._[n]}function p(){var n=[];for(var t in this._)n.push(f(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function m(){this._=Object.create(null)}function y(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=da.length;r>e;++e){var u=da[e]+t;if(u in n)return u}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new l;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function S(){ta.event.preventDefault()}function k(){for(var n,t=ta.event;n=t.sourceEvent;)t=n;return t}function E(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[e]]=w(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=ta.event;u.target=n,ta.event=u,t[u.type].apply(e,r)}finally{ta.event=i}}},t}function A(n){return ya(n,_a),n}function N(n){return"function"==typeof n?n:function(){return Ma(n,this)}}function C(n){return"function"==typeof n?n:function(){return xa(n,this)}}function z(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=ta.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function q(n){return n.trim().replace(/\s+/g," ")}function L(n){return new RegExp("(?:^|\\s+)"+ta.requote(n)+"(?:\\s+|$)","g")}function T(n){return(n+"").trim().split(/^|\s+/)}function R(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=T(n).map(D);var u=n.length;return"function"==typeof t?r:e}function D(n){var t=L(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",q(u+" "+n))):e.setAttribute("class",q(u.replace(t," ")))}}function P(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function U(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;return e?t.createElementNS(e,n):t.createElement(n)}function e(){return this.ownerDocument.createElementNS(n.space,n.local)}return"function"==typeof n?n:(n=ta.ns.qualify(n)).local?e:t}function F(){var n=this.parentNode;n&&n.removeChild(this)}function H(n){return{__data__:n}}function O(n){return function(){return ba(this,n)}}function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function Z(n){return ya(n,Sa),n}function V(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,ra(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+ta.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=$;a>0&&(n=n.slice(0,a));var l=ka.get(n);return l&&(n=l,c=B),a?t?u:r:t?b:i}function $(n,t){return function(e){var r=ta.event;ta.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ta.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Aa,u="click"+r,i=ta.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ea&&(Ea="onselectstart"in e?!1:x(e.style,"userSelect")),Ea){var o=n(e).style,a=o[Ea];o[Ea]="none"}return function(n){if(i.on(r,null),Ea&&(o[Ea]=a),n){var t=function(){i.on(u,null)};i.on(u,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var u=r.createSVGPoint();if(0>Na){var i=t(n);if(i.scrollX||i.scrollY){r=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Na=!(o.f||o.e),r.remove()}}return Na?(u.x=e.pageX,u.y=e.pageY):(u.x=e.clientX,u.y=e.clientY),u=u.matrixTransform(n.getScreenCTM().inverse()),[u.x,u.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ta.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nt(n){return n>1?0:-1>n?qa:Math.acos(n)}function tt(n){return n>1?Ra:-1>n?-Ra:Math.asin(n)}function et(n){return((n=Math.exp(n))-1/n)/2}function rt(n){return((n=Math.exp(n))+1/n)/2}function ut(n){return((n=Math.exp(2*n))-1)/(n+1)}function it(n){return(n=Math.sin(n/2))*n}function ot(){}function at(n,t,e){return this instanceof at?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof at?new at(n.h,n.s,n.l):bt(""+n,_t,at):new at(n,t,e)}function ct(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new mt(u(n+120),u(n),u(n-120))}function lt(n,t,e){return this instanceof lt?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof lt?new lt(n.h,n.c,n.l):n instanceof ft?gt(n.l,n.a,n.b):gt((n=wt((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new lt(n,t,e)}function st(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new ft(e,Math.cos(n*=Da)*t,Math.sin(n)*t)}function ft(n,t,e){return this instanceof ft?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof ft?new ft(n.l,n.a,n.b):n instanceof lt?st(n.h,n.c,n.l):wt((n=mt(n)).r,n.g,n.b):new ft(n,t,e)}function ht(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=pt(u)*Xa,r=pt(r)*$a,i=pt(i)*Ba,new mt(dt(3.2404542*u-1.5371385*r-.4985314*i),dt(-.969266*u+1.8760108*r+.041556*i),dt(.0556434*u-.2040259*r+1.0572252*i))}function gt(n,t,e){return n>0?new lt(Math.atan2(e,t)*Pa,Math.sqrt(t*t+e*e),n):new lt(0/0,0/0,n)}function pt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function vt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function dt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mt(n,t,e){return this instanceof mt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mt?new mt(n.r,n.g,n.b):bt(""+n,mt,ct):new mt(n,t,e)}function yt(n){return new mt(n>>16,n>>8&255,255&n)}function Mt(n){return yt(n)+""}function xt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function bt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(kt(u[0]),kt(u[1]),kt(u[2]))}return(i=Ga.get(n.toLowerCase()))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function _t(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new at(r,u,c)}function wt(n,t,e){n=St(n),t=St(t),e=St(e);var r=vt((.4124564*n+.3575761*t+.1804375*e)/Xa),u=vt((.2126729*n+.7151522*t+.072175*e)/$a),i=vt((.0193339*n+.119192*t+.9503041*e)/Ba);return ft(116*u-16,500*(r-u),200*(u-i))}function St(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function kt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function Et(n){return"function"==typeof n?n:function(){return n}}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return void o.error.call(i,r)}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=ta.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!this.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=ta.event;ta.event=n;try{o.progress.call(i,c)}finally{ta.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ra(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},ta.rebind(i,o,"on"),null==r?i:i.get(Ct(r))}function Ct(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qt(){var n=Lt(),t=Tt()-n;t>24?(isFinite(t)&&(clearTimeout(tc),tc=setTimeout(qt,t)),nc=0):(nc=1,rc(qt))}function Lt(){var n=Date.now();for(ec=Ka;ec;)n>=ec.t&&(ec.f=ec.c(n-ec.t)),ec=ec.n;return n}function Tt(){for(var n,t=Ka,e=1/0;t;)t.f?t=n?n.n=t.n:Ka=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Qa=n,e}function Rt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Dt(n,t){var e=Math.pow(10,3*ga(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:y;return function(n){var e=ic.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=oc.get(g)||Ut;var M=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=ta.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!l&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new cc(e-1)),1),e}function i(n,e){return t(n=new cc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{cc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{cc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{cc=jt;var r=new jt;return r._=t,n(r,e)._}finally{cc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(c,a)),null!=(u=sc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=N[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.slice(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&cc!==jt,o=new(i?jt:cc);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,l=e.length;c>a;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=C[o in sc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,N.c.toString(),t,r)}function c(n,t,r){return e(n,N.x.toString(),t,r)}function l(n,t,r){return e(n,N.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{cc=jt;var t=new cc;return t._=n,r(t)}finally{cc=Date}}var r=t(n);return e.parse=function(n){try{cc=jt;var t=r.parse(n);return t&&t._}finally{cc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=Yt(v),b=Zt(v),_=Yt(d),w=Zt(d),S=Yt(m),k=Zt(m),E=Yt(y),A=Zt(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var N={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return It(n.getDate(),t,2)},e:function(n,t){return It(n.getDate(),t,2)},H:function(n,t){return It(n.getHours(),t,2)},I:function(n,t){return It(n.getHours()%12||12,t,2)},j:function(n,t){return It(1+ac.dayOfYear(n),t,3)},L:function(n,t){return It(n.getMilliseconds(),t,3)},m:function(n,t){return It(n.getMonth()+1,t,2)},M:function(n,t){return It(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return It(n.getSeconds(),t,2)},U:function(n,t){return It(ac.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return It(ac.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return It(n.getFullYear()%100,t,2)},Y:function(n,t){return It(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},C={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function It(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Yt(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new l,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Vt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Xt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function $t(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Bt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Wt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.y=Gt(+r[0]),e+r[0].length):-1}function Jt(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Gt(n){return n+(n>68?1900:2e3)}function Kt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=ga(t)/60|0,u=ga(t)%60;return e+It(r,"0",2)+It(u,"0",2)}function oe(n,t,e){hc.lastIndex=0;var r=hc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ce(){}function le(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function se(n,t){n&&dc.hasOwnProperty(n.type)&&dc[n.type](n,t)}function fe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function he(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)fe(n[e],t,1);t.polygonEnd()}function ge(){function n(n,t){n*=Da,t=t*Da/2+qa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);yc.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;Mc.point=function(o,a){Mc.point=n,r=(t=o)*Da,u=Math.cos(a=(e=a)*Da/2+qa/4),i=Math.sin(a)},Mc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Me(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function xe(n){return[Math.atan2(n[1],n[0]),tt(n[2])]}function be(n,t){return ga(n[0]-t[0])<Ca&&ga(n[1]-t[1])<Ca}function _e(n,t){n*=Da;var e=Math.cos(t*=Da);we(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function we(n,t,e){++xc,_c+=(n-_c)/xc,wc+=(t-wc)/xc,Sc+=(e-Sc)/xc}function Se(){function n(n,u){n*=Da;var i=Math.cos(u*=Da),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),l=Math.atan2(Math.sqrt((l=e*c-r*a)*l+(l=r*o-t*c)*l+(l=t*a-e*o)*l),t*o+e*a+r*c);bc+=l,kc+=l*(t+(t=o)),Ec+=l*(e+(e=a)),Ac+=l*(r+(r=c)),we(t,e,r)}var t,e,r;qc.point=function(u,i){u*=Da;var o=Math.cos(i*=Da);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),qc.point=n,we(t,e,r)}}function ke(){qc.point=_e}function Ee(){function n(n,t){n*=Da;var e=Math.cos(t*=Da),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),l=u*c-i*a,s=i*o-r*c,f=r*a-u*o,h=Math.sqrt(l*l+s*s+f*f),g=r*o+u*a+i*c,p=h&&-nt(g)/h,v=Math.atan2(h,g);Nc+=p*l,Cc+=p*s,zc+=p*f,bc+=v,kc+=v*(r+(r=o)),Ec+=v*(u+(u=a)),Ac+=v*(i+(i=c)),we(r,u,i)}var t,e,r,u,i;qc.point=function(o,a){t=o,e=a,qc.point=n,o*=Da;var c=Math.cos(a*=Da);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),we(r,u,i)},qc.lineEnd=function(){n(t,e),qc.lineEnd=ke,qc.point=_e}}function Ae(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function Ne(){return!0}function Ce(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(be(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return void u.lineEnd()}var c=new qe(e,n,null,!0),l=new qe(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new qe(r,n,null,!1),l=new qe(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),ze(i),ze(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ze(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function qe(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Le(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function l(){y.point=o,d.lineEnd()}function s(n,t){v.push([n,t]);var e=u(n,t);x.point(e[0],e[1])}function f(){x.lineStart(),v=[]}function h(){s(v[0][0],v[0][1]),x.lineEnd();var n,t=x.clean(),e=M.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r)if(1&t){n=e[0];var u,r=n.length-1,o=-1;if(r>0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);i.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=ta.merge(g);var n=Fe(m,p);g.length?(b||(i.polygonStart(),b=!0),Ce(g,De,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Re(),x=t(M),b=!1;return y}}function Te(n){return n.length>1}function Re(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function De(n,t){return((n=n.x)[0]<0?n[1]-Ra-Ca:Ra-n[1])-((t=t.x)[0]<0?t[1]-Ra-Ca:Ra-t[1])}function Pe(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?qa:-qa,c=ga(i-e);ga(c-qa)<Ca?(n.point(e,r=(r+o)/2>0?Ra:-Ra),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=qa&&(ga(e-u)<Ca&&(e-=u*Ca),ga(i-a)<Ca&&(i-=a*Ca),r=Ue(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function Ue(n,t,e,r){var u,i,o=Math.sin(n-e);return ga(o)>Ca?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function je(n,t,e,r){var u;if(null==n)u=e*Ra,r.point(-qa,u),r.point(0,u),r.point(qa,u),r.point(qa,0),r.point(qa,-u),r.point(0,-u),r.point(-qa,-u),r.point(-qa,0),r.point(-qa,u);else if(ga(n[0]-t[0])>Ca){var i=n[0]<t[0]?qa:-qa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Fe(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;yc.reset();for(var a=0,c=t.length;c>a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+qa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+qa/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>qa,k=p*M;if(yc.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*La:b,S^h>=e^m>=e){var E=de(pe(f),pe(n));Me(E);var A=de(u,E);Me(A);var N=(S^b>=0?-1:1)*tt(A[2]);(r>N||r===N&&(E[0]||E[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Ca>i||Ca>i&&0>yc)^1&o}function He(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?qa:-qa),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ca,p[1]+=Ca,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&be(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),M=m*m-y*(ve(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=ye(d,(-m-x)/y);if(me(b,p),b=xe(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=ga(A-qa)<Ca,C=N||Ca>A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(ga(b[0]-w)<Ca?k:E):k<=b[1]&&b[1]<=E:A>qa^(w<=b[0]&&b[0]<=S)){var z=ye(d,(-m+x)/y);return me(z,p),[b,xe(z)]}}}function u(t,e){var r=o?n:qa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ga(i)>Ca,c=gr(n,6*Da);return Le(t,e,c,o?[0,-n]:[-qa,n-qa])}function Oe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Ie(n,t,e,r){function u(r,u){return ga(r[0]-n)<Ca?u>0?0:3:ga(r[0]-e)<Ca?u>0?2:1:ga(r[1]-t)<Ca?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&Q(l,i,n)>0&&++t:i[1]<=r&&Q(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=0/0}function g(){v&&(p(y,M),x&&w&&A.rejoin(),v.push(A.buffer())),C.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Tc,Math.min(Tc,n)),t=Math.max(-Tc,Math.min(Tc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};N(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,E=a,A=Re(),N=Oe(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=ta.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return C}}function Ye(n){var t=0,e=qa/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*qa/180,e=n[1]*qa/180):[t/qa*180,e/qa*180]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,tt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Dc+=u*n-r*t,r=n,u=t}var t,e,r,u;Hc.point=function(i,o){Hc.point=n,t=r=i,e=u=o},Hc.lineEnd=function(){n(t,e)}}function Xe(n,t){Pc>n&&(Pc=n),n>jc&&(jc=n),Uc>t&&(Uc=t),t>Fc&&(Fc=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){_c+=n,wc+=t,++Sc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);kc+=o*(t+n)/2,Ec+=o*(e+r)/2,Ac+=o,We(t=n,e=r)}var t,e;Ic.point=function(r,u){Ic.point=n,We(t=r,e=u)}}function Ge(){Ic.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);kc+=o*(r+n)/2,Ec+=o*(u+t)/2,Ac+=o,o=u*n-r*t,Nc+=o*(r+n),Cc+=o*(u+t),zc+=3*o,We(r=n,u=t)}var t,e,r,u;Ic.point=function(i,o){Ic.point=n,We(t=r=i,e=u=o)},Ic.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,La)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(M,x,y,b,_,w,M=o[0],x=o[1],y=e,b=i[0],_=i[1],w=i[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c
  19286. },polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,l,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=a+g,_=c+p,w=l+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),E=ga(ga(w)-1)<Ca||ga(r-h)<Ca?(r+h)/2:Math.atan2(_,b),A=n(E,k),N=A[0],C=A[1],z=N-t,q=C-e,L=M*z-y*q;(L*L/x>i||ga((y*z+M*q)/x-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,N,C,E,b/=S,_/=S,w,d,m),m.point(N,C),u(N,C,E,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Da),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Pa,e*Pa])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*Da,n[1]*Da),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Pa,n[1]*Pa]}function r(){a=Ae(o=lr(m,M,x),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,M=0,x=0,b=Lc,_=y,w=null,S=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(b(o,f(_(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Lc):He((w=+n)*Da),u()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Ie(n[0][0],n[0][1],n[1][0],n[1][1]):y,u()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Da,d=n[1]%360*Da,r()):[v*Pa,d*Pa]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Da,M=n[1]%360*Da,x=n.length>2?n[2]%360*Da:0,r()):[m*Pa,M*Pa,x*Pa]},ta.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*Da,e*Da)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>qa?n-La:-qa>n?n+La:n,t]}function lr(n,t,e){return n?t||e?Ae(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>qa?t-La:-qa>t?t+La:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),tt(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),tt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*La)):(u=n+o*La,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=xe([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,Me(e);var r=nt(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ca)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function Mr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(it(r-t)+u*o*it(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Pa,Math.atan2(o,Math.sqrt(r*r+u*u))*Pa]}:function(){return[n*Pa,t*Pa]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Da),o=Math.cos(u),a=ga((n*=Da)-t),c=Math.cos(a);Yc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Zc.point=function(u,i){t=u*Da,e=Math.sin(i*=Da),r=Math.cos(i),Zc.point=n},Zc.lineEnd=function(){Zc.point=Zc.lineEnd=b}}function br(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function _r(n,t){function e(n,t){o>0?-Ra+Ca>t&&(t=-Ra+Ca):t>Ra-Ca&&(t=Ra-Ca);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(qa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=K(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ra]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ga(u)<Ca?ar:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-K(u)*Math.sqrt(n*n+e*e)]},e)}function Sr(n,t){return[n,Math.log(Math.tan(qa/4+t/2))]}function kr(n){var t,e=ur(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=qa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Er(n,t){return[Math.log(Math.tan(qa/4+t/2)),-n]}function Ar(n){return n[0]}function Nr(n){return n[1]}function Cr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function qr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Lr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function Tr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=el.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),Qc.remove(n),el.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&ga(e-c.circle.x)<Ca&&ga(r-c.circle.cy)<Ca;)i=c.P,a.unshift(c),Pr(c),c=i;a.unshift(c),Xr(c);for(var l=o;l.circle&&ga(e-l.circle.x)<Ca&&ga(r-l.circle.cy)<Ca;)o=l.N,a.push(l),Pr(l),l=o;a.push(l),Xr(l);var s,f=a.length;for(s=1;f>s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Qc._;a;)if(r=Fr(a,o)-i,r>Ca)a=a.L;else{if(u=i-Hr(a,o),!(u>Ca)){r>-Ca?(t=a.P,e=a):u>-Ca?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(Qc.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),Qc.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),void Vr(e);if(!e)return void(c.edge=Jr(t.site,c.site));Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};Kr(e.edge,l,p,x),c.edge=Jr(l,n,null,x),e.edge=Jr(n,p,null,x),Vr(t),Vr(e)}}function Fr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Ir(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Kc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(ga(r-t)>Ca||ga(u-e)>Ca)&&(a.splice(o,0,new Qr(Gr(i.site,s,ga(r-f)<Ca&&p-u>Ca?{x:f,y:ga(t-f)<Ca?e:p}:ga(u-p)<Ca&&h-r>Ca?{x:ga(e-p)<Ca?t:h,y:p}:ga(r-h)<Ca&&u-g>Ca?{x:h,y:ga(t-h)<Ca?e:g}:ga(u-g)<Ca&&r-f>Ca?{x:ga(e-g)<Ca?t:f,y:g}:null),i.site,null)),++c)}function Yr(n,t){return t.angle-n.angle}function Zr(){tu(this),this.x=this.y=this.arc=this.site=this.cy=null}function Vr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,l=r.y-a,s=i.x-o,f=i.y-a,h=2*(c*f-l*s);if(!(h>=-za)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=rl.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,M=tl._;M;)if(m.y<M.y||m.y===M.y&&m.x<=M.x){if(!M.L){y=M.P;break}M=M.L}else{if(!M.R){y=M;break}M=M.R}tl.insert(y,m),y||(nl=m)}}}}function Xr(n){var t=n.circle;t&&(t.P||(nl=t.N),tl.remove(t),rl.push(t),tu(t),n.circle=null)}function $r(n){for(var t,e=Gc,r=Oe(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Br(t,n)||!r(t)||ga(t.a.x-t.b.x)<Ca&&ga(t.a.y-t.b.y)<Ca)&&(t.a=t.b=null,e.splice(u,1))}function Br(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],l=t[1][1],s=n.l,f=n.r,h=s.x,g=s.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.y<c)return}else i={x:d,y:l};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}else{if(i){if(i.y<c)return}else i={x:(l-u)/r,y:l};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Wr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Jr(n,t,e,r){var u=new Wr(n,t);return Gc.push(u),e&&Kr(u,n,t,e),r&&Kr(u,t,n,r),Kc[n.i].edges.push(new Qr(u,n,t)),Kc[t.i].edges.push(new Qr(u,t,n)),u}function Gr(n,t,e){var r=new Wr(n,null);return r.a=t,r.b=e,Gc.push(r),r}function Kr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Qr(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function nu(){this._=null}function tu(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function eu(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function ru(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function uu(n){for(;n.L;)n=n.L;return n}function iu(n,t){var e,r,u,i=n.sort(ou).pop();for(Gc=[],Kc=new Array(n.length),Qc=new nu,tl=new nu;;)if(u=nl,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Kc[i.i]=new Or(i),jr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;Ur(u.arc)}t&&($r(t),Ir(t));var o={cells:Kc,edges:Gc};return Qc=tl=Gc=Kc=null,o}function ou(n,t){return t.y-n.y||t.x-n.x}function au(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function cu(n){return n.x}function lu(n){return n.y}function su(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function fu(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&fu(n,c[0],e,r,o,a),c[1]&&fu(n,c[1],o,r,u,a),c[2]&&fu(n,c[2],e,a,o,i),c[3]&&fu(n,c[3],o,a,u,i)}}function hu(n,t,e,r,u,i,o){var a,c=1/0;return function l(n,s,f,h,g){if(!(s>i||f>o||r>h||u>g)){if(p=n.point){var p,v=t-n.x,d=e-n.y,m=v*v+d*d;if(c>m){var y=Math.sqrt(c=m);r=t-y,u=e-y,i=t+y,o=e+y,a=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:l(n,s,f,x,b);break;case 1:l(n,x,f,h,b);break;case 2:l(n,s,b,x,g);break;case 3:l(n,x,b,h,g)}}}(n,r,u,i,o),a}function gu(n,t){n=ta.rgb(n),t=ta.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+xt(Math.round(e+i*n))+xt(Math.round(r+o*n))+xt(Math.round(u+a*n))}}function pu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=mu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function vu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function du(n,t){var e,r,u,i=il.lastIndex=ol.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=il.exec(n))&&(r=ol.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:vu(e,r)})),i=ol.lastIndex;return i<t.length&&(u=t.slice(i),a[o]?a[o]+=u:a[++o]=u),a.length<2?c[0]?(t=c[0].x,function(n){return t(n)+""}):function(){return t}:(t=c.length,function(n){for(var e,r=0;t>r;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function mu(n,t){for(var e,r=ta.interpolators.length;--r>=0&&!(e=ta.interpolators[r](n,t)););return e}function yu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(mu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Mu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function bu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function wu(n){return n*n*n}function Su(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function ku(n){return function(t){return Math.pow(t,n)}}function Eu(n){return 1-Math.cos(n*Ra)}function Au(n){return Math.pow(2,10*(n-1))}function Nu(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/La*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*La/t)}}function zu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function qu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Lu(n,t){n=ta.hcl(n),t=ta.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return st(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=ta.hsl(n),t=ta.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){n=ta.lab(n),t=ta.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ht(e+i*n,r+o*n,u+a*n)+""}}function Du(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Pu(n){var t=[n.a,n.b],e=[n.c,n.d],r=ju(t),u=Uu(t,e),i=ju(Fu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Pa,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*Pa:0}function Uu(n,t){return n[0]*t[0]+n[1]*t[1]}function ju(n){var t=Math.sqrt(Uu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Fu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Hu(n,t){var e,r=[],u=[],i=ta.transform(n),o=ta.transform(t),a=i.translate,c=o.translate,l=i.rotate,s=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:vu(a[0],c[0])},{i:3,x:vu(a[1],c[1])})):r.push(c[0]||c[1]?"translate("+c+")":""),l!=s?(l-s>180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:vu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:vu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:vu(g[0],p[0])},{i:e-2,x:vu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Ou(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}function Iu(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,Math.min(1,(e-n)/t))}}function Yu(n){for(var t=n.source,e=n.target,r=Vu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function Zu(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Vu(n,t){if(n===t)return n;for(var e=Zu(n),r=Zu(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Xu(n){n.fixed|=2}function $u(n){n.fixed&=-7}function Bu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Wu(n){n.fixed&=-5}function Ju(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Ju(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var l=t*e[n.point.index];n.charge+=n.pointCharge=l,r+=l*n.point.x,u+=l*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Gu(n,t){return ta.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=ri,n}function Ku(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(u=n.children)&&(r=u.length))for(var r,u;--r>=0;)e.push(u[r])}function Qu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++o<u;)e.push(i[o]);for(;null!=(n=r.pop());)t(n)}function ni(n){return n.children}function ti(n){return n.value}function ei(n,t){return t.value-n.value}function ri(n){return ta.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function ui(n){return n.x}function ii(n){return n.y}function oi(n,t,e){n.y0=t,n.y=e}function ai(n){return ta.range(n.length)}function ci(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function li(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function si(n){return n.reduce(fi,0)}function fi(n,t){return n+t[1]}function hi(n,t){return gi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function gi(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function pi(n){return[ta.min(n),ta.max(n)]}function vi(n,t){return n.value-t.value}function di(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function mi(n,t){n._pack_next=t,t._pack_prev=n}function yi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Mi(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],wi(r,u,i),t(i),di(r,i),r._pack_prev=i,di(i,u),u=r._pack_next,o=3;l>o;o++){wi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(yi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!yi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?mi(r,u=a):mi(r=c,u),o--):(di(r,i),u=i,t(i))}var m=(s+f)/2,y=(h+g)/2,M=0;for(o=0;l>o;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(bi)}}function xi(n){n._pack_next=n._pack_prev=n}function bi(n){delete n._pack_next,delete n._pack_prev}function _i(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)_i(u[i],t,e,r)}function wi(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),l=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+l*i,e.y=n.y+c*i-l*u}else e.x=n.x+r,e.y=n.y}function Si(n,t){return n.parent==t.parent?1:2}function ki(n){var t=n.children;return t.length?t[0]:n.t}function Ei(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function Ai(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function Ni(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function zi(n){return 1+ta.max(n,function(n){return n.y})}function qi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function Ri(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Di(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Pi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ui(n){return n.rangeExtent?n.rangeExtent():Pi(n.range())}function ji(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Fi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Hi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ml}function Oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=ta.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Ii(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?Oi:ji,c=r?Iu:Ou;return o=u(n,t,c,e),a=u(t,n,c,mu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Du)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Xi(n,t)},i.tickFormat=function(t,e){return $i(n,t,e)},i.nice=function(t){return Zi(n,t),u()},i.copy=function(){return Ii(n,t,e,r)},u()}function Yi(n,t){return ta.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Zi(n,t){return Fi(n,Hi(Vi(n,t)[2]))}function Vi(n,t){null==t&&(t=10);var e=Pi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Xi(n,t){return ta.range.apply(ta,Vi(n,t))}function $i(n,t,e){var r=Vi(n,t);if(e){var u=ic.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(ga(r[0]),ga(r[1])));return u[7]||(u[7]="."+Bi(i.scale(r[2]))),u[8]="f",e=ta.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Wi(u[8],r)),e=u.join("")}else e=",."+Bi(r[2])+"f";return ta.format(e)}function Bi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Wi(n,t){var e=Bi(t[2]);return n in yl?Math.abs(e-Bi(Math.max(ga(t[0]),ga(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ji(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Fi(r.map(u),e?Math:xl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Pi(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++<s;)for(var h=f-1;h>0;h--)o.push(i(l)*h);for(l=0;o[l]<a;l++);for(s=o.length;o[s-1]>c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return Ml;arguments.length<2?t=Ml:"function"!=typeof t&&(t=ta.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Ji(n.copy(),t,e,r)},Yi(o,n)}function Gi(n,t,e){function r(t){return n(u(t))}var u=Ki(t),i=Ki(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Xi(e,n)},r.tickFormat=function(n,t){return $i(e,n,t)},r.nice=function(n){return r.domain(Zi(e,n))},r.exponent=function(o){return arguments.length?(u=Ki(t=o),i=Ki(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Gi(n.copy(),t,e)},Yi(r,n)}function Ki(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Qi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return ta.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new l;for(var i,o=-1,a=r.length;++o<a;)u.has(i=r[o])||u.set(i,n.push(i));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(i=n,o=0,t={t:"range",a:arguments},e):i},e.rangePoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=(c+l)/2,0):(l-c)/(n.length-1+a);return i=r(c+s*a/2,s),o=0,t={t:"rangePoints",a:arguments},e},e.rangeRoundPoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=l=Math.round((c+l)/2),0):(l-c)/(n.length-1+a)|0;return i=r(c+Math.round(s*a/2+(l-c-(n.length-1+a)*s)/2),s),o=0,t={t:"rangeRoundPoints",a:arguments},e},e.rangeBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=(f-s)/(n.length-a+2*c);return i=r(s+h*c,h),l&&i.reverse(),o=h*(1-a),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=Math.floor((f-s)/(n.length-a+2*c));return i=r(s+Math.round((f-s-(n.length-a)*h)/2),h),l&&i.reverse(),o=Math.round(h*(1-a)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Pi(t.a[0])},e.copy=function(){return Qi(n,t)},e.domain(n)}function no(n,t){function i(){var e=0,r=t.length;for(a=[];++e<r;)a[e-1]=ta.quantile(n,e/r);return o}function o(n){return isNaN(n=+n)?void 0:t[ta.bisect(a,n)]}var a;return o.domain=function(t){return arguments.length?(n=t.map(r).filter(u).sort(e),i()):n},o.range=function(n){return arguments.length?(t=n,i()):t},o.quantiles=function(){return a},o.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?a[e-1]:n[0],e<a.length?a[e]:n[n.length-1]]},o.copy=function(){return no(n,t)},i()}function to(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return to(n,t,e)},u()}function eo(n,t){function e(e){return e>=e?t[ta.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return eo(n,t)},e}function ro(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Xi(n,t)},t.tickFormat=function(t,e){return $i(n,t,e)},t.copy=function(){return ro(n)},t}function uo(){return 0}function io(n){return n.innerRadius}function oo(n){return n.outerRadius}function ao(n){return n.startAngle}function co(n){return n.endAngle}function lo(n){return n&&n.padAngle}function so(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function fo(n,t,e,r,u){var i=n[0]-t[0],o=n[1]-t[1],a=(u?r:-r)/Math.sqrt(i*i+o*o),c=a*o,l=-a*i,s=n[0]+c,f=n[1]+l,h=t[0]+c,g=t[1]+l,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(M*M*y-x*x),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,E=_-p,A=w-v,N=S-p,C=k-v;return E*E+A*A>N*N+C*C&&(_=S,w=k),[[_-c,w-l],[_*e/M,w*e/M]]}function ho(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=Et(e),p=Et(r);++f<h;)u.call(this,c=t[f],f)?s.push([+g.call(this,c,f),+p.call(this,c,f)]):s.length&&(o(),s=[]);return s.length&&o(),l.length?l.join(""):null}var e=Ar,r=Nr,u=Ne,i=go,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=El.get(n)||go).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function go(n){return n.join("L")}function po(n){return go(n)+"Z"}function vo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function mo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function yo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function Mo(n,t){return n.length<4?go(n):n[1]+_o(n.slice(1,-1),wo(n,t))}function xo(n,t){return n.length<3?go(n):n[0]+_o((n.push(n[0]),n),wo([n[n.length-2]].concat(n,[n[1]]),t))}function bo(n,t){return n.length<3?go(n):n[0]+_o(n,wo(n,t))}function _o(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return go(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l<t.length;l++,c++)i=n[c],a=t[l],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var s=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+s[0]+","+s[1]}return r}function wo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function So(n){if(n.length<3)return go(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",No(Cl,o),",",No(Cl,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Co(c,o,a);return n.pop(),c.push("L",r),c.join("")}function ko(n){if(n.length<4)return go(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(No(Cl,i)+","+No(Cl,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),Co(e,i,o);return e.join("")}function Eo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[No(Cl,o),",",No(Cl,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Co(t,o,a);return t.join("")}function Ao(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,l=-1;++l<=e;)r=n[l],u=l/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return So(n)}function No(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Co(n,t,e){n.push("C",No(Al,t),",",No(Al,e),",",No(Nl,t),",",No(Nl,e),",",No(Cl,t),",",No(Cl,e))}function zo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function qo(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=zo(u,i);++t<e;)r[t]=(o+(o=zo(u=i,i=n[t+1])))/2;return r[t]=o,r}function Lo(n){for(var t,e,r,u,i=[],o=qo(n),a=-1,c=n.length-1;++a<c;)t=zo(n[a],n[a+1]),ga(t)<Ca?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function To(n){return n.length<3?go(n):n[0]+_o(n,Lo(n))}function Ro(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]-Ra,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Do(n){function t(t){function c(){v.push("M",a(n(m),f),s,l(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,M=t.length,x=Et(e),b=Et(u),_=e===r?function(){return g}:Et(r),w=u===i?function(){return p}:Et(i);++y<M;)o.call(this,h=t[y],y)?(d.push([g=+x.call(this,h,y),p=+b.call(this,h,y)]),m.push([+_.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=Ar,r=Ar,u=0,i=Nr,o=Ne,a=go,c=a.key,l=a,s="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r
  19287. },t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=El.get(n)||go).key,l=a.reverse||a,s=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function Po(n){return n.radius}function Uo(n){return[n.x,n.y]}function jo(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]-Ra;return[e*Math.cos(r),e*Math.sin(r)]}}function Fo(){return 64}function Ho(){return"circle"}function Oo(n){var t=Math.sqrt(n/qa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Io(n){return function(){var t,e;(t=this[n])&&(e=t[t.active])&&(--t.count?delete t[t.active]:delete this[n],t.active+=.5,e.event&&e.event.interrupt.call(this,this.__data__,e.index))}}function Yo(n,t,e){return ya(n,Pl),n.namespace=t,n.id=e,n}function Zo(n,t,e,r){var u=n.id,i=n.namespace;return Y(n,"function"==typeof e?function(n,o,a){n[i][u].tween.set(t,r(e.call(n,n.__data__,o,a)))}:(e=r(e),function(n){n[i][u].tween.set(t,e)}))}function Vo(n){return null==n&&(n=""),function(){this.textContent=n}}function Xo(n){return null==n?"__transition__":"__transition_"+n+"__"}function $o(n,t,e,r,u){var i=n[e]||(n[e]={active:0,count:0}),o=i[r];if(!o){var a=u.time;o=i[r]={tween:new l,time:a,delay:u.delay,duration:u.duration,ease:u.ease,index:t},u=null,++i.count,ta.timer(function(u){function c(e){if(i.active>r)return s();var u=i[i.active];u&&(--i.count,delete i[i.active],u.event&&u.event.interrupt.call(n,n.__data__,u.index)),i.active=r,o.event&&o.event.start.call(n,n.__data__,t),o.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&v.push(r)}),h=o.ease,f=o.duration,ta.timer(function(){return p.c=l(e||1)?Ne:l,1},0,a)}function l(e){if(i.active!==r)return 1;for(var u=e/f,a=h(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,n.__data__,t),s()):void 0}function s(){return--i.count?delete i[r]:delete n[e],1}var f,h,g=o.delay,p=ec,v=[];return p.t=g+a,u>=g?c(u-g):void(p.c=c)},0,a)}}function Bo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Wo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Jo(n){return n.toISOString()}function Go(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=ta.bisect(Vl,u);return i==Vl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Vl[i-1]<Vl[i]/u?i-1:i]:[Bl,Vi(n,e)[2]]}return r.invert=function(t){return Ko(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Ko)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Ko(+e+1),t).length}var i=r.domain(),o=Pi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Fi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Ko(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Ko(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Pi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Ko(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Go(n.copy(),t,e)},Yi(r,n)}function Ko(n){return new Date(n)}function Qo(n){return JSON.parse(n.responseText)}function na(n){var t=ua.createRange();return t.selectNode(ua.body),t.createContextualFragment(n.responseText)}var ta={version:"3.5.5"},ea=[].slice,ra=function(n){return ea.call(n)},ua=this.document;if(ua)try{ra(ua.documentElement.childNodes)[0].nodeType}catch(ia){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),ua)try{ua.createElement("DIV").style.setProperty("opacity",0,"")}catch(oa){var aa=this.Element.prototype,ca=aa.setAttribute,la=aa.setAttributeNS,sa=this.CSSStyleDeclaration.prototype,fa=sa.setProperty;aa.setAttribute=function(n,t){ca.call(this,n,t+"")},aa.setAttributeNS=function(n,t,e){la.call(this,n,t,e+"")},sa.setProperty=function(n,t,e){fa.call(this,n,t+"",e)}}ta.ascending=e,ta.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ta.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o;)if(null!=(r=n[i])&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},ta.sum=function(n,t){var e,r=0,i=n.length,o=-1;if(1===arguments.length)for(;++o<i;)u(e=+n[o])&&(r+=e);else for(;++o<i;)u(e=+t.call(n,n[o],o))&&(r+=e);return r},ta.mean=function(n,t){var e,i=0,o=n.length,a=-1,c=o;if(1===arguments.length)for(;++a<o;)u(e=r(n[a]))?i+=e:--c;else for(;++a<o;)u(e=r(t.call(n,n[a],a)))?i+=e:--c;return c?i/c:void 0},ta.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},ta.median=function(n,t){var i,o=[],a=n.length,c=-1;if(1===arguments.length)for(;++c<a;)u(i=r(n[c]))&&o.push(i);else for(;++c<a;)u(i=r(t.call(n,n[c],c)))&&o.push(i);return o.length?ta.quantile(o.sort(e),.5):void 0},ta.variance=function(n,t){var e,i,o=n.length,a=0,c=0,l=-1,s=0;if(1===arguments.length)for(;++l<o;)u(e=r(n[l]))&&(i=e-a,a+=i/++s,c+=i*(e-a));else for(;++l<o;)u(e=r(t.call(n,n[l],l)))&&(i=e-a,a+=i/++s,c+=i*(e-a));return s>1?c/(s-1):void 0},ta.deviation=function(){var n=ta.variance.apply(this,arguments);return n?Math.sqrt(n):n};var ha=i(e);ta.bisectLeft=ha.left,ta.bisect=ta.bisectRight=ha.right,ta.bisector=function(n){return i(1===n.length?function(t,r){return e(n(t),r)}:n)},ta.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=Math.random()*i--|0,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},ta.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ta.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},ta.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=ta.min(arguments,o),e=new Array(t);++n<t;)for(var r,u=-1,i=e[n]=new Array(r);++u<r;)i[u]=arguments[u][n];return e},ta.transpose=function(n){return ta.zip.apply(ta,n)},ta.keys=function(n){var t=[];for(var e in n)t.push(e);return t},ta.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},ta.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},ta.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ga=Math.abs;ta.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,u=[],i=a(ga(e)),o=-1;if(n*=i,t*=i,e*=i,0>e)for(;(r=n+e*++o)>t;)u.push(r/i);else for(;(r=n+e*++o)<t;)u.push(r/i);return u},ta.map=function(n,t){var e=new l;if(n instanceof l)n.forEach(function(n,t){e.set(n,t)});else if(Array.isArray(n)){var r,u=-1,i=n.length;if(1===arguments.length)for(;++u<i;)e.set(u,n[u]);else for(;++u<i;)e.set(t.call(n,r=n[u],u),r)}else for(var o in n)e.set(o,n[o]);return e};var pa="__proto__",va="\x00";c(l,{has:h,get:function(n){return this._[s(n)]},set:function(n,t){return this._[s(n)]=t},remove:g,keys:p,values:function(){var n=[];for(var t in this._)n.push(this._[t]);return n},entries:function(){var n=[];for(var t in this._)n.push({key:f(t),value:this._[t]});return n},size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t),this._[t])}}),ta.nest=function(){function n(t,o,a){if(a>=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var c,s,f,h,g=-1,p=o.length,v=i[a++],d=new l;++g<p;)(h=d.get(c=v(s=o[g])))?h.push(s):d.set(c,[s]);return t?(s=t(),f=function(e,r){s.set(e,n(t,r,a))}):(s={},f=function(e,r){s[e]=n(t,r,a)}),d.forEach(f),s}function t(n,e){if(e>=i.length)return n;var r=[],u=o[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ta.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ta.set=function(n){var t=new m;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},c(m,{has:h,add:function(n){return this._[s(n+="")]=!0,n},remove:g,values:p,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t))}}),ta.behavior={},ta.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=M(n,t,t[e]);return n};var da=["webkit","ms","moz","Moz","o","O"];ta.dispatch=function(){for(var n=new _,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=w(n);return n},_.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ta.event=null,ta.requote=function(n){return n.replace(ma,"\\$&")};var ma=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ya={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},Ma=function(n,t){return t.querySelector(n)},xa=function(n,t){return t.querySelectorAll(n)},ba=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(ba=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(Ma=function(n,t){return Sizzle(n,t)[0]||null},xa=Sizzle,ba=Sizzle.matchesSelector),ta.selection=function(){return ta.select(ua.documentElement)};var _a=ta.selection.prototype=[];_a.select=function(n){var t,e,r,u,i=[];n=N(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,l=r.length;++c<l;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return A(i)},_a.selectAll=function(n){var t,e,r=[];n=C(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=ra(n.call(e,e.__data__,a,u))),t.parentNode=e);return A(r)};var wa={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};ta.ns={prefix:wa,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.slice(0,t),n=n.slice(t+1)),wa.hasOwnProperty(e)?{space:wa[e],local:n}:n}},_a.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ta.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},_a.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!L(n[u]).test(t))return!1;return!0}for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},_a.style=function(n,e,r){var u=arguments.length;if(3>u){if("string"!=typeof n){2>u&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>u){var i=this.node();return t(i).getComputedStyle(i,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},_a.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},_a.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},_a.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},_a.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},_a.insert=function(n,t){return n=j(n),t=N(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},_a.remove=function(){return this.each(F)},_a.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new l,y=new Array(o);for(r=-1;++r<o;)m.has(d=t.call(u=n[r],u.__data__,r))?v[r]=u:m.set(d,u),y[r]=d;for(r=-1;++r<f;)(u=m.get(d=t.call(e,i=e[r],r)))?u!==!0&&(g[r]=u,u.__data__=i):p[r]=H(i),m.set(d,!0);for(r=-1;++r<o;)m.get(y[r])!==!0&&(v[r]=n[r])}else{for(r=-1;++r<h;)u=n[r],i=e[r],u?(u.__data__=i,g[r]=u):p[r]=H(i);for(;f>r;++r)p[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,a.push(p),c.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++i<o;)(u=r[i])&&(n[i]=u.__data__);return n}var a=Z([]),c=A([]),s=A([]);if("function"==typeof n)for(;++i<o;)e(r=this[i],n.call(r,r.parentNode.__data__,i));else for(;++i<o;)e(r=this[i],n);return c.enter=function(){return a},c.exit=function(){return s},c},_a.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},_a.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return A(u)},_a.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},_a.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},_a.each=function(n){return Y(this,function(t,e,r){n.call(t,t.__data__,e,r)})},_a.call=function(n){var t=ra(arguments);return n.apply(t[0]=this,t),this},_a.empty=function(){return!this.node()},_a.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},_a.size=function(){var n=0;return Y(this,function(){++n}),n};var Sa=[];ta.selection.enter=Z,ta.selection.enter.prototype=Sa,Sa.append=_a.append,Sa.empty=_a.empty,Sa.node=_a.node,Sa.call=_a.call,Sa.size=_a.size,Sa.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var l=-1,s=u.length;++l<s;)(i=u[l])?(t.push(r[l]=e=n.call(u.parentNode,i.__data__,l,a)),e.__data__=i.__data__):t.push(null)}return A(o)},Sa.insert=function(n,t){return arguments.length<2&&(t=V(this)),_a.insert.call(this,n,t)},ta.select=function(t){var e;return"string"==typeof t?(e=[Ma(t,ua)],e.parentNode=ua.documentElement):(e=[t],e.parentNode=n(t)),A([e])},ta.selectAll=function(n){var t;return"string"==typeof n?(t=ra(xa(n,ua)),t.parentNode=ua.documentElement):(t=n,t.parentNode=null),A([t])},_a.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var ka=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});ua&&ka.forEach(function(n){"on"+n in ua&&ka.remove(n)});var Ea,Aa=0;ta.mouse=function(n){return J(n,k())};var Na=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return J(n,r)},ta.behavior.drag=function(){function n(){this.on("mousedown.drag",i).on("touchstart.drag",o)}function e(n,t,e,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&ta.event.target===f),g({type:"dragend"}))}var l,s=this,f=ta.event.target,h=s.parentNode,g=r.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(e(f)).on(i+d,a).on(o+d,c),y=W(f),M=t(h,v);u?(l=u.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var r=E(n,"drag","dragstart","dragend"),u=null,i=e(b,ta.mouse,t,"mousemove","mouseup"),o=e(G,ta.touch,y,"touchmove","touchend");return n.origin=function(t){return arguments.length?(u=t,n):u},ta.rebind(n,r,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?ra(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Ca=1e-6,za=Ca*Ca,qa=Math.PI,La=2*qa,Ta=La-Ca,Ra=qa/2,Da=qa/180,Pa=180/qa,Ua=Math.SQRT2,ja=2,Fa=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=rt(v),o=i/(ja*h)*(e*ut(Ua*t+v)-et(v));return[r+o*l,u+o*s,i*e/rt(Ua*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Ua*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Fa*f)/(2*i*ja*h),p=(c*c-i*i-Fa*f)/(2*c*ja*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ua;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(q,f).on(Oa+".zoom",g).on("dblclick.zoom",p).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function u(n){k.k=Math.max(N[0],Math.min(N[1],n))}function i(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},u(Math.pow(2,o)),i(d=e,r),t=ta.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function c(n){z++||n({type:"zoomstart"})}function l(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function s(n){--z||n({type:"zoomend"}),d=null}function f(){function n(){f=1,i(ta.mouse(u),g),l(a)}function r(){h.on(L,null).on(T,null),p(f&&ta.event.target===o),s(a)}var u=this,o=ta.event.target,a=D.of(u,arguments),f=0,h=ta.select(t(u)).on(L,n).on(T,r),g=e(ta.mouse(u)),p=W(u);Dl.call(u),c(a)}function h(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ta.event.target;ta.select(t).on(x,r).on(b,a),_.push(t);for(var e=ta.event.changedTouches,u=0,i=e.length;i>u;++u)d[e[u].identifier]=null;var c=n(),l=Date.now();if(1===c.length){if(500>l-M){var s=c[0];o(p,s,d[s.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=l}else if(c.length>1){var s=c[0],f=c[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function r(){var n,t,e,r,o=ta.touches(p);Dl.call(p);for(var a=0,c=o.length;c>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],u(f*g)}M=null,i(n,t),l(v)}function a(){if(ta.event.touches.length){for(var t=ta.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}ta.selectAll(_).on(y,null),w.on(q,f).on(R,h),E(),s(v)}var g,p=this,v=D.of(p,arguments),d={},m=0,y=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+y,b="touchend"+y,_=[],w=ta.select(p),E=W(p);t(),c(v),w.on(q,null).on(R,t)}function g(){var n=D.of(this,arguments);y?clearTimeout(y):(v=e(d=m||ta.mouse(this)),Dl.call(this),c(n)),y=setTimeout(function(){y=null,s(n)},50),S(),u(Math.pow(2,.002*Ha())*k.k),i(d,v),l(n)}function p(){var n=ta.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ta.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,m,y,M,x,b,_,w,k={x:0,y:0,k:1},A=[960,500],N=Ia,C=250,z=0,q="mousedown.zoom",L="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=E(n,"zoomstart","zoom","zoomend");return Oa||(Oa="onwheel"in ua?(Ha=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Ha=function(){return ta.event.wheelDelta},"mousewheel"):(Ha=function(){return-ta.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Tl?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},c(n)}).tween("zoom:zoom",function(){var e=A[0],r=A[1],u=d?d[0]:e/2,i=d?d[1]:r/2,o=ta.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:u-r[0]*a,y:i-r[1]*a,k:a},l(n)}}).each("interrupt.zoom",function(){s(n)}).each("end.zoom",function(){s(n)}):(this.__chart__=k,c(n),l(n),s(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(N=null==t?Ia:[+t[0],+t[1]],n):N},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(A=t&&[+t[0],+t[1]],n):A},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ta.rebind(n,D,"on")};var Ha,Oa,Ia=[0,1/0];ta.color=ot,ot.prototype.toString=function(){return this.rgb()+""},ta.hsl=at;var Ya=at.prototype=new ot;Ya.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,this.l/n)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,n*this.l)},Ya.rgb=function(){return ct(this.h,this.s,this.l)},ta.hcl=lt;var Za=lt.prototype=new ot;Za.brighter=function(n){return new lt(this.h,this.c,Math.min(100,this.l+Va*(arguments.length?n:1)))},Za.darker=function(n){return new lt(this.h,this.c,Math.max(0,this.l-Va*(arguments.length?n:1)))},Za.rgb=function(){return st(this.h,this.c,this.l).rgb()},ta.lab=ft;var Va=18,Xa=.95047,$a=1,Ba=1.08883,Wa=ft.prototype=new ot;Wa.brighter=function(n){return new ft(Math.min(100,this.l+Va*(arguments.length?n:1)),this.a,this.b)},Wa.darker=function(n){return new ft(Math.max(0,this.l-Va*(arguments.length?n:1)),this.a,this.b)},Wa.rgb=function(){return ht(this.l,this.a,this.b)},ta.rgb=mt;var Ja=mt.prototype=new ot;Ja.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new mt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mt(u,u,u)},Ja.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mt(n*this.r,n*this.g,n*this.b)},Ja.hsl=function(){return _t(this.r,this.g,this.b)},Ja.toString=function(){return"#"+xt(this.r)+xt(this.g)+xt(this.b)};var Ga=ta.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ga.forEach(function(n,t){Ga.set(n,yt(t))}),ta.functor=Et,ta.xhr=At(y),ta.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++<l;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}s=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++s):10===r&&(u=!0),n.slice(t+1,e).replace(/""/g,'"')}for(;l>s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,f++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new m,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},ta.csv=ta.dsv(",","text/csv"),ta.tsv=ta.dsv(" ","text/tab-separated-values");var Ka,Qa,nc,tc,ec,rc=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ta.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Qa?Qa.n=i:Ka=i,Qa=i,nc||(tc=clearTimeout(tc),nc=1,rc(qt))},ta.timer.flush=function(){Lt(),Tt()},ta.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var uc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);ta.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ta.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),uc[8+e/3]};var ic=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,oc=ta.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ta.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),ac=ta.time={},cc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){lc.setUTCDate.apply(this._,arguments)},setDay:function(){lc.setUTCDay.apply(this._,arguments)},setFullYear:function(){lc.setUTCFullYear.apply(this._,arguments)},setHours:function(){lc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){lc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){lc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){lc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){lc.setUTCSeconds.apply(this._,arguments)},setTime:function(){lc.setTime.apply(this._,arguments)}};var lc=Date.prototype;ac.year=Ft(function(n){return n=ac.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ac.years=ac.year.range,ac.years.utc=ac.year.utc.range,ac.day=Ft(function(n){var t=new cc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ac.days=ac.day.range,ac.days.utc=ac.day.utc.range,ac.dayOfYear=function(n){var t=ac.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ac[n]=Ft(function(n){return(n=ac.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ac[n+"s"]=e.range,ac[n+"s"].utc=e.utc.range,ac[n+"OfYear"]=function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)}}),ac.week=ac.sunday,ac.weeks=ac.sunday.range,ac.weeks.utc=ac.sunday.utc.range,ac.weekOfYear=ac.sundayOfYear;var sc={"-":"",_:" ",0:"0"},fc=/^\s*\d+/,hc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var gc=ta.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ta.format=gc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,pc),le(pc.s,this.s,this),this.s?this.t+=pc.t:this.s=pc.t
  19288. },reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var pc=new ce;ta.geo.stream=function(n,t){n&&vc.hasOwnProperty(n.type)?vc[n.type](n,t):se(n,t)};var vc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)se(e[r].geometry,t)}},dc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){fe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)fe(e[r],t,0)},Polygon:function(n,t){he(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)he(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)se(e[r],t)}};ta.geo.area=function(n){return mc=0,ta.geo.stream(n,Mc),mc};var mc,yc=new ce,Mc={sphere:function(){mc+=4*qa},point:b,lineStart:b,lineEnd:b,polygonStart:function(){yc.reset(),Mc.lineStart=ge},polygonEnd:function(){var n=2*yc;mc+=0>n?4*qa+n:n,Mc.lineStart=Mc.lineEnd=Mc.point=b}};ta.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*Da,e*Da]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);Me(o),o=xe(o);var c=t-p,l=c>0?1:-1,v=o[0]*Pa*l,d=ga(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Pa;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Pa;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ga(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Mc.point(n,e),t(n,e)}function i(){Mc.lineStart()}function o(){u(v,d),Mc.lineEnd(),ga(y)>Ca&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var s,f,h,g,p,v,d,m,y,M,x,b={point:n,lineStart:e,lineEnd:r,polygonStart:function(){b.point=u,b.lineStart=i,b.lineEnd=o,y=0,Mc.polygonStart()},polygonEnd:function(){Mc.polygonEnd(),b.point=n,b.lineStart=e,b.lineEnd=r,0>yc?(s=-(h=180),f=-(g=90)):y>Ca?g=90:-Ca>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ta.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ta.geo.centroid=function(n){xc=bc=_c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,qc);var t=Nc,e=Cc,r=zc,u=t*t+e*e+r*r;return za>u&&(t=kc,e=Ec,r=Ac,Ca>bc&&(t=_c,e=wc,r=Sc),u=t*t+e*e+r*r,za>u)?[0/0,0/0]:[Math.atan2(e,t)*Pa,tt(r/Math.sqrt(u))*Pa]};var xc,bc,_c,wc,Sc,kc,Ec,Ac,Nc,Cc,zc,qc={sphere:b,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){qc.lineStart=Ee},polygonEnd:function(){qc.lineStart=Se}},Lc=Le(Ne,Pe,je,[-qa,-qa/2]),Tc=1e9;ta.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ie(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ta.geo.conicEqualArea=function(){return Ye(Ze)}).raw=Ze,ta.geo.albers=function(){return ta.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ta.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=ta.geo.albers(),o=ta.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ta.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Ca,f+.12*l+Ca],[s-.214*l-Ca,f+.234*l-Ca]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ca,f+.166*l+Ca],[s-.115*l-Ca,f+.234*l-Ca]]).stream(c).point,n},n.scale(1070)};var Rc,Dc,Pc,Uc,jc,Fc,Hc={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Dc=0,Hc.lineStart=Ve},polygonEnd:function(){Hc.lineStart=Hc.lineEnd=Hc.point=b,Rc+=ga(Dc/2)}},Oc={point:Xe,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Ic={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Ic.lineStart=Ke},polygonEnd:function(){Ic.point=We,Ic.lineStart=Je,Ic.lineEnd=Ge}};ta.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),ta.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Rc=0,ta.geo.stream(n,u(Hc)),Rc},n.centroid=function(n){return _c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,u(Ic)),zc?[Nc/zc,Cc/zc]:Ac?[kc/Ac,Ec/Ac]:Sc?[_c/Sc,wc/Sc]:[0/0,0/0]},n.bounds=function(n){return jc=Fc=-(Pc=Uc=1/0),ta.geo.stream(n,u(Oc)),[[Pc,Uc],[jc,Fc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):y,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(ta.geo.albersUsa()).context(null)},ta.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ta.geo.projection=ur,ta.geo.projectionMutator=ir,(ta.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,ta.geo.rotation=function(n){function t(t){return t=n(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t}return n=lr(n[0]%360*Da,n[1]*Da,n.length>2?n[2]*Da:0),t.invert=function(t){return t=n.invert(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t},t},cr.invert=ar,ta.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*Da,-n[1]*Da,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Pa,n[1]*=Pa}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*Da,u*Da),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Da,(u=+r)*Da),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Da,u=n[1]*Da,i=t[1]*Da,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},ta.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ta.range(Math.ceil(i/d)*d,u,d).map(h).concat(ta.range(Math.ceil(l/m)*m,c,m).map(g)).concat(ta.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ga(n%d)>Ca}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ga(n%m)>Ca}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ca],[180,90-Ca]]).minorExtent([[-180,-80-Ca],[180,80+Ca]])},ta.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return ta.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},ta.geo.interpolate=function(n,t){return Mr(n[0]*Da,n[1]*Da,t[0]*Da,t[1]*Da)},ta.geo.length=function(n){return Yc=0,ta.geo.stream(n,Zc),Yc};var Yc,Zc={sphere:b,point:b,lineStart:xr,lineEnd:b,polygonStart:b,polygonEnd:b},Vc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Vc)}).raw=Vc;var Xc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},y);(ta.geo.azimuthalEquidistant=function(){return ur(Xc)}).raw=Xc,(ta.geo.conicConformal=function(){return Ye(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ye(wr)}).raw=wr;var $c=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur($c)}).raw=$c,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ra]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Bc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Bc)}).raw=Bc;var Wc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Wc)}).raw=Wc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ra]},(ta.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Er,ta.geom={},ta.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=Et(e),i=Et(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Cr(a),s=Cr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t<s.length-h;++t)g.push(n[a[s[t]][2]]);return g}var e=Ar,r=Nr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},ta.geom.polygon=function(n){return ya(n,Jc),n};var Jc=ta.geom.polygon.prototype=[];Jc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Jc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Jc.clip=function(n){for(var t,e,r,u,i,o,a=Tr(n),c=-1,l=this.length-Tr(this),s=this[l-1];++c<l;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],qr(o,s,u)?(qr(i,s,u)||n.push(Lr(i,o,s,u)),n.push(o)):qr(i,s,u)&&n.push(Lr(i,o,s,u)),i=o;a&&n.push(n[0]),s=u}return n};var Gc,Kc,Qc,nl,tl,el=[],rl=[];Or.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Yr),t.length},Qr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},nu.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=uu(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(eu(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ru(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(ru(this,e),n=e,e=n.U),e.C=!1,r.C=!0,eu(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?uu(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return void(n.C=!1);do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,eu(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,ru(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,eu(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,ru(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,eu(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,ru(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},ta.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return iu(e(n),a).cells.forEach(function(e,a){var c=e.edges,l=e.site,s=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):l.x>=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ca)*Ca,y:Math.round(o(n,t)/Ca)*Ca,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=ul;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Yr),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c<l;)u=s,i=f,s=a[c].edge,f=s.l===o?s.r:s.l,r<i.i&&r<f.i&&au(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=Et(r=n),t):r},t.y=function(n){return arguments.length?(o=Et(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?ul:n,t):a===ul?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===ul?null:a&&a[1]},t)};var ul=[[-1e6,-1e6],[1e6,1e6]];ta.geom.delaunay=function(n){return ta.geom.voronoi().triangles(n)},ta.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,s=n.y;if(null!=c)if(ga(c-e)+ga(s-r)<.01)l(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,l(n,f,c,s,u,i,o,a),l(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else l(n,t,e,r,u,i,o,a)}function l(n,t,e,r,u,o,a,c){var l=.5*(u+a),s=.5*(o+c),f=e>=l,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,M=Et(a),x=Et(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.x<v&&(v=s.x),s.y<d&&(d=s.y),s.x>m&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=s=null,k}var o,a=Ar,c=Nr;return(o=arguments.length)?(a=cu,c=lu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},ta.interpolateRgb=gu,ta.interpolateObject=pu,ta.interpolateNumber=vu,ta.interpolateString=du;var il=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,ol=new RegExp(il.source,"g");ta.interpolate=mu,ta.interpolators=[function(n,t){var e=typeof t;return("string"===e?Ga.has(t)||/^(#|rgb\(|hsl\()/.test(t)?gu:du:t instanceof ot?gu:Array.isArray(t)?yu:"object"===e&&isNaN(t)?pu:vu)(n,t)}],ta.interpolateArray=yu;var al=function(){return y},cl=ta.map({linear:al,poly:ku,quad:function(){return _u},cubic:function(){return wu},sin:function(){return Eu},exp:function(){return Au},circle:function(){return Nu},elastic:Cu,back:zu,bounce:function(){return qu}}),ll=ta.map({"in":y,out:xu,"in-out":bu,"out-in":function(n){return bu(xu(n))}});ta.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=cl.get(e)||al,r=ll.get(r)||y,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:sl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var sl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Yu(n[e]));return t}},ta.layout.chord=function(){function n(){var n,l,f,h,g,p={},v=[],d=ta.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(l=0,g=-1;++g<i;)l+=u[h][g];v.push(l),m.push(ta.range(i)),n+=l}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(La-s*i)/n,l=0,h=-1;++h<i;){for(f=l,g=-1;++g<i;){var y=d[h],M=m[y][g],x=u[y][M],b=l,_=l+=x*n;p[y+"-"+M]={index:y,subindex:M,startAngle:b,endAngle:_,value:x}}r[y]={index:y,startAngle:f,endAngle:l,value:(l-f)/n},l+=s}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,l={},s=0;return l.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,l):u},l.padding=function(n){return arguments.length?(s=n,e=r=null,l):s},l.sortGroups=function(n){return arguments.length?(o=n,e=r=null,l):o},l.sortSubgroups=function(n){return arguments.length?(a=n,e=null,l):a},l.sortChords=function(n){return arguments.length?(c=n,e&&t(),l):c},l.chords=function(){return e||n(),e},l.groups=function(){return r||n(),r},l},ta.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=fl,h=hl,g=-30,p=gl,v=.1,d=.64,m=[],M=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,y,x,b=m.length,_=M.length;for(e=0;_>e;++e)a=M[e],f=a.source,h=a.target,y=h.x-f.x,x=h.y-f.y,(p=y*y+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,y*=p,x*=p,h.x-=y*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=y*(d=1-d),f.y+=x*d);if((d=r*v)&&(y=l[0]/2,x=l[1]/2,e=-1,d))for(;++e<b;)a=m[e],a.x+=(y-a.x)*d,a.y+=(x-a.y)*d;if(g)for(Ju(t=ta.geom.quadtree(m),r,o),e=-1;++e<b;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<b;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*s,a.y-=(a.py-(a.py=a.y))*s);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(M=n,a):M},a.size=function(n){return arguments.length?(l=n,a):l},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(s=+n,a):s},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=M[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++a<l;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,s=M.length,p=l[0],v=l[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=M[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,M[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,M[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=ta.behavior.drag().origin(y).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?void this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e):e},ta.rebind(a,c,"on")};var fl=20,hl=1,gl=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ta.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++l<o;)n(a=i[l],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=ta.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Gu(e,r)},ta.layout.pie=function(){function n(o){var a,c=o.length,l=o.map(function(e,r){return+t.call(n,e,r)}),s=+("function"==typeof r?r.apply(this,arguments):r),f=("function"==typeof u?u.apply(this,arguments):u)-s,h=Math.min(Math.abs(f)/c,+("function"==typeof i?i.apply(this,arguments):i)),g=h*(0>f?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===pl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=pl,r=0,u=La,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var pl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=y,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:vl.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:dl.get(t)||ci,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var vl=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),dl=ta.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=l[i],a>=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=Et(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:Et(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(f,function(n){n.x<g.x&&(g=n),n.x>p.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ni(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=ta.layout.hierarchy().sort(null).value(null),e=Si,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Gu(n,t)},ta.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++i<o;)u=n[i],u.x=a,u.y=l,u.dy=s,a+=u.dx=Math.min(e.x+e.dx-a,s?c(u.area/s):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=s,e.dy-=s}else{for((r||s>e.dx)&&(s=e.dx);++i<o;)u=n[i],u.x=a,u.y=l,u.dx=s,l+=u.dy=Math.min(e.y+e.dy-l,s?c(u.area/s):0);u.z=!1,u.dy+=e.y+e.dy-l,e.x+=s,e.dx-=s}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=l[0],i.dy=l[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=ta.layout.hierarchy(),c=Math.round,l=[1,1],s=null,f=Ri,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));
  19289. return i.size=function(n){return arguments.length?(l=n,i):l},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ri(t):Di(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return Di(t,n)}if(!arguments.length)return s;var r;return f=null==(s=n)?Ri:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Gu(i,a)},ta.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ta.scale={};var ml={floor:y,ceil:y};ta.scale.linear=function(){return Ii([0,1],[0,1],mu,!1)};var yl={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var Ml=ta.format(".0e"),xl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(bl)},ta.scale.category20=function(){return ta.scale.ordinal().range(_l)},ta.scale.category20b=function(){return ta.scale.ordinal().range(wl)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Sl)};var bl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(Mt),_l=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(Mt),wl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(Mt),Sl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(Mt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-Ra,f=a.apply(this,arguments)-Ra,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ta)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===kl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=tt(d/l*Math.sin(m))),n&&(E=tt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=qa?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=qa?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),I=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],I[1][0],I[1][1]),",",g," ",I[1],"A",H,",",H," 0 0,",v," ",I[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",I[0])}else N.push("M",y,",",M);if(null!=S){var Y=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-Y,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-Y,g);p===Y?N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",Y,",",Y," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=kl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=Et(t),n):e},n.outerRadius=function(t){return arguments.length?(r=Et(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=Et(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==kl?kl:Et(t),n):i},n.startAngle=function(t){return arguments.length?(o=Et(t),n):o},n.endAngle=function(t){return arguments.length?(a=Et(t),n):a},n.padAngle=function(t){return arguments.length?(c=Et(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Ra;return[Math.cos(t)*n,Math.sin(t)*n]},n};var kl="auto";ta.svg.line=function(){return ho(y)};var El=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});El.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Al=[0,2/3,1/3,0],Nl=[0,1/3,2/3,0],Cl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(y)},ta.svg.area.radial=function(){var n=Do(Ro);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)-Ra,s=l.call(n,u,r)-Ra;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>qa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=Et(t),n):a},n.source=function(t){return arguments.length?(i=Et(t),n):i},n.target=function(t){return arguments.length?(o=Et(t),n):o},n.startAngle=function(t){return arguments.length?(c=Et(t),n):c},n.endAngle=function(t){return arguments.length?(l=Et(t),n):l},n},ta.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=Et(e),n):t},n.target=function(t){return arguments.length?(e=Et(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(zl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=Et(e),n):t},n.size=function(t){return arguments.length?(e=Et(t),n):e},n};var zl=ta.map({circle:Oo,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Ll)),e=t*Ll;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=zl.keys();var ql=Math.sqrt(3),Ll=Math.tan(30*Da);_a.transition=function(n){for(var t,e,r=Tl||++Ul,u=Xo(n),i=[],o=Rl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++a<c;){i.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(e=l[s])&&$o(e,s,u,r,o),t.push(e)}return Yo(i,u,r)},_a.interrupt=function(n){return this.each(null==n?Dl:Io(Xo(n)))};var Tl,Rl,Dl=Io(Xo()),Pl=[],Ul=0;Pl.call=_a.call,Pl.empty=_a.empty,Pl.node=_a.node,Pl.size=_a.size,ta.transition=function(n,t){return n&&n.transition?Tl?n.transition(t):n:ta.selection().transition(n)},ta.transition.prototype=Pl,Pl.select=function(n){var t,e,r,u=this.id,i=this.namespace,o=[];n=N(n);for(var a=-1,c=this.length;++a<c;){o.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(r=l[s])&&(e=n.call(r,r.__data__,s,a))?("__data__"in r&&(e.__data__=r.__data__),$o(e,s,i,u,r[i][u]),t.push(e)):t.push(null)}return Yo(o,i,u)},Pl.selectAll=function(n){var t,e,r,u,i,o=this.id,a=this.namespace,c=[];n=C(n);for(var l=-1,s=this.length;++l<s;)for(var f=this[l],h=-1,g=f.length;++h<g;)if(r=f[h]){i=r[a][o],e=n.call(r,r.__data__,h,l),c.push(t=[]);for(var p=-1,v=e.length;++p<v;)(u=e[p])&&$o(u,p,a,o,i),t.push(u)}return Yo(c,a,o)},Pl.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Yo(u,this.namespace,this.id)},Pl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Pl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Pl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Pl.style=function(n,e,r){function u(){this.style.removeProperty(n)}function i(e){return null==e?u:(e+="",function(){var u,i=t(this).getComputedStyle(this,null).getPropertyValue(n);return i!==e&&(u=mu(i,e),function(t){this.style.setProperty(n,u(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Zo(this,"style."+n,e,i)},Pl.styleTween=function(n,e,r){function u(u,i){var o=e.call(this,u,i,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,u)},Pl.text=function(n){return Zo(this,"text",n,Vo)},Pl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Pl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),Y(this,function(r){r[e][t].ease=n}))},Pl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Pl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Pl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=Rl,i=Tl;try{Tl=e,Y(this,function(t,u,i){Rl=t[r][e],n.call(t,t.__data__,u,i)})}finally{Rl=u,Tl=i}}else Y(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Pl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ul,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Yo(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):y:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ca),d=ta.transition(p.exit()).style("opacity",Ca).remove(),m=ta.transition(p.order()).style("opacity",1),M=Math.max(u,0)+o,x=Ui(f),b=l.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ta.transition(b));v.append("line"),v.append("text");var w,S,k,E,A=v.select("line"),N=m.select("line"),C=p.select("text").text(g),z=v.select("text"),q=m.select("text"),L="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,w="x",k="y",S="x2",E="y2",C.attr("dy",0>L?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+L*i+"V0H"+x[1]+"V"+L*i)):(n=Wo,w="y",k="x",S="y2",E="x2",C.attr("dy",".32em").style("text-anchor",0>L?"end":"start"),_.attr("d","M"+L*i+","+x[0]+"H0V"+x[1]+"H"+L*i)),A.attr(E,L*u),z.attr(k,L*M),N.attr(S,0).attr(E,L*u),q.attr(w,0).attr(k,L*M),f.rangeBand){var T=f,R=T.rangeBand()/2;s=f=function(n){return T(n)+R}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=jl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Fl?t+"":jl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var jl="bottom",Fl={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(t){t.each(function(){var t=ta.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",i).on("touchstart.brush",i),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,y);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Hl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var c,f=ta.transition(t),h=ta.transition(o);l&&(c=Ui(l),h.attr("x",c[0]).attr("width",c[1]-c[0]),r(f)),s&&(c=Ui(s),h.attr("y",c[0]).attr("height",c[1]-c[0]),u(f)),e(f)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+f[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",f[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1]-f[0])}function u(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function i(){function i(){32==ta.event.keyCode&&(C||(M=null,q[0]-=f[1],q[1]-=h[1],C=2),S())}function v(){32==ta.event.keyCode&&2==C&&(q[0]+=f[1],q[1]+=h[1],C=0,S())}function d(){var n=ta.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ta.event.altKey?(M||(M=[(f[0]+f[1])/2,(h[0]+h[1])/2]),q[0]=f[+(n[0]<M[0])],q[1]=h[+(n[1]<M[1])]):M=null),A&&m(n,l,0)&&(r(k),t=!0),N&&m(n,s,1)&&(u(k),t=!0),t&&(e(k),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,i=Ui(t),c=i[0],l=i[1],s=q[e],v=e?h:f,d=v[1]-v[0];return C&&(c-=s,l-=d+s),r=(e?p:g)?Math.max(c,Math.min(l,n[e])):n[e],C?u=(r+=s)+d:(M&&(s=Math.max(c,Math.min(l,2*M[e]-r))),r>s?(u=r,r=s):u=s),v[0]!=r||v[1]!=u?(e?a=null:o=null,v[0]=r,v[1]=u,!0):void 0}function y(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ta.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ta.select(ta.event.target),w=c.of(b,arguments),k=ta.select(b),E=_.datum(),A=!/^(n|s)$/.test(E)&&l,N=!/^(e|w)$/.test(E)&&s,C=_.classed("extent"),z=W(b),q=ta.mouse(b),L=ta.select(t(b)).on("keydown.brush",i).on("keyup.brush",v);if(ta.event.changedTouches?L.on("touchmove.brush",d).on("touchend.brush",y):L.on("mousemove.brush",d).on("mouseup.brush",y),k.interrupt().selectAll("*").interrupt(),C)q[0]=f[0]-q[0],q[1]=h[0]-q[1];else if(E){var T=+/w$/.test(E),R=+/^n/.test(E);x=[f[1-T]-q[0],h[1-R]-q[1]],q[0]=f[T],q[1]=h[R]}else ta.event.altKey&&(M=q.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,c=E(n,"brushstart","brush","brushend"),l=null,s=null,f=[0,0],h=[0,0],g=!0,p=!0,v=Ol[0];return n.event=function(n){n.each(function(){var n=c.of(this,arguments),t={x:f,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Tl?ta.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,f=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(f,t.x),r=yu(h,t.y);return o=a=null,function(u){f=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(l=t,v=Ol[!l<<1|!s],n):l},n.y=function(t){return arguments.length?(s=t,v=Ol[!l<<1|!s],n):s},n.clamp=function(t){return arguments.length?(l&&s?(g=!!t[0],p=!!t[1]):l?g=!!t:s&&(p=!!t),n):l&&s?[g,p]:l?g:s?p:null},n.extent=function(t){var e,r,u,i,c;return arguments.length?(l&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),o=[e,r],l.invert&&(e=l(e),r=l(r)),e>r&&(c=e,e=r,r=c),(e!=f[0]||r!=f[1])&&(f=[e,r])),s&&(u=t[0],i=t[1],l&&(u=u[1],i=i[1]),a=[u,i],s.invert&&(u=s(u),i=s(i)),u>i&&(c=u,u=i,i=c),(u!=h[0]||i!=h[1])&&(h=[u,i])),n):(l&&(o?(e=o[0],r=o[1]):(e=f[0],r=f[1],l.invert&&(e=l.invert(e),r=l.invert(r)),e>r&&(c=e,e=r,r=c))),s&&(a?(u=a[0],i=a[1]):(u=h[0],i=h[1],s.invert&&(u=s.invert(u),i=s.invert(i)),u>i&&(c=u,u=i,i=c))),l&&s?[[e,u],[r,i]]:l?[e,r]:s&&[u,i])},n.clear=function(){return n.empty()||(f=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!l&&f[0]==f[1]||!!s&&h[0]==h[1]},ta.rebind(n,c,"on")};var Hl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ol=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Il=ac.format=gc.timeFormat,Yl=Il.utc,Zl=Yl("%Y-%m-%dT%H:%M:%S.%LZ");Il.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Zl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Zl.toString,ac.second=Ft(function(n){return new cc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ac.seconds=ac.second.range,ac.seconds.utc=ac.second.utc.range,ac.minute=Ft(function(n){return new cc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ac.minutes=ac.minute.range,ac.minutes.utc=ac.minute.utc.range,ac.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new cc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ac.hours=ac.hour.range,ac.hours.utc=ac.hour.utc.range,ac.month=Ft(function(n){return n=ac.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ac.months=ac.month.range,ac.months.utc=ac.month.utc.range;var Vl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Xl=[[ac.second,1],[ac.second,5],[ac.second,15],[ac.second,30],[ac.minute,1],[ac.minute,5],[ac.minute,15],[ac.minute,30],[ac.hour,1],[ac.hour,3],[ac.hour,6],[ac.hour,12],[ac.day,1],[ac.day,2],[ac.week,1],[ac.month,1],[ac.month,3],[ac.year,1]],$l=Il.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ne]]),Bl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:y,ceil:y};Xl.year=ac.year,ac.scale=function(){return Go(ta.scale.linear(),Xl,$l)};var Wl=Xl.map(function(n){return[n[0].utc,n[1]]}),Jl=Yl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ne]]);Wl.year=ac.year.utc,ac.scale.utc=function(){return Go(ta.scale.linear(),Wl,Jl)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}();/*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl
  19290. * Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT
  19291. * */
  19292. !function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='&shy;<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b<s.length;b++){var c=s[b],e=c.href,f=c.media,g=c.rel&&"stylesheet"===c.rel.toLowerCase();e&&g&&!o[e]&&(c.styleSheet&&c.styleSheet.rawCssText?(v(c.styleSheet.rawCssText,e,f),o[e]=!0):(!/^([a-zA-Z:]*\/\/)/.test(e)&&!r||e.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&("//"===e.substring(0,2)&&(e=a.location.protocol+e),d.push({href:e,media:f})))}w()};x(),c.update=x,c.getEmValue=t,a.addEventListener?a.addEventListener("resize",b,!1):a.attachEvent&&a.attachEvent("onresize",b)}}(this);/**
  19293. * @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
  19294. */
  19295. !function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.2",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b)}(this,document);/*!
  19296. Holder - client side image placeholders
  19297. Version 2.7.1+6hydf
  19298. © 2015 Ivan Malopinsky - http://imsky.co
  19299. Site: http://holderjs.com
  19300. Issues: https://github.com/imsky/holder/issues
  19301. License: http://opensource.org/licenses/MIT
  19302. */
  19303. !function(a){if(a.document){var b=a.document;b.querySelectorAll||(b.querySelectorAll=function(c){var d,e=b.createElement("style"),f=[];for(b.documentElement.firstChild.appendChild(e),b._qsa=[],e.styleSheet.cssText=c+"{x-qsa:expression(document._qsa && document._qsa.push(this))}",a.scrollBy(0,0),e.parentNode.removeChild(e);b._qsa.length;)d=b._qsa.shift(),d.style.removeAttribute("x-qsa"),f.push(d);return b._qsa=null,f}),b.querySelector||(b.querySelector=function(a){var c=b.querySelectorAll(a);return c.length?c[0]:null}),b.getElementsByClassName||(b.getElementsByClassName=function(a){return a=String(a).replace(/^|\s+/g,"."),b.querySelectorAll(a)}),Object.keys||(Object.keys=function(a){if(a!==Object(a))throw TypeError("Object.keys called on non-object");var b,c=[];for(b in a)Object.prototype.hasOwnProperty.call(a,b)&&c.push(b);return c}),function(a){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";a.atob=a.atob||function(a){a=String(a);var c,d=0,e=[],f=0,g=0;if(a=a.replace(/\s/g,""),a.length%4===0&&(a=a.replace(/=+$/,"")),a.length%4===1)throw Error("InvalidCharacterError");if(/[^+/0-9A-Za-z]/.test(a))throw Error("InvalidCharacterError");for(;d<a.length;)c=b.indexOf(a.charAt(d)),f=f<<6|c,g+=6,24===g&&(e.push(String.fromCharCode(f>>16&255)),e.push(String.fromCharCode(f>>8&255)),e.push(String.fromCharCode(255&f)),g=0,f=0),d+=1;return 12===g?(f>>=4,e.push(String.fromCharCode(255&f))):18===g&&(f>>=2,e.push(String.fromCharCode(f>>8&255)),e.push(String.fromCharCode(255&f))),e.join("")},a.btoa=a.btoa||function(a){a=String(a);var c,d,e,f,g,h,i,j=0,k=[];if(/[^\x00-\xFF]/.test(a))throw Error("InvalidCharacterError");for(;j<a.length;)c=a.charCodeAt(j++),d=a.charCodeAt(j++),e=a.charCodeAt(j++),f=c>>2,g=(3&c)<<4|d>>4,h=(15&d)<<2|e>>6,i=63&e,j===a.length+2?(h=64,i=64):j===a.length+1&&(i=64),k.push(b.charAt(f),b.charAt(g),b.charAt(h),b.charAt(i));return k.join("")}}(a),Object.prototype.hasOwnProperty||(Object.prototype.hasOwnProperty=function(a){var b=this.__proto__||this.constructor.prototype;return a in this&&(!(a in b)||b[a]!==this[a])}),function(){if("performance"in a==!1&&(a.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in a.performance==!1){var b=Date.now();performance.timing&&performance.timing.navigationStart&&(b=performance.timing.navigationStart),a.performance.now=function(){return Date.now()-b}}}(),a.requestAnimationFrame||(a.webkitRequestAnimationFrame?!function(a){a.requestAnimationFrame=function(b){return webkitRequestAnimationFrame(function(){b(a.performance.now())})},a.cancelAnimationFrame=webkitCancelAnimationFrame}(a):a.mozRequestAnimationFrame?!function(a){a.requestAnimationFrame=function(b){return mozRequestAnimationFrame(function(){b(a.performance.now())})},a.cancelAnimationFrame=mozCancelAnimationFrame}(a):!function(a){a.requestAnimationFrame=function(b){return a.setTimeout(b,1e3/60)},a.cancelAnimationFrame=a.clearTimeout}(a))}}(this),function(a,b){"object"==typeof exports&&"object"==typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):"object"==typeof exports?exports.Holder=b():a.Holder=b()}(this,function(){return function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={exports:{},id:d,loaded:!1};return a[d].call(e.exports,e,e.exports,b),e.loaded=!0,e.exports}var c={};return b.m=a,b.c=c,b.p="",b(0)}([function(a,b,c){(function(b){function d(a,b,c,d){var f=e(c.substr(c.lastIndexOf(a.domain)),a);f&&h({mode:null,el:d,flags:f,engineSettings:b})}function e(a,b){var c={theme:B(J.settings.themes.gray,null),stylesheets:b.stylesheets,instanceOptions:b};return a.match(/([\d]+p?)x([\d]+p?)(?:\?|$)/)?f(a,c):g(a,c)}function f(a,b){var c=a.split("?"),d=c[0].split("/");b.holderURL=a;var e=d[1],f=e.match(/([\d]+p?)x([\d]+p?)/);if(!f)return!1;if(b.fluid=-1!==e.indexOf("p"),b.dimensions={width:f[1].replace("p","%"),height:f[2].replace("p","%")},2===c.length){var g=A.parse(c[1]);if(g.bg&&(b.theme.background=(-1===g.bg.indexOf("#")?"#":"")+g.bg),g.fg&&(b.theme.foreground=(-1===g.fg.indexOf("#")?"#":"")+g.fg),g.theme&&b.instanceOptions.themes.hasOwnProperty(g.theme)&&(b.theme=B(b.instanceOptions.themes[g.theme],null)),g.text&&(b.text=g.text),g.textmode&&(b.textmode=g.textmode),g.size&&(b.size=g.size),g.font&&(b.font=g.font),g.align&&(b.align=g.align),b.nowrap=z.truthy(g.nowrap),b.auto=z.truthy(g.auto),z.truthy(g.random)){J.vars.cache.themeKeys=J.vars.cache.themeKeys||Object.keys(b.instanceOptions.themes);var h=J.vars.cache.themeKeys[0|Math.random()*J.vars.cache.themeKeys.length];b.theme=B(b.instanceOptions.themes[h],null)}}return b}function g(a,b){var c=!1,d=String.fromCharCode(11),e=a.replace(/([^\\])\//g,"$1"+d).split(d),f=/%[0-9a-f]{2}/gi,g=b.instanceOptions;b.holderURL=[];for(var h=e.length,i=0;h>i;i++){var j=e[i];if(j.match(f))try{j=decodeURIComponent(j)}catch(k){j=e[i]}var l=!1;if(J.flags.dimensions.match(j))c=!0,b.dimensions=J.flags.dimensions.output(j),l=!0;else if(J.flags.fluid.match(j))c=!0,b.dimensions=J.flags.fluid.output(j),b.fluid=!0,l=!0;else if(J.flags.textmode.match(j))b.textmode=J.flags.textmode.output(j),l=!0;else if(J.flags.colors.match(j)){var m=J.flags.colors.output(j);b.theme=B(b.theme,m),l=!0}else if(g.themes[j])g.themes.hasOwnProperty(j)&&(b.theme=B(g.themes[j],null)),l=!0;else if(J.flags.font.match(j))b.font=J.flags.font.output(j),l=!0;else if(J.flags.auto.match(j))b.auto=!0,l=!0;else if(J.flags.text.match(j))b.text=J.flags.text.output(j),l=!0;else if(J.flags.size.match(j))b.size=J.flags.size.output(j),l=!0;else if(J.flags.random.match(j)){null==J.vars.cache.themeKeys&&(J.vars.cache.themeKeys=Object.keys(g.themes));var n=J.vars.cache.themeKeys[0|Math.random()*J.vars.cache.themeKeys.length];b.theme=B(g.themes[n],null),l=!0}l&&b.holderURL.push(j)}return b.holderURL.unshift(g.domain),b.holderURL=b.holderURL.join("/"),c?b:!1}function h(a){var b=a.mode,c=a.el,d=a.flags,e=a.engineSettings,f=d.dimensions,g=d.theme,h=f.width+"x"+f.height;if(b=null==b?d.fluid?"fluid":"image":b,null!=d.text&&(g.text=d.text,"object"===c.nodeName.toLowerCase())){for(var j=g.text.split("\\n"),k=0;k<j.length;k++)j[k]=z.encodeHtmlEntity(j[k]);g.text=j.join("\\n")}var n=d.holderURL,o=B(e,null);if(d.font&&(g.font=d.font,!o.noFontFallback&&"img"===c.nodeName.toLowerCase()&&J.setup.supportsCanvas&&"svg"===o.renderer&&(o=B(o,{renderer:"canvas"}))),d.font&&"canvas"==o.renderer&&(o.reRender=!0),"background"==b)null==c.getAttribute("data-background-src")&&r(c,{"data-background-src":n});else{var p={};p[J.vars.dataAttr]=n,r(c,p)}d.theme=g,c.holderData={flags:d,engineSettings:o},("image"==b||"fluid"==b)&&r(c,{alt:g.text?g.text+" ["+h+"]":h});var q={mode:b,el:c,holderSettings:{dimensions:f,theme:g,flags:d},engineSettings:o};"image"==b?("html"!=o.renderer&&d.auto||(c.style.width=f.width+"px",c.style.height=f.height+"px"),"html"==o.renderer?c.style.backgroundColor=g.background:(i(q),"exact"==d.textmode&&(c.holderData.resizeUpdate=!0,J.vars.resizableImages.push(c),l(c)))):"background"==b&&"html"!=o.renderer?i(q):"fluid"==b&&(c.holderData.resizeUpdate=!0,"%"==f.height.slice(-1)?c.style.height=f.height:null!=d.auto&&d.auto||(c.style.height=f.height+"px"),"%"==f.width.slice(-1)?c.style.width=f.width:null!=d.auto&&d.auto||(c.style.width=f.width+"px"),("inline"==c.style.display||""===c.style.display||"none"==c.style.display)&&(c.style.display="block"),m(c),"html"==o.renderer?c.style.backgroundColor=g.background:(J.vars.resizableImages.push(c),l(c)))}function i(a){function c(){var b=null;switch(h.renderer){case"canvas":b=L(k,a);break;case"svg":b=M(k,a);break;default:throw"Holder: invalid renderer: "+h.renderer}return b}var d=null,e=a.mode,f=a.holderSettings,g=a.el,h=a.engineSettings;switch(h.renderer){case"svg":if(!J.setup.supportsSVG)return;break;case"canvas":if(!J.setup.supportsCanvas)return;break;default:return}var i={width:f.dimensions.width,height:f.dimensions.height,theme:f.theme,flags:f.flags},k=j(i);if(d=c(),null==d)throw"Holder: couldn't render placeholder";"background"==e?(g.style.backgroundImage="url("+d+")",g.style.backgroundSize=i.width+"px "+i.height+"px"):("img"===g.nodeName.toLowerCase()?r(g,{src:d}):"object"===g.nodeName.toLowerCase()&&(r(g,{data:d}),r(g,{type:"image/svg+xml"})),h.reRender&&b.setTimeout(function(){var a=c();if(null==a)throw"Holder: couldn't render placeholder";"img"===g.nodeName.toLowerCase()?r(g,{src:a}):"object"===g.nodeName.toLowerCase()&&(r(g,{data:a}),r(g,{type:"image/svg+xml"}))},100)),r(g,{"data-holder-rendered":!0})}function j(a){function b(a,b,c,d){b.width=c,b.height=d,a.width=Math.max(a.width,b.width),a.height+=b.height}var c=J.defaults.size;switch(parseFloat(a.theme.size)?c=a.theme.size:parseFloat(a.flags.size)&&(c=a.flags.size),a.font={family:a.theme.font?a.theme.font:"Arial, Helvetica, Open Sans, sans-serif",size:k(a.width,a.height,c),units:a.theme.units?a.theme.units:J.defaults.units,weight:a.theme.fontweight?a.theme.fontweight:"bold"},a.text=a.theme.text||Math.floor(a.width)+"x"+Math.floor(a.height),a.noWrap=a.theme.nowrap||a.flags.nowrap,a.align=a.theme.align||a.flags.align||"center",a.flags.textmode){case"literal":a.text=a.flags.dimensions.width+"x"+a.flags.dimensions.height;break;case"exact":if(!a.flags.exactDimensions)break;a.text=Math.floor(a.flags.exactDimensions.width)+"x"+Math.floor(a.flags.exactDimensions.height)}var d=new y({width:a.width,height:a.height}),e=d.Shape,f=new e.Rect("holderBg",{fill:a.theme.background});f.resize(a.width,a.height),d.root.add(f);var g=new e.Group("holderTextGroup",{text:a.text,align:a.align,font:a.font,fill:a.theme.foreground});g.moveTo(null,null,1),d.root.add(g);var h=g.textPositionData=K(d);if(!h)throw"Holder: staging fallback not supported yet.";g.properties.leading=h.boundingBox.height;var i=null,j=null,l=a.width*J.setup.lineWrapRatio,m=l;if(h.lineCount>1){var n,o=0,p=0,q=0;j=new e.Group("line"+q),("left"===a.align||"right"===a.align)&&(m=a.width*(1-2*(1-J.setup.lineWrapRatio)));for(var r=0;r<h.words.length;r++){var s=h.words[r];i=new e.Text(s.text);var t="\\n"==s.text;!a.noWrap&&(o+s.width>=m||t===!0)&&(b(g,j,o,g.properties.leading),g.add(j),o=0,p+=g.properties.leading,q+=1,j=new e.Group("line"+q),j.y=p),t!==!0&&(i.moveTo(o,0),o+=h.spaceWidth+s.width,j.add(i))}if(b(g,j,o,g.properties.leading),g.add(j),"left"===a.align)g.moveTo(a.width-l,null,null);else if("right"===a.align){for(n in g.children)j=g.children[n],j.moveTo(a.width-j.width,null,null);g.moveTo(0-(a.width-l),null,null)}else{for(n in g.children)j=g.children[n],j.moveTo((g.width-j.width)/2,null,null);g.moveTo((a.width-g.width)/2,null,null)}g.moveTo(null,(a.height-g.height)/2,null),(a.height-g.height)/2<0&&g.moveTo(null,0,null)}else i=new e.Text(a.text),j=new e.Group("line0"),j.add(i),g.add(j),"left"===a.align?g.moveTo(a.width-l,null,null):"right"===a.align?g.moveTo(0-(a.width-l),null,null):g.moveTo((a.width-h.boundingBox.width)/2,null,null),g.moveTo(null,(a.height-h.boundingBox.height)/2,null);return d}function k(a,b,c){var d=parseInt(a,10),e=parseInt(b,10),f=Math.max(d,e),g=Math.min(d,e),h=.8*Math.min(g,f*J.defaults.scale);return Math.round(Math.max(c,h))}function l(a){var b;b=null==a||null==a.nodeType?J.vars.resizableImages:[a];for(var c=0,d=b.length;d>c;c++){var e=b[c];if(e.holderData){var f=e.holderData.flags,g=D(e);if(g){if(!e.holderData.resizeUpdate)continue;if(f.fluid&&f.auto){var h=e.holderData.fluidConfig;switch(h.mode){case"width":g.height=g.width/h.ratio;break;case"height":g.width=g.height*h.ratio}}var j={mode:"image",holderSettings:{dimensions:g,theme:f.theme,flags:f},el:e,engineSettings:e.holderData.engineSettings};"exact"==f.textmode&&(f.exactDimensions=g,j.holderSettings.dimensions=f.dimensions),i(j)}else p(e)}}}function m(a){if(a.holderData){var b=D(a);if(b){var c=a.holderData.flags,d={fluidHeight:"%"==c.dimensions.height.slice(-1),fluidWidth:"%"==c.dimensions.width.slice(-1),mode:null,initialDimensions:b};d.fluidWidth&&!d.fluidHeight?(d.mode="width",d.ratio=d.initialDimensions.width/parseFloat(c.dimensions.height)):!d.fluidWidth&&d.fluidHeight&&(d.mode="height",d.ratio=parseFloat(c.dimensions.width)/d.initialDimensions.height),a.holderData.fluidConfig=d}else p(a)}}function n(){for(var a,c=[],d=Object.keys(J.vars.invisibleImages),e=0,f=d.length;f>e;e++)a=J.vars.invisibleImages[d[e]],D(a)&&"img"==a.nodeName.toLowerCase()&&(c.push(a),delete J.vars.invisibleImages[d[e]]);c.length&&I.run({images:c}),b.requestAnimationFrame(n)}function o(){J.vars.visibilityCheckStarted||(b.requestAnimationFrame(n),J.vars.visibilityCheckStarted=!0)}function p(a){a.holderData.invisibleId||(J.vars.invisibleId+=1,J.vars.invisibleImages["i"+J.vars.invisibleId]=a,a.holderData.invisibleId=J.vars.invisibleId)}function q(a,b){return null==b?document.createElement(a):document.createElementNS(b,a)}function r(a,b){for(var c in b)a.setAttribute(c,b[c])}function s(a,b,c){var d,e;null==a?(a=q("svg",E),d=q("defs",E),e=q("style",E),r(e,{type:"text/css"}),d.appendChild(e),a.appendChild(d)):e=a.querySelector("style"),a.webkitMatchesSelector&&a.setAttribute("xmlns",E);for(var f=0;f<a.childNodes.length;f++)a.childNodes[f].nodeType===F&&a.removeChild(a.childNodes[f]);for(;e.childNodes.length;)e.removeChild(e.childNodes[0]);return r(a,{width:b,height:c,viewBox:"0 0 "+b+" "+c,preserveAspectRatio:"none"}),a}function t(a,c){if(b.XMLSerializer){var d=new XMLSerializer,e="",f=c.stylesheets;if(c.svgXMLStylesheet){for(var g=u(),h=f.length-1;h>=0;h--){var i=g.createProcessingInstruction("xml-stylesheet",'href="'+f[h]+'" rel="stylesheet"');g.insertBefore(i,g.firstChild)}g.removeChild(g.documentElement),e=d.serializeToString(g)}var j=d.serializeToString(a);return j=j.replace(/\&amp;(\#[0-9]{2,}\;)/g,"&$1"),e+j}}function u(){return b.DOMParser?(new DOMParser).parseFromString("<xml />","application/xml"):void 0}function v(a){J.vars.debounceTimer||a.call(this),J.vars.debounceTimer&&b.clearTimeout(J.vars.debounceTimer),J.vars.debounceTimer=b.setTimeout(function(){J.vars.debounceTimer=null,a.call(this)},J.setup.debounce)}function w(){v(function(){l(null)})}var x=c(1),y=c(2),z=c(3),A=c(4),B=z.extend,C=z.getNodeArray,D=z.dimensionCheck,E="http://www.w3.org/2000/svg",F=8,G="2.7.1",H="\nCreated with Holder.js "+G+".\nLearn more at http://holderjs.com\n(c) 2012-2015 Ivan Malopinsky - http://imsky.co\n",I={version:G,addTheme:function(a,b){return null!=a&&null!=b&&(J.settings.themes[a]=b),delete J.vars.cache.themeKeys,this},addImage:function(a,b){var c=document.querySelectorAll(b);if(c.length)for(var d=0,e=c.length;e>d;d++){var f=q("img"),g={};g[J.vars.dataAttr]=a,r(f,g),c[d].appendChild(f)}return this},setResizeUpdate:function(a,b){a.holderData&&(a.holderData.resizeUpdate=!!b,a.holderData.resizeUpdate&&l(a))},run:function(a){a=a||{};var c={},f=B(J.settings,a);J.vars.preempted=!0,J.vars.dataAttr=f.dataAttr||J.vars.dataAttr,c.renderer=f.renderer?f.renderer:J.setup.renderer,-1===J.setup.renderers.join(",").indexOf(c.renderer)&&(c.renderer=J.setup.supportsSVG?"svg":J.setup.supportsCanvas?"canvas":"html");var g=C(f.images),i=C(f.bgnodes),j=C(f.stylenodes),k=C(f.objects);c.stylesheets=[],c.svgXMLStylesheet=!0,c.noFontFallback=f.noFontFallback?f.noFontFallback:!1;for(var l=0;l<j.length;l++){var m=j[l];if(m.attributes.rel&&m.attributes.href&&"stylesheet"==m.attributes.rel.value){var n=m.attributes.href.value,o=q("a");o.href=n;var p=o.protocol+"//"+o.host+o.pathname+o.search;c.stylesheets.push(p)}}for(l=0;l<i.length;l++)if(b.getComputedStyle){var r=b.getComputedStyle(i[l],null).getPropertyValue("background-image"),s=i[l].getAttribute("data-background-src"),t=null;t=null==s?r:s;var u=null,v="?"+f.domain+"/";if(0===t.indexOf(v))u=t.slice(1);else if(-1!=t.indexOf(v)){var w=t.substr(t.indexOf(v)).slice(1),x=w.match(/([^\"]*)"?\)/);null!=x&&(u=x[1])}if(null!=u){var y=e(u,f);y&&h({mode:"background",el:i[l],flags:y,engineSettings:c})}}for(l=0;l<k.length;l++){var A=k[l],D={};try{D.data=A.getAttribute("data"),D.dataSrc=A.getAttribute(J.vars.dataAttr)}catch(E){}var F=null!=D.data&&0===D.data.indexOf(f.domain),G=null!=D.dataSrc&&0===D.dataSrc.indexOf(f.domain);F?d(f,c,D.data,A):G&&d(f,c,D.dataSrc,A)}for(l=0;l<g.length;l++){var H=g[l],I={};try{I.src=H.getAttribute("src"),I.dataSrc=H.getAttribute(J.vars.dataAttr),I.rendered=H.getAttribute("data-holder-rendered")}catch(E){}var K=null!=I.src,L=null!=I.dataSrc&&0===I.dataSrc.indexOf(f.domain),M=null!=I.rendered&&"true"==I.rendered;K?0===I.src.indexOf(f.domain)?d(f,c,I.src,H):L&&(M?d(f,c,I.dataSrc,H):!function(a,b,c,e,f){z.imageExists(a,function(a){a||d(b,c,e,f)})}(I.src,f,c,I.dataSrc,H)):L&&d(f,c,I.dataSrc,H)}return this}},J={settings:{domain:"holder.js",images:"img",objects:"object",bgnodes:"body .holderjs",stylenodes:"head link.holderjs",stylesheets:[],themes:{gray:{background:"#EEEEEE",foreground:"#AAAAAA"},social:{background:"#3a5a97",foreground:"#FFFFFF"},industrial:{background:"#434A52",foreground:"#C2F200"},sky:{background:"#0D8FDB",foreground:"#FFFFFF"},vine:{background:"#39DBAC",foreground:"#1E292C"},lava:{background:"#F8591A",foreground:"#1C2846"}}},defaults:{size:10,units:"pt",scale:1/16},flags:{dimensions:{regex:/^(\d+)x(\d+)$/,output:function(a){var b=this.regex.exec(a);return{width:+b[1],height:+b[2]}}},fluid:{regex:/^([0-9]+%?)x([0-9]+%?)$/,output:function(a){var b=this.regex.exec(a);return{width:b[1],height:b[2]}}},colors:{regex:/(?:#|\^)([0-9a-f]{3,})\:(?:#|\^)([0-9a-f]{3,})/i,output:function(a){var b=this.regex.exec(a);return{foreground:"#"+b[2],background:"#"+b[1]}}},text:{regex:/text\:(.*)/,output:function(a){return this.regex.exec(a)[1].replace("\\/","/")}},font:{regex:/font\:(.*)/,output:function(a){return this.regex.exec(a)[1]}},auto:{regex:/^auto$/},textmode:{regex:/textmode\:(.*)/,output:function(a){return this.regex.exec(a)[1]}},random:{regex:/^random$/},size:{regex:/size\:(\d+)/,output:function(a){return this.regex.exec(a)[1]}}}},K=function(){var a=null,b=null,c=null;return function(d){var e=d.root;if(J.setup.supportsSVG){var f=!1,g=function(a){return document.createTextNode(a)};(null==a||a.parentNode!==document.body)&&(f=!0),a=s(a,e.properties.width,e.properties.height),a.style.display="block",f&&(b=q("text",E),c=g(null),r(b,{x:0}),b.appendChild(c),a.appendChild(b),document.body.appendChild(a),a.style.visibility="hidden",a.style.position="absolute",a.style.top="-100%",a.style.left="-100%");var h=e.children.holderTextGroup,i=h.properties;r(b,{y:i.font.size,style:z.cssProps({"font-weight":i.font.weight,"font-size":i.font.size+i.font.units,"font-family":i.font.family})}),c.nodeValue=i.text;var j=b.getBBox(),k=Math.ceil(j.width/(e.properties.width*J.setup.lineWrapRatio)),l=i.text.split(" "),m=i.text.match(/\\n/g);k+=null==m?0:m.length,c.nodeValue=i.text.replace(/[ ]+/g,"");var n=b.getComputedTextLength(),o=j.width-n,p=Math.round(o/Math.max(1,l.length-1)),t=[];if(k>1){c.nodeValue="";for(var u=0;u<l.length;u++)if(0!==l[u].length){c.nodeValue=z.decodeHtmlEntity(l[u]);var v=b.getBBox();t.push({text:l[u],width:v.width})}}return a.style.display="none",{spaceWidth:p,lineCount:k,boundingBox:j,words:t}}return!1}}(),L=function(){var a=q("canvas"),b=null;return function(c){null==b&&(b=a.getContext("2d"));var d=c.root;a.width=J.dpr(d.properties.width),a.height=J.dpr(d.properties.height),b.textBaseline="middle",b.fillStyle=d.children.holderBg.properties.fill,b.fillRect(0,0,J.dpr(d.children.holderBg.width),J.dpr(d.children.holderBg.height));{var e=d.children.holderTextGroup;e.properties}b.font=e.properties.font.weight+" "+J.dpr(e.properties.font.size)+e.properties.font.units+" "+e.properties.font.family+", monospace",b.fillStyle=e.properties.fill;for(var f in e.children){var g=e.children[f];for(var h in g.children){var i=g.children[h],j=J.dpr(e.x+g.x+i.x),k=J.dpr(e.y+g.y+i.y+e.properties.leading/2);b.fillText(i.properties.text,j,k)}}return a.toDataURL("image/png")}}(),M=function(){if(b.XMLSerializer){var a=u(),c=s(null,0,0),d=q("rect",E);return c.appendChild(d),function(b,e){var f=b.root;s(c,f.properties.width,f.properties.height);for(var g=c.querySelectorAll("g"),h=0;h<g.length;h++)g[h].parentNode.removeChild(g[h]);var i=e.holderSettings.flags.holderURL,j="holder_"+(Number(new Date)+32768+(0|32768*Math.random())).toString(16),k=q("g",E),l=f.children.holderTextGroup,m=l.properties,n=q("g",E),o=l.textPositionData,p="#"+j+" text { "+z.cssProps({fill:m.fill,"font-weight":m.font.weight,"font-family":m.font.family+", monospace","font-size":m.font.size+m.font.units})+" } ",u=a.createComment("\nSource URL: "+i+H),v=a.createCDATASection(p),w=c.querySelector("style");r(k,{id:j}),c.insertBefore(u,c.firstChild),w.appendChild(v),k.appendChild(d),k.appendChild(n),c.appendChild(k),r(d,{width:f.children.holderBg.width,height:f.children.holderBg.height,fill:f.children.holderBg.properties.fill}),l.y+=.8*o.boundingBox.height;for(var x in l.children){var y=l.children[x];for(var A in y.children){var B=y.children[A],C=l.x+y.x+B.x,D=l.y+y.y+B.y,F=q("text",E),G=document.createTextNode(null);r(F,{x:C,y:D}),G.nodeValue=B.properties.text,F.appendChild(G),n.appendChild(F)}}var I=N(t(c,e.engineSettings),"background"===e.mode);return I}}}(),N=function(){var a="data:image/svg+xml;charset=UTF-8,",b="data:image/svg+xml;charset=UTF-8;base64,";return function(c,d){return d?b+btoa(unescape(encodeURIComponent(c))):a+encodeURIComponent(c)}}();for(var O in J.flags)J.flags.hasOwnProperty(O)&&(J.flags[O].match=function(a){return a.match(this.regex)});J.setup={renderer:"html",debounce:100,ratio:1,supportsCanvas:!1,supportsSVG:!1,lineWrapRatio:.9,renderers:["html","canvas","svg"]},J.dpr=function(a){return a*J.setup.ratio},J.vars={preempted:!1,resizableImages:[],invisibleImages:{},invisibleId:0,visibilityCheckStarted:!1,debounceTimer:null,cache:{},dataAttr:"data-src"},function(){var a=1,c=1,d=q("canvas"),e=null;d.getContext&&-1!=d.toDataURL("image/png").indexOf("data:image/png")&&(J.setup.renderer="canvas",e=d.getContext("2d"),J.setup.supportsCanvas=!0),J.setup.supportsCanvas&&(a=b.devicePixelRatio||1,c=e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1),J.setup.ratio=a/c,document.createElementNS&&document.createElementNS(E,"svg").createSVGRect&&(J.setup.renderer="svg",J.setup.supportsSVG=!0)}(),o(),x&&x(function(){J.vars.preempted||I.run(),b.addEventListener?(b.addEventListener("resize",w,!1),b.addEventListener("orientationchange",w,!1)):b.attachEvent("onresize",w),"object"==typeof b.Turbolinks&&b.document.addEventListener("page:change",function(){I.run()})}),a.exports=I}).call(b,function(){return this}())},function(a){function b(a){function b(a){if(!v){if(!g.body)return e(b);for(v=!0;a=w.shift();)e(a)}}function c(a){(t||a.type===i||g[m]===l)&&(d(),b())}function d(){t?(g[s](q,c,j),a[s](i,c,j)):(g[o](r,c),a[o](k,c))}function e(a,b){setTimeout(a,+b>=0?b:1)}function f(a){v?e(a):w.push(a)}null==document.readyState&&document.addEventListener&&(document.addEventListener("DOMContentLoaded",function y(){document.removeEventListener("DOMContentLoaded",y,!1),document.readyState="complete"},!1),document.readyState="loading");var g=a.document,h=g.documentElement,i="load",j=!1,k="on"+i,l="complete",m="readyState",n="attachEvent",o="detachEvent",p="addEventListener",q="DOMContentLoaded",r="onreadystatechange",s="removeEventListener",t=p in g,u=j,v=j,w=[];if(g[m]===l)e(b);else if(t)g[p](q,c,j),a[p](i,c,j);else{g[n](r,c),a[n](k,c);try{u=null==a.frameElement&&h}catch(x){}u&&u.doScroll&&!function z(){if(!v){try{u.doScroll("left")}catch(a){return e(z,50)}d(),b()}}()}return f.version="1.4.0",f.isReady=function(){return v},f}a.exports="undefined"!=typeof window&&b(window)},function(a,b,c){var d=c(5),e=function(a){function b(a,b){for(var c in b)a[c]=b[c];return a}var c=1,e=d.defclass({constructor:function(a){c++,this.parent=null,this.children={},this.id=c,this.name="n"+c,null!=a&&(this.name=a),this.x=0,this.y=0,this.z=0,this.width=0,this.height=0},resize:function(a,b){null!=a&&(this.width=a),null!=b&&(this.height=b)},moveTo:function(a,b,c){this.x=null!=a?a:this.x,this.y=null!=b?b:this.y,this.z=null!=c?c:this.z},add:function(a){var b=a.name;if(null!=this.children[b])throw"SceneGraph: child with that name already exists: "+b;this.children[b]=a,a.parent=this}}),f=d(e,function(b){this.constructor=function(){b.constructor.call(this,"root"),this.properties=a}}),g=d(e,function(a){function c(c,d){if(a.constructor.call(this,c),this.properties={fill:"#000"},null!=d)b(this.properties,d);else if(null!=c&&"string"!=typeof c)throw"SceneGraph: invalid node name"}this.Group=d.extend(this,{constructor:c,type:"group"}),this.Rect=d.extend(this,{constructor:c,type:"rect"}),this.Text=d.extend(this,{constructor:function(a){c.call(this),this.properties.text=a},type:"text"})}),h=new f;return this.Shape=g,this.root=h,this};a.exports=e},function(a,b){(function(a){b.extend=function(a,b){var c={};for(var d in a)a.hasOwnProperty(d)&&(c[d]=a[d]);if(null!=b)for(var e in b)b.hasOwnProperty(e)&&(c[e]=b[e]);return c},b.cssProps=function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(c+":"+a[c]);return b.join(";")},b.encodeHtmlEntity=function(a){for(var b=[],c=0,d=a.length-1;d>=0;d--)c=a.charCodeAt(d),b.unshift(c>128?["&#",c,";"].join(""):a[d]);return b.join("")},b.getNodeArray=function(b){var c=null;return"string"==typeof b?c=document.querySelectorAll(b):a.NodeList&&b instanceof a.NodeList?c=b:a.Node&&b instanceof a.Node?c=[b]:a.HTMLCollection&&b instanceof a.HTMLCollection?c=b:b instanceof Array?c=b:null===b&&(c=[]),c},b.imageExists=function(a,b){var c=new Image;c.onerror=function(){b.call(this,!1)},c.onload=function(){b.call(this,!0)},c.src=a},b.decodeHtmlEntity=function(a){return a.replace(/&#(\d+);/g,function(a,b){return String.fromCharCode(b)})},b.dimensionCheck=function(a){var b={height:a.clientHeight,width:a.clientWidth};return b.height&&b.width?b:!1},b.truthy=function(a){return"string"==typeof a?"true"===a||"yes"===a||"1"===a||"on"===a||"✓"===a:!!a}}).call(b,function(){return this}())},function(a,b,c){var d=encodeURIComponent,e=decodeURIComponent,f=c(6),g=c(7),h=/(\w+)\[(\d+)\]/,i=/\w+\.\w+/;b.parse=function(a){if("string"!=typeof a)return{};if(a=f(a),""===a)return{};"?"===a.charAt(0)&&(a=a.slice(1));for(var b={},c=a.split("&"),d=0;d<c.length;d++){var g,j,k,l=c[d].split("="),m=e(l[0]);if(g=h.exec(m))b[g[1]]=b[g[1]]||[],b[g[1]][g[2]]=e(l[1]);else if(g=i.test(m)){for(g=m.split("."),j=b;g.length;)if(k=g.shift(),k.length){if(j[k]){if(j[k]&&"object"!=typeof j[k])break}else j[k]={};g.length||(j[k]=e(l[1])),j=j[k]}}else b[l[0]]=null==l[1]?"":e(l[1])}return b},b.stringify=function(a){if(!a)return"";var b=[];for(var c in a){var e=a[c];if("array"!=g(e))b.push(d(c)+"="+d(a[c]));else for(var f=0;f<e.length;++f)b.push(d(c+"["+f+"]")+"="+d(e[f]))}return b.join("&")}},function(a){var b=function(){},c=Array.prototype.slice,d=function(a,d){var e=b.prototype="function"==typeof a?a.prototype:a,f=new b,g=d.apply(f,c.call(arguments,2).concat(e));if("object"==typeof g)for(var h in g)f[h]=g[h];if(!f.hasOwnProperty("constructor"))return f;var i=f.constructor;return i.prototype=f,i};d.defclass=function(a){var b=a.constructor;return b.prototype=a,b},d.extend=function(a,b){return d(a,function(a){return this.uber=a,b})},a.exports=d},function(a,b){function c(a){return a.replace(/^\s*|\s*$/g,"")}b=a.exports=c,b.left=function(a){return a.replace(/^\s*/,"")},b.right=function(a){return a.replace(/\s*$/,"")}},function(a){var b=Object.prototype.toString;a.exports=function(a){switch(b.call(a)){case"[object Date]":return"date";case"[object RegExp]":return"regexp";case"[object Arguments]":return"arguments";case"[object Array]":return"array";case"[object Error]":return"error"}return null===a?"null":void 0===a?"undefined":a!==a?"nan":a&&1===a.nodeType?"element":(a=a.valueOf?a.valueOf():Object.prototype.valueOf.apply(a),typeof a)}}])}),function(a,b){b&&(Holder=a.Holder)}(this,"undefined"!=typeof Meteor&&"undefined"!=typeof Package);
  19304. /* nvd3 version 1.8.1 (https://github.com/novus/nvd3) 2015-06-17 */
  19305. !function(){var a={};a.dev=!1,a.tooltip=a.tooltip||{},a.utils=a.utils||{},a.models=a.models||{},a.charts={},a.logs={},a.dom={},a.dispatch=d3.dispatch("render_start","render_end"),Function.prototype.bind||(Function.prototype.bind=function(a){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var b=Array.prototype.slice.call(arguments,1),c=this,d=function(){},e=function(){return c.apply(this instanceof d&&a?this:a,b.concat(Array.prototype.slice.call(arguments)))};return d.prototype=this.prototype,e.prototype=new d,e}),a.dev&&(a.dispatch.on("render_start",function(){a.logs.startTime=+new Date}),a.dispatch.on("render_end",function(){a.logs.endTime=+new Date,a.logs.totalTime=a.logs.endTime-a.logs.startTime,a.log("total",a.logs.totalTime)})),a.log=function(){if(a.dev&&window.console&&console.log&&console.log.apply)console.log.apply(console,arguments);else if(a.dev&&window.console&&"function"==typeof console.log&&Function.prototype.bind){var b=Function.prototype.bind.call(console.log,console);b.apply(console,arguments)}return arguments[arguments.length-1]},a.deprecated=function(a,b){console&&console.warn&&console.warn("nvd3 warning: `"+a+"` has been deprecated. ",b||"")},a.render=function(b){b=b||1,a.render.active=!0,a.dispatch.render_start();var c=function(){for(var d,e,f=0;b>f&&(e=a.render.queue[f]);f++)d=e.generate(),typeof e.callback==typeof Function&&e.callback(d);a.render.queue.splice(0,f),a.render.queue.length?setTimeout(c):(a.dispatch.render_end(),a.render.active=!1)};setTimeout(c)},a.render.active=!1,a.render.queue=[],a.addGraph=function(b){typeof arguments[0]==typeof Function&&(b={generate:arguments[0],callback:arguments[1]}),a.render.queue.push(b),a.render.active||a.render()},"undefined"!=typeof module&&"undefined"!=typeof exports&&(module.exports=a),"undefined"!=typeof window&&(window.nv=a),a.dom.write=function(a){return void 0!==window.fastdom?fastdom.write(a):a()},a.dom.read=function(a){return void 0!==window.fastdom?fastdom.read(a):a()},a.interactiveGuideline=function(){"use strict";function b(l){l.each(function(l){function m(){var a=d3.mouse(this),d=a[0],e=a[1],i=!0,j=!1;if(k&&(d=d3.event.offsetX,e=d3.event.offsetY,"svg"!==d3.event.target.tagName&&(i=!1),d3.event.target.className.baseVal.match("nv-legend")&&(j=!0)),i&&(d-=f.left,e-=f.top),0>d||0>e||d>o||e>p||d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement||j){if(k&&d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement&&(void 0===d3.event.relatedTarget.className||d3.event.relatedTarget.className.match(c.nvPointerEventsClass)))return;return h.elementMouseout({mouseX:d,mouseY:e}),b.renderGuideLine(null),void c.hidden(!0)}c.hidden(!1);var l=g.invert(d);h.elementMousemove({mouseX:d,mouseY:e,pointXValue:l}),"dblclick"===d3.event.type&&h.elementDblclick({mouseX:d,mouseY:e,pointXValue:l}),"click"===d3.event.type&&h.elementClick({mouseX:d,mouseY:e,pointXValue:l})}var n=d3.select(this),o=d||960,p=e||400,q=n.selectAll("g.nv-wrap.nv-interactiveLineLayer").data([l]),r=q.enter().append("g").attr("class"," nv-wrap nv-interactiveLineLayer");r.append("g").attr("class","nv-interactiveGuideLine"),j&&(j.on("touchmove",m).on("mousemove",m,!0).on("mouseout",m,!0).on("dblclick",m).on("click",m),b.guideLine=null,b.renderGuideLine=function(c){i&&(b.guideLine&&b.guideLine.attr("x1")===c||a.dom.write(function(){var b=q.select(".nv-interactiveGuideLine").selectAll("line").data(null!=c?[a.utils.NaNtoZero(c)]:[],String);b.enter().append("line").attr("class","nv-guideline").attr("x1",function(a){return a}).attr("x2",function(a){return a}).attr("y1",p).attr("y2",0),b.exit().remove()}))})})}var c=a.models.tooltip();c.duration(0).hideDelay(0)._isInteractiveLayer(!0).hidden(!1);var d=null,e=null,f={left:0,top:0},g=d3.scale.linear(),h=d3.dispatch("elementMousemove","elementMouseout","elementClick","elementDblclick"),i=!0,j=null,k="ActiveXObject"in window;return b.dispatch=h,b.tooltip=c,b.margin=function(a){return arguments.length?(f.top="undefined"!=typeof a.top?a.top:f.top,f.left="undefined"!=typeof a.left?a.left:f.left,b):f},b.width=function(a){return arguments.length?(d=a,b):d},b.height=function(a){return arguments.length?(e=a,b):e},b.xScale=function(a){return arguments.length?(g=a,b):g},b.showGuideLine=function(a){return arguments.length?(i=a,b):i},b.svgContainer=function(a){return arguments.length?(j=a,b):j},b},a.interactiveBisect=function(a,b,c){"use strict";if(!(a instanceof Array))return null;var d;d="function"!=typeof c?function(a){return a.x}:c;var e=function(a,b){return d(a)-b},f=d3.bisector(e).left,g=d3.max([0,f(a,b)-1]),h=d(a[g]);if("undefined"==typeof h&&(h=g),h===b)return g;var i=d3.min([g+1,a.length-1]),j=d(a[i]);return"undefined"==typeof j&&(j=i),Math.abs(j-b)>=Math.abs(h-b)?g:i},a.nearestValueIndex=function(a,b,c){"use strict";var d=1/0,e=null;return a.forEach(function(a,f){var g=Math.abs(b-a);null!=a&&d>=g&&c>g&&(d=g,e=f)}),e},function(){"use strict";a.models.tooltip=function(){function b(){if(k){var a=d3.select(k);"svg"!==a.node().tagName&&(a=a.select("svg"));var b=a.node()?a.attr("viewBox"):null;if(b){b=b.split(" ");var c=parseInt(a.style("width"),10)/b[2];p.left=p.left*c,p.top=p.top*c}}}function c(){if(!n){var a;a=k?k:document.body,n=d3.select(a).append("div").attr("class","nvtooltip "+(j?j:"xy-tooltip")).attr("id",v),n.style("top",0).style("left",0),n.style("opacity",0),n.selectAll("div, table, td, tr").classed(w,!0),n.classed(w,!0),o=n.node()}}function d(){if(r&&B(e)){b();var f=p.left,g=null!==i?i:p.top;return a.dom.write(function(){c();var b=A(e);b&&(o.innerHTML=b),k&&u?a.dom.read(function(){var a=k.getElementsByTagName("svg")[0],b={left:0,top:0};if(a){var c=a.getBoundingClientRect(),d=k.getBoundingClientRect(),e=c.top;if(0>e){var i=k.getBoundingClientRect();e=Math.abs(e)>i.height?0:e}b.top=Math.abs(e-d.top),b.left=Math.abs(c.left-d.left)}f+=k.offsetLeft+b.left-2*k.scrollLeft,g+=k.offsetTop+b.top-2*k.scrollTop,h&&h>0&&(g=Math.floor(g/h)*h),C([f,g])}):C([f,g])}),d}}var e=null,f="w",g=25,h=0,i=null,j=null,k=null,l=!0,m=400,n=null,o=null,p={left:null,top:null},q={left:0,top:0},r=!0,s=100,t=!0,u=!1,v="nvtooltip-"+Math.floor(1e5*Math.random()),w="nv-pointer-events-none",x=function(a){return a},y=function(a){return a},z=function(a){return a},A=function(a){if(null===a)return"";var b=d3.select(document.createElement("table"));if(t){var c=b.selectAll("thead").data([a]).enter().append("thead");c.append("tr").append("td").attr("colspan",3).append("strong").classed("x-value",!0).html(y(a.value))}var d=b.selectAll("tbody").data([a]).enter().append("tbody"),e=d.selectAll("tr").data(function(a){return a.series}).enter().append("tr").classed("highlight",function(a){return a.highlight});e.append("td").classed("legend-color-guide",!0).append("div").style("background-color",function(a){return a.color}),e.append("td").classed("key",!0).html(function(a,b){return z(a.key,b)}),e.append("td").classed("value",!0).html(function(a,b){return x(a.value,b)}),e.selectAll("td").each(function(a){if(a.highlight){var b=d3.scale.linear().domain([0,1]).range(["#fff",a.color]),c=.6;d3.select(this).style("border-bottom-color",b(c)).style("border-top-color",b(c))}});var f=b.node().outerHTML;return void 0!==a.footer&&(f+="<div class='footer'>"+a.footer+"</div>"),f},B=function(a){if(a&&a.series){if(a.series instanceof Array)return!!a.series.length;if(a.series instanceof Object)return a.series=[a.series],!0}return!1},C=function(b){o&&a.dom.read(function(){var c,d,e=parseInt(o.offsetHeight,10),h=parseInt(o.offsetWidth,10),i=a.utils.windowSize().width,j=a.utils.windowSize().height,k=window.pageYOffset,p=window.pageXOffset;j=window.innerWidth>=document.body.scrollWidth?j:j-16,i=window.innerHeight>=document.body.scrollHeight?i:i-16;var r,t,u=function(a){var b=d;do isNaN(a.offsetTop)||(b+=a.offsetTop),a=a.offsetParent;while(a);return b},v=function(a){var b=c;do isNaN(a.offsetLeft)||(b+=a.offsetLeft),a=a.offsetParent;while(a);return b};switch(f){case"e":c=b[0]-h-g,d=b[1]-e/2,r=v(o),t=u(o),p>r&&(c=b[0]+g>p?b[0]+g:p-r+c),k>t&&(d=k-t+d),t+e>k+j&&(d=k+j-t+d-e);break;case"w":c=b[0]+g,d=b[1]-e/2,r=v(o),t=u(o),r+h>i&&(c=b[0]-h-g),k>t&&(d=k+5),t+e>k+j&&(d=k+j-t+d-e);break;case"n":c=b[0]-h/2-5,d=b[1]+g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),t+e>k+j&&(d=k+j-t+d-e);break;case"s":c=b[0]-h/2,d=b[1]-e-g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),k>t&&(d=k);break;case"none":c=b[0],d=b[1]-g,r=v(o),t=u(o)}c-=q.left,d-=q.top;var w=o.getBoundingClientRect(),k=window.pageYOffset||document.documentElement.scrollTop,p=window.pageXOffset||document.documentElement.scrollLeft,x="translate("+(w.left+p)+"px, "+(w.top+k)+"px)",y="translate("+c+"px, "+d+"px)",z=d3.interpolateString(x,y),A=n.style("opacity")<.1;l?n.transition().delay(m).duration(0).style("opacity",0):n.interrupt().transition().duration(A?0:s).styleTween("transform",function(){return z},"important").style("-webkit-transform",y).style("opacity",1)})};return d.nvPointerEventsClass=w,d.options=a.utils.optionsFunc.bind(d),d._options=Object.create({},{duration:{get:function(){return s},set:function(a){s=a}},gravity:{get:function(){return f},set:function(a){f=a}},distance:{get:function(){return g},set:function(a){g=a}},snapDistance:{get:function(){return h},set:function(a){h=a}},classes:{get:function(){return j},set:function(a){j=a}},chartContainer:{get:function(){return k},set:function(a){k=a}},fixedTop:{get:function(){return i},set:function(a){i=a}},enabled:{get:function(){return r},set:function(a){r=a}},hideDelay:{get:function(){return m},set:function(a){m=a}},contentGenerator:{get:function(){return A},set:function(a){A=a}},valueFormatter:{get:function(){return x},set:function(a){x=a}},headerFormatter:{get:function(){return y},set:function(a){y=a}},keyFormatter:{get:function(){return z},set:function(a){z=a}},headerEnabled:{get:function(){return t},set:function(a){t=a}},_isInteractiveLayer:{get:function(){return u},set:function(a){u=!!a}},position:{get:function(){return p},set:function(a){p.left=void 0!==a.left?a.left:p.left,p.top=void 0!==a.top?a.top:p.top}},offset:{get:function(){return q},set:function(a){q.left=void 0!==a.left?a.left:q.left,q.top=void 0!==a.top?a.top:q.top}},hidden:{get:function(){return l},set:function(a){l!=a&&(l=!!a,d())}},data:{get:function(){return e},set:function(a){a.point&&(a.value=a.point.x,a.series=a.series||{},a.series.value=a.point.y,a.series.color=a.point.color||a.series.color),e=a}},tooltipElem:{get:function(){return o},set:function(){}},id:{get:function(){return v},set:function(){}}}),a.utils.initOptions(d),d}}(),a.utils.windowSize=function(){var a={width:640,height:480};return window.innerWidth&&window.innerHeight?(a.width=window.innerWidth,a.height=window.innerHeight,a):"CSS1Compat"==document.compatMode&&document.documentElement&&document.documentElement.offsetWidth?(a.width=document.documentElement.offsetWidth,a.height=document.documentElement.offsetHeight,a):document.body&&document.body.offsetWidth?(a.width=document.body.offsetWidth,a.height=document.body.offsetHeight,a):a},a.utils.windowResize=function(b){return window.addEventListener?window.addEventListener("resize",b):a.log("ERROR: Failed to bind to window.resize with: ",b),{callback:b,clear:function(){window.removeEventListener("resize",b)}}},a.utils.getColor=function(b){if(void 0===b)return a.utils.defaultColor();if(Array.isArray(b)){var c=d3.scale.ordinal().range(b);return function(a,b){var d=void 0===b?a:b;return a.color||c(d)}}return b},a.utils.defaultColor=function(){return a.utils.getColor(d3.scale.category20().range())},a.utils.customTheme=function(a,b,c){b=b||function(a){return a.key},c=c||d3.scale.category20().range();var d=c.length;return function(e){var f=b(e);return"function"==typeof a[f]?a[f]():void 0!==a[f]?a[f]:(d||(d=c.length),d-=1,c[d])}},a.utils.pjax=function(b,c){var d=function(d){d3.html(d,function(d){var e=d3.select(c).node();e.parentNode.replaceChild(d3.select(d).select(c).node(),e),a.utils.pjax(b,c)})};d3.selectAll(b).on("click",function(){history.pushState(this.href,this.textContent,this.href),d(this.href),d3.event.preventDefault()}),d3.select(window).on("popstate",function(){d3.event.state&&d(d3.event.state)})},a.utils.calcApproxTextWidth=function(a){if("function"==typeof a.style&&"function"==typeof a.text){var b=parseInt(a.style("font-size").replace("px",""),10),c=a.text().length;return c*b*.5}return 0},a.utils.NaNtoZero=function(a){return"number"!=typeof a||isNaN(a)||null===a||1/0===a||a===-1/0?0:a},d3.selection.prototype.watchTransition=function(a){var b=[this].concat([].slice.call(arguments,1));return a.transition.apply(a,b)},a.utils.renderWatch=function(b,c){if(!(this instanceof a.utils.renderWatch))return new a.utils.renderWatch(b,c);var d=void 0!==c?c:250,e=[],f=this;this.models=function(a){return a=[].slice.call(arguments,0),a.forEach(function(a){a.__rendered=!1,function(a){a.dispatch.on("renderEnd",function(){a.__rendered=!0,f.renderEnd("model")})}(a),e.indexOf(a)<0&&e.push(a)}),this},this.reset=function(a){void 0!==a&&(d=a),e=[]},this.transition=function(a,b,c){if(b=arguments.length>1?[].slice.call(arguments,1):[],c=b.length>1?b.pop():void 0!==d?d:250,a.__rendered=!1,e.indexOf(a)<0&&e.push(a),0===c)return a.__rendered=!0,a.delay=function(){return this},a.duration=function(){return this},a;a.__rendered=0===a.length?!0:a.every(function(a){return!a.length})?!0:!1;var g=0;return a.transition().duration(c).each(function(){++g}).each("end",function(){0===--g&&(a.__rendered=!0,f.renderEnd.apply(this,b))})},this.renderEnd=function(){e.every(function(a){return a.__rendered})&&(e.forEach(function(a){a.__rendered=!1}),b.renderEnd.apply(this,arguments))}},a.utils.deepExtend=function(b){var c=arguments.length>1?[].slice.call(arguments,1):[];c.forEach(function(c){for(var d in c){var e=b[d]instanceof Array,f="object"==typeof b[d],g="object"==typeof c[d];f&&!e&&g?a.utils.deepExtend(b[d],c[d]):b[d]=c[d]}})},a.utils.state=function(){if(!(this instanceof a.utils.state))return new a.utils.state;var b={},c=function(){},d=function(){return{}},e=null,f=null;this.dispatch=d3.dispatch("change","set"),this.dispatch.on("set",function(a){c(a,!0)}),this.getter=function(a){return d=a,this},this.setter=function(a,b){return b||(b=function(){}),c=function(c,d){a(c),d&&b()},this},this.init=function(b){e=e||{},a.utils.deepExtend(e,b)};var g=function(){var a=d();if(JSON.stringify(a)===JSON.stringify(b))return!1;for(var c in a)void 0===b[c]&&(b[c]={}),b[c]=a[c],f=!0;return!0};this.update=function(){e&&(c(e,!1),e=null),g.call(this)&&this.dispatch.change(b)}},a.utils.optionsFunc=function(a){return a&&d3.map(a).forEach(function(a,b){"function"==typeof this[a]&&this[a](b)}.bind(this)),this},a.utils.calcTicksX=function(b,c){var d=1,e=0;for(e;e<c.length;e+=1){var f=c[e]&&c[e].values?c[e].values.length:0;d=f>d?f:d}return a.log("Requested number of ticks: ",b),a.log("Calculated max values to be: ",d),b=b>d?b=d-1:b,b=1>b?1:b,b=Math.floor(b),a.log("Calculating tick count as: ",b),b},a.utils.calcTicksY=function(b,c){return a.utils.calcTicksX(b,c)},a.utils.initOption=function(a,b){a._calls&&a._calls[b]?a[b]=a._calls[b]:(a[b]=function(c){return arguments.length?(a._overrides[b]=!0,a._options[b]=c,a):a._options[b]},a["_"+b]=function(c){return arguments.length?(a._overrides[b]||(a._options[b]=c),a):a._options[b]})},a.utils.initOptions=function(b){b._overrides=b._overrides||{};var c=Object.getOwnPropertyNames(b._options||{}),d=Object.getOwnPropertyNames(b._calls||{});c=c.concat(d);for(var e in c)a.utils.initOption(b,c[e])},a.utils.inheritOptionsD3=function(a,b,c){a._d3options=c.concat(a._d3options||[]),c.unshift(b),c.unshift(a),d3.rebind.apply(this,c)},a.utils.arrayUnique=function(a){return a.sort().filter(function(b,c){return!c||b!=a[c-1]})},a.utils.symbolMap=d3.map(),a.utils.symbol=function(){function b(b,e){var f=c.call(this,b,e),g=d.call(this,b,e);return-1!==d3.svg.symbolTypes.indexOf(f)?d3.svg.symbol().type(f).size(g)():a.utils.symbolMap.get(f)(g)}var c,d=64;return b.type=function(a){return arguments.length?(c=d3.functor(a),b):c},b.size=function(a){return arguments.length?(d=d3.functor(a),b):d},b},a.utils.inheritOptions=function(b,c){var d=Object.getOwnPropertyNames(c._options||{}),e=Object.getOwnPropertyNames(c._calls||{}),f=c._inherited||[],g=c._d3options||[],h=d.concat(e).concat(f).concat(g);h.unshift(c),h.unshift(b),d3.rebind.apply(this,h),b._inherited=a.utils.arrayUnique(d.concat(e).concat(f).concat(d).concat(b._inherited||[])),b._d3options=a.utils.arrayUnique(g.concat(b._d3options||[]))},a.utils.initSVG=function(a){a.classed({"nvd3-svg":!0})},a.utils.sanitizeHeight=function(a,b){return a||parseInt(b.style("height"),10)||400},a.utils.sanitizeWidth=function(a,b){return a||parseInt(b.style("width"),10)||960},a.utils.availableHeight=function(b,c,d){return a.utils.sanitizeHeight(b,c)-d.top-d.bottom},a.utils.availableWidth=function(b,c,d){return a.utils.sanitizeWidth(b,c)-d.left-d.right},a.utils.noData=function(b,c){var d=b.options(),e=d.margin(),f=d.noData(),g=null==f?["No Data Available."]:[f],h=a.utils.availableHeight(d.height(),c,e),i=a.utils.availableWidth(d.width(),c,e),j=e.left+i/2,k=e.top+h/2;c.selectAll("g").remove();var l=c.selectAll(".nv-noData").data(g);l.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),l.attr("x",j).attr("y",k).text(function(a){return a})},a.models.axis=function(){"use strict";function b(g){return s.reset(),g.each(function(b){var g=d3.select(this);a.utils.initSVG(g);var p=g.selectAll("g.nv-wrap.nv-axis").data([b]),q=p.enter().append("g").attr("class","nvd3 nv-wrap nv-axis"),t=(q.append("g"),p.select("g"));null!==n?c.ticks(n):("top"==c.orient()||"bottom"==c.orient())&&c.ticks(Math.abs(d.range()[1]-d.range()[0])/100),t.watchTransition(s,"axis").call(c),r=r||c.scale();var u=c.tickFormat();null==u&&(u=r.tickFormat());var v=t.selectAll("text.nv-axislabel").data([h||null]);v.exit().remove();var w,x,y;switch(c.orient()){case"top":v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",0).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b))+",0)"}).select("text").attr("dy","-0.5em").attr("y",-c.tickPadding()).attr("text-anchor","middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max top").attr("transform",function(b,c){return"translate("+a.utils.NaNtoZero(d.range()[c])+",0)"}));break;case"bottom":w=o+36;var z=30,A=0,B=t.selectAll("g").select("text"),C="";if(j%360){B.each(function(){var a=this.getBoundingClientRect(),b=a.width;A=a.height,b>z&&(z=b)}),C="rotate("+j+" 0,"+(A/2+c.tickPadding())+")";var D=Math.abs(Math.sin(j*Math.PI/180));w=(D?D*z:z)+30,B.attr("transform",C).style("text-anchor",j%360>0?"start":"end")}v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",w).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data([d.domain()[0],d.domain()[d.domain().length-1]]),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",c.tickPadding()).attr("transform",C).style("text-anchor",j?j%360>0?"start":"end":"middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max bottom").attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"})),l&&B.attr("transform",function(a,b){return"translate(0,"+(b%2==0?"0":"12")+")"});break;case"right":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"begin").attr("transform",k?"rotate(90)":"").attr("y",k?-Math.max(e.right,f)+12:-10).attr("x",k?d3.max(d.range())/2:c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(d(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",c.tickPadding()).style("text-anchor","start").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1));break;case"left":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"end").attr("transform",k?"rotate(-90)":"").attr("y",k?-Math.max(e.left,f)+25-(o||0):-10).attr("x",k?-d3.max(d.range())/2:-c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(r(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-c.tickPadding()).attr("text-anchor","end").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1))}if(v.text(function(a){return a}),!i||"left"!==c.orient()&&"right"!==c.orient()||(t.selectAll("g").each(function(a){d3.select(this).select("text").attr("opacity",1),(d(a)<d.range()[1]+10||d(a)>d.range()[0]-10)&&((a>1e-10||-1e-10>a)&&d3.select(this).attr("opacity",0),d3.select(this).select("text").attr("opacity",0))}),d.domain()[0]==d.domain()[1]&&0==d.domain()[0]&&p.selectAll("g.nv-axisMaxMin").style("opacity",function(a,b){return b?0:1})),i&&("top"===c.orient()||"bottom"===c.orient())){var E=[];p.selectAll("g.nv-axisMaxMin").each(function(a,b){try{E.push(b?d(a)-this.getBoundingClientRect().width-4:d(a)+this.getBoundingClientRect().width+4)}catch(c){E.push(b?d(a)-4:d(a)+4)}}),t.selectAll("g").each(function(a){(d(a)<E[0]||d(a)>E[1])&&(a>1e-10||-1e-10>a?d3.select(this).remove():d3.select(this).select("text").remove())})}t.selectAll(".tick").filter(function(a){return!parseFloat(Math.round(1e5*a)/1e6)&&void 0!==a}).classed("zero",!0),r=d.copy()}),s.renderEnd("axis immediate"),b}var c=d3.svg.axis(),d=d3.scale.linear(),e={top:0,right:0,bottom:0,left:0},f=75,g=60,h=null,i=!0,j=0,k=!0,l=!1,m=!1,n=null,o=0,p=250,q=d3.dispatch("renderEnd");c.scale(d).orient("bottom").tickFormat(function(a){return a});var r,s=a.utils.renderWatch(q,p);return b.axis=c,b.dispatch=q,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{axisLabelDistance:{get:function(){return o},set:function(a){o=a}},staggerLabels:{get:function(){return l},set:function(a){l=a}},rotateLabels:{get:function(){return j},set:function(a){j=a}},rotateYLabel:{get:function(){return k},set:function(a){k=a}},showMaxMin:{get:function(){return i},set:function(a){i=a}},axisLabel:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return g},set:function(a){g=a}},ticks:{get:function(){return n},set:function(a){n=a}},width:{get:function(){return f},set:function(a){f=a}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},duration:{get:function(){return p},set:function(a){p=a,s.reset(p)}},scale:{get:function(){return d},set:function(e){d=e,c.scale(d),m="function"==typeof d.rangeBands,a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"])}}}),a.utils.initOptions(b),a.utils.inheritOptionsD3(b,c,["orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"]),a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"]),b},a.models.boxPlot=function(){"use strict";function b(l){return v.reset(),l.each(function(b){var l=j-i.left-i.right,p=k-i.top-i.bottom;r=d3.select(this),a.utils.initSVG(r),m.domain(c||b.map(function(a,b){return o(a,b)})).rangeBands(e||[0,l],.1);var w=[];if(!d){var x=d3.min(b.map(function(a){var b=[];return b.push(a.values.Q1),a.values.hasOwnProperty("whisker_low")&&null!==a.values.whisker_low&&b.push(a.values.whisker_low),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.min(b)})),y=d3.max(b.map(function(a){var b=[];return b.push(a.values.Q3),a.values.hasOwnProperty("whisker_high")&&null!==a.values.whisker_high&&b.push(a.values.whisker_high),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.max(b)}));w=[x,y]}n.domain(d||w),n.range(f||[p,0]),g=g||m,h=h||n.copy().range([n(0),n(0)]);{var z=r.selectAll("g.nv-wrap").data([b]);z.enter().append("g").attr("class","nvd3 nv-wrap")}z.attr("transform","translate("+i.left+","+i.top+")");var A=z.selectAll(".nv-boxplot").data(function(a){return a}),B=A.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);A.attr("class","nv-boxplot").attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}).classed("hover",function(a){return a.hover}),A.watchTransition(v,"nv-boxplot: boxplots").style("stroke-opacity",1).style("fill-opacity",.75).delay(function(a,c){return c*t/b.length}).attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}),A.exit().remove(),B.each(function(a,b){var c=d3.select(this);["low","high"].forEach(function(d){a.values.hasOwnProperty("whisker_"+d)&&null!==a.values["whisker_"+d]&&(c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-whisker nv-boxplot-"+d),c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-tick nv-boxplot-"+d))})});var C=A.selectAll(".nv-boxplot-outlier").data(function(a){return a.values.hasOwnProperty("outliers")&&null!==a.values.outliers?a.values.outliers:[]});C.enter().append("circle").style("fill",function(a,b,c){return q(a,c)}).style("stroke",function(a,b,c){return q(a,c)}).on("mouseover",function(a,b,c){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:a,color:q(a,c)},e:d3.event})}).on("mouseout",function(a,b,c){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:a,color:q(a,c)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),C.attr("class","nv-boxplot-outlier"),C.watchTransition(v,"nv-boxplot: nv-boxplot-outlier").attr("cx",.45*m.rangeBand()).attr("cy",function(a){return n(a)}).attr("r","3"),C.exit().remove();var D=function(){return null===u?.9*m.rangeBand():Math.min(75,.9*m.rangeBand())},E=function(){return.45*m.rangeBand()-D()/2},F=function(){return.45*m.rangeBand()+D()/2};["low","high"].forEach(function(a){var b="low"===a?"Q1":"Q3";A.select("line.nv-boxplot-whisker.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",.45*m.rangeBand()).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",.45*m.rangeBand()).attr("y2",function(a){return n(a.values[b])}),A.select("line.nv-boxplot-tick.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",E).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",F).attr("y2",function(b){return n(b.values["whisker_"+a])})}),["low","high"].forEach(function(a){B.selectAll(".nv-boxplot-"+a).on("mouseover",function(b,c,d){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mouseout",function(b,c,d){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})})}),B.append("rect").attr("class","nv-boxplot-box").on("mouseover",function(a,b){d3.select(this).classed("hover",!0),s.elementMouseover({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),s.elementMouseout({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),A.select("rect.nv-boxplot-box").watchTransition(v,"nv-boxplot: boxes").attr("y",function(a){return n(a.values.Q3)}).attr("width",D).attr("x",E).attr("height",function(a){return Math.abs(n(a.values.Q3)-n(a.values.Q1))||1}).style("fill",function(a,b){return a.color||q(a,b)}).style("stroke",function(a,b){return a.color||q(a,b)}),B.append("line").attr("class","nv-boxplot-median"),A.select("line.nv-boxplot-median").watchTransition(v,"nv-boxplot: boxplots line").attr("x1",E).attr("y1",function(a){return n(a.values.Q2)}).attr("x2",F).attr("y2",function(a){return n(a.values.Q2)}),g=m.copy(),h=n.copy()}),v.renderEnd("nv-boxplot immediate"),b}var c,d,e,f,g,h,i={top:0,right:0,bottom:0,left:0},j=960,k=500,l=Math.floor(1e4*Math.random()),m=d3.scale.ordinal(),n=d3.scale.linear(),o=function(a){return a.x},p=function(a){return a.y},q=a.utils.defaultColor(),r=null,s=d3.dispatch("elementMouseover","elementMouseout","elementMousemove","renderEnd"),t=250,u=null,v=a.utils.renderWatch(s,t);return b.dispatch=s,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},maxBoxWidth:{get:function(){return u},set:function(a){u=a}},x:{get:function(){return o},set:function(a){o=a}},y:{get:function(){return p},set:function(a){p=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return l},set:function(a){l=a}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}},duration:{get:function(){return t},set:function(a){t=a,v.reset(t)}}}),a.utils.initOptions(b),b},a.models.boxPlotChart=function(){"use strict";function b(k){return t.reset(),t.models(e),l&&t.models(f),m&&t.models(g),k.each(function(k){var p=d3.select(this);a.utils.initSVG(p);var t=(i||parseInt(p.style("width"))||960)-h.left-h.right,u=(j||parseInt(p.style("height"))||400)-h.top-h.bottom;if(b.update=function(){r.beforeUpdate(),p.transition().duration(s).call(b)},b.container=this,!(k&&k.length&&k.filter(function(a){return a.values.hasOwnProperty("Q1")&&a.values.hasOwnProperty("Q2")&&a.values.hasOwnProperty("Q3")}).length)){var v=p.selectAll(".nv-noData").data([q]);return v.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),v.attr("x",h.left+t/2).attr("y",h.top+u/2).text(function(a){return a}),b}p.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var w=p.selectAll("g.nv-wrap.nv-boxPlotWithAxes").data([k]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-boxPlotWithAxes").append("g"),y=x.append("defs"),z=w.select("g");
  19306. x.append("g").attr("class","nv-x nv-axis"),x.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),x.append("g").attr("class","nv-barsWrap"),z.attr("transform","translate("+h.left+","+h.top+")"),n&&z.select(".nv-y.nv-axis").attr("transform","translate("+t+",0)"),e.width(t).height(u);var A=z.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));if(A.transition().call(e),y.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),z.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(o?2:1)).attr("height",16).attr("x",-c.rangeBand()/(o?1:2)),l){f.scale(c).ticks(a.utils.calcTicksX(t/100,k)).tickSize(-u,0),z.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),z.select(".nv-x.nv-axis").call(f);var B=z.select(".nv-x.nv-axis").selectAll("g");o&&B.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}m&&(g.scale(d).ticks(Math.floor(u/36)).tickSize(-t,0),z.select(".nv-y.nv-axis").call(g)),z.select(".nv-zeroLine line").attr("x1",0).attr("x2",t).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("nv-boxplot chart immediate"),b}var c,d,e=a.models.boxPlot(),f=a.models.axis(),g=a.models.axis(),h={top:15,right:10,bottom:50,left:60},i=null,j=null,k=a.utils.getColor(),l=!0,m=!0,n=!1,o=!1,p=a.models.tooltip(),q="No Data Available.",r=d3.dispatch("tooltipShow","tooltipHide","beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(n?"right":"left").tickFormat(d3.format(",.1f")),p.duration(0);var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){p.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(a){p.data(a).hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){p.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.boxplot=e,b.xAxis=f,b.yAxis=g,b.tooltip=p,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},staggerLabels:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return l},set:function(a){l=a}},showYAxis:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return tooltips},set:function(a){tooltips=a}},tooltipContent:{get:function(){return p},set:function(a){p=a}},noData:{get:function(){return q},set:function(a){q=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!==a.top?a.top:h.top,h.right=void 0!==a.right?a.right:h.right,h.bottom=void 0!==a.bottom?a.bottom:h.bottom,h.left=void 0!==a.left?a.left:h.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}},rightAlignYAxis:{get:function(){return n},set:function(a){n=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.bullet=function(){"use strict";function b(d){return d.each(function(b,d){var p=m-c.left-c.right,s=n-c.top-c.bottom;o=d3.select(this),a.utils.initSVG(o);{var t=f.call(this,b,d).slice().sort(d3.descending),u=g.call(this,b,d).slice().sort(d3.descending),v=h.call(this,b,d).slice().sort(d3.descending),w=i.call(this,b,d).slice(),x=j.call(this,b,d).slice(),y=k.call(this,b,d).slice(),z=d3.scale.linear().domain(d3.extent(d3.merge([l,t]))).range(e?[p,0]:[0,p]);this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range())}this.__chart__=z;var A=d3.min(t),B=d3.max(t),C=t[1],D=o.selectAll("g.nv-wrap.nv-bullet").data([b]),E=D.enter().append("g").attr("class","nvd3 nv-wrap nv-bullet"),F=E.append("g"),G=D.select("g");F.append("rect").attr("class","nv-range nv-rangeMax"),F.append("rect").attr("class","nv-range nv-rangeAvg"),F.append("rect").attr("class","nv-range nv-rangeMin"),F.append("rect").attr("class","nv-measure"),D.attr("transform","translate("+c.left+","+c.top+")");var H=function(a){return Math.abs(z(a)-z(0))},I=function(a){return z(0>a?a:0)};G.select("rect.nv-rangeMax").attr("height",s).attr("width",H(B>0?B:A)).attr("x",I(B>0?B:A)).datum(B>0?B:A),G.select("rect.nv-rangeAvg").attr("height",s).attr("width",H(C)).attr("x",I(C)).datum(C),G.select("rect.nv-rangeMin").attr("height",s).attr("width",H(B)).attr("x",I(B)).attr("width",H(B>0?A:B)).attr("x",I(B>0?A:B)).datum(B>0?A:B),G.select("rect.nv-measure").style("fill",q).attr("height",s/3).attr("y",s/3).attr("width",0>v?z(0)-z(v[0]):z(v[0])-z(0)).attr("x",I(v)).on("mouseover",function(){r.elementMouseover({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mouseout",function(){r.elementMouseout({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})});var J=s/6,K=u.map(function(a,b){return{value:a,label:x[b]}});F.selectAll("path.nv-markerTriangle").data(K).enter().append("path").attr("class","nv-markerTriangle").attr("transform",function(a){return"translate("+z(a.value)+","+s/2+")"}).attr("d","M0,"+J+"L"+J+","+-J+" "+-J+","+-J+"Z").on("mouseover",function(a){r.elementMouseover({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill"),pos:[z(a.value),s/2]})}).on("mousemove",function(a){r.elementMousemove({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a){r.elementMouseout({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}),D.selectAll(".nv-range").on("mouseover",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseover({value:a,label:c,color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseout({value:a,label:c,color:d3.select(this).style("fill")})})}),b}var c={top:0,right:0,bottom:0,left:0},d="left",e=!1,f=function(a){return a.ranges},g=function(a){return a.markers?a.markers:[0]},h=function(a){return a.measures},i=function(a){return a.rangeLabels?a.rangeLabels:[]},j=function(a){return a.markerLabels?a.markerLabels:[]},k=function(a){return a.measureLabels?a.measureLabels:[]},l=[0],m=380,n=30,o=null,p=null,q=a.utils.getColor(["#1f77b4"]),r=d3.dispatch("elementMouseover","elementMouseout","elementMousemove");return b.dispatch=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return f},set:function(a){f=a}},markers:{get:function(){return g},set:function(a){g=a}},measures:{get:function(){return h},set:function(a){h=a}},forceX:{get:function(){return l},set:function(a){l=a}},width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},tickFormat:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},orient:{get:function(){return d},set:function(a){d=a,e="right"==d||"bottom"==d}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.bulletChart=function(){"use strict";function b(d){return d.each(function(e,o){var p=d3.select(this);a.utils.initSVG(p);var q=a.utils.availableWidth(k,p,g),r=l-g.top-g.bottom;if(b.update=function(){b(d)},b.container=this,!e||!h.call(this,e,o))return a.utils.noData(b,p),b;p.selectAll(".nv-noData").remove();var s=h.call(this,e,o).slice().sort(d3.descending),t=i.call(this,e,o).slice().sort(d3.descending),u=j.call(this,e,o).slice().sort(d3.descending),v=p.selectAll("g.nv-wrap.nv-bulletChart").data([e]),w=v.enter().append("g").attr("class","nvd3 nv-wrap nv-bulletChart"),x=w.append("g"),y=v.select("g");x.append("g").attr("class","nv-bulletWrap"),x.append("g").attr("class","nv-titles"),v.attr("transform","translate("+g.left+","+g.top+")");var z=d3.scale.linear().domain([0,Math.max(s[0],t[0],u[0])]).range(f?[q,0]:[0,q]),A=this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range());this.__chart__=z;var B=x.select(".nv-titles").append("g").attr("text-anchor","end").attr("transform","translate(-6,"+(l-g.top-g.bottom)/2+")");B.append("text").attr("class","nv-title").text(function(a){return a.title}),B.append("text").attr("class","nv-subtitle").attr("dy","1em").text(function(a){return a.subtitle}),c.width(q).height(r);var C=y.select(".nv-bulletWrap");d3.transition(C).call(c);var D=m||z.tickFormat(q/100),E=y.selectAll("g.nv-tick").data(z.ticks(n?n:q/50),function(a){return this.textContent||D(a)}),F=E.enter().append("g").attr("class","nv-tick").attr("transform",function(a){return"translate("+A(a)+",0)"}).style("opacity",1e-6);F.append("line").attr("y1",r).attr("y2",7*r/6),F.append("text").attr("text-anchor","middle").attr("dy","1em").attr("y",7*r/6).text(D);var G=d3.transition(E).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1);G.select("line").attr("y1",r).attr("y2",7*r/6),G.select("text").attr("y",7*r/6),d3.transition(E.exit()).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1e-6).remove()}),d3.timer.flush(),b}var c=a.models.bullet(),d=a.models.tooltip(),e="left",f=!1,g={top:5,right:40,bottom:20,left:120},h=function(a){return a.ranges},i=function(a){return a.markers?a.markers:[0]},j=function(a){return a.measures},k=null,l=55,m=null,n=null,o=null,p=d3.dispatch("tooltipShow","tooltipHide");return d.duration(0).headerEnabled(!1),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.label,value:a.value,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.bullet=c,b.dispatch=p,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return h},set:function(a){h=a}},markers:{get:function(){return i},set:function(a){i=a}},measures:{get:function(){return j},set:function(a){j=a}},width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},tickFormat:{get:function(){return m},set:function(a){m=a}},ticks:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return o},set:function(a){o=a}},tooltips:{get:function(){return d.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),d.enabled(!!b)}},tooltipContent:{get:function(){return d.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),d.contentGenerator(b)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},orient:{get:function(){return e},set:function(a){e=a,f="right"==e||"bottom"==e}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.candlestickBar=function(){"use strict";function b(x){return x.each(function(b){c=d3.select(this);var x=a.utils.availableWidth(i,c,h),y=a.utils.availableHeight(j,c,h);a.utils.initSVG(c);var A=x/b[0].values.length*.45;l.domain(d||d3.extent(b[0].values.map(n).concat(t))),l.range(v?f||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:f||[5+A/2,x-A/2-5]),m.domain(e||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(g||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var B=d3.select(this).selectAll("g.nv-wrap.nv-candlestickBar").data([b[0].values]),C=B.enter().append("g").attr("class","nvd3 nv-wrap nv-candlestickBar"),D=C.append("defs"),E=C.append("g"),F=B.select("g");E.append("g").attr("class","nv-ticks"),B.attr("transform","translate("+h.left+","+h.top+")"),c.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:k})}),D.append("clipPath").attr("id","nv-chart-clip-path-"+k).append("rect"),B.select("#nv-chart-clip-path-"+k+" rect").attr("width",x).attr("height",y),F.attr("clip-path",w?"url(#nv-chart-clip-path-"+k+")":"");var G=B.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});G.exit().remove();{var H=G.enter().append("g").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b});H.append("line").attr("class","nv-candlestick-lines").attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),H.append("rect").attr("class","nv-candlestick-rects nv-bars").attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}c.selectAll(".nv-candlestick-lines").transition().attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),c.selectAll(".nv-candlestick-rects").transition().attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}),b}var c,d,e,f,g,h={top:0,right:0,bottom:0,left:0},i=null,j=null,k=Math.floor(1e4*Math.random()),l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,d){b.clearHighlights(),c.select(".nv-candlestickBar .nv-tick-0-"+a).classed("hover",d)},b.clearHighlights=function(){c.select(".nv-candlestickBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return k},set:function(a){k=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!=a.top?a.top:h.top,h.right=void 0!=a.right?a.right:h.right,h.bottom=void 0!=a.bottom?a.bottom:h.bottom,h.left=void 0!=a.left?a.left:h.left}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.cumulativeLineChart=function(){"use strict";function b(l){return H.reset(),H.models(f),r&&H.models(g),s&&H.models(h),l.each(function(l){function A(){d3.select(b.container).style("cursor","ew-resize")}function E(){G.x=d3.event.x,G.i=Math.round(F.invert(G.x)),K()}function H(){d3.select(b.container).style("cursor","auto"),y.index=G.i,C.stateChange(y)}function K(){bb.data([G]);var a=b.duration();b.duration(0),b.update(),b.duration(a)}var L=d3.select(this);a.utils.initSVG(L),L.classed("nv-chart-"+x,!0);var M=this,N=a.utils.availableWidth(o,L,m),O=a.utils.availableHeight(p,L,m);if(b.update=function(){0===D?L.call(b):L.transition().duration(D).call(b)},b.container=this,y.setter(J(l),b.update).getter(I(l)).update(),y.disabled=l.map(function(a){return!!a.disabled}),!z){var P;z={};for(P in y)z[P]=y[P]instanceof Array?y[P].slice(0):y[P]}var Q=d3.behavior.drag().on("dragstart",A).on("drag",E).on("dragend",H);if(!(l&&l.length&&l.filter(function(a){return a.values.length}).length))return a.utils.noData(b,L),b;if(L.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale(),w)f.yDomain(null);else{var R=l.filter(function(a){return!a.disabled}).map(function(a){var b=d3.extent(a.values,f.y());return b[0]<-.95&&(b[0]=-.95),[(b[0]-b[1])/(1+b[1]),(b[1]-b[0])/(1+b[0])]}),S=[d3.min(R,function(a){return a[0]}),d3.max(R,function(a){return a[1]})];f.yDomain(S)}F.domain([0,l[0].values.length-1]).range([0,N]).clamp(!0);var l=c(G.i,l),T=v?"none":"all",U=L.selectAll("g.nv-wrap.nv-cumulativeLine").data([l]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-cumulativeLine").append("g"),W=U.select("g");if(V.append("g").attr("class","nv-interactive"),V.append("g").attr("class","nv-x nv-axis").style("pointer-events","none"),V.append("g").attr("class","nv-y nv-axis"),V.append("g").attr("class","nv-background"),V.append("g").attr("class","nv-linesWrap").style("pointer-events",T),V.append("g").attr("class","nv-avgLinesWrap").style("pointer-events","none"),V.append("g").attr("class","nv-legendWrap"),V.append("g").attr("class","nv-controlsWrap"),q&&(i.width(N),W.select(".nv-legendWrap").datum(l).call(i),m.top!=i.height()&&(m.top=i.height(),O=a.utils.availableHeight(p,L,m)),W.select(".nv-legendWrap").attr("transform","translate(0,"+-m.top+")")),u){var X=[{key:"Re-scale y-axis",disabled:!w}];j.width(140).color(["#444","#444","#444"]).rightAlign(!1).margin({top:5,right:0,bottom:5,left:20}),W.select(".nv-controlsWrap").datum(X).attr("transform","translate(0,"+-m.top+")").call(j)}U.attr("transform","translate("+m.left+","+m.top+")"),t&&W.select(".nv-y.nv-axis").attr("transform","translate("+N+",0)");var Y=l.filter(function(a){return a.tempDisabled});U.select(".tempDisabled").remove(),Y.length&&U.append("text").attr("class","tempDisabled").attr("x",N/2).attr("y","-.71em").style("text-anchor","end").text(Y.map(function(a){return a.key}).join(", ")+" values cannot be calculated for this time period."),v&&(k.width(N).height(O).margin({left:m.left,top:m.top}).svgContainer(L).xScale(d),U.select(".nv-interactive").call(k)),V.select(".nv-background").append("rect"),W.select(".nv-background rect").attr("width",N).attr("height",O),f.y(function(a){return a.display.y}).width(N).height(O).color(l.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!l[b].disabled&&!l[b].tempDisabled}));var Z=W.select(".nv-linesWrap").datum(l.filter(function(a){return!a.disabled&&!a.tempDisabled}));Z.call(f),l.forEach(function(a,b){a.seriesIndex=b});var $=l.filter(function(a){return!a.disabled&&!!B(a)}),_=W.select(".nv-avgLinesWrap").selectAll("line").data($,function(a){return a.key}),ab=function(a){var b=e(B(a));return 0>b?0:b>O?O:b};_.enter().append("line").style("stroke-width",2).style("stroke-dasharray","10,10").style("stroke",function(a){return f.color()(a,a.seriesIndex)}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.style("stroke-opacity",function(a){var b=e(B(a));return 0>b||b>O?0:1}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.exit().remove();var bb=Z.selectAll(".nv-indexLine").data([G]);bb.enter().append("rect").attr("class","nv-indexLine").attr("width",3).attr("x",-2).attr("fill","red").attr("fill-opacity",.5).style("pointer-events","all").call(Q),bb.attr("transform",function(a){return"translate("+F(a.i)+",0)"}).attr("height",O),r&&(g.scale(d)._ticks(a.utils.calcTicksX(N/70,l)).tickSize(-O,0),W.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),W.select(".nv-x.nv-axis").call(g)),s&&(h.scale(e)._ticks(a.utils.calcTicksY(O/36,l)).tickSize(-N,0),W.select(".nv-y.nv-axis").call(h)),W.select(".nv-background rect").on("click",function(){G.x=d3.mouse(this)[0],G.i=Math.round(F.invert(G.x)),y.index=G.i,C.stateChange(y),K()}),f.dispatch.on("elementClick",function(a){G.i=a.pointIndex,G.x=F(G.i),y.index=G.i,C.stateChange(y),K()}),j.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,w=!a.disabled,y.rescaleY=w,C.stateChange(y),b.update()}),i.dispatch.on("stateChange",function(a){for(var c in a)y[c]=a[c];C.stateChange(y),b.update()}),k.dispatch.on("elementMousemove",function(c){f.clearHighlights();var d,e,i,j=[];if(l.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g,h){e=a.interactiveBisect(g.values,c.pointXValue,b.x()),f.highlightPoint(h,e,!0);var k=g.values[e];"undefined"!=typeof k&&("undefined"==typeof d&&(d=k),"undefined"==typeof i&&(i=b.xScale()(b.x()(k,e))),j.push({key:g.key,value:b.y()(k,e),color:n(g,g.seriesIndex)}))}),j.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(j.map(function(a){return a.value}),o,q);null!==r&&(j[r].highlight=!0)}var s=g.tickFormat()(b.x()(d,e),e);k.tooltip.position({left:i+m.left,top:c.mouseY+m.top}).chartContainer(M.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:s,series:j})(),k.renderGuideLine(i)}),k.dispatch.on("elementMouseout",function(){f.clearHighlights()}),C.on("changeState",function(a){"undefined"!=typeof a.disabled&&(l.forEach(function(b,c){b.disabled=a.disabled[c]}),y.disabled=a.disabled),"undefined"!=typeof a.index&&(G.i=a.index,G.x=F(G.i),y.index=a.index,bb.data([G])),"undefined"!=typeof a.rescaleY&&(w=a.rescaleY),b.update()})}),H.renderEnd("cumulativeLineChart immediate"),b}function c(a,b){return K||(K=f.y()),b.map(function(b){if(!b.values)return b;var c=b.values[a];if(null==c)return b;var d=K(c,a);return-.95>d&&!E?(b.tempDisabled=!0,b):(b.tempDisabled=!1,b.values=b.values.map(function(a,b){return a.display={y:(K(a,b)-d)/(1+d)},a}),b)})}var d,e,f=a.models.line(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.models.legend(),k=a.interactiveGuideline(),l=a.models.tooltip(),m={top:30,right:30,bottom:50,left:60},n=a.utils.defaultColor(),o=null,p=null,q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=!0,x=f.id(),y=a.utils.state(),z=null,A=null,B=function(a){return a.average},C=d3.dispatch("stateChange","changeState","renderEnd"),D=250,E=!1;y.index=0,y.rescaleY=w,g.orient("bottom").tickPadding(7),h.orient(t?"right":"left"),l.valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)}),j.updateState(!1);var F=d3.scale.linear(),G={i:0,x:0},H=a.utils.renderWatch(C,D),I=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),index:G.i,rescaleY:w}}},J=function(a){return function(b){void 0!==b.index&&(G.i=b.index),void 0!==b.rescaleY&&(w=b.rescaleY),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};f.dispatch.on("elementMouseover.tooltip",function(a){var c={x:b.x()(a.point),y:b.y()(a.point),color:a.point.color};a.point=c,l.data(a).position(a.pos).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){l.hidden(!0)});var K=null;return b.dispatch=C,b.lines=f,b.legend=i,b.controls=j,b.xAxis=g,b.yAxis=h,b.interactiveLayer=k,b.state=y,b.tooltip=l,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return o},set:function(a){o=a}},height:{get:function(){return p},set:function(a){p=a}},rescaleY:{get:function(){return w},set:function(a){w=a}},showControls:{get:function(){return u},set:function(a){u=a}},showLegend:{get:function(){return q},set:function(a){q=a}},average:{get:function(){return B},set:function(a){B=a}},defaultState:{get:function(){return z},set:function(a){z=a}},noData:{get:function(){return A},set:function(a){A=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},noErrorCheck:{get:function(){return E},set:function(a){E=a}},tooltips:{get:function(){return l.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),l.enabled(!!b)}},tooltipContent:{get:function(){return l.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),l.contentGenerator(b)}},margin:{get:function(){return m},set:function(a){m.top=void 0!==a.top?a.top:m.top,m.right=void 0!==a.right?a.right:m.right,m.bottom=void 0!==a.bottom?a.bottom:m.bottom,m.left=void 0!==a.left?a.left:m.left}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),i.color(n)}},useInteractiveGuideline:{get:function(){return v},set:function(a){v=a,a===!0&&(b.interactive(!1),b.useVoronoi(!1))}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,h.orient(a?"right":"left")}},duration:{get:function(){return D},set:function(a){D=a,f.duration(D),g.duration(D),h.duration(D),H.reset(D)}}}),a.utils.inheritOptions(b,f),a.utils.initOptions(b),b},a.models.discreteBar=function(){"use strict";function b(m){return y.reset(),m.each(function(b){var m=k-j.left-j.right,x=l-j.top-j.bottom;c=d3.select(this),a.utils.initSVG(c),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var z=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),y0:a.y0}})});n.domain(d||d3.merge(z).map(function(a){return a.x})).rangeBands(f||[0,m],.1),o.domain(e||d3.extent(d3.merge(z).map(function(a){return a.y}).concat(r))),o.range(t?g||[x-(o.domain()[0]<0?12:0),o.domain()[1]>0?12:0]:g||[x,0]),h=h||n,i=i||o.copy().range([o(0),o(0)]);{var A=c.selectAll("g.nv-wrap.nv-discretebar").data([b]),B=A.enter().append("g").attr("class","nvd3 nv-wrap nv-discretebar"),C=B.append("g");A.select("g")}C.append("g").attr("class","nv-groups"),A.attr("transform","translate("+j.left+","+j.top+")");var D=A.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});D.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),D.exit().watchTransition(y,"discreteBar: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),D.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),D.watchTransition(y,"discreteBar: groups").style("stroke-opacity",1).style("fill-opacity",.75);var E=D.selectAll("g.nv-bar").data(function(a){return a.values});E.exit().remove();var F=E.enter().append("g").attr("transform",function(a,b){return"translate("+(n(p(a,b))+.05*n.rangeBand())+", "+o(0)+")"}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),v.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),v.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){v.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){v.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()});F.append("rect").attr("height",0).attr("width",.9*n.rangeBand()/b.length),t?(F.append("text").attr("text-anchor","middle"),E.select("text").text(function(a,b){return u(q(a,b))}).watchTransition(y,"discreteBar: bars text").attr("x",.9*n.rangeBand()/2).attr("y",function(a,b){return q(a,b)<0?o(q(a,b))-o(0)+12:-4})):E.selectAll("text").remove(),E.attr("class",function(a,b){return q(a,b)<0?"nv-bar negative":"nv-bar positive"}).style("fill",function(a,b){return a.color||s(a,b)}).style("stroke",function(a,b){return a.color||s(a,b)}).select("rect").attr("class",w).watchTransition(y,"discreteBar: bars rect").attr("width",.9*n.rangeBand()/b.length),E.watchTransition(y,"discreteBar: bars").attr("transform",function(a,b){var c=n(p(a,b))+.05*n.rangeBand(),d=q(a,b)<0?o(0):o(0)-o(q(a,b))<1?o(0)-1:o(q(a,b));return"translate("+c+", "+d+")"}).select("rect").attr("height",function(a,b){return Math.max(Math.abs(o(q(a,b))-o(e&&e[0]||0))||1)}),h=n.copy(),i=o.copy()}),y.renderEnd("discreteBar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=d3.scale.ordinal(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=[0],s=a.utils.defaultColor(),t=!1,u=d3.format(",.2f"),v=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),w="discreteBar",x=250,y=a.utils.renderWatch(v,x);return b.dispatch=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},forceY:{get:function(){return r},set:function(a){r=a}},showValues:{get:function(){return t},set:function(a){t=a}},x:{get:function(){return p},set:function(a){p=a}},y:{get:function(){return q},set:function(a){q=a}},xScale:{get:function(){return n},set:function(a){n=a}},yScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},valueFormat:{get:function(){return u},set:function(a){u=a}},id:{get:function(){return m},set:function(a){m=a}},rectClass:{get:function(){return w},set:function(a){w=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b)}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x)}}}),a.utils.initOptions(b),b},a.models.discreteBarChart=function(){"use strict";function b(h){return t.reset(),t.models(e),m&&t.models(f),n&&t.models(g),h.each(function(h){var l=d3.select(this);a.utils.initSVG(l);var q=a.utils.availableWidth(j,l,i),t=a.utils.availableHeight(k,l,i);if(b.update=function(){r.beforeUpdate(),l.transition().duration(s).call(b)},b.container=this,!(h&&h.length&&h.filter(function(a){return a.values.length}).length))return a.utils.noData(b,l),b;l.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var u=l.selectAll("g.nv-wrap.nv-discreteBarWithAxes").data([h]),v=u.enter().append("g").attr("class","nvd3 nv-wrap nv-discreteBarWithAxes").append("g"),w=v.append("defs"),x=u.select("g");v.append("g").attr("class","nv-x nv-axis"),v.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),v.append("g").attr("class","nv-barsWrap"),x.attr("transform","translate("+i.left+","+i.top+")"),o&&x.select(".nv-y.nv-axis").attr("transform","translate("+q+",0)"),e.width(q).height(t);var y=x.select(".nv-barsWrap").datum(h.filter(function(a){return!a.disabled}));if(y.transition().call(e),w.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),x.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(p?2:1)).attr("height",16).attr("x",-c.rangeBand()/(p?1:2)),m){f.scale(c)._ticks(a.utils.calcTicksX(q/100,h)).tickSize(-t,0),x.select(".nv-x.nv-axis").attr("transform","translate(0,"+(d.range()[0]+(e.showValues()&&d.domain()[0]<0?16:0))+")"),x.select(".nv-x.nv-axis").call(f);
  19307. var z=x.select(".nv-x.nv-axis").selectAll("g");p&&z.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}n&&(g.scale(d)._ticks(a.utils.calcTicksY(t/36,h)).tickSize(-q,0),x.select(".nv-y.nv-axis").call(g)),x.select(".nv-zeroLine line").attr("x1",0).attr("x2",q).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("discreteBar chart immediate"),b}var c,d,e=a.models.discreteBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.tooltip(),i={top:15,right:10,bottom:50,left:60},j=null,k=null,l=a.utils.getColor(),m=!0,n=!0,o=!1,p=!1,q=null,r=d3.dispatch("beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(o?"right":"left").tickFormat(d3.format(",.1f")),h.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).keyFormatter(function(a,b){return f.tickFormat()(a,b)});var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},h.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){h.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){h.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.discretebar=e,b.xAxis=f,b.yAxis=g,b.tooltip=h,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},staggerLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return m},set:function(a){m=a}},showYAxis:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return q},set:function(a){q=a}},tooltips:{get:function(){return h.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),h.enabled(!!b)}},tooltipContent:{get:function(){return h.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),h.contentGenerator(b)}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),e.color(l)}},rightAlignYAxis:{get:function(){return o},set:function(a){o=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.distribution=function(){"use strict";function b(k){return m.reset(),k.each(function(b){var k=(e-("x"===g?d.left+d.right:d.top+d.bottom),"x"==g?"y":"x"),l=d3.select(this);a.utils.initSVG(l),c=c||j;var n=l.selectAll("g.nv-distribution").data([b]),o=n.enter().append("g").attr("class","nvd3 nv-distribution"),p=(o.append("g"),n.select("g"));n.attr("transform","translate("+d.left+","+d.top+")");var q=p.selectAll("g.nv-dist").data(function(a){return a},function(a){return a.key});q.enter().append("g"),q.attr("class",function(a,b){return"nv-dist nv-series-"+b}).style("stroke",function(a,b){return i(a,b)});var r=q.selectAll("line.nv-dist"+g).data(function(a){return a.values});r.enter().append("line").attr(g+"1",function(a,b){return c(h(a,b))}).attr(g+"2",function(a,b){return c(h(a,b))}),m.transition(q.exit().selectAll("line.nv-dist"+g),"dist exit").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}).style("stroke-opacity",0).remove(),r.attr("class",function(a,b){return"nv-dist"+g+" nv-dist"+g+"-"+b}).attr(k+"1",0).attr(k+"2",f),m.transition(r,"dist").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}),c=j.copy()}),m.renderEnd("distribution immediate"),b}var c,d={top:0,right:0,bottom:0,left:0},e=400,f=8,g="x",h=function(a){return a[g]},i=a.utils.defaultColor(),j=d3.scale.linear(),k=250,l=d3.dispatch("renderEnd"),m=a.utils.renderWatch(l,k);return b.options=a.utils.optionsFunc.bind(b),b.dispatch=l,b.margin=function(a){return arguments.length?(d.top="undefined"!=typeof a.top?a.top:d.top,d.right="undefined"!=typeof a.right?a.right:d.right,d.bottom="undefined"!=typeof a.bottom?a.bottom:d.bottom,d.left="undefined"!=typeof a.left?a.left:d.left,b):d},b.width=function(a){return arguments.length?(e=a,b):e},b.axis=function(a){return arguments.length?(g=a,b):g},b.size=function(a){return arguments.length?(f=a,b):f},b.getData=function(a){return arguments.length?(h=d3.functor(a),b):h},b.scale=function(a){return arguments.length?(j=a,b):j},b.color=function(c){return arguments.length?(i=a.utils.getColor(c),b):i},b.duration=function(a){return arguments.length?(k=a,m.reset(k),b):k},b},a.models.furiousLegend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?g(a,b):"#fff":m?void 0:a.disabled?g(a,b):"#fff"}function r(a,b){return m&&"furious"==o?a.disengaged?"#fff":g(a,b):a.disabled?"#fff":g(a,b)}return p.each(function(b){var p=d-c.left-c.right,s=d3.select(this);a.utils.initSVG(s);var t=s.selectAll("g.nv-legend").data([b]),u=(t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),t.select("g"));t.attr("transform","translate("+c.left+","+c.top+")");var v,w=u.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),x=w.enter().append("g").attr("class","nv-series");if("classic"==o)x.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),v=w.select("circle");else if("furious"==o){x.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),v=w.select("rect"),x.append("g").attr("class","nv-check-box").property("innerHTML",'<path d="M0.5,5 L22.5,5 L22.5,26.5 L0.5,26.5 L0.5,5 Z" class="nv-box"></path><path d="M5.5,12.8618467 L11.9185089,19.2803556 L31,0.198864511" class="nv-check"></path>').attr("transform","translate(-10,-8)scale(0.5)");var y=w.select(".nv-check-box");y.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}x.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var z=w.select("text.nv-legend-text");w.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=w.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=w.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),w.classed("nv-disabled",function(a){return a.userDisabled}),w.exit().remove(),z.attr("fill",q).text(f);var A;switch(o){case"furious":A=23;break;case"classic":A=20}if(h){var B=[];w.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}B.push(b+i)});for(var C=0,D=0,E=[];p>D&&C<B.length;)E[C]=B[C],D+=B[C++];for(0===C&&(C=1);D>p&&C>1;){E=[],C--;for(var F=0;F<B.length;F++)B[F]>(E[F%C]||0)&&(E[F%C]=B[F]);D=E.reduce(function(a,b){return a+b})}for(var G=[],H=0,I=0;C>H;H++)G[H]=I,I+=E[H];w.attr("transform",function(a,b){return"translate("+G[b%C]+","+(5+Math.floor(b/C)*A)+")"}),j?u.attr("transform","translate("+(d-c.right-D)+","+c.top+")"):u.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(B.length/C)*A}else{var J,K=5,L=5,M=0;w.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return J=L,d<c.left+c.right+J+a&&(L=J=5,K+=A),L+=a,L>M&&(M=L),"translate("+J+","+K+")"}),u.attr("transform","translate("+(d-c.right-M)+","+c.top+")"),e=c.top+c.bottom+K+15}"furious"==o&&v.attr("width",function(a,b){return z[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),v.style("fill",r).style("stroke",function(a,b){return a.color||g(a,b)})}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=28,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBar=function(){"use strict";function b(x){return x.each(function(b){w.reset(),k=d3.select(this);var x=a.utils.availableWidth(h,k,g),y=a.utils.availableHeight(i,k,g);a.utils.initSVG(k),l.domain(c||d3.extent(b[0].values.map(n).concat(p))),l.range(r?e||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:e||[0,x]),m.domain(d||d3.extent(b[0].values.map(o).concat(q))).range(f||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var z=k.selectAll("g.nv-wrap.nv-historicalBar-"+j).data([b[0].values]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBar-"+j),B=A.append("defs"),C=A.append("g"),D=z.select("g");C.append("g").attr("class","nv-bars"),z.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){u.chartClick({data:a,index:b,pos:d3.event,id:j})}),B.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),z.select("#nv-chart-clip-path-"+j+" rect").attr("width",x).attr("height",y),D.attr("clip-path",s?"url(#nv-chart-clip-path-"+j+")":"");var E=z.select(".nv-bars").selectAll(".nv-bar").data(function(a){return a},function(a,b){return n(a,b)});E.exit().remove(),E.enter().append("rect").attr("x",0).attr("y",function(b,c){return a.utils.NaNtoZero(m(Math.max(0,o(b,c))))}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.abs(m(o(b,c))-m(0)))}).attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).on("mouseover",function(a,b){v&&(d3.select(this).classed("hover",!0),u.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mouseout",function(a,b){v&&(d3.select(this).classed("hover",!1),u.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mousemove",function(a,b){v&&u.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v&&(u.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}).on("dblclick",function(a,b){v&&(u.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}),E.attr("fill",function(a,b){return t(a,b)}).attr("class",function(a,b,c){return(o(a,b)<0?"nv-bar negative":"nv-bar positive")+" nv-bar-"+c+"-"+b}).watchTransition(w,"bars").attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).attr("width",x/b[0].values.length*.9),E.watchTransition(w,"bars").attr("y",function(b,c){var d=o(b,c)<0?m(0):m(0)-m(o(b,c))<1?m(0)-1:m(o(b,c));return a.utils.NaNtoZero(d)}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.max(Math.abs(m(o(b,c))-m(0)),1))})}),w.renderEnd("historicalBar immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=[],q=[0],r=!1,s=!0,t=a.utils.defaultColor(),u=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),v=!0,w=a.utils.renderWatch(u,0);return b.highlightPoint=function(a,b){k.select(".nv-bars .nv-bar-0-"+a).classed("hover",b)},b.clearHighlights=function(){k.select(".nv-bars .nv-bar.hover").classed("hover",!1)},b.dispatch=u,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},forceX:{get:function(){return p},set:function(a){p=a}},forceY:{get:function(){return q},set:function(a){q=a}},padData:{get:function(){return r},set:function(a){r=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},clipEdge:{get:function(){return s},set:function(a){s=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return v},set:function(a){v=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return t},set:function(b){t=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBarChart=function(b){"use strict";function c(b){return b.each(function(k){z.reset(),z.models(f),q&&z.models(g),r&&z.models(h);var w=d3.select(this),A=this;a.utils.initSVG(w);var B=a.utils.availableWidth(n,w,l),C=a.utils.availableHeight(o,w,l);if(c.update=function(){w.transition().duration(y).call(c)},c.container=this,u.disabled=k.map(function(a){return!!a.disabled}),!v){var D;v={};for(D in u)v[D]=u[D]instanceof Array?u[D].slice(0):u[D]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(c,w),c;w.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale();var E=w.selectAll("g.nv-wrap.nv-historicalBarChart").data([k]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBarChart").append("g"),G=E.select("g");F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-barsWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),p&&(i.width(B),G.select(".nv-legendWrap").datum(k).call(i),l.top!=i.height()&&(l.top=i.height(),C=a.utils.availableHeight(o,w,l)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-l.top+")")),E.attr("transform","translate("+l.left+","+l.top+")"),s&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),t&&(j.width(B).height(C).margin({left:l.left,top:l.top}).svgContainer(w).xScale(d),E.select(".nv-interactive").call(j)),f.width(B).height(C).color(k.map(function(a,b){return a.color||m(a,b)}).filter(function(a,b){return!k[b].disabled}));var H=G.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));H.transition().call(f),q&&(g.scale(d)._ticks(a.utils.calcTicksX(B/100,k)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),G.select(".nv-x.nv-axis").transition().call(g)),r&&(h.scale(e)._ticks(a.utils.calcTicksY(C/36,k)).tickSize(-B,0),G.select(".nv-y.nv-axis").transition().call(h)),j.dispatch.on("elementMousemove",function(b){f.clearHighlights();var d,e,i,n=[];k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g){e=a.interactiveBisect(g.values,b.pointXValue,c.x()),f.highlightPoint(e,!0);var h=g.values[e];void 0!==h&&(void 0===d&&(d=h),void 0===i&&(i=c.xScale()(c.x()(h,e))),n.push({key:g.key,value:c.y()(h,e),color:m(g,g.seriesIndex),data:g.values[e]}))});var o=g.tickFormat()(c.x()(d,e));j.tooltip.position({left:i+l.left,top:b.mouseY+l.top}).chartContainer(A.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:o,index:e,series:n})(),j.renderGuideLine(i)}),j.dispatch.on("elementMouseout",function(){x.tooltipHide(),f.clearHighlights()}),i.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,k.filter(function(a){return!a.disabled}).length||k.map(function(a){return a.disabled=!1,E.selectAll(".nv-series").classed("disabled",!1),a}),u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),b.transition().call(c)}),i.dispatch.on("legendDblclick",function(a){k.forEach(function(a){a.disabled=!0}),a.disabled=!1,u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),c.update()}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),c.update()})}),z.renderEnd("historicalBarChart immediate"),c}var d,e,f=b||a.models.historicalBar(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:90,bottom:50,left:90},m=a.utils.defaultColor(),n=null,o=null,p=!1,q=!0,r=!0,s=!1,t=!1,u={},v=null,w=null,x=d3.dispatch("tooltipHide","stateChange","changeState","renderEnd"),y=250;g.orient("bottom").tickPadding(7),h.orient(s?"right":"left"),k.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)});var z=a.utils.renderWatch(x,0);return f.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:c.x()(a.data),value:c.y()(a.data),color:a.color},k.data(a).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),f.dispatch.on("elementMousemove.tooltip",function(){k.position({top:d3.event.pageY,left:d3.event.pageX})()}),c.dispatch=x,c.bars=f,c.legend=i,c.xAxis=g,c.yAxis=h,c.interactiveLayer=j,c.tooltip=k,c.options=a.utils.optionsFunc.bind(c),c._options=Object.create({},{width:{get:function(){return n},set:function(a){n=a}},height:{get:function(){return o},set:function(a){o=a}},showLegend:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return q},set:function(a){q=a}},showYAxis:{get:function(){return r},set:function(a){r=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b),i.color(m),f.color(m)}},duration:{get:function(){return y},set:function(a){y=a,z.reset(y),h.duration(y),g.duration(y)}},rightAlignYAxis:{get:function(){return s},set:function(a){s=a,h.orient(a?"right":"left")}},useInteractiveGuideline:{get:function(){return t},set:function(a){t=a,a===!0&&c.interactive(!1)}}}),a.utils.inheritOptions(c,f),a.utils.initOptions(c),c},a.models.ohlcBarChart=function(){var b=a.models.historicalBarChart(a.models.ohlcBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open<c.close?"2ca02c":"d62728";return'<h3 style="color: #'+d+'">'+a.value+"</h3><table><tr><td>open:</td><td>"+b.yAxis.tickFormat()(c.open)+"</td></tr><tr><td>close:</td><td>"+b.yAxis.tickFormat()(c.close)+"</td></tr><tr><td>high</td><td>"+b.yAxis.tickFormat()(c.high)+"</td></tr><tr><td>low:</td><td>"+b.yAxis.tickFormat()(c.low)+"</td></tr></table>"}),b},a.models.candlestickBarChart=function(){var b=a.models.historicalBarChart(a.models.candlestickBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open<c.close?"2ca02c":"d62728";return'<h3 style="color: #'+d+'">'+a.value+"</h3><table><tr><td>open:</td><td>"+b.yAxis.tickFormat()(c.open)+"</td></tr><tr><td>close:</td><td>"+b.yAxis.tickFormat()(c.close)+"</td></tr><tr><td>high</td><td>"+b.yAxis.tickFormat()(c.high)+"</td></tr><tr><td>low:</td><td>"+b.yAxis.tickFormat()(c.low)+"</td></tr></table>"}),b},a.models.legend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?"#000":"#fff":m?void 0:(a.color||(a.color=g(a,b)),a.disabled?a.color:"#fff")}function r(a,b){return m&&"furious"==o&&a.disengaged?"#eee":a.color||g(a,b)}function s(a){return m&&"furious"==o?1:a.disabled?0:1}return p.each(function(b){var g=d-c.left-c.right,p=d3.select(this);a.utils.initSVG(p);var t=p.selectAll("g.nv-legend").data([b]),u=t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),v=t.select("g");t.attr("transform","translate("+c.left+","+c.top+")");var w,x,y=v.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),z=y.enter().append("g").attr("class","nv-series");switch(o){case"furious":x=23;break;case"classic":x=20}if("classic"==o)z.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),w=y.select("circle");else if("furious"==o){z.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),w=y.select(".nv-legend-symbol"),z.append("g").attr("class","nv-check-box").property("innerHTML",'<path d="M0.5,5 L22.5,5 L22.5,26.5 L0.5,26.5 L0.5,5 Z" class="nv-box"></path><path d="M5.5,12.8618467 L11.9185089,19.2803556 L31,0.198864511" class="nv-check"></path>').attr("transform","translate(-10,-8)scale(0.5)");var A=y.select(".nv-check-box");A.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}z.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var B=y.select("text.nv-legend-text");y.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=y.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=y.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),y.classed("nv-disabled",function(a){return a.userDisabled}),y.exit().remove(),B.attr("fill",q).text(f);var C=0;if(h){var D=[];y.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}D.push(b+i)});var E=0,F=[];for(C=0;g>C&&E<D.length;)F[E]=D[E],C+=D[E++];for(0===E&&(E=1);C>g&&E>1;){F=[],E--;for(var G=0;G<D.length;G++)D[G]>(F[G%E]||0)&&(F[G%E]=D[G]);C=F.reduce(function(a,b){return a+b})}for(var H=[],I=0,J=0;E>I;I++)H[I]=J,J+=F[I];y.attr("transform",function(a,b){return"translate("+H[b%E]+","+(5+Math.floor(b/E)*x)+")"}),j?v.attr("transform","translate("+(d-c.right-C)+","+c.top+")"):v.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(D.length/E)*x}else{var K,L=5,M=5,N=0;y.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return K=M,d<c.left+c.right+K+a&&(M=K=5,L+=x),M+=a,M>N&&(N=M),K+N>C&&(C=K+N),"translate("+K+","+L+")"}),v.attr("transform","translate("+(d-c.right-N)+","+c.top+")"),e=c.top+c.bottom+L+15}if("furious"==o){w.attr("width",function(a,b){return B[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),u.insert("rect",":first-child").attr("class","nv-legend-bg").attr("fill","#eee").attr("opacity",0);var O=v.select(".nv-legend-bg");O.transition().duration(300).attr("x",-x).attr("width",C+x-12).attr("height",e+10).attr("y",-c.top-10).attr("opacity",m?1:0)}w.style("fill",r).style("fill-opacity",s).style("stroke",r)}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=32,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.line=function(){"use strict";function b(r){return v.reset(),v.models(e),r.each(function(b){i=d3.select(this);var r=a.utils.availableWidth(g,i,f),s=a.utils.availableHeight(h,i,f);a.utils.initSVG(i),c=e.xScale(),d=e.yScale(),t=t||c,u=u||d;var w=i.selectAll("g.nv-wrap.nv-line").data([b]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-line"),y=x.append("defs"),z=x.append("g"),A=w.select("g");z.append("g").attr("class","nv-groups"),z.append("g").attr("class","nv-scatterWrap"),w.attr("transform","translate("+f.left+","+f.top+")"),e.width(r).height(s);var B=w.select(".nv-scatterWrap");B.call(e),y.append("clipPath").attr("id","nv-edge-clip-"+e.id()).append("rect"),w.select("#nv-edge-clip-"+e.id()+" rect").attr("width",r).attr("height",s>0?s:0),A.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":""),B.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":"");var C=w.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});C.enter().append("g").style("stroke-opacity",1e-6).style("stroke-width",function(a){return a.strokeWidth||j}).style("fill-opacity",1e-6),C.exit().remove(),C.attr("class",function(a,b){return(a.classed||"")+" nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return k(a,b)}).style("stroke",function(a,b){return k(a,b)}),C.watchTransition(v,"line: groups").style("stroke-opacity",1).style("fill-opacity",function(a){return a.fillOpacity||.5});var D=C.selectAll("path.nv-area").data(function(a){return o(a)?[a]:[]});D.enter().append("path").attr("class","nv-area").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y0(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))}).y1(function(){return u(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])}),C.exit().selectAll("path.nv-area").remove(),D.watchTransition(v,"line: areaPaths").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y0(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))}).y1(function(){return d(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])});var E=C.selectAll("path.nv-line").data(function(a){return[a.values]});E.enter().append("path").attr("class","nv-line").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))})),E.watchTransition(v,"line: linePaths").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))})),t=c.copy(),u=d.copy()}),v.renderEnd("line immediate"),b}var c,d,e=a.models.scatter(),f={top:0,right:0,bottom:0,left:0},g=960,h=500,i=null,j=1.5,k=a.utils.defaultColor(),l=function(a){return a.x},m=function(a){return a.y},n=function(a,b){return!isNaN(m(a,b))&&null!==m(a,b)},o=function(a){return a.area},p=!1,q="linear",r=250,s=d3.dispatch("elementClick","elementMouseover","elementMouseout","renderEnd");e.pointSize(16).pointDomain([16,256]);var t,u,v=a.utils.renderWatch(s,r);return b.dispatch=s,b.scatter=e,e.dispatch.on("elementClick",function(){s.elementClick.apply(this,arguments)}),e.dispatch.on("elementMouseover",function(){s.elementMouseover.apply(this,arguments)}),e.dispatch.on("elementMouseout",function(){s.elementMouseout.apply(this,arguments)}),b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},defined:{get:function(){return n},set:function(a){n=a}},interpolate:{get:function(){return q},set:function(a){q=a}},clipEdge:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}},duration:{get:function(){return r},set:function(a){r=a,v.reset(r),e.duration(r)}},isArea:{get:function(){return o},set:function(a){o=d3.functor(a)}},x:{get:function(){return l},set:function(a){l=a,e.x(a)}},y:{get:function(){return m},set:function(a){m=a,e.y(a)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.lineChart=function(){"use strict";function b(j){return y.reset(),y.models(e),p&&y.models(f),q&&y.models(g),j.each(function(j){var v=d3.select(this),y=this;a.utils.initSVG(v);var B=a.utils.availableWidth(m,v,k),C=a.utils.availableHeight(n,v,k);if(b.update=function(){0===x?v.call(b):v.transition().duration(x).call(b)},b.container=this,t.setter(A(j),b.update).getter(z(j)).update(),t.disabled=j.map(function(a){return!!a.disabled}),!u){var D;u={};for(D in t)u[D]=t[D]instanceof Array?t[D].slice(0):t[D]
  19308. }if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,v),b;v.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var E=v.selectAll("g.nv-wrap.nv-lineChart").data([j]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-lineChart").append("g"),G=E.select("g");F.append("rect").style("opacity",0),F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-linesWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),G.select("rect").attr("width",B).attr("height",C>0?C:0),o&&(h.width(B),G.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),C=a.utils.availableHeight(n,v,k)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-k.top+")")),E.attr("transform","translate("+k.left+","+k.top+")"),r&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),s&&(i.width(B).height(C).margin({left:k.left,top:k.top}).svgContainer(v).xScale(c),E.select(".nv-interactive").call(i)),e.width(B).height(C).color(j.map(function(a,b){return a.color||l(a,b)}).filter(function(a,b){return!j[b].disabled}));var H=G.select(".nv-linesWrap").datum(j.filter(function(a){return!a.disabled}));H.call(e),p&&(f.scale(c)._ticks(a.utils.calcTicksX(B/100,j)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),G.select(".nv-x.nv-axis").call(f)),q&&(g.scale(d)._ticks(a.utils.calcTicksY(C/36,j)).tickSize(-B,0),G.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)t[c]=a[c];w.stateChange(t),b.update()}),i.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,h,m,n=[];if(j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,g){h=a.interactiveBisect(f.values,c.pointXValue,b.x());var i=f.values[h],j=b.y()(i,h);null!=j&&e.highlightPoint(g,h,!0),void 0!==i&&(void 0===d&&(d=i),void 0===m&&(m=b.xScale()(b.x()(i,h))),n.push({key:f.key,value:j,color:l(f,f.seriesIndex)}))}),n.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(n.map(function(a){return a.value}),o,q);null!==r&&(n[r].highlight=!0)}var s=f.tickFormat()(b.x()(d,h));i.tooltip.position({left:c.mouseX+k.left,top:c.mouseY+k.top}).chartContainer(y.parentNode).valueFormatter(function(a){return null==a?"N/A":g.tickFormat()(a)}).data({value:s,index:h,series:n})(),i.renderGuideLine(m)}),i.dispatch.on("elementClick",function(c){var d,f=[];j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(e){var g=a.interactiveBisect(e.values,c.pointXValue,b.x()),h=e.values[g];if("undefined"!=typeof h){"undefined"==typeof d&&(d=b.xScale()(b.x()(h,g)));var i=b.yScale()(b.y()(h,g));f.push({point:h,pointIndex:g,pos:[d,i],seriesIndex:e.seriesIndex,series:e})}}),e.dispatch.elementClick(f)}),i.dispatch.on("elementMouseout",function(){e.clearHighlights()}),w.on("changeState",function(a){"undefined"!=typeof a.disabled&&j.length===a.disabled.length&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),t.disabled=a.disabled),b.update()})}),y.renderEnd("lineChart immediate"),b}var c,d,e=a.models.line(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.interactiveGuideline(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=a.utils.defaultColor(),m=null,n=null,o=!0,p=!0,q=!0,r=!1,s=!1,t=a.utils.state(),u=null,v=null,w=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),x=250;f.orient("bottom").tickPadding(7),g.orient(r?"right":"left"),j.valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)});var y=a.utils.renderWatch(w,x),z=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},A=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){j.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),b.dispatch=w,b.lines=e,b.legend=h,b.xAxis=f,b.yAxis=g,b.interactiveLayer=i,b.tooltip=j,b.dispatch=w,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return p},set:function(a){p=a}},showYAxis:{get:function(){return q},set:function(a){q=a}},defaultState:{get:function(){return u},set:function(a){u=a}},noData:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x),e.duration(x),f.duration(x),g.duration(x)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),h.color(l),e.color(l)}},rightAlignYAxis:{get:function(){return r},set:function(a){r=a,g.orient(r?"right":"left")}},useInteractiveGuideline:{get:function(){return s},set:function(a){s=a,s&&(e.interactive(!1),e.useVoronoi(!1))}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.linePlusBarChart=function(){"use strict";function b(v){return v.each(function(v){function J(a){var b=+("e"==a),c=b?1:-1,d=X/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function S(){u.empty()||u.extent(I),kb.data([u.empty()?e.domain():I]).each(function(a){var b=e(a[0])-e.range()[0],c=e.range()[1]-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>c?0:c)})}function T(){I=u.empty()?null:u.extent(),c=u.empty()?e.domain():u.extent(),K.brush({extent:c,brush:u}),S(),l.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),j.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var b=db.select(".nv-focus .nv-barsWrap").datum(Z.length?Z.map(function(a){return{key:a.key,values:a.values.filter(function(a,b){return l.x()(a,b)>=c[0]&&l.x()(a,b)<=c[1]})}}):[{values:[]}]),h=db.select(".nv-focus .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$.map(function(a){return{area:a.area,fillOpacity:a.fillOpacity,key:a.key,values:a.values.filter(function(a,b){return j.x()(a,b)>=c[0]&&j.x()(a,b)<=c[1]})}}));d=Z.length?l.xScale():j.xScale(),n.scale(d)._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-W,0),n.domain([Math.ceil(c[0]),Math.floor(c[1])]),db.select(".nv-x.nv-axis").transition().duration(L).call(n),b.transition().duration(L).call(l),h.transition().duration(L).call(j),db.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),p.scale(f)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(-V,0),q.scale(g)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(Z.length?0:-V,0),db.select(".nv-focus .nv-y1.nv-axis").style("opacity",Z.length?1:0),db.select(".nv-focus .nv-y2.nv-axis").style("opacity",$.length&&!$[0].disabled?1:0).attr("transform","translate("+d.range()[1]+",0)"),db.select(".nv-focus .nv-y1.nv-axis").transition().duration(L).call(p),db.select(".nv-focus .nv-y2.nv-axis").transition().duration(L).call(q)}var U=d3.select(this);a.utils.initSVG(U);var V=a.utils.availableWidth(y,U,w),W=a.utils.availableHeight(z,U,w)-(E?H:0),X=H-x.top-x.bottom;if(b.update=function(){U.transition().duration(L).call(b)},b.container=this,M.setter(R(v),b.update).getter(Q(v)).update(),M.disabled=v.map(function(a){return!!a.disabled}),!N){var Y;N={};for(Y in M)N[Y]=M[Y]instanceof Array?M[Y].slice(0):M[Y]}if(!(v&&v.length&&v.filter(function(a){return a.values.length}).length))return a.utils.noData(b,U),b;U.selectAll(".nv-noData").remove();var Z=v.filter(function(a){return!a.disabled&&a.bar}),$=v.filter(function(a){return!a.bar});d=l.xScale(),e=o.scale(),f=l.yScale(),g=j.yScale(),h=m.yScale(),i=k.yScale();var _=v.filter(function(a){return!a.disabled&&a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})}),ab=v.filter(function(a){return!a.disabled&&!a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})});d.range([0,V]),e.domain(d3.extent(d3.merge(_.concat(ab)),function(a){return a.x})).range([0,V]);var bb=U.selectAll("g.nv-wrap.nv-linePlusBar").data([v]),cb=bb.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g"),db=bb.select("g");cb.append("g").attr("class","nv-legendWrap");var eb=cb.append("g").attr("class","nv-focus");eb.append("g").attr("class","nv-x nv-axis"),eb.append("g").attr("class","nv-y1 nv-axis"),eb.append("g").attr("class","nv-y2 nv-axis"),eb.append("g").attr("class","nv-barsWrap"),eb.append("g").attr("class","nv-linesWrap");var fb=cb.append("g").attr("class","nv-context");if(fb.append("g").attr("class","nv-x nv-axis"),fb.append("g").attr("class","nv-y1 nv-axis"),fb.append("g").attr("class","nv-y2 nv-axis"),fb.append("g").attr("class","nv-barsWrap"),fb.append("g").attr("class","nv-linesWrap"),fb.append("g").attr("class","nv-brushBackground"),fb.append("g").attr("class","nv-x nv-brush"),D){var gb=t.align()?V/2:V,hb=t.align()?gb:0;t.width(gb),db.select(".nv-legendWrap").datum(v.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(a.bar?O:P),a})).call(t),w.top!=t.height()&&(w.top=t.height(),W=a.utils.availableHeight(z,U,w)-H),db.select(".nv-legendWrap").attr("transform","translate("+hb+","+-w.top+")")}bb.attr("transform","translate("+w.left+","+w.top+")"),db.select(".nv-context").style("display",E?"initial":"none"),m.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),k.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var ib=db.select(".nv-context .nv-barsWrap").datum(Z.length?Z:[{values:[]}]),jb=db.select(".nv-context .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$);db.select(".nv-context").attr("transform","translate(0,"+(W+w.bottom+x.top)+")"),ib.transition().call(m),jb.transition().call(k),G&&(o._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-X,0),db.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+h.range()[0]+")"),db.select(".nv-context .nv-x.nv-axis").transition().call(o)),F&&(r.scale(h)._ticks(X/36).tickSize(-V,0),s.scale(i)._ticks(X/36).tickSize(Z.length?0:-V,0),db.select(".nv-context .nv-y3.nv-axis").style("opacity",Z.length?1:0).attr("transform","translate(0,"+e.range()[0]+")"),db.select(".nv-context .nv-y2.nv-axis").style("opacity",$.length?1:0).attr("transform","translate("+e.range()[1]+",0)"),db.select(".nv-context .nv-y1.nv-axis").transition().call(r),db.select(".nv-context .nv-y2.nv-axis").transition().call(s)),u.x(e).on("brush",T),I&&u.extent(I);var kb=db.select(".nv-brushBackground").selectAll("g").data([I||u.extent()]),lb=kb.enter().append("g");lb.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",X),lb.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",X);var mb=db.select(".nv-x.nv-brush").call(u);mb.selectAll("rect").attr("height",X),mb.selectAll(".resize").append("path").attr("d",J),t.dispatch.on("stateChange",function(a){for(var c in a)M[c]=a[c];K.stateChange(M),b.update()}),K.on("changeState",function(a){"undefined"!=typeof a.disabled&&(v.forEach(function(b,c){b.disabled=a.disabled[c]}),M.disabled=a.disabled),b.update()}),T()}),b}var c,d,e,f,g,h,i,j=a.models.line(),k=a.models.line(),l=a.models.historicalBar(),m=a.models.historicalBar(),n=a.models.axis(),o=a.models.axis(),p=a.models.axis(),q=a.models.axis(),r=a.models.axis(),s=a.models.axis(),t=a.models.legend(),u=d3.svg.brush(),v=a.models.tooltip(),w={top:30,right:30,bottom:30,left:60},x={top:0,right:30,bottom:20,left:60},y=null,z=null,A=function(a){return a.x},B=function(a){return a.y},C=a.utils.defaultColor(),D=!0,E=!0,F=!1,G=!0,H=50,I=null,J=null,K=d3.dispatch("brush","stateChange","changeState"),L=0,M=a.utils.state(),N=null,O=" (left axis)",P=" (right axis)";j.clipEdge(!0),k.interactive(!1),k.pointActive(function(){return!1}),n.orient("bottom").tickPadding(5),p.orient("left"),q.orient("right"),o.orient("bottom").tickPadding(5),r.orient("left"),s.orient("right"),v.headerEnabled(!0).headerFormatter(function(a,b){return n.tickFormat()(a,b)});var Q=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},R=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return j.dispatch.on("elementMouseover.tooltip",function(a){v.duration(100).valueFormatter(function(a,b){return q.tickFormat()(a,b)}).data(a).position(a.pos).hidden(!1)}),j.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={value:b.y()(a.data),color:a.color},v.duration(0).valueFormatter(function(a,b){return p.tickFormat()(a,b)}).data(a).hidden(!1)}),l.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMousemove.tooltip",function(){v.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=K,b.legend=t,b.lines=j,b.lines2=k,b.bars=l,b.bars2=m,b.xAxis=n,b.x2Axis=o,b.y1Axis=p,b.y2Axis=q,b.y3Axis=r,b.y4Axis=s,b.tooltip=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return y},set:function(a){y=a}},height:{get:function(){return z},set:function(a){z=a}},showLegend:{get:function(){return D},set:function(a){D=a}},brushExtent:{get:function(){return I},set:function(a){I=a}},noData:{get:function(){return J},set:function(a){J=a}},focusEnable:{get:function(){return E},set:function(a){E=a}},focusHeight:{get:function(){return H},set:function(a){H=a}},focusShowAxisX:{get:function(){return G},set:function(a){G=a}},focusShowAxisY:{get:function(){return F},set:function(a){F=a}},legendLeftAxisHint:{get:function(){return O},set:function(a){O=a}},legendRightAxisHint:{get:function(){return P},set:function(a){P=a}},tooltips:{get:function(){return v.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),v.enabled(!!b)}},tooltipContent:{get:function(){return v.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),v.contentGenerator(b)}},margin:{get:function(){return w},set:function(a){w.top=void 0!==a.top?a.top:w.top,w.right=void 0!==a.right?a.right:w.right,w.bottom=void 0!==a.bottom?a.bottom:w.bottom,w.left=void 0!==a.left?a.left:w.left}},focusMargin:{get:function(){return x},set:function(a){x.top=void 0!==a.top?a.top:x.top,x.right=void 0!==a.right?a.right:x.right,x.bottom=void 0!==a.bottom?a.bottom:x.bottom,x.left=void 0!==a.left?a.left:x.left}},duration:{get:function(){return L},set:function(a){L=a}},color:{get:function(){return C},set:function(b){C=a.utils.getColor(b),t.color(C)}},x:{get:function(){return A},set:function(a){A=a,j.x(a),k.x(a),l.x(a),m.x(a)}},y:{get:function(){return B},set:function(a){B=a,j.y(a),k.y(a),l.y(a),m.y(a)}}}),a.utils.inheritOptions(b,j),a.utils.initOptions(b),b},a.models.lineWithFocusChart=function(){"use strict";function b(o){return o.each(function(o){function z(a){var b=+("e"==a),c=b?1:-1,d=M/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function G(){n.empty()||n.extent(y),U.data([n.empty()?e.domain():y]).each(function(a){var b=e(a[0])-c.range()[0],d=K-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>d?0:d)})}function H(){y=n.empty()?null:n.extent();var a=n.empty()?e.domain():n.extent();if(!(Math.abs(a[0]-a[1])<=1)){A.brush({extent:a,brush:n}),G();var b=Q.select(".nv-focus .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}).map(function(b){return{key:b.key,area:b.area,values:b.values.filter(function(b,c){return g.x()(b,c)>=a[0]&&g.x()(b,c)<=a[1]})}}));b.transition().duration(B).call(g),Q.select(".nv-focus .nv-x.nv-axis").transition().duration(B).call(i),Q.select(".nv-focus .nv-y.nv-axis").transition().duration(B).call(j)}}var I=d3.select(this),J=this;a.utils.initSVG(I);var K=a.utils.availableWidth(t,I,q),L=a.utils.availableHeight(u,I,q)-v,M=v-r.top-r.bottom;if(b.update=function(){I.transition().duration(B).call(b)},b.container=this,C.setter(F(o),b.update).getter(E(o)).update(),C.disabled=o.map(function(a){return!!a.disabled}),!D){var N;D={};for(N in C)D[N]=C[N]instanceof Array?C[N].slice(0):C[N]}if(!(o&&o.length&&o.filter(function(a){return a.values.length}).length))return a.utils.noData(b,I),b;I.selectAll(".nv-noData").remove(),c=g.xScale(),d=g.yScale(),e=h.xScale(),f=h.yScale();var O=I.selectAll("g.nv-wrap.nv-lineWithFocusChart").data([o]),P=O.enter().append("g").attr("class","nvd3 nv-wrap nv-lineWithFocusChart").append("g"),Q=O.select("g");P.append("g").attr("class","nv-legendWrap");var R=P.append("g").attr("class","nv-focus");R.append("g").attr("class","nv-x nv-axis"),R.append("g").attr("class","nv-y nv-axis"),R.append("g").attr("class","nv-linesWrap"),R.append("g").attr("class","nv-interactive");var S=P.append("g").attr("class","nv-context");S.append("g").attr("class","nv-x nv-axis"),S.append("g").attr("class","nv-y nv-axis"),S.append("g").attr("class","nv-linesWrap"),S.append("g").attr("class","nv-brushBackground"),S.append("g").attr("class","nv-x nv-brush"),x&&(m.width(K),Q.select(".nv-legendWrap").datum(o).call(m),q.top!=m.height()&&(q.top=m.height(),L=a.utils.availableHeight(u,I,q)-v),Q.select(".nv-legendWrap").attr("transform","translate(0,"+-q.top+")")),O.attr("transform","translate("+q.left+","+q.top+")"),w&&(p.width(K).height(L).margin({left:q.left,top:q.top}).svgContainer(I).xScale(c),O.select(".nv-interactive").call(p)),g.width(K).height(L).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),h.defined(g.defined()).width(K).height(M).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),Q.select(".nv-context").attr("transform","translate(0,"+(L+q.bottom+r.top)+")");var T=Q.select(".nv-context .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}));d3.transition(T).call(h),i.scale(c)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-L,0),j.scale(d)._ticks(a.utils.calcTicksY(L/36,o)).tickSize(-K,0),Q.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+L+")"),n.x(e).on("brush",function(){H()}),y&&n.extent(y);var U=Q.select(".nv-brushBackground").selectAll("g").data([y||n.extent()]),V=U.enter().append("g");V.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",M),V.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",M);var W=Q.select(".nv-x.nv-brush").call(n);W.selectAll("rect").attr("height",M),W.selectAll(".resize").append("path").attr("d",z),H(),k.scale(e)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-M,0),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),d3.transition(Q.select(".nv-context .nv-x.nv-axis")).call(k),l.scale(f)._ticks(a.utils.calcTicksY(M/36,o)).tickSize(-K,0),d3.transition(Q.select(".nv-context .nv-y.nv-axis")).call(l),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),m.dispatch.on("stateChange",function(a){for(var c in a)C[c]=a[c];A.stateChange(C),b.update()}),p.dispatch.on("elementMousemove",function(c){g.clearHighlights();var d,f,h,k=[];if(o.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(i,j){var l=n.empty()?e.domain():n.extent(),m=i.values.filter(function(a,b){return g.x()(a,b)>=l[0]&&g.x()(a,b)<=l[1]});f=a.interactiveBisect(m,c.pointXValue,g.x());var o=m[f],p=b.y()(o,f);null!=p&&g.highlightPoint(j,f,!0),void 0!==o&&(void 0===d&&(d=o),void 0===h&&(h=b.xScale()(b.x()(o,f))),k.push({key:i.key,value:b.y()(o,f),color:s(i,i.seriesIndex)}))}),k.length>2){var l=b.yScale().invert(c.mouseY),m=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),r=.03*m,t=a.nearestValueIndex(k.map(function(a){return a.value}),l,r);null!==t&&(k[t].highlight=!0)}var u=i.tickFormat()(b.x()(d,f));p.tooltip.position({left:c.mouseX+q.left,top:c.mouseY+q.top}).chartContainer(J.parentNode).valueFormatter(function(a){return null==a?"N/A":j.tickFormat()(a)}).data({value:u,index:f,series:k})(),p.renderGuideLine(h)}),p.dispatch.on("elementMouseout",function(){g.clearHighlights()}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&o.forEach(function(b,c){b.disabled=a.disabled[c]}),b.update()})}),b}var c,d,e,f,g=a.models.line(),h=a.models.line(),i=a.models.axis(),j=a.models.axis(),k=a.models.axis(),l=a.models.axis(),m=a.models.legend(),n=d3.svg.brush(),o=a.models.tooltip(),p=a.interactiveGuideline(),q={top:30,right:30,bottom:30,left:60},r={top:0,right:30,bottom:20,left:60},s=a.utils.defaultColor(),t=null,u=null,v=50,w=!1,x=!0,y=null,z=null,A=d3.dispatch("brush","stateChange","changeState"),B=250,C=a.utils.state(),D=null;g.clipEdge(!0).duration(0),h.interactive(!1),h.pointActive(function(){return!1}),i.orient("bottom").tickPadding(5),j.orient("left"),k.orient("bottom").tickPadding(5),l.orient("left"),o.valueFormatter(function(a,b){return j.tickFormat()(a,b)}).headerFormatter(function(a,b){return i.tickFormat()(a,b)});var E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return g.dispatch.on("elementMouseover.tooltip",function(a){o.data(a).position(a.pos).hidden(!1)}),g.dispatch.on("elementMouseout.tooltip",function(){o.hidden(!0)}),b.dispatch=A,b.legend=m,b.lines=g,b.lines2=h,b.xAxis=i,b.yAxis=j,b.x2Axis=k,b.y2Axis=l,b.interactiveLayer=p,b.tooltip=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return t},set:function(a){t=a}},height:{get:function(){return u},set:function(a){u=a}},focusHeight:{get:function(){return v},set:function(a){v=a}},showLegend:{get:function(){return x},set:function(a){x=a}},brushExtent:{get:function(){return y},set:function(a){y=a}},defaultState:{get:function(){return D},set:function(a){D=a}},noData:{get:function(){return z},set:function(a){z=a}},tooltips:{get:function(){return o.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),o.enabled(!!b)}},tooltipContent:{get:function(){return o.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),o.contentGenerator(b)}},margin:{get:function(){return q},set:function(a){q.top=void 0!==a.top?a.top:q.top,q.right=void 0!==a.right?a.right:q.right,q.bottom=void 0!==a.bottom?a.bottom:q.bottom,q.left=void 0!==a.left?a.left:q.left}},focusMargin:{get:function(){return r},set:function(a){r.top=void 0!==a.top?a.top:r.top,r.right=void 0!==a.right?a.right:r.right,r.bottom=void 0!==a.bottom?a.bottom:r.bottom,r.left=void 0!==a.left?a.left:r.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b),m.color(s)}},interpolate:{get:function(){return g.interpolate()},set:function(a){g.interpolate(a),h.interpolate(a)}},xTickFormat:{get:function(){return i.tickFormat()},set:function(a){i.tickFormat(a),k.tickFormat(a)}},yTickFormat:{get:function(){return j.tickFormat()},set:function(a){j.tickFormat(a),l.tickFormat(a)}},duration:{get:function(){return B},set:function(a){B=a,j.duration(B),l.duration(B),i.duration(B),k.duration(B)}},x:{get:function(){return g.x()},set:function(a){g.x(a),h.x(a)}},y:{get:function(){return g.y()},set:function(a){g.y(a),h.y(a)}},useInteractiveGuideline:{get:function(){return w},set:function(a){w=a,w&&(g.interactive(!1),g.useVoronoi(!1))}}}),a.utils.inheritOptions(b,g),a.utils.initOptions(b),b},a.models.multiBar=function(){"use strict";function b(G){return E.reset(),G.each(function(b){var G=k-j.left-j.right,H=l-j.top-j.bottom;p=d3.select(this),a.utils.initSVG(p);var I=0;if(z&&b.length&&(z=[{values:b[0].values.map(function(a){return{x:a.x,y:0,series:a.series,size:.01}})}]),v){var J=d3.layout.stack().offset(w).values(function(a){return a.values}).y(r)(!b.length&&z?z:b);J.forEach(function(a,c){a.nonStackable?(b[c].nonStackableSeries=I++,J[c]=b[c]):c>0&&J[c-1].nonStackable&&J[c].values.map(function(a,b){a.y0-=J[c-1].values[b].y,a.y1=a.y0+a.y})}),b=J}b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),v&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a,f){if(!b[f].nonStackable){var g=a.values[c];g.size=Math.abs(g.y),g.y<0?(g.y1=e,e-=g.size):(g.y1=g.size+d,d+=g.size)}})});var K=d&&e?[]:b.map(function(a,b){return a.values.map(function(a,c){return{x:q(a,c),y:r(a,c),y0:a.y0,y1:a.y1,idx:b,yErr:s(a,c)}})});m.domain(d||d3.merge(K).map(function(a){return a.x})).rangeBands(f||[0,G],C),n.domain(e||d3.extent(d3.merge(d3.merge(K).map(function(a){var c=a.y;v&&!b[a.idx].nonStackable&&(c=a.y>0?a.y1:a.y1+a.y);var d=a.yErr;return d?d.length?[c+d[0],c+d[1]]:(d=Math.abs(d),[c-d,c+d]):[c]})).concat(t))).range(g||[H,0]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]+.01*n.domain()[0],n.domain()[1]-.01*n.domain()[1]]:[-1,1]),h=h||m,i=i||n;var L=p.selectAll("g.nv-wrap.nv-multibar").data([b]),M=L.enter().append("g").attr("class","nvd3 nv-wrap nv-multibar"),N=M.append("defs"),O=M.append("g"),P=L.select("g");O.append("g").attr("class","nv-groups"),L.attr("transform","translate("+j.left+","+j.top+")"),N.append("clipPath").attr("id","nv-edge-clip-"+o).append("rect"),L.select("#nv-edge-clip-"+o+" rect").attr("width",G).attr("height",H),P.attr("clip-path",u?"url(#nv-edge-clip-"+o+")":"");var Q=L.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});Q.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);var R=E.transition(Q.exit().selectAll("g.nv-bar"),"multibarExit",Math.min(100,B)).attr("y",function(a){var c=i(0)||0;return v&&b[a.series]&&!b[a.series].nonStackable&&(c=i(a.y0)),c}).attr("height",0).remove();R.delay&&R.delay(function(a,b){var c=b*(B/(F+1))-b;return c}),Q.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return x(a,b)}).style("stroke",function(a,b){return x(a,b)}),Q.style("stroke-opacity",1).style("fill-opacity",.75);var S=Q.selectAll("g.nv-bar").data(function(a){return z&&!b.length?z.values:a.values});S.exit().remove();var T=S.enter().append("g").attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("transform",function(a,c,d){var e=v&&!b[d].nonStackable?0:d*m.rangeBand()/b.length,f=i(v&&!b[d].nonStackable?a.y0:0)||0;return"translate("+e+","+f+")"});T.append("rect").attr("height",0).attr("width",function(a,c,d){return m.rangeBand()/(v&&!b[d].nonStackable?1:b.length)}).style("fill",function(a,b,c){return x(a,c,b)}).style("stroke",function(a,b,c){return x(a,c,b)}),S.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),D.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){D.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){D.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){D.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),s(b[0].values[0],0)&&(T.append("polyline"),S.select("polyline").attr("fill","none").attr("stroke",function(a,b,c){return y(a,c,b)}).attr("points",function(a,c){var d=s(a,c),e=.8*m.rangeBand()/(2*(v?1:b.length));d=d.length?d:[-Math.abs(d),Math.abs(d)],d=d.map(function(a){return n(a)-n(0)});var f=[[-e,d[0]],[e,d[0]],[0,d[0]],[0,d[1]],[-e,d[1]],[e,d[1]]];return f.map(function(a){return a.join(",")}).join(" ")}).attr("transform",function(a,c){var d=m.rangeBand()/(2*(v?1:b.length)),e=r(a,c)<0?n(r(a,c))-n(0):0;return"translate("+d+", "+e+")"})),S.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}),A&&(c||(c=b.map(function(){return!0})),S.select("rect").style("fill",function(a,b,d){return d3.rgb(A(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(A(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}));var U=S.watchTransition(E,"multibar",Math.min(250,B)).delay(function(a,c){return c*B/b[0].values.length});v?U.attr("transform",function(a,c,d){var e=0;e=b[d].nonStackable?r(a,c)<0?n(0):n(0)-n(r(a,c))<-1?n(0)-1:n(r(a,c))||0:n(a.y1);var f=0;b[d].nonStackable&&(f=a.series*m.rangeBand()/b.length,b.length!==I&&(f=b[d].nonStackableSeries*m.rangeBand()/(2*I)));var g=f+m(q(a,c));return"translate("+g+","+e+")"}).select("rect").attr("height",function(a,c,d){return b[d].nonStackable?Math.max(Math.abs(n(r(a,c))-n(0)),1)||0:Math.max(Math.abs(n(a.y+a.y0)-n(a.y0)),1)}).attr("width",function(a,c,d){if(b[d].nonStackable){var e=m.rangeBand()/I;return b.length!==I&&(e=m.rangeBand()/(2*I)),e}return m.rangeBand()}):U.attr("transform",function(a,c){var d=a.series*m.rangeBand()/b.length+m(q(a,c)),e=r(a,c)<0?n(0):n(0)-n(r(a,c))<1?n(0)-1:n(r(a,c))||0;return"translate("+d+","+e+")"}).select("rect").attr("width",m.rangeBand()/b.length).attr("height",function(a,b){return Math.max(Math.abs(n(r(a,b))-n(0)),1)||0}),h=m.copy(),i=n.copy(),b[0]&&b[0].values&&(F=b[0].values.length)}),E.renderEnd("multibar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=d3.scale.ordinal(),n=d3.scale.linear(),o=Math.floor(1e4*Math.random()),p=null,q=function(a){return a.x},r=function(a){return a.y},s=function(a){return a.yErr},t=[0],u=!0,v=!1,w="zero",x=a.utils.defaultColor(),y=a.utils.defaultColor(),z=!1,A=null,B=500,C=.1,D=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),E=a.utils.renderWatch(D,B),F=0;return b.dispatch=D,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},yErr:{get:function(){return s},set:function(a){s=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return t},set:function(a){t=a}},stacked:{get:function(){return v},set:function(a){v=a}},stackOffset:{get:function(){return w},set:function(a){w=a}},clipEdge:{get:function(){return u},set:function(a){u=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return o},set:function(a){o=a}},hideable:{get:function(){return z
  19309. },set:function(a){z=a}},groupSpacing:{get:function(){return C},set:function(a){C=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return B},set:function(a){B=a,E.reset(B)}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}},barColor:{get:function(){return A},set:function(b){A=b?a.utils.getColor(b):null}},errorBarColor:{get:function(){return y},set:function(b){y=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarChart=function(){"use strict";function b(j){return D.reset(),D.models(e),r&&D.models(f),s&&D.models(g),j.each(function(j){var z=d3.select(this);a.utils.initSVG(z);var D=a.utils.availableWidth(l,z,k),H=a.utils.availableHeight(m,z,k);if(b.update=function(){0===C?z.call(b):z.transition().duration(C).call(b)},b.container=this,x.setter(G(j),b.update).getter(F(j)).update(),x.disabled=j.map(function(a){return!!a.disabled}),!y){var I;y={};for(I in x)y[I]=x[I]instanceof Array?x[I].slice(0):x[I]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,z),b;z.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var J=z.selectAll("g.nv-wrap.nv-multiBarWithLegend").data([j]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarWithLegend").append("g"),L=J.select("g");if(K.append("g").attr("class","nv-x nv-axis"),K.append("g").attr("class","nv-y nv-axis"),K.append("g").attr("class","nv-barsWrap"),K.append("g").attr("class","nv-legendWrap"),K.append("g").attr("class","nv-controlsWrap"),q&&(h.width(D-B()),L.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),H=a.utils.availableHeight(m,z,k)),L.select(".nv-legendWrap").attr("transform","translate("+B()+","+-k.top+")")),o){var M=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(B()).color(["#444","#444","#444"]),L.select(".nv-controlsWrap").datum(M).attr("transform","translate(0,"+-k.top+")").call(i)}J.attr("transform","translate("+k.left+","+k.top+")"),t&&L.select(".nv-y.nv-axis").attr("transform","translate("+D+",0)"),e.disabled(j.map(function(a){return a.disabled})).width(D).height(H).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var N=L.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(N.call(e),r){f.scale(c)._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-H,0),L.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),L.select(".nv-x.nv-axis").call(f);var O=L.select(".nv-x.nv-axis > g").selectAll("g");if(O.selectAll("line, text").style("opacity",1),v){var P=function(a,b){return"translate("+a+","+b+")"},Q=5,R=17;O.selectAll("text").attr("transform",function(a,b,c){return P(0,c%2==0?Q:R)});var S=d3.selectAll(".nv-x.nv-axis .nv-wrap g g text")[0].length;L.selectAll(".nv-x.nv-axis .nv-axisMaxMin text").attr("transform",function(a,b){return P(0,0===b||S%2!==0?R:Q)})}u&&O.filter(function(a,b){return b%Math.ceil(j[0].values.length/(D/100))!==0}).selectAll("text, line").style("opacity",0),w&&O.selectAll(".tick text").attr("transform","rotate("+w+" 0,0)").style("text-anchor",w>0?"start":"end"),L.select(".nv-x.nv-axis").selectAll("g.nv-axisMaxMin text").style("opacity",1)}s&&(g.scale(d)._ticks(a.utils.calcTicksY(H/36,j)).tickSize(-D,0),L.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)x[c]=a[c];A.stateChange(x),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(M=M.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":case p.grouped:e.stacked(!1);break;case"Stacked":case p.stacked:e.stacked(!0)}x.stacked=e.stacked(),A.stateChange(x),b.update()}}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),x.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),x.stacked=a.stacked,E=a.stacked),b.update()})}),D.renderEnd("multibarchart immediate"),b}var c,d,e=a.models.multiBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=0,x=a.utils.state(),y=null,z=null,A=d3.dispatch("stateChange","changeState","renderEnd"),B=function(){return o?180:0},C=250;x.stacked=!1,e.stacked(!1),f.orient("bottom").tickPadding(7).showMaxMin(!1).tickFormat(function(a){return a}),g.orient(t?"right":"left").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var D=a.utils.renderWatch(A),E=!1,F=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:E}}},G=function(a){return function(b){void 0!==b.stacked&&(E=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=A,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=x,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return y},set:function(a){y=a}},noData:{get:function(){return z},set:function(a){z=a}},reduceXTicks:{get:function(){return u},set:function(a){u=a}},rotateLabels:{get:function(){return w},set:function(a){w=a}},staggerLabels:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return C},set:function(a){C=a,e.duration(C),f.duration(C),g.duration(C),D.reset(C)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiBarHorizontal=function(){"use strict";function b(m){return F.reset(),m.each(function(b){var m=k-j.left-j.right,D=l-j.top-j.bottom;n=d3.select(this),a.utils.initSVG(n),x&&(b=d3.layout.stack().offset("zero").values(function(a){return a.values}).y(r)(b)),b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),x&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a){var b=a.values[c];b.size=Math.abs(b.y),b.y<0?(b.y1=e-b.size,e-=b.size):(b.y1=d,d+=b.size)})});var G=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:q(a,b),y:r(a,b),y0:a.y0,y1:a.y1,yErr:s(a,b)}})});o.domain(d||d3.merge(G).map(function(a){return a.x})).rangeBands(f||[0,D],B),p.domain(e||d3.extent(d3.merge(d3.merge(G).map(function(a){var b=a.y;x&&(b=a.y>0?a.y1+a.y:a.y1);var c=a.yErr;return c?c.length?[b+c[0],b+c[1]]:(c=Math.abs(c),[b-c,b+c]):[b]})).concat(t))),p.range(y&&!x?g||[p.domain()[0]<0?A:0,m-(p.domain()[1]>0?A:0)]:g||[0,m]),h=h||o,i=i||d3.scale.linear().domain(p.domain()).range([p(0),p(0)]);{var H=d3.select(this).selectAll("g.nv-wrap.nv-multibarHorizontal").data([b]),I=H.enter().append("g").attr("class","nvd3 nv-wrap nv-multibarHorizontal"),J=(I.append("defs"),I.append("g"));H.select("g")}J.append("g").attr("class","nv-groups"),H.attr("transform","translate("+j.left+","+j.top+")");var K=H.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});K.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),K.exit().watchTransition(F,"multibarhorizontal: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),K.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return u(a,b)}).style("stroke",function(a,b){return u(a,b)}),K.watchTransition(F,"multibarhorizontal: groups").style("stroke-opacity",1).style("fill-opacity",.75);var L=K.selectAll("g.nv-bar").data(function(a){return a.values});L.exit().remove();var M=L.enter().append("g").attr("transform",function(a,c,d){return"translate("+i(x?a.y0:0)+","+(x?0:d*o.rangeBand()/b.length+o(q(a,c)))+")"});M.append("rect").attr("width",0).attr("height",o.rangeBand()/(x?1:b.length)),L.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),E.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),E.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){E.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){E.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){E.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){E.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),s(b[0].values[0],0)&&(M.append("polyline"),L.select("polyline").attr("fill","none").attr("stroke",function(a,b,c){return w(a,c,b)}).attr("points",function(a,c){var d=s(a,c),e=.8*o.rangeBand()/(2*(x?1:b.length));d=d.length?d:[-Math.abs(d),Math.abs(d)],d=d.map(function(a){return p(a)-p(0)});var f=[[d[0],-e],[d[0],e],[d[0],0],[d[1],0],[d[1],-e],[d[1],e]];return f.map(function(a){return a.join(",")}).join(" ")}).attr("transform",function(a,c){var d=o.rangeBand()/(2*(x?1:b.length));return"translate("+(r(a,c)<0?0:p(r(a,c))-p(0))+", "+d+")"})),M.append("text"),y&&!x?(L.select("text").attr("text-anchor",function(a,b){return r(a,b)<0?"end":"start"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){var c=C(r(a,b)),d=s(a,b);return void 0===d?c:d.length?c+"+"+C(Math.abs(d[1]))+"-"+C(Math.abs(d[0])):c+"±"+C(Math.abs(d))}),L.watchTransition(F,"multibarhorizontal: bars").select("text").attr("x",function(a,b){return r(a,b)<0?-4:p(r(a,b))-p(0)+4})):L.selectAll("text").text(""),z&&!x?(M.append("text").classed("nv-bar-label",!0),L.select("text.nv-bar-label").attr("text-anchor",function(a,b){return r(a,b)<0?"start":"end"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){return q(a,b)}),L.watchTransition(F,"multibarhorizontal: bars").select("text.nv-bar-label").attr("x",function(a,b){return r(a,b)<0?p(0)-p(r(a,b))+4:-4})):L.selectAll("text.nv-bar-label").text(""),L.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}),v&&(c||(c=b.map(function(){return!0})),L.style("fill",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()})),x?L.watchTransition(F,"multibarhorizontal: bars").attr("transform",function(a,b){return"translate("+p(a.y1)+","+o(q(a,b))+")"}).select("rect").attr("width",function(a,b){return Math.abs(p(r(a,b)+a.y0)-p(a.y0))}).attr("height",o.rangeBand()):L.watchTransition(F,"multibarhorizontal: bars").attr("transform",function(a,c){return"translate("+p(r(a,c)<0?r(a,c):0)+","+(a.series*o.rangeBand()/b.length+o(q(a,c)))+")"}).select("rect").attr("height",o.rangeBand()/b.length).attr("width",function(a,b){return Math.max(Math.abs(p(r(a,b))-p(0)),1)}),h=o.copy(),i=p.copy()}),F.renderEnd("multibarHorizontal immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=null,o=d3.scale.ordinal(),p=d3.scale.linear(),q=function(a){return a.x},r=function(a){return a.y},s=function(a){return a.yErr},t=[0],u=a.utils.defaultColor(),v=null,w=a.utils.defaultColor(),x=!1,y=!1,z=!1,A=60,B=.1,C=d3.format(",.2f"),D=250,E=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),F=a.utils.renderWatch(E,D);return b.dispatch=E,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},yErr:{get:function(){return s},set:function(a){s=a}},xScale:{get:function(){return o},set:function(a){o=a}},yScale:{get:function(){return p},set:function(a){p=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return t},set:function(a){t=a}},stacked:{get:function(){return x},set:function(a){x=a}},showValues:{get:function(){return y},set:function(a){y=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return m},set:function(a){m=a}},valueFormat:{get:function(){return C},set:function(a){C=a}},valuePadding:{get:function(){return A},set:function(a){A=a}},groupSpacing:{get:function(){return B},set:function(a){B=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return D},set:function(a){D=a,F.reset(D)}},color:{get:function(){return u},set:function(b){u=a.utils.getColor(b)}},barColor:{get:function(){return v},set:function(b){v=b?a.utils.getColor(b):null}},errorBarColor:{get:function(){return w},set:function(b){w=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarHorizontalChart=function(){"use strict";function b(j){return C.reset(),C.models(e),r&&C.models(f),s&&C.models(g),j.each(function(j){var w=d3.select(this);a.utils.initSVG(w);var C=a.utils.availableWidth(l,w,k),D=a.utils.availableHeight(m,w,k);if(b.update=function(){w.transition().duration(z).call(b)},b.container=this,t=e.stacked(),u.setter(B(j),b.update).getter(A(j)).update(),u.disabled=j.map(function(a){return!!a.disabled}),!v){var E;v={};for(E in u)v[E]=u[E]instanceof Array?u[E].slice(0):u[E]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,w),b;w.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var F=w.selectAll("g.nv-wrap.nv-multiBarHorizontalChart").data([j]),G=F.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarHorizontalChart").append("g"),H=F.select("g");if(G.append("g").attr("class","nv-x nv-axis"),G.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),G.append("g").attr("class","nv-barsWrap"),G.append("g").attr("class","nv-legendWrap"),G.append("g").attr("class","nv-controlsWrap"),q&&(h.width(C-y()),H.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),D=a.utils.availableHeight(m,w,k)),H.select(".nv-legendWrap").attr("transform","translate("+y()+","+-k.top+")")),o){var I=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(y()).color(["#444","#444","#444"]),H.select(".nv-controlsWrap").datum(I).attr("transform","translate(0,"+-k.top+")").call(i)}F.attr("transform","translate("+k.left+","+k.top+")"),e.disabled(j.map(function(a){return a.disabled})).width(C).height(D).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var J=H.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(J.transition().call(e),r){f.scale(c)._ticks(a.utils.calcTicksY(D/24,j)).tickSize(-C,0),H.select(".nv-x.nv-axis").call(f);var K=H.select(".nv-x.nv-axis").selectAll("g");K.selectAll("line, text")}s&&(g.scale(d)._ticks(a.utils.calcTicksX(C/100,j)).tickSize(-D,0),H.select(".nv-y.nv-axis").attr("transform","translate(0,"+D+")"),H.select(".nv-y.nv-axis").call(g)),H.select(".nv-zeroLine line").attr("x1",d(0)).attr("x2",d(0)).attr("y1",0).attr("y2",-D),h.dispatch.on("stateChange",function(a){for(var c in a)u[c]=a[c];x.stateChange(u),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(I=I.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":e.stacked(!1);break;case"Stacked":e.stacked(!0)}u.stacked=e.stacked(),x.stateChange(u),t=e.stacked(),b.update()}}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),u.stacked=a.stacked,t=a.stacked),b.update()})}),C.renderEnd("multibar horizontal chart immediate"),b}var c,d,e=a.models.multiBarHorizontal(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend().height(30),i=a.models.legend().height(30),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=a.utils.state(),v=null,w=null,x=d3.dispatch("stateChange","changeState","renderEnd"),y=function(){return o?180:0},z=250;u.stacked=!1,e.stacked(t),f.orient("left").tickPadding(5).showMaxMin(!1).tickFormat(function(a){return a}),g.orient("bottom").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var A=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:t}}},B=function(a){return function(b){void 0!==b.stacked&&(t=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},C=a.utils.renderWatch(x,z);return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=x,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=u,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z),e.duration(z),f.duration(z),g.duration(z)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiChart=function(){"use strict";function b(j){return j.each(function(j){function k(a){var b=2===j[a.seriesIndex].yAxis?B:A;a.value=a.point.x,a.series={value:a.point.y,color:a.point.color},D.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function l(a){var b=2===j[a.seriesIndex].yAxis?B:A;a.value=a.point.x,a.series={value:a.point.y,color:a.point.color},D.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function n(a){var b=2===j[a.seriesIndex].yAxis?B:A;a.point.x=x.x()(a.point),a.point.y=x.y()(a.point),D.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function E(a){var b=2===j[a.data.series].yAxis?B:A;a.value=v.x()(a.data),a.series={value:v.y()(a.data),color:a.color},D.duration(0).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).hidden(!1)}var F=d3.select(this);a.utils.initSVG(F),b.update=function(){F.transition().call(b)},b.container=this;var G=a.utils.availableWidth(g,F,e),H=a.utils.availableHeight(h,F,e),I=j.filter(function(a){return"line"==a.type&&1==a.yAxis}),J=j.filter(function(a){return"line"==a.type&&2==a.yAxis}),K=j.filter(function(a){return"scatter"==a.type&&1==a.yAxis}),L=j.filter(function(a){return"scatter"==a.type&&2==a.yAxis}),M=j.filter(function(a){return"bar"==a.type&&1==a.yAxis}),N=j.filter(function(a){return"bar"==a.type&&2==a.yAxis}),O=j.filter(function(a){return"area"==a.type&&1==a.yAxis}),P=j.filter(function(a){return"area"==a.type&&2==a.yAxis});if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,F),b;F.selectAll(".nv-noData").remove();var Q=j.filter(function(a){return!a.disabled&&1==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})}),R=j.filter(function(a){return!a.disabled&&2==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})});o.domain(d3.extent(d3.merge(Q.concat(R)),function(a){return a.x})).range([0,G]);var S=F.selectAll("g.wrap.multiChart").data([j]),T=S.enter().append("g").attr("class","wrap nvd3 multiChart").append("g");T.append("g").attr("class","nv-x nv-axis"),T.append("g").attr("class","nv-y1 nv-axis"),T.append("g").attr("class","nv-y2 nv-axis"),T.append("g").attr("class","lines1Wrap"),T.append("g").attr("class","lines2Wrap"),T.append("g").attr("class","scatters1Wrap"),T.append("g").attr("class","scatters2Wrap"),T.append("g").attr("class","bars1Wrap"),T.append("g").attr("class","bars2Wrap"),T.append("g").attr("class","stack1Wrap"),T.append("g").attr("class","stack2Wrap"),T.append("g").attr("class","legendWrap");var U=S.select("g"),V=j.map(function(a,b){return j[b].color||f(a,b)});if(i){var W=C.align()?G/2:G,X=C.align()?W:0;C.width(W),C.color(V),U.select(".legendWrap").datum(j.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(1==a.yAxis?"":" (right axis)"),a})).call(C),e.top!=C.height()&&(e.top=C.height(),H=a.utils.availableHeight(h,F,e)),U.select(".legendWrap").attr("transform","translate("+X+","+-e.top+")")}r.width(G).height(H).interpolate(m).color(V.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"line"==j[b].type})),s.width(G).height(H).interpolate(m).color(V.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"line"==j[b].type})),t.width(G).height(H).color(V.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"scatter"==j[b].type})),u.width(G).height(H).color(V.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"scatter"==j[b].type})),v.width(G).height(H).color(V.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"bar"==j[b].type})),w.width(G).height(H).color(V.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"bar"==j[b].type})),x.width(G).height(H).color(V.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"area"==j[b].type})),y.width(G).height(H).color(V.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"area"==j[b].type})),U.attr("transform","translate("+e.left+","+e.top+")");var Y=U.select(".lines1Wrap").datum(I.filter(function(a){return!a.disabled})),Z=U.select(".scatters1Wrap").datum(K.filter(function(a){return!a.disabled})),$=U.select(".bars1Wrap").datum(M.filter(function(a){return!a.disabled})),_=U.select(".stack1Wrap").datum(O.filter(function(a){return!a.disabled})),ab=U.select(".lines2Wrap").datum(J.filter(function(a){return!a.disabled})),bb=U.select(".scatters2Wrap").datum(L.filter(function(a){return!a.disabled})),cb=U.select(".bars2Wrap").datum(N.filter(function(a){return!a.disabled})),db=U.select(".stack2Wrap").datum(P.filter(function(a){return!a.disabled})),eb=O.length?O.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[],fb=P.length?P.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[];p.domain(c||d3.extent(d3.merge(Q).concat(eb),function(a){return a.y})).range([0,H]),q.domain(d||d3.extent(d3.merge(R).concat(fb),function(a){return a.y})).range([0,H]),r.yDomain(p.domain()),t.yDomain(p.domain()),v.yDomain(p.domain()),x.yDomain(p.domain()),s.yDomain(q.domain()),u.yDomain(q.domain()),w.yDomain(q.domain()),y.yDomain(q.domain()),O.length&&d3.transition(_).call(x),P.length&&d3.transition(db).call(y),M.length&&d3.transition($).call(v),N.length&&d3.transition(cb).call(w),I.length&&d3.transition(Y).call(r),J.length&&d3.transition(ab).call(s),K.length&&d3.transition(Z).call(t),L.length&&d3.transition(bb).call(u),z._ticks(a.utils.calcTicksX(G/100,j)).tickSize(-H,0),U.select(".nv-x.nv-axis").attr("transform","translate(0,"+H+")"),d3.transition(U.select(".nv-x.nv-axis")).call(z),A._ticks(a.utils.calcTicksY(H/36,j)).tickSize(-G,0),d3.transition(U.select(".nv-y1.nv-axis")).call(A),B._ticks(a.utils.calcTicksY(H/36,j)).tickSize(-G,0),d3.transition(U.select(".nv-y2.nv-axis")).call(B),U.select(".nv-y1.nv-axis").classed("nv-disabled",Q.length?!1:!0).attr("transform","translate("+o.range()[0]+",0)"),U.select(".nv-y2.nv-axis").classed("nv-disabled",R.length?!1:!0).attr("transform","translate("+o.range()[1]+",0)"),C.dispatch.on("stateChange",function(){b.update()}),r.dispatch.on("elementMouseover.tooltip",k),s.dispatch.on("elementMouseover.tooltip",k),r.dispatch.on("elementMouseout.tooltip",function(){D.hidden(!0)}),s.dispatch.on("elementMouseout.tooltip",function(){D.hidden(!0)}),t.dispatch.on("elementMouseover.tooltip",l),u.dispatch.on("elementMouseover.tooltip",l),t.dispatch.on("elementMouseout.tooltip",function(){D.hidden(!0)}),u.dispatch.on("elementMouseout.tooltip",function(){D.hidden(!0)}),x.dispatch.on("elementMouseover.tooltip",n),y.dispatch.on("elementMouseover.tooltip",n),x.dispatch.on("elementMouseout.tooltip",function(){D.hidden(!0)}),y.dispatch.on("elementMouseout.tooltip",function(){D.hidden(!0)}),v.dispatch.on("elementMouseover.tooltip",E),w.dispatch.on("elementMouseover.tooltip",E),v.dispatch.on("elementMouseout.tooltip",function(){D.hidden(!0)}),w.dispatch.on("elementMouseout.tooltip",function(){D.hidden(!0)}),v.dispatch.on("elementMousemove.tooltip",function(){D.position({top:d3.event.pageY,left:d3.event.pageX})()}),w.dispatch.on("elementMousemove.tooltip",function(){D.position({top:d3.event.pageY,left:d3.event.pageX})()})}),b}var c,d,e={top:30,right:20,bottom:50,left:60},f=a.utils.defaultColor(),g=null,h=null,i=!0,j=null,k=function(a){return a.x},l=function(a){return a.y},m="monotone",n=!0,o=d3.scale.linear(),p=d3.scale.linear(),q=d3.scale.linear(),r=a.models.line().yScale(p),s=a.models.line().yScale(q),t=a.models.scatter().yScale(p),u=a.models.scatter().yScale(q),v=a.models.multiBar().stacked(!1).yScale(p),w=a.models.multiBar().stacked(!1).yScale(q),x=a.models.stackedArea().yScale(p),y=a.models.stackedArea().yScale(q),z=a.models.axis().scale(o).orient("bottom").tickPadding(5),A=a.models.axis().scale(p).orient("left"),B=a.models.axis().scale(q).orient("right"),C=a.models.legend().height(30),D=a.models.tooltip(),E=d3.dispatch();return b.dispatch=E,b.lines1=r,b.lines2=s,b.scatters1=t,b.scatters2=u,b.bars1=v,b.bars2=w,b.stack1=x,b.stack2=y,b.xAxis=z,b.yAxis1=A,b.yAxis2=B,b.tooltip=D,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},showLegend:{get:function(){return i},set:function(a){i=a}},yDomain1:{get:function(){return c},set:function(a){c=a}},yDomain2:{get:function(){return d},set:function(a){d=a}},noData:{get:function(){return j},set:function(a){j=a}},interpolate:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return D.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),D.enabled(!!b)}},tooltipContent:{get:function(){return D.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),D.contentGenerator(b)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return f},set:function(b){f=a.utils.getColor(b)}},x:{get:function(){return k},set:function(a){k=a,r.x(a),s.x(a),t.x(a),u.x(a),v.x(a),w.x(a),x.x(a),y.x(a)}},y:{get:function(){return l},set:function(a){l=a,r.y(a),s.y(a),t.y(a),u.y(a),x.y(a),y.y(a),v.y(a),w.y(a)}},useVoronoi:{get:function(){return n},set:function(a){n=a,r.useVoronoi(a),s.useVoronoi(a),x.useVoronoi(a),y.useVoronoi(a)}}}),a.utils.initOptions(b),b},a.models.ohlcBar=function(){"use strict";function b(y){return y.each(function(b){k=d3.select(this);var y=a.utils.availableWidth(h,k,g),A=a.utils.availableHeight(i,k,g);a.utils.initSVG(k);var B=y/b[0].values.length*.9;l.domain(c||d3.extent(b[0].values.map(n).concat(t))),l.range(v?e||[.5*y/b[0].values.length,y*(b[0].values.length-.5)/b[0].values.length]:e||[5+B/2,y-B/2-5]),m.domain(d||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(f||[A,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var C=d3.select(this).selectAll("g.nv-wrap.nv-ohlcBar").data([b[0].values]),D=C.enter().append("g").attr("class","nvd3 nv-wrap nv-ohlcBar"),E=D.append("defs"),F=D.append("g"),G=C.select("g");F.append("g").attr("class","nv-ticks"),C.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:j})}),E.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),C.select("#nv-chart-clip-path-"+j+" rect").attr("width",y).attr("height",A),G.attr("clip-path",w?"url(#nv-chart-clip-path-"+j+")":"");var H=C.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});H.exit().remove(),H.enter().append("path").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b
  19310. }).attr("d",function(a,b){return"m0,0l0,"+(m(p(a,b))-m(r(a,b)))+"l"+-B/2+",0l"+B/2+",0l0,"+(m(s(a,b))-m(p(a,b)))+"l0,"+(m(q(a,b))-m(s(a,b)))+"l"+B/2+",0l"+-B/2+",0z"}).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("fill",function(){return x[0]}).attr("stroke",function(){return x[0]}).attr("x",0).attr("y",function(a,b){return m(Math.max(0,o(a,b)))}).attr("height",function(a,b){return Math.abs(m(o(a,b))-m(0))}),H.attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}),d3.transition(H).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("d",function(a,c){var d=y/b[0].values.length*.9;return"m0,0l0,"+(m(p(a,c))-m(r(a,c)))+"l"+-d/2+",0l"+d/2+",0l0,"+(m(s(a,c))-m(p(a,c)))+"l0,"+(m(q(a,c))-m(s(a,c)))+"l"+d/2+",0l"+-d/2+",0z"})}),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,c){b.clearHighlights(),k.select(".nv-ohlcBar .nv-tick-0-"+a).classed("hover",c)},b.clearHighlights=function(){k.select(".nv-ohlcBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!=a.top?a.top:g.top,g.right=void 0!=a.right?a.right:g.right,g.bottom=void 0!=a.bottom?a.bottom:g.bottom,g.left=void 0!=a.left?a.left:g.left}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.parallelCoordinates=function(){"use strict";function b(p){return p.each(function(b){function p(a){return F(h.map(function(b){if(isNaN(a[b])||isNaN(parseFloat(a[b]))){var c=g[b].domain(),d=g[b].range(),e=c[0]-(c[1]-c[0])/9;if(J.indexOf(b)<0){var h=d3.scale.linear().domain([e,c[1]]).range([x-12,d[1]]);g[b].brush.y(h),J.push(b)}return[f(b),g[b](e)]}return J.length>0?(D.style("display","inline"),E.style("display","inline")):(D.style("display","none"),E.style("display","none")),[f(b),g[b](a[b])]}))}function q(){var a=h.filter(function(a){return!g[a].brush.empty()}),b=a.map(function(a){return g[a].brush.extent()});k=[],a.forEach(function(a,c){k[c]={dimension:a,extent:b[c]}}),l=[],M.style("display",function(c){var d=a.every(function(a,d){return isNaN(c[a])&&b[d][0]==g[a].brush.y().domain()[0]?!0:b[d][0]<=c[a]&&c[a]<=b[d][1]});return d&&l.push(c),d?null:"none"}),o.brush({filters:k,active:l})}function r(a){m[a]=this.parentNode.__origin__=f(a),L.attr("visibility","hidden")}function s(a){m[a]=Math.min(w,Math.max(0,this.parentNode.__origin__+=d3.event.x)),M.attr("d",p),h.sort(function(a,b){return u(a)-u(b)}),f.domain(h),N.attr("transform",function(a){return"translate("+u(a)+")"})}function t(a){delete this.parentNode.__origin__,delete m[a],d3.select(this.parentNode).attr("transform","translate("+f(a)+")"),M.attr("d",p),L.attr("d",p).attr("visibility",null)}function u(a){var b=m[a];return null==b?f(a):b}var v=d3.select(this),w=a.utils.availableWidth(d,v,c),x=a.utils.availableHeight(e,v,c);a.utils.initSVG(v),l=b,f.rangePoints([0,w],1).domain(h);var y={};h.forEach(function(a){var c=d3.extent(b,function(b){return+b[a]});return y[a]=!1,void 0===c[0]&&(y[a]=!0,c[0]=0,c[1]=0),c[0]===c[1]&&(c[0]=c[0]-1,c[1]=c[1]+1),g[a]=d3.scale.linear().domain(c).range([.9*(x-12),0]),g[a].brush=d3.svg.brush().y(g[a]).on("brush",q),"name"!=a});var z=v.selectAll("g.nv-wrap.nv-parallelCoordinates").data([b]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-parallelCoordinates"),B=A.append("g"),C=z.select("g");B.append("g").attr("class","nv-parallelCoordinates background"),B.append("g").attr("class","nv-parallelCoordinates foreground"),B.append("g").attr("class","nv-parallelCoordinates missingValuesline"),z.attr("transform","translate("+c.left+","+c.top+")");var D,E,F=d3.svg.line().interpolate("cardinal").tension(n),G=d3.svg.axis().orient("left"),H=d3.behavior.drag().on("dragstart",r).on("drag",s).on("dragend",t),I=f.range()[1]-f.range()[0],J=[],K=[0+I/2,x-12,w-I/2,x-12];D=z.select(".missingValuesline").selectAll("line").data([K]),D.enter().append("line"),D.exit().remove(),D.attr("x1",function(a){return a[0]}).attr("y1",function(a){return a[1]}).attr("x2",function(a){return a[2]}).attr("y2",function(a){return a[3]}),E=z.select(".missingValuesline").selectAll("text").data(["undefined values"]),E.append("text").data(["undefined values"]),E.enter().append("text"),E.exit().remove(),E.attr("y",x).attr("x",w-92-I/2).text(function(a){return a});var L=z.select(".background").selectAll("path").data(b);L.enter().append("path"),L.exit().remove(),L.attr("d",p);var M=z.select(".foreground").selectAll("path").data(b);M.enter().append("path"),M.exit().remove(),M.attr("d",p).attr("stroke",j),M.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),o.elementMouseover({label:a.name,data:a.data,index:b,pos:[d3.mouse(this.parentNode)[0],d3.mouse(this.parentNode)[1]]})}),M.on("mouseout",function(a,b){d3.select(this).classed("hover",!1),o.elementMouseout({label:a.name,data:a.data,index:b})});var N=C.selectAll(".dimension").data(h),O=N.enter().append("g").attr("class","nv-parallelCoordinates dimension");O.append("g").attr("class","nv-parallelCoordinates nv-axis"),O.append("g").attr("class","nv-parallelCoordinates-brush"),O.append("text").attr("class","nv-parallelCoordinates nv-label"),N.attr("transform",function(a){return"translate("+f(a)+",0)"}),N.exit().remove(),N.select(".nv-label").style("cursor","move").attr("dy","-1em").attr("text-anchor","middle").text(String).on("mouseover",function(a){o.elementMouseover({dim:a,pos:[d3.mouse(this.parentNode.parentNode)[0],d3.mouse(this.parentNode.parentNode)[1]]})}).on("mouseout",function(a){o.elementMouseout({dim:a})}).call(H),N.select(".nv-axis").each(function(a,b){d3.select(this).call(G.scale(g[a]).tickFormat(d3.format(i[b])))}),N.select(".nv-parallelCoordinates-brush").each(function(a){d3.select(this).call(g[a].brush)}).selectAll("rect").attr("x",-8).attr("width",16)}),b}var c={top:30,right:0,bottom:10,left:0},d=null,e=null,f=d3.scale.ordinal(),g={},h=[],i=[],j=a.utils.defaultColor(),k=[],l=[],m=[],n=1,o=d3.dispatch("brush","elementMouseover","elementMouseout");return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},dimensionNames:{get:function(){return h},set:function(a){h=a}},dimensionFormats:{get:function(){return i},set:function(a){i=a}},lineTension:{get:function(){return n},set:function(a){n=a}},dimensions:{get:function(){return h},set:function(b){a.deprecated("dimensions","use dimensionNames instead"),h=b}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.pie=function(){"use strict";function b(E){return D.reset(),E.each(function(b){function E(a,b){a.endAngle=isNaN(a.endAngle)?0:a.endAngle,a.startAngle=isNaN(a.startAngle)?0:a.startAngle,p||(a.innerRadius=0);var c=d3.interpolate(this._current,a);return this._current=c(0),function(a){return B[b](c(a))}}var F=d-c.left-c.right,G=e-c.top-c.bottom,H=Math.min(F,G)/2,I=[],J=[];if(i=d3.select(this),0===z.length)for(var K=H-H/5,L=y*H,M=0;M<b[0].length;M++)I.push(K),J.push(L);else I=z.map(function(a){return(a.outer-a.outer/5)*H}),J=z.map(function(a){return(a.inner-a.inner/5)*H}),y=d3.min(z.map(function(a){return a.inner-a.inner/5}));a.utils.initSVG(i);var N=i.selectAll(".nv-wrap.nv-pie").data(b),O=N.enter().append("g").attr("class","nvd3 nv-wrap nv-pie nv-chart-"+h),P=O.append("g"),Q=N.select("g"),R=P.append("g").attr("class","nv-pie");P.append("g").attr("class","nv-pieLabels"),N.attr("transform","translate("+c.left+","+c.top+")"),Q.select(".nv-pie").attr("transform","translate("+F/2+","+G/2+")"),Q.select(".nv-pieLabels").attr("transform","translate("+F/2+","+G/2+")"),i.on("click",function(a,b){A.chartClick({data:a,index:b,pos:d3.event,id:h})}),B=[],C=[];for(var M=0;M<b[0].length;M++){var S=d3.svg.arc().outerRadius(I[M]),T=d3.svg.arc().outerRadius(I[M]+5);u!==!1&&(S.startAngle(u),T.startAngle(u)),w!==!1&&(S.endAngle(w),T.endAngle(w)),p&&(S.innerRadius(J[M]),T.innerRadius(J[M])),S.cornerRadius&&x&&(S.cornerRadius(x),T.cornerRadius(x)),B.push(S),C.push(T)}var U=d3.layout.pie().sort(null).value(function(a){return a.disabled?0:g(a)});U.padAngle&&v&&U.padAngle(v),p&&q&&(R.append("text").attr("class","nv-pie-title"),N.select(".nv-pie-title").style("text-anchor","middle").text(function(){return q}).style("font-size",Math.min(F,G)*y*2/(q.length+2)+"px").attr("dy","0.35em").attr("transform",function(){return"translate(0, "+s+")"}));var V=N.select(".nv-pie").selectAll(".nv-slice").data(U),W=N.select(".nv-pieLabels").selectAll(".nv-label").data(U);V.exit().remove(),W.exit().remove();var X=V.enter().append("g");X.attr("class","nv-slice"),X.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),r&&d3.select(this).select("path").transition().duration(70).attr("d",C[b]),A.elementMouseover({data:a.data,index:b,color:d3.select(this).style("fill")})}),X.on("mouseout",function(a,b){d3.select(this).classed("hover",!1),r&&d3.select(this).select("path").transition().duration(50).attr("d",B[b]),A.elementMouseout({data:a.data,index:b})}),X.on("mousemove",function(a,b){A.elementMousemove({data:a.data,index:b})}),X.on("click",function(a,b){A.elementClick({data:a.data,index:b,color:d3.select(this).style("fill")})}),X.on("dblclick",function(a,b){A.elementDblClick({data:a.data,index:b,color:d3.select(this).style("fill")})}),V.attr("fill",function(a,b){return j(a.data,b)}),V.attr("stroke",function(a,b){return j(a.data,b)});X.append("path").each(function(a){this._current=a});if(V.select("path").transition().attr("d",function(a,b){return B[b](a)}).attrTween("d",E),l){for(var Y=[],M=0;M<b[0].length;M++)Y.push(B[M]),m?p&&(Y[M]=d3.svg.arc().outerRadius(B[M].outerRadius()),u!==!1&&Y[M].startAngle(u),w!==!1&&Y[M].endAngle(w)):p||Y[M].innerRadius(0);W.enter().append("g").classed("nv-label",!0).each(function(a){var b=d3.select(this);b.attr("transform",function(a,b){if(t){a.outerRadius=I[b]+10,a.innerRadius=I[b]+15;var c=(a.startAngle+a.endAngle)/2*(180/Math.PI);return(a.startAngle+a.endAngle)/2<Math.PI?c-=90:c+=90,"translate("+Y[b].centroid(a)+") rotate("+c+")"}return a.outerRadius=H+10,a.innerRadius=H+15,"translate("+Y[b].centroid(a)+")"}),b.append("rect").style("stroke","#fff").style("fill","#fff").attr("rx",3).attr("ry",3),b.append("text").style("text-anchor",t?(a.startAngle+a.endAngle)/2<Math.PI?"start":"end":"middle").style("fill","#000")});var Z={},$=14,_=140,ab=function(a){return Math.floor(a[0]/_)*_+","+Math.floor(a[1]/$)*$};W.watchTransition(D,"pie labels").attr("transform",function(a,b){if(t){a.outerRadius=I[b]+10,a.innerRadius=I[b]+15;var c=(a.startAngle+a.endAngle)/2*(180/Math.PI);return(a.startAngle+a.endAngle)/2<Math.PI?c-=90:c+=90,"translate("+Y[b].centroid(a)+") rotate("+c+")"}a.outerRadius=H+10,a.innerRadius=H+15;var d=Y[b].centroid(a);if(a.value){var e=ab(d);Z[e]&&(d[1]-=$),Z[ab(d)]=!0}return"translate("+d+")"}),W.select(".nv-label text").style("text-anchor",function(a){return t?(a.startAngle+a.endAngle)/2<Math.PI?"start":"end":"middle"}).text(function(a,b){var c=(a.endAngle-a.startAngle)/(2*Math.PI),d="";if(!a.value||o>c)return"";if("function"==typeof n)d=n(a,b,{key:f(a.data),value:g(a.data),percent:k(c)});else switch(n){case"key":d=f(a.data);break;case"value":d=k(g(a.data));break;case"percent":d=d3.format("%")(c)}return d})}}),D.renderEnd("pie immediate"),b}var c={top:0,right:0,bottom:0,left:0},d=500,e=500,f=function(a){return a.x},g=function(a){return a.y},h=Math.floor(1e4*Math.random()),i=null,j=a.utils.defaultColor(),k=d3.format(",.2f"),l=!0,m=!1,n="key",o=.02,p=!1,q=!1,r=!0,s=0,t=!1,u=!1,v=!1,w=!1,x=0,y=.5,z=[],A=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),B=[],C=[],D=a.utils.renderWatch(A);return b.dispatch=A,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{arcsRadius:{get:function(){return z},set:function(a){z=a}},width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},showLabels:{get:function(){return l},set:function(a){l=a}},title:{get:function(){return q},set:function(a){q=a}},titleOffset:{get:function(){return s},set:function(a){s=a}},labelThreshold:{get:function(){return o},set:function(a){o=a}},valueFormat:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return h},set:function(a){h=a}},endAngle:{get:function(){return w},set:function(a){w=a}},startAngle:{get:function(){return u},set:function(a){u=a}},padAngle:{get:function(){return v},set:function(a){v=a}},cornerRadius:{get:function(){return x},set:function(a){x=a}},donutRatio:{get:function(){return y},set:function(a){y=a}},labelsOutside:{get:function(){return m},set:function(a){m=a}},labelSunbeamLayout:{get:function(){return t},set:function(a){t=a}},donut:{get:function(){return p},set:function(a){p=a}},growOnHover:{get:function(){return r},set:function(a){r=a}},pieLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("pieLabelsOutside","use labelsOutside instead")}},donutLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("donutLabelsOutside","use labelsOutside instead")}},labelFormat:{get:function(){return k},set:function(b){k=b,a.deprecated("labelFormat","use valueFormat instead")}},margin:{get:function(){return c},set:function(a){c.top="undefined"!=typeof a.top?a.top:c.top,c.right="undefined"!=typeof a.right?a.right:c.right,c.bottom="undefined"!=typeof a.bottom?a.bottom:c.bottom,c.left="undefined"!=typeof a.left?a.left:c.left}},y:{get:function(){return g},set:function(a){g=d3.functor(a)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},labelType:{get:function(){return n},set:function(a){n=a||"key"}}}),a.utils.initOptions(b),b},a.models.pieChart=function(){"use strict";function b(e){return q.reset(),q.models(c),e.each(function(e){var k=d3.select(this);a.utils.initSVG(k);var n=a.utils.availableWidth(g,k,f),o=a.utils.availableHeight(h,k,f);if(b.update=function(){k.transition().call(b)},b.container=this,l.setter(s(e),b.update).getter(r(e)).update(),l.disabled=e.map(function(a){return!!a.disabled}),!m){var q;m={};for(q in l)m[q]=l[q]instanceof Array?l[q].slice(0):l[q]}if(!e||!e.length)return a.utils.noData(b,k),b;k.selectAll(".nv-noData").remove();var t=k.selectAll("g.nv-wrap.nv-pieChart").data([e]),u=t.enter().append("g").attr("class","nvd3 nv-wrap nv-pieChart").append("g"),v=t.select("g");if(u.append("g").attr("class","nv-pieWrap"),u.append("g").attr("class","nv-legendWrap"),i)if("top"===j)d.width(n).key(c.x()),t.select(".nv-legendWrap").datum(e).call(d),f.top!=d.height()&&(f.top=d.height(),o=a.utils.availableHeight(h,k,f)),t.select(".nv-legendWrap").attr("transform","translate(0,"+-f.top+")");else if("right"===j){var w=a.models.legend().width();w>n/2&&(w=n/2),d.height(o).key(c.x()),d.width(w),n-=d.width(),t.select(".nv-legendWrap").datum(e).call(d).attr("transform","translate("+n+",0)")}t.attr("transform","translate("+f.left+","+f.top+")"),c.width(n).height(o);var x=v.select(".nv-pieWrap").datum([e]);d3.transition(x).call(c),d.dispatch.on("stateChange",function(a){for(var c in a)l[c]=a[c];p.stateChange(l),b.update()}),p.on("changeState",function(a){"undefined"!=typeof a.disabled&&(e.forEach(function(b,c){b.disabled=a.disabled[c]}),l.disabled=a.disabled),b.update()})}),q.renderEnd("pieChart immediate"),b}var c=a.models.pie(),d=a.models.legend(),e=a.models.tooltip(),f={top:30,right:20,bottom:20,left:20},g=null,h=null,i=!0,j="top",k=a.utils.defaultColor(),l=a.utils.state(),m=null,n=null,o=250,p=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd");e.headerEnabled(!1).duration(0).valueFormatter(function(a,b){return c.valueFormat()(a,b)});var q=a.utils.renderWatch(p),r=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},s=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},e.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){e.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){e.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.legend=d,b.dispatch=p,b.pie=c,b.tooltip=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return i},set:function(a){i=a}},legendPosition:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return e.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),e.enabled(!!b)}},tooltipContent:{get:function(){return e.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),e.contentGenerator(b)}},color:{get:function(){return k},set:function(a){k=a,d.color(k),c.color(k)}},duration:{get:function(){return o},set:function(a){o=a,q.reset(o)}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.scatter=function(){"use strict";function b(N){return P.reset(),N.each(function(b){function N(){if(O=!1,!w)return!1;if(M===!0){var a=d3.merge(b.map(function(a,b){return a.values.map(function(a,c){var d=p(a,c),e=q(a,c);return[m(d)+1e-4*Math.random(),n(e)+1e-4*Math.random(),b,c,a]}).filter(function(a,b){return x(a[4],b)})}));if(0==a.length)return!1;a.length<3&&(a.push([m.range()[0]-20,n.range()[0]-20,null,null]),a.push([m.range()[1]+20,n.range()[1]+20,null,null]),a.push([m.range()[0]-20,n.range()[0]+20,null,null]),a.push([m.range()[1]+20,n.range()[1]-20,null,null]));var c=d3.geom.polygon([[-10,-10],[-10,i+10],[h+10,i+10],[h+10,-10]]),d=d3.geom.voronoi(a).map(function(b,d){return{data:c.clip(b),series:a[d][2],point:a[d][3]}});U.select(".nv-point-paths").selectAll("path").remove();var e=U.select(".nv-point-paths").selectAll("path").data(d),f=e.enter().append("svg:path").attr("d",function(a){return a&&a.data&&0!==a.data.length?"M"+a.data.join(",")+"Z":"M 0 0"}).attr("id",function(a,b){return"nv-path-"+b}).attr("clip-path",function(a,b){return"url(#nv-clip-"+k+"-"+b+")"});C&&f.style("fill",d3.rgb(230,230,230)).style("fill-opacity",.4).style("stroke-opacity",1).style("stroke",d3.rgb(200,200,200)),B&&(U.select(".nv-point-clips").selectAll("clipPath").remove(),U.select(".nv-point-clips").selectAll("clipPath").data(a).enter().append("svg:clipPath").attr("id",function(a,b){return"nv-clip-"+k+"-"+b}).append("svg:circle").attr("cx",function(a){return a[0]}).attr("cy",function(a){return a[1]}).attr("r",D));var o=function(a,c){if(O)return 0;var d=b[a.series];if(void 0!==d){var e=d.values[a.point];e.color=j(d,a.series),e.x=p(e),e.y=q(e);var f=l.node().getBoundingClientRect(),h=window.pageYOffset||document.documentElement.scrollTop,i=window.pageXOffset||document.documentElement.scrollLeft,k={left:m(p(e,a.point))+f.left+i+g.left+10,top:n(q(e,a.point))+f.top+h+g.top+10};c({point:e,series:d,pos:k,seriesIndex:a.series,pointIndex:a.point})}};e.on("click",function(a){o(a,L.elementClick)}).on("dblclick",function(a){o(a,L.elementDblClick)}).on("mouseover",function(a){o(a,L.elementMouseover)}).on("mouseout",function(a){o(a,L.elementMouseout)})}else U.select(".nv-groups").selectAll(".nv-group").selectAll(".nv-point").on("click",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("dblclick",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementDblClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("mouseover",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseover({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c,color:j(a,c)})}).on("mouseout",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseout({point:e,series:d,seriesIndex:a.series,pointIndex:c,color:j(a,c)})})}l=d3.select(this);var R=a.utils.availableWidth(h,l,g),S=a.utils.availableHeight(i,l,g);a.utils.initSVG(l),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var T=E&&F&&I?[]:d3.merge(b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),size:r(a,b)}})}));m.domain(E||d3.extent(T.map(function(a){return a.x}).concat(t))),m.range(y&&b[0]?G||[(R*z+R)/(2*b[0].values.length),R-R*(1+z)/(2*b[0].values.length)]:G||[0,R]),n.domain(F||d3.extent(T.map(function(a){return a.y}).concat(u))).range(H||[S,0]),o.domain(I||d3.extent(T.map(function(a){return a.size}).concat(v))).range(J||Q),K=m.domain()[0]===m.domain()[1]||n.domain()[0]===n.domain()[1],m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]-.01*n.domain()[0],n.domain()[1]+.01*n.domain()[1]]:[-1,1]),isNaN(m.domain()[0])&&m.domain([-1,1]),isNaN(n.domain()[0])&&n.domain([-1,1]),c=c||m,d=d||n,e=e||o;var U=l.selectAll("g.nv-wrap.nv-scatter").data([b]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-scatter nv-chart-"+k),W=V.append("defs"),X=V.append("g"),Y=U.select("g");U.classed("nv-single-point",K),X.append("g").attr("class","nv-groups"),X.append("g").attr("class","nv-point-paths"),V.append("g").attr("class","nv-point-clips"),U.attr("transform","translate("+g.left+","+g.top+")"),W.append("clipPath").attr("id","nv-edge-clip-"+k).append("rect"),U.select("#nv-edge-clip-"+k+" rect").attr("width",R).attr("height",S>0?S:0),Y.attr("clip-path",A?"url(#nv-edge-clip-"+k+")":""),O=!0;var Z=U.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});Z.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),Z.exit().remove(),Z.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),Z.watchTransition(P,"scatter: groups").style("fill",function(a,b){return j(a,b)}).style("stroke",function(a,b){return j(a,b)}).style("stroke-opacity",1).style("fill-opacity",.5);var $=Z.selectAll("path.nv-point").data(function(a){return a.values.map(function(a,b){return[a,b]}).filter(function(a,b){return x(a[0],b)})});$.enter().append("path").style("fill",function(a){return a.color}).style("stroke",function(a){return a.color}).attr("transform",function(a){return"translate("+c(p(a[0],a[1]))+","+d(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),$.exit().remove(),Z.exit().selectAll("path.nv-point").watchTransition(P,"scatter exit").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).remove(),$.each(function(a){d3.select(this).classed("nv-point",!0).classed("nv-point-"+a[1],!0).classed("nv-noninteractive",!w).classed("hover",!1)}),$.watchTransition(P,"scatter points").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),clearTimeout(f),f=setTimeout(N,300),c=m.copy(),d=n.copy(),e=o.copy()}),P.renderEnd("scatter immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=a.utils.defaultColor(),k=Math.floor(1e5*Math.random()),l=null,m=d3.scale.linear(),n=d3.scale.linear(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=function(a){return a.size||1},s=function(a){return a.shape||"circle"},t=[],u=[],v=[],w=!0,x=function(a){return!a.notActive},y=!1,z=.1,A=!1,B=!0,C=!1,D=function(){return 25},E=null,F=null,G=null,H=null,I=null,J=null,K=!1,L=d3.dispatch("elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),M=!0,N=250,O=!1,P=a.utils.renderWatch(L,N),Q=[16,256];return b.dispatch=L,b.options=a.utils.optionsFunc.bind(b),b._calls=new function(){this.clearHighlights=function(){return a.dom.write(function(){l.selectAll(".nv-point.hover").classed("hover",!1)}),null},this.highlightPoint=function(b,c,d){a.dom.write(function(){l.select(" .nv-series-"+b+" .nv-point-"+c).classed("hover",d)})}},L.on("elementMouseover.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!0)}),L.on("elementMouseout.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!1)}),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},pointScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return E},set:function(a){E=a}},yDomain:{get:function(){return F},set:function(a){F=a}},pointDomain:{get:function(){return I},set:function(a){I=a}},xRange:{get:function(){return G},set:function(a){G=a}},yRange:{get:function(){return H},set:function(a){H=a}},pointRange:{get:function(){return J},set:function(a){J=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},forcePoint:{get:function(){return v},set:function(a){v=a}},interactive:{get:function(){return w},set:function(a){w=a}},pointActive:{get:function(){return x},set:function(a){x=a}},padDataOuter:{get:function(){return z},set:function(a){z=a}},padData:{get:function(){return y},set:function(a){y=a}},clipEdge:{get:function(){return A},set:function(a){A=a}},clipVoronoi:{get:function(){return B},set:function(a){B=a}},clipRadius:{get:function(){return D},set:function(a){D=a}},showVoronoi:{get:function(){return C},set:function(a){C=a}},id:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return p},set:function(a){p=d3.functor(a)}},y:{get:function(){return q},set:function(a){q=d3.functor(a)}},pointSize:{get:function(){return r},set:function(a){r=d3.functor(a)}},pointShape:{get:function(){return s},set:function(a){s=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},duration:{get:function(){return N},set:function(a){N=a,P.reset(N)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},useVoronoi:{get:function(){return M},set:function(a){M=a,M===!1&&(B=!1)}}}),a.utils.initOptions(b),b},a.models.scatterChart=function(){"use strict";function b(z){return D.reset(),D.models(c),t&&D.models(d),u&&D.models(e),q&&D.models(g),r&&D.models(h),z.each(function(z){m=d3.select(this),a.utils.initSVG(m);var G=a.utils.availableWidth(k,m,j),H=a.utils.availableHeight(l,m,j);if(b.update=function(){0===A?m.call(b):m.transition().duration(A).call(b)},b.container=this,w.setter(F(z),b.update).getter(E(z)).update(),w.disabled=z.map(function(a){return!!a.disabled}),!x){var I;x={};for(I in w)x[I]=w[I]instanceof Array?w[I].slice(0):w[I]}if(!(z&&z.length&&z.filter(function(a){return a.values.length}).length))return a.utils.noData(b,m),D.renderEnd("scatter immediate"),b;m.selectAll(".nv-noData").remove(),o=c.xScale(),p=c.yScale();var J=m.selectAll("g.nv-wrap.nv-scatterChart").data([z]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+c.id()),L=K.append("g"),M=J.select("g");if(L.append("rect").attr("class","nvd3 nv-background").style("pointer-events","none"),L.append("g").attr("class","nv-x nv-axis"),L.append("g").attr("class","nv-y nv-axis"),L.append("g").attr("class","nv-scatterWrap"),L.append("g").attr("class","nv-regressionLinesWrap"),L.append("g").attr("class","nv-distWrap"),L.append("g").attr("class","nv-legendWrap"),v&&M.select(".nv-y.nv-axis").attr("transform","translate("+G+",0)"),s){var N=G;f.width(N),J.select(".nv-legendWrap").datum(z).call(f),j.top!=f.height()&&(j.top=f.height(),H=a.utils.availableHeight(l,m,j)),J.select(".nv-legendWrap").attr("transform","translate(0,"+-j.top+")")}J.attr("transform","translate("+j.left+","+j.top+")"),c.width(G).height(H).color(z.map(function(a,b){return a.color=a.color||n(a,b),a.color}).filter(function(a,b){return!z[b].disabled})),J.select(".nv-scatterWrap").datum(z.filter(function(a){return!a.disabled})).call(c),J.select(".nv-regressionLinesWrap").attr("clip-path","url(#nv-edge-clip-"+c.id()+")");var O=J.select(".nv-regressionLinesWrap").selectAll(".nv-regLines").data(function(a){return a});O.enter().append("g").attr("class","nv-regLines");var P=O.selectAll(".nv-regLine").data(function(a){return[a]});P.enter().append("line").attr("class","nv-regLine").style("stroke-opacity",0),P.filter(function(a){return a.intercept&&a.slope}).watchTransition(D,"scatterPlusLineChart: regline").attr("x1",o.range()[0]).attr("x2",o.range()[1]).attr("y1",function(a){return p(o.domain()[0]*a.slope+a.intercept)}).attr("y2",function(a){return p(o.domain()[1]*a.slope+a.intercept)}).style("stroke",function(a,b,c){return n(a,c)}).style("stroke-opacity",function(a){return a.disabled||"undefined"==typeof a.slope||"undefined"==typeof a.intercept?0:1}),t&&(d.scale(o)._ticks(a.utils.calcTicksX(G/100,z)).tickSize(-H,0),M.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(d)),u&&(e.scale(p)._ticks(a.utils.calcTicksY(H/36,z)).tickSize(-G,0),M.select(".nv-y.nv-axis").call(e)),q&&(g.getData(c.x()).scale(o).width(G).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),M.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(z.filter(function(a){return!a.disabled})).call(g)),r&&(h.getData(c.y()).scale(p).width(H).color(z.map(function(a,b){return a.color||n(a,b)
  19311. }).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),M.select(".nv-distributionY").attr("transform","translate("+(v?G:-h.size())+",0)").datum(z.filter(function(a){return!a.disabled})).call(h)),f.dispatch.on("stateChange",function(a){for(var c in a)w[c]=a[c];y.stateChange(w),b.update()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&(z.forEach(function(b,c){b.disabled=a.disabled[c]}),w.disabled=a.disabled),b.update()}),c.dispatch.on("elementMouseout.tooltip",function(a){i.hidden(!0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",h.size())}),c.dispatch.on("elementMouseover.tooltip",function(a){m.select(".nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",a.pos.top-H-j.top),m.select(".nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",a.pos.left+g.size()-j.left),i.position(a.pos).data(a).hidden(!1)}),B=o.copy(),C=p.copy()}),D.renderEnd("scatter with line immediate"),b}var c=a.models.scatter(),d=a.models.axis(),e=a.models.axis(),f=a.models.legend(),g=a.models.distribution(),h=a.models.distribution(),i=a.models.tooltip(),j={top:30,right:20,bottom:50,left:75},k=null,l=null,m=null,n=a.utils.defaultColor(),o=c.xScale(),p=c.yScale(),q=!1,r=!1,s=!0,t=!0,u=!0,v=!1,w=a.utils.state(),x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=null,A=250;c.xScale(o).yScale(p),d.orient("bottom").tickPadding(10),e.orient(v?"right":"left").tickPadding(10),g.axis("x"),h.axis("y"),i.headerFormatter(function(a,b){return d.tickFormat()(a,b)}).valueFormatter(function(a,b){return e.tickFormat()(a,b)});var B,C,D=a.utils.renderWatch(y,A),E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return b.dispatch=y,b.scatter=c,b.legend=f,b.xAxis=d,b.yAxis=e,b.distX=g,b.distY=h,b.tooltip=i,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},container:{get:function(){return m},set:function(a){m=a}},showDistX:{get:function(){return q},set:function(a){q=a}},showDistY:{get:function(){return r},set:function(a){r=a}},showLegend:{get:function(){return s},set:function(a){s=a}},showXAxis:{get:function(){return t},set:function(a){t=a}},showYAxis:{get:function(){return u},set:function(a){u=a}},defaultState:{get:function(){return x},set:function(a){x=a}},noData:{get:function(){return z},set:function(a){z=a}},duration:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return i.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),i.enabled(!!b)}},tooltipContent:{get:function(){return i.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),i.contentGenerator(b)}},tooltipXContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},tooltipYContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},rightAlignYAxis:{get:function(){return v},set:function(a){v=a,e.orient(a?"right":"left")}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),f.color(n),g.color(n),h.color(n)}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.sparkline=function(){"use strict";function b(k){return k.each(function(b){var k=h-g.left-g.right,q=i-g.top-g.bottom;j=d3.select(this),a.utils.initSVG(j),l.domain(c||d3.extent(b,n)).range(e||[0,k]),m.domain(d||d3.extent(b,o)).range(f||[q,0]);{var r=j.selectAll("g.nv-wrap.nv-sparkline").data([b]),s=r.enter().append("g").attr("class","nvd3 nv-wrap nv-sparkline");s.append("g"),r.select("g")}r.attr("transform","translate("+g.left+","+g.top+")");var t=r.selectAll("path").data(function(a){return[a]});t.enter().append("path"),t.exit().remove(),t.style("stroke",function(a,b){return a.color||p(a,b)}).attr("d",d3.svg.line().x(function(a,b){return l(n(a,b))}).y(function(a,b){return m(o(a,b))}));var u=r.selectAll("circle.nv-point").data(function(a){function b(b){if(-1!=b){var c=a[b];return c.pointIndex=b,c}return null}var c=a.map(function(a,b){return o(a,b)}),d=b(c.lastIndexOf(m.domain()[1])),e=b(c.indexOf(m.domain()[0])),f=b(c.length-1);return[e,d,f].filter(function(a){return null!=a})});u.enter().append("circle"),u.exit().remove(),u.attr("cx",function(a){return l(n(a,a.pointIndex))}).attr("cy",function(a){return m(o(a,a.pointIndex))}).attr("r",2).attr("class",function(a){return n(a,a.pointIndex)==l.domain()[1]?"nv-point nv-currentValue":o(a,a.pointIndex)==m.domain()[0]?"nv-point nv-minValue":"nv-point nv-maxValue"})}),b}var c,d,e,f,g={top:2,right:0,bottom:2,left:0},h=400,i=32,j=null,k=!0,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=a.utils.getColor(["#000"]);return b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},animate:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return n},set:function(a){n=d3.functor(a)}},y:{get:function(){return o},set:function(a){o=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return p},set:function(b){p=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sparklinePlus=function(){"use strict";function b(p){return p.each(function(p){function q(){if(!j){var a=z.selectAll(".nv-hoverValue").data(i),b=a.enter().append("g").attr("class","nv-hoverValue").style("stroke-opacity",0).style("fill-opacity",0);a.exit().transition().duration(250).style("stroke-opacity",0).style("fill-opacity",0).remove(),a.attr("transform",function(a){return"translate("+c(e.x()(p[a],a))+",0)"}).transition().duration(250).style("stroke-opacity",1).style("fill-opacity",1),i.length&&(b.append("line").attr("x1",0).attr("y1",-f.top).attr("x2",0).attr("y2",u),b.append("text").attr("class","nv-xValue").attr("x",-6).attr("y",-f.top).attr("text-anchor","end").attr("dy",".9em"),z.select(".nv-hoverValue .nv-xValue").text(k(e.x()(p[i[0]],i[0]))),b.append("text").attr("class","nv-yValue").attr("x",6).attr("y",-f.top).attr("text-anchor","start").attr("dy",".9em"),z.select(".nv-hoverValue .nv-yValue").text(l(e.y()(p[i[0]],i[0]))))}}function r(){function a(a,b){for(var c=Math.abs(e.x()(a[0],0)-b),d=0,f=0;f<a.length;f++)Math.abs(e.x()(a[f],f)-b)<c&&(c=Math.abs(e.x()(a[f],f)-b),d=f);return d}if(!j){var b=d3.mouse(this)[0]-f.left;i=[a(p,Math.round(c.invert(b)))],q()}}var s=d3.select(this);a.utils.initSVG(s);var t=a.utils.availableWidth(g,s,f),u=a.utils.availableHeight(h,s,f);if(b.update=function(){s.call(b)},b.container=this,!p||!p.length)return a.utils.noData(b,s),b;s.selectAll(".nv-noData").remove();var v=e.y()(p[p.length-1],p.length-1);c=e.xScale(),d=e.yScale();var w=s.selectAll("g.nv-wrap.nv-sparklineplus").data([p]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-sparklineplus"),y=x.append("g"),z=w.select("g");y.append("g").attr("class","nv-sparklineWrap"),y.append("g").attr("class","nv-valueWrap"),y.append("g").attr("class","nv-hoverArea"),w.attr("transform","translate("+f.left+","+f.top+")");var A=z.select(".nv-sparklineWrap");if(e.width(t).height(u),A.call(e),m){var B=z.select(".nv-valueWrap"),C=B.selectAll(".nv-currentValue").data([v]);C.enter().append("text").attr("class","nv-currentValue").attr("dx",o?-8:8).attr("dy",".9em").style("text-anchor",o?"end":"start"),C.attr("x",t+(o?f.right:0)).attr("y",n?function(a){return d(a)}:0).style("fill",e.color()(p[p.length-1],p.length-1)).text(l(v))}y.select(".nv-hoverArea").append("rect").on("mousemove",r).on("click",function(){j=!j}).on("mouseout",function(){i=[],q()}),z.select(".nv-hoverArea rect").attr("transform",function(){return"translate("+-f.left+","+-f.top+")"}).attr("width",t+f.left+f.right).attr("height",u+f.top)}),b}var c,d,e=a.models.sparkline(),f={top:15,right:100,bottom:10,left:50},g=null,h=null,i=[],j=!1,k=d3.format(",r"),l=d3.format(",.2f"),m=!0,n=!0,o=!1,p=null;return b.sparkline=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},xTickFormat:{get:function(){return k},set:function(a){k=a}},yTickFormat:{get:function(){return l},set:function(a){l=a}},showLastValue:{get:function(){return m},set:function(a){m=a}},alignValue:{get:function(){return n},set:function(a){n=a}},rightAlignValue:{get:function(){return o},set:function(a){o=a}},noData:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.stackedArea=function(){"use strict";function b(m){return u.reset(),u.models(r),m.each(function(m){var s=f-e.left-e.right,v=g-e.top-e.bottom;j=d3.select(this),a.utils.initSVG(j),c=r.xScale(),d=r.yScale();var w=m;m.forEach(function(a,b){a.seriesIndex=b,a.values=a.values.map(function(a,c){return a.index=c,a.seriesIndex=b,a})});var x=m.filter(function(a){return!a.disabled});m=d3.layout.stack().order(o).offset(n).values(function(a){return a.values}).x(k).y(l).out(function(a,b,c){a.display={y:c,y0:b}})(x);var y=j.selectAll("g.nv-wrap.nv-stackedarea").data([m]),z=y.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedarea"),A=z.append("defs"),B=z.append("g"),C=y.select("g");B.append("g").attr("class","nv-areaWrap"),B.append("g").attr("class","nv-scatterWrap"),y.attr("transform","translate("+e.left+","+e.top+")"),0==r.forceY().length&&r.forceY().push(0),r.width(s).height(v).x(k).y(function(a){return a.display.y+a.display.y0}).forceY([0]).color(m.map(function(a){return a.color||h(a,a.seriesIndex)}));var D=C.select(".nv-scatterWrap").datum(m);D.call(r),A.append("clipPath").attr("id","nv-edge-clip-"+i).append("rect"),y.select("#nv-edge-clip-"+i+" rect").attr("width",s).attr("height",v),C.attr("clip-path",q?"url(#nv-edge-clip-"+i+")":"");var E=d3.svg.area().x(function(a,b){return c(k(a,b))}).y0(function(a){return d(a.display.y0)}).y1(function(a){return d(a.display.y+a.display.y0)}).interpolate(p),F=d3.svg.area().x(function(a,b){return c(k(a,b))}).y0(function(a){return d(a.display.y0)}).y1(function(a){return d(a.display.y0)}),G=C.select(".nv-areaWrap").selectAll("path.nv-area").data(function(a){return a});G.enter().append("path").attr("class",function(a,b){return"nv-area nv-area-"+b}).attr("d",function(a){return F(a.values,a.seriesIndex)}).on("mouseover",function(a){d3.select(this).classed("hover",!0),t.areaMouseover({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}).on("mouseout",function(a){d3.select(this).classed("hover",!1),t.areaMouseout({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}).on("click",function(a){d3.select(this).classed("hover",!1),t.areaClick({point:a,series:a.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:a.seriesIndex})}),G.exit().remove(),G.style("fill",function(a){return a.color||h(a,a.seriesIndex)}).style("stroke",function(a){return a.color||h(a,a.seriesIndex)}),G.watchTransition(u,"stackedArea path").attr("d",function(a,b){return E(a.values,b)}),r.dispatch.on("elementMouseover.area",function(a){C.select(".nv-chart-"+i+" .nv-area-"+a.seriesIndex).classed("hover",!0)}),r.dispatch.on("elementMouseout.area",function(a){C.select(".nv-chart-"+i+" .nv-area-"+a.seriesIndex).classed("hover",!1)}),b.d3_stackedOffset_stackPercent=function(a){var b,c,d,e=a.length,f=a[0].length,g=[];for(c=0;f>c;++c){for(b=0,d=0;b<w.length;b++)d+=l(w[b].values[c]);if(d)for(b=0;e>b;b++)a[b][c][1]/=d;else for(b=0;e>b;b++)a[b][c][1]=0}for(c=0;f>c;++c)g[c]=0;return g}}),u.renderEnd("stackedArea immediate"),b}var c,d,e={top:0,right:0,bottom:0,left:0},f=960,g=500,h=a.utils.defaultColor(),i=Math.floor(1e5*Math.random()),j=null,k=function(a){return a.x},l=function(a){return a.y},m="stack",n="zero",o="default",p="linear",q=!1,r=a.models.scatter(),s=250,t=d3.dispatch("areaClick","areaMouseover","areaMouseout","renderEnd","elementClick","elementMouseover","elementMouseout");r.pointSize(2.2).pointDomain([2.2,2.2]);var u=a.utils.renderWatch(t,s);return b.dispatch=t,b.scatter=r,r.dispatch.on("elementClick",function(){t.elementClick.apply(this,arguments)}),r.dispatch.on("elementMouseover",function(){t.elementMouseover.apply(this,arguments)}),r.dispatch.on("elementMouseout",function(){t.elementMouseout.apply(this,arguments)}),b.interpolate=function(a){return arguments.length?(p=a,b):p},b.duration=function(a){return arguments.length?(s=a,u.reset(s),r.duration(s),b):s},b.dispatch=t,b.scatter=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return f},set:function(a){f=a}},height:{get:function(){return g},set:function(a){g=a}},clipEdge:{get:function(){return q},set:function(a){q=a}},offset:{get:function(){return n},set:function(a){n=a}},order:{get:function(){return o},set:function(a){o=a}},interpolate:{get:function(){return p},set:function(a){p=a}},x:{get:function(){return k},set:function(a){k=d3.functor(a)}},y:{get:function(){return l},set:function(a){l=d3.functor(a)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return h},set:function(b){h=a.utils.getColor(b)}},style:{get:function(){return m},set:function(a){switch(m=a){case"stack":b.offset("zero"),b.order("default");break;case"stream":b.offset("wiggle"),b.order("inside-out");break;case"stream-center":b.offset("silhouette"),b.order("inside-out");break;case"expand":b.offset("expand"),b.order("default");break;case"stack_percent":b.offset(b.d3_stackedOffset_stackPercent),b.order("default")}}},duration:{get:function(){return s},set:function(a){s=a,u.reset(s),r.duration(s)}}}),a.utils.inheritOptions(b,r),a.utils.initOptions(b),b},a.models.stackedAreaChart=function(){"use strict";function b(k){return F.reset(),F.models(e),r&&F.models(f),s&&F.models(g),k.each(function(k){var x=d3.select(this),F=this;a.utils.initSVG(x);var K=a.utils.availableWidth(m,x,l),L=a.utils.availableHeight(n,x,l);if(b.update=function(){x.transition().duration(C).call(b)},b.container=this,v.setter(I(k),b.update).getter(H(k)).update(),v.disabled=k.map(function(a){return!!a.disabled}),!w){var M;w={};for(M in v)w[M]=v[M]instanceof Array?v[M].slice(0):v[M]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(b,x),b;x.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var N=x.selectAll("g.nv-wrap.nv-stackedAreaChart").data([k]),O=N.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedAreaChart").append("g"),P=N.select("g");if(O.append("rect").style("opacity",0),O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y nv-axis"),O.append("g").attr("class","nv-stackedWrap"),O.append("g").attr("class","nv-legendWrap"),O.append("g").attr("class","nv-controlsWrap"),O.append("g").attr("class","nv-interactive"),P.select("rect").attr("width",K).attr("height",L),q){var Q=p?K-z:K;h.width(Q),P.select(".nv-legendWrap").datum(k).call(h),l.top!=h.height()&&(l.top=h.height(),L=a.utils.availableHeight(n,x,l)),P.select(".nv-legendWrap").attr("transform","translate("+(K-Q)+","+-l.top+")")}if(p){var R=[{key:B.stacked||"Stacked",metaKey:"Stacked",disabled:"stack"!=e.style(),style:"stack"},{key:B.stream||"Stream",metaKey:"Stream",disabled:"stream"!=e.style(),style:"stream"},{key:B.expanded||"Expanded",metaKey:"Expanded",disabled:"expand"!=e.style(),style:"expand"},{key:B.stack_percent||"Stack %",metaKey:"Stack_Percent",disabled:"stack_percent"!=e.style(),style:"stack_percent"}];z=A.length/3*260,R=R.filter(function(a){return-1!==A.indexOf(a.metaKey)}),i.width(z).color(["#444","#444","#444"]),P.select(".nv-controlsWrap").datum(R).call(i),l.top!=Math.max(i.height(),h.height())&&(l.top=Math.max(i.height(),h.height()),L=a.utils.availableHeight(n,x,l)),P.select(".nv-controlsWrap").attr("transform","translate(0,"+-l.top+")")}N.attr("transform","translate("+l.left+","+l.top+")"),t&&P.select(".nv-y.nv-axis").attr("transform","translate("+K+",0)"),u&&(j.width(K).height(L).margin({left:l.left,top:l.top}).svgContainer(x).xScale(c),N.select(".nv-interactive").call(j)),e.width(K).height(L);var S=P.select(".nv-stackedWrap").datum(k);if(S.transition().call(e),r&&(f.scale(c)._ticks(a.utils.calcTicksX(K/100,k)).tickSize(-L,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+L+")"),P.select(".nv-x.nv-axis").transition().duration(0).call(f)),s){var T;if(T="wiggle"===e.offset()?0:a.utils.calcTicksY(L/36,k),g.scale(d)._ticks(T).tickSize(-K,0),"expand"===e.style()||"stack_percent"===e.style()){var U=g.tickFormat();D&&U===J||(D=U),g.tickFormat(J)}else D&&(g.tickFormat(D),D=null);P.select(".nv-y.nv-axis").transition().duration(0).call(g)}e.dispatch.on("areaClick.toggle",function(a){k.forEach(1===k.filter(function(a){return!a.disabled}).length?function(a){a.disabled=!1}:function(b,c){b.disabled=c!=a.seriesIndex}),v.disabled=k.map(function(a){return!!a.disabled}),y.stateChange(v),b.update()}),h.dispatch.on("stateChange",function(a){for(var c in a)v[c]=a[c];y.stateChange(v),b.update()}),i.dispatch.on("legendClick",function(a){a.disabled&&(R=R.map(function(a){return a.disabled=!0,a}),a.disabled=!1,e.style(a.style),v.style=e.style(),y.stateChange(v),b.update())}),j.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,g,h,i=[];if(k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,j){g=a.interactiveBisect(f.values,c.pointXValue,b.x());var k=f.values[g],l=b.y()(k,g);if(null!=l&&e.highlightPoint(j,g,!0),"undefined"!=typeof k){"undefined"==typeof d&&(d=k),"undefined"==typeof h&&(h=b.xScale()(b.x()(k,g)));var m="expand"==e.style()?k.display.y:b.y()(k,g);i.push({key:f.key,value:m,color:o(f,f.seriesIndex),stackedValue:k.display})}}),i.reverse(),i.length>2){var m=b.yScale().invert(c.mouseY),n=null;i.forEach(function(a,b){m=Math.abs(m);var c=Math.abs(a.stackedValue.y0),d=Math.abs(a.stackedValue.y);return m>=c&&d+c>=m?void(n=b):void 0}),null!=n&&(i[n].highlight=!0)}var p=f.tickFormat()(b.x()(d,g)),q=j.tooltip.valueFormatter();"expand"===e.style()||"stack_percent"===e.style()?(E||(E=q),q=d3.format(".1%")):E&&(q=E,E=null),j.tooltip.position({left:h+l.left,top:c.mouseY+l.top}).chartContainer(F.parentNode).valueFormatter(q).data({value:p,series:i})(),j.renderGuideLine(h)}),j.dispatch.on("elementMouseout",function(){e.clearHighlights()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&k.length===a.disabled.length&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),v.disabled=a.disabled),"undefined"!=typeof a.style&&(e.style(a.style),G=a.style),b.update()})}),F.renderEnd("stacked Area chart immediate"),b}var c,d,e=a.models.stackedArea(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:25,bottom:50,left:60},m=null,n=null,o=a.utils.defaultColor(),p=!0,q=!0,r=!0,s=!0,t=!1,u=!1,v=a.utils.state(),w=null,x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=250,A=["Stacked","Stream","Expanded"],B={},C=250;v.style=e.style(),f.orient("bottom").tickPadding(7),g.orient(t?"right":"left"),k.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)}),j.tooltip.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)});var D=null,E=null;i.updateState(!1);var F=a.utils.renderWatch(y),G=e.style(),H=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),style:e.style()}}},I=function(a){return function(b){void 0!==b.style&&(G=b.style),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},J=d3.format("%");return e.dispatch.on("elementMouseover.tooltip",function(a){a.point.x=e.x()(a.point),a.point.y=e.y()(a.point),k.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),b.dispatch=y,b.stacked=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.interactiveLayer=j,b.tooltip=k,b.dispatch=y,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return w},set:function(a){w=a}},noData:{get:function(){return x},set:function(a){x=a}},showControls:{get:function(){return p},set:function(a){p=a}},controlLabels:{get:function(){return B},set:function(a){B=a}},controlOptions:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},duration:{get:function(){return C},set:function(a){C=a,F.reset(C),e.duration(C),f.duration(C),g.duration(C)}},color:{get:function(){return o},set:function(b){o=a.utils.getColor(b),h.color(o),e.color(o)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},useInteractiveGuideline:{get:function(){return u},set:function(a){u=!!a,b.interactive(!a),b.useVoronoi(!a),e.scatter.interactive(!a)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.sunburst=function(){"use strict";function b(u){return t.reset(),u.each(function(b){function t(a){a.x0=a.x,a.dx0=a.dx}function u(a){var b=d3.interpolate(p.domain(),[a.x,a.x+a.dx]),c=d3.interpolate(q.domain(),[a.y,1]),d=d3.interpolate(q.range(),[a.y?20:0,y]);return function(a,e){return e?function(){return s(a)}:function(e){return p.domain(b(e)),q.domain(c(e)).range(d(e)),s(a)}}}l=d3.select(this);var v,w=a.utils.availableWidth(g,l,f),x=a.utils.availableHeight(h,l,f),y=Math.min(w,x)/2;a.utils.initSVG(l);var z=l.selectAll(".nv-wrap.nv-sunburst").data(b),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburst nv-chart-"+k),B=A.selectAll("nv-sunburst");z.attr("transform","translate("+w/2+","+x/2+")"),l.on("click",function(a,b){o.chartClick({data:a,index:b,pos:d3.event,id:k})}),q.range([0,y]),c=c||b,e=b[0],r.value(j[i]||j.count),v=B.data(r.nodes).enter().append("path").attr("d",s).style("fill",function(a){return m((a.children?a:a.parent).name)}).style("stroke","#FFF").on("click",function(a){d!==c&&c!==a&&(d=c),c=a,v.transition().duration(n).attrTween("d",u(a))}).each(t).on("dblclick",function(a){d.parent==a&&v.transition().duration(n).attrTween("d",u(e))}).each(t).on("mouseover",function(a){d3.select(this).classed("hover",!0).style("opacity",.8),o.elementMouseover({data:a,color:d3.select(this).style("fill")})}).on("mouseout",function(a){d3.select(this).classed("hover",!1).style("opacity",1),o.elementMouseout({data:a})}).on("mousemove",function(a){o.elementMousemove({data:a})})}),t.renderEnd("sunburst immediate"),b}var c,d,e,f={top:0,right:0,bottom:0,left:0},g=null,h=null,i="count",j={count:function(){return 1},size:function(a){return a.size}},k=Math.floor(1e4*Math.random()),l=null,m=a.utils.defaultColor(),n=500,o=d3.dispatch("chartClick","elementClick","elementDblClick","elementMousemove","elementMouseover","elementMouseout","renderEnd"),p=d3.scale.linear().range([0,2*Math.PI]),q=d3.scale.sqrt(),r=d3.layout.partition().sort(null).value(function(){return 1}),s=d3.svg.arc().startAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x)))}).endAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x+a.dx)))}).innerRadius(function(a){return Math.max(0,q(a.y))}).outerRadius(function(a){return Math.max(0,q(a.y+a.dy))}),t=a.utils.renderWatch(o);return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},mode:{get:function(){return i},set:function(a){i=a}},id:{get:function(){return k},set:function(a){k=a}},duration:{get:function(){return n},set:function(a){n=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!=a.top?a.top:f.top,f.right=void 0!=a.right?a.right:f.right,f.bottom=void 0!=a.bottom?a.bottom:f.bottom,f.left=void 0!=a.left?a.left:f.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sunburstChart=function(){"use strict";function b(d){return m.reset(),m.models(c),d.each(function(d){var h=d3.select(this);a.utils.initSVG(h);var i=a.utils.availableWidth(f,h,e),j=a.utils.availableHeight(g,h,e);if(b.update=function(){0===k?h.call(b):h.transition().duration(k).call(b)},b.container=this,!d||!d.length)return a.utils.noData(b,h),b;h.selectAll(".nv-noData").remove();var l=h.selectAll("g.nv-wrap.nv-sunburstChart").data(d),m=l.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburstChart").append("g"),n=l.select("g");m.append("g").attr("class","nv-sunburstWrap"),l.attr("transform","translate("+e.left+","+e.top+")"),c.width(i).height(j);var o=n.select(".nv-sunburstWrap").datum(d);d3.transition(o).call(c)}),m.renderEnd("sunburstChart immediate"),b}var c=a.models.sunburst(),d=a.models.tooltip(),e={top:30,right:20,bottom:20,left:20},f=null,g=null,h=a.utils.defaultColor(),i=(Math.round(1e5*Math.random()),null),j=null,k=250,l=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),m=a.utils.renderWatch(l);return d.headerEnabled(!1).duration(0).valueFormatter(function(a){return a}),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.data.name,value:a.data.size,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=l,b.sunburst=c,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return i},set:function(a){i=a}},color:{get:function(){return h},set:function(a){h=a,c.color(h)}},duration:{get:function(){return k},set:function(a){k=a,m.reset(k),c.duration(k)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.version="1.8.1"}();/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
  19312. !function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function qa(){}qa.prototype=d.filters=d.pseudos,d.setFilters=new qa,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function ra(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;
  19313. return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[m.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=Z.test(e)?this.mouseHooks:Y.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new m.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||y),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||y,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ca()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ca()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return m.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return m.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=m.extend(new m.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?m.event.trigger(e,null,b):m.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},m.removeEvent=y.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===K&&(a[d]=null),a.detachEvent(d,c))},m.Event=function(a,b){return this instanceof m.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?aa:ba):this.type=a,b&&m.extend(this,b),this.timeStamp=a&&a.timeStamp||m.now(),void(this[m.expando]=!0)):new m.Event(a,b)},m.Event.prototype={isDefaultPrevented:ba,isPropagationStopped:ba,isImmediatePropagationStopped:ba,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=aa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=aa,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=aa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},m.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){m.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!m.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.submitBubbles||(m.event.special.submit={setup:function(){return m.nodeName(this,"form")?!1:void m.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=m.nodeName(b,"input")||m.nodeName(b,"button")?b.form:void 0;c&&!m._data(c,"submitBubbles")&&(m.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),m._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&m.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return m.nodeName(this,"form")?!1:void m.event.remove(this,"._submit")}}),k.changeBubbles||(m.event.special.change={setup:function(){return X.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(m.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),m.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),m.event.simulate("change",this,a,!0)})),!1):void m.event.add(this,"beforeactivate._change",function(a){var b=a.target;X.test(b.nodeName)&&!m._data(b,"changeBubbles")&&(m.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||m.event.simulate("change",this.parentNode,a,!0)}),m._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return m.event.remove(this,"._change"),!X.test(this.nodeName)}}),k.focusinBubbles||m.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){m.event.simulate(b,a.target,m.event.fix(a),!0)};m.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=m._data(d,b);e||d.addEventListener(a,c,!0),m._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=m._data(d,b)-1;e?m._data(d,b,e):(d.removeEventListener(a,c,!0),m._removeData(d,b))}}}),m.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=ba;else if(!d)return this;return 1===e&&(g=d,d=function(a){return m().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=m.guid++)),this.each(function(){m.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,m(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=ba),this.each(function(){m.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){m.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?m.event.trigger(a,b,c,!0):void 0}});function da(a){var b=ea.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var ea="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",fa=/ jQuery\d+="(?:null|\d+)"/g,ga=new RegExp("<(?:"+ea+")[\\s/>]","i"),ha=/^\s+/,ia=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ja=/<([\w:]+)/,ka=/<tbody/i,la=/<|&#?\w+;/,ma=/<(?:script|style|link)/i,na=/checked\s*(?:[^=]|=\s*.checked.)/i,oa=/^$|\/(?:java|ecma)script/i,pa=/^true\/(.*)/,qa=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ra={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:k.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},sa=da(y),ta=sa.appendChild(y.createElement("div"));ra.optgroup=ra.option,ra.tbody=ra.tfoot=ra.colgroup=ra.caption=ra.thead,ra.th=ra.td;function ua(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ua(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function va(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wa(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xa(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function ya(a){var b=pa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function za(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Aa(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Ba(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xa(b).text=a.text,ya(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!ga.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ta.innerHTML=a.outerHTML,ta.removeChild(f=ta.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ua(f),h=ua(a),g=0;null!=(e=h[g]);++g)d[g]&&Ba(e,d[g]);if(b)if(c)for(h=h||ua(a),d=d||ua(f),g=0;null!=(e=h[g]);g++)Aa(e,d[g]);else Aa(a,f);return d=ua(f,"script"),d.length>0&&za(d,!i&&ua(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=da(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(la.test(f)){h=h||o.appendChild(b.createElement("div")),i=(ja.exec(f)||["",""])[1].toLowerCase(),l=ra[i]||ra._default,h.innerHTML=l[1]+f.replace(ia,"<$1></$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&ha.test(f)&&p.push(b.createTextNode(ha.exec(f)[0])),!k.tbody){f="table"!==i||ka.test(f)?"<table>"!==l[1]||ka.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ua(p,"input"),va),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ua(o.appendChild(f),"script"),g&&za(h),c)){e=0;while(f=h[e++])oa.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ua(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&za(ua(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ua(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fa,""):void 0;if(!("string"!=typeof a||ma.test(a)||!k.htmlSerialize&&ga.test(a)||!k.leadingWhitespace&&ha.test(a)||ra[(ja.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ia,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ua(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ua(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&na.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ua(i,"script"),xa),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ua(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,ya),j=0;f>j;j++)d=g[j],oa.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qa,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Ca,Da={};function Ea(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fa(a){var b=y,c=Da[a];return c||(c=Ea(a,b),"none"!==c&&c||(Ca=(Ca||m("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ca[0].contentWindow||Ca[0].contentDocument).document,b.write(),b.close(),c=Ea(a,b),Ca.detach()),Da[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Ga=/^margin/,Ha=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ia,Ja,Ka=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ia=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)},Ja=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ia(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Ha.test(g)&&Ga.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ia=function(a){return a.currentStyle},Ja=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ia(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ha.test(g)&&!Ka.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function La(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight),b.removeChild(i)),b.innerHTML="<table><tr><td></td><td>t</td></tr></table>",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Ma=/alpha\([^)]*\)/i,Na=/opacity\s*=\s*([^)]*)/,Oa=/^(none|table(?!-c[ea]).+)/,Pa=new RegExp("^("+S+")(.*)$","i"),Qa=new RegExp("^([+-])=("+S+")","i"),Ra={position:"absolute",visibility:"hidden",display:"block"},Sa={letterSpacing:"0",fontWeight:"400"},Ta=["Webkit","O","Moz","ms"];function Ua(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ta.length;while(e--)if(b=Ta[e]+c,b in a)return b;return d}function Va(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fa(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wa(a,b,c){var d=Pa.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xa(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Ya(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ia(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Ja(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ha.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xa(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ja(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ua(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qa.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ua(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Ja(a,b,d)),"normal"===f&&b in Sa&&(f=Sa[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Oa.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Ra,function(){return Ya(a,b,d)}):Ya(a,b,d):void 0},set:function(a,c,d){var e=d&&Ia(a);return Wa(a,c,d?Xa(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Na.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Ma,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Ma.test(f)?f.replace(Ma,e):f+" "+e)}}),m.cssHooks.marginRight=La(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Ja,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Ga.test(a)||(m.cssHooks[a+b].set=Wa)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ia(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Va(this,!0)},hide:function(){return Va(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Za(a,b,c,d,e){
  19314. return new Za.prototype.init(a,b,c,d,e)}m.Tween=Za,Za.prototype={constructor:Za,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Za.propHooks[this.prop];return a&&a.get?a.get(this):Za.propHooks._default.get(this)},run:function(a){var b,c=Za.propHooks[this.prop];return this.options.duration?this.pos=b=m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Za.propHooks._default.set(this),this}},Za.prototype.init.prototype=Za.prototype,Za.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Za.propHooks.scrollTop=Za.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Za.prototype.init,m.fx.step={};var $a,_a,ab=/^(?:toggle|show|hide)$/,bb=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cb=/queueHooks$/,db=[ib],eb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bb.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bb.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fb(){return setTimeout(function(){$a=void 0}),$a=m.now()}function gb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hb(a,b,c){for(var d,e=(eb[b]||[]).concat(eb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fa(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fa(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ab.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fa(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hb(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=db.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$a||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$a||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);g>f;f++)if(d=db[f].call(j,a,k,j.opts))return d;return m.map(k,hb,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kb,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],eb[c]=eb[c]||[],eb[c].unshift(b)},prefilter:function(a,b){b?db.unshift(a):db.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kb(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),m.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($a=m.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||m.fx.stop(),$a=void 0},m.fx.timer=function(a){m.timers.push(a),a()?m.fx.start():m.timers.pop()},m.fx.interval=13,m.fx.start=function(){_a||(_a=setInterval(m.fx.tick,m.fx.interval))},m.fx.stop=function(){clearInterval(_a),_a=null},m.fx.speeds={slow:600,fast:200,_default:400},m.fn.delay=function(a,b){return a=m.fx?m.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=y.createElement("div"),b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lb=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lb,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mb,nb,ob=m.expr.attrHandle,pb=/^(?:checked|selected)$/i,qb=k.getSetAttribute,rb=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nb:mb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rb&&qb||!pb.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qb?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nb={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rb&&qb||!pb.test(c)?a.setAttribute(!qb&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ob[b]||m.find.attr;ob[b]=rb&&qb||!pb.test(b)?function(a,b,d){var e,f;return d||(f=ob[b],ob[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,ob[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rb&&qb||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mb&&mb.set(a,b,c)}}),qb||(mb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},ob.id=ob.name=ob.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mb.set},m.attrHooks.contenteditable={set:function(a,b,c){mb.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sb=/^(?:input|select|textarea|button|object)$/i,tb=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sb.test(a.nodeName)||tb.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var ub=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ub," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ub," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ub," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vb=m.now(),wb=/\?/,xb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yb,zb,Ab=/#.*$/,Bb=/([?&])_=[^&]*/,Cb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Db=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Eb=/^(?:GET|HEAD)$/,Fb=/^\/\//,Gb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hb={},Ib={},Jb="*/".concat("*");try{zb=location.href}catch(Kb){zb=y.createElement("a"),zb.href="",zb=zb.href}yb=Gb.exec(zb.toLowerCase())||[];function Lb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mb(a,b,c,d){var e={},f=a===Ib;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nb(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Ob(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zb,type:"GET",isLocal:Db.test(yb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nb(Nb(a,m.ajaxSettings),b):Nb(m.ajaxSettings,a)},ajaxPrefilter:Lb(Hb),ajaxTransport:Lb(Ib),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cb.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zb)+"").replace(Ab,"").replace(Fb,yb[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gb.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yb[1]&&c[2]===yb[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yb[3]||("http:"===yb[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mb(Hb,k,b,v),2===t)return v;h=m.event&&k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Eb.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wb.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bb.test(e)?e.replace(Bb,"$1_="+vb++):e+(wb.test(e)?"&":"?")+"_="+vb++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jb+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mb(Ib,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Ob(k,v,c)),u=Pb(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qb=/%20/g,Rb=/\[\]$/,Sb=/\r?\n/g,Tb=/^(?:submit|button|image|reset|file)$/i,Ub=/^(?:input|select|textarea|keygen)/i;function Vb(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rb.test(a)?d(a,e):Vb(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vb(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vb(c,a[c],b,e);return d.join("&").replace(Qb,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Ub.test(this.nodeName)&&!Tb.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sb,"\r\n")}}):{name:b.name,value:c.replace(Sb,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zb()||$b()}:Zb;var Wb=0,Xb={},Yb=m.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Xb)Xb[a](void 0,!0)}),k.cors=!!Yb&&"withCredentials"in Yb,Yb=k.ajax=!!Yb,Yb&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wb;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xb[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xb[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zb(){try{return new a.XMLHttpRequest}catch(b){}}function $b(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _b=[],ac=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_b.pop()||m.expando+"_"+vb++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ac.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ac.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ac,"$1"+e):b.jsonp!==!1&&(b.url+=(wb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_b.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bc=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bc)return bc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("<div>").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cc=a.document.documentElement;function dc(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cc;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cc})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=La(k.pixelPosition,function(a,c){return c?(c=Ja(a,b),Ha.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ec=a.jQuery,fc=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fc),b&&a.jQuery===m&&(a.jQuery=ec),m},typeof b===K&&(a.jQuery=a.$=m),m});
  19315. <tr>
  19316. <td class="{{classes_level}}">{{name}}</td>
  19317. <td class="{{classes_level}} big">{{classes_bar}}</td>
  19318. <td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
  19319. <td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
  19320. <td class="{{methods_level}} big">{{methods_bar}}</td>
  19321. <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
  19322. <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
  19323. <td class="{{methods_level}} small">{{crap}}</td>
  19324. <td class="{{lines_level}} big">{{lines_bar}}</td>
  19325. <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
  19326. <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
  19327. </tr>
  19328. <tr>
  19329. <td class="{{methods_level}}" colspan="4">{{name}}</td>
  19330. <td class="{{methods_level}} big">{{methods_bar}}</td>
  19331. <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
  19332. <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
  19333. <td class="{{methods_level}} small">{{crap}}</td>
  19334. <td class="{{lines_level}} big">{{lines_bar}}</td>
  19335. <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
  19336. <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
  19337. </tr>
  19338. <tr>
  19339. <td class="{{lines_level}}">{{icon}}{{name}}</td>
  19340. <td class="{{lines_level}} big">{{lines_bar}}</td>
  19341. <td class="{{lines_level}} small"><div align="right">{{lines_executed_percent}}</div></td>
  19342. <td class="{{lines_level}} small"><div align="right">{{lines_number}}</div></td>
  19343. <td class="{{methods_level}} big">{{methods_bar}}</td>
  19344. <td class="{{methods_level}} small"><div align="right">{{methods_tested_percent}}</div></td>
  19345. <td class="{{methods_level}} small"><div align="right">{{methods_number}}</div></td>
  19346. <td class="{{classes_level}} big">{{classes_bar}}</td>
  19347. <td class="{{classes_level}} small"><div align="right">{{classes_tested_percent}}</div></td>
  19348. <td class="{{classes_level}} small"><div align="right">{{classes_number}}</div></td>
  19349. </tr>
  19350. <!DOCTYPE html>
  19351. <html lang="en">
  19352. <head>
  19353. <meta charset="UTF-8">
  19354. <title>Code Coverage for {{full_path}}</title>
  19355. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  19356. <link href="{{path_to_root}}css/bootstrap.min.css" rel="stylesheet">
  19357. <link href="{{path_to_root}}css/style.css" rel="stylesheet">
  19358. <!--[if lt IE 9]>
  19359. <script src="{{path_to_root}}js/html5shiv.min.js"></script>
  19360. <script src="{{path_to_root}}js/respond.min.js"></script>
  19361. <![endif]-->
  19362. </head>
  19363. <body>
  19364. <header>
  19365. <div class="container">
  19366. <div class="row">
  19367. <div class="col-md-12">
  19368. <ol class="breadcrumb">
  19369. {{breadcrumbs}}
  19370. </ol>
  19371. </div>
  19372. </div>
  19373. </div>
  19374. </header>
  19375. <div class="container">
  19376. <table class="table table-bordered">
  19377. <thead>
  19378. <tr>
  19379. <td>&nbsp;</td>
  19380. <td colspan="10"><div align="center"><strong>Code Coverage</strong></div></td>
  19381. </tr>
  19382. <tr>
  19383. <td>&nbsp;</td>
  19384. <td colspan="3"><div align="center"><strong>Classes and Traits</strong></div></td>
  19385. <td colspan="4"><div align="center"><strong>Functions and Methods</strong></div></td>
  19386. <td colspan="3"><div align="center"><strong>Lines</strong></div></td>
  19387. </tr>
  19388. </thead>
  19389. <tbody>
  19390. {{items}}
  19391. </tbody>
  19392. </table>
  19393. <table id="code" class="table table-borderless table-condensed">
  19394. <tbody>
  19395. {{lines}}
  19396. </tbody>
  19397. </table>
  19398. <footer>
  19399. <hr/>
  19400. <h4>Legend</h4>
  19401. <p>
  19402. <span class="success"><strong>Executed</strong></span>
  19403. <span class="danger"><strong>Not Executed</strong></span>
  19404. <span class="warning"><strong>Dead Code</strong></span>
  19405. </p>
  19406. <p>
  19407. <small>Generated by <a href="http://github.com/sebastianbergmann/php-code-coverage" target="_top">PHP_CodeCoverage {{version}}</a> using <a href="{{runtime_link}}" target="_top">{{runtime_name}} {{runtime_version}}</a>{{generator}} at {{date}}.</small>
  19408. </p>
  19409. <a title="Back to the top" id="toplink" href="#"><span class="glyphicon glyphicon-arrow-up"></span></a>
  19410. </footer>
  19411. </div>
  19412. <script src="{{path_to_root}}js/jquery.min.js" type="text/javascript"></script>
  19413. <script src="{{path_to_root}}js/bootstrap.min.js" type="text/javascript"></script>
  19414. <script src="{{path_to_root}}js/holder.min.js" type="text/javascript"></script>
  19415. <script type="text/javascript">
  19416. $(function() {
  19417. var $window = $(window)
  19418. , $top_link = $('#toplink')
  19419. , $body = $('body, html')
  19420. , offset = $('#code').offset().top;
  19421. $top_link.hide().click(function(event) {
  19422. event.preventDefault();
  19423. $body.animate({scrollTop:0}, 800);
  19424. });
  19425. $window.scroll(function() {
  19426. if($window.scrollTop() > offset) {
  19427. $top_link.fadeIn();
  19428. } else {
  19429. $top_link.fadeOut();
  19430. }
  19431. }).scroll();
  19432. $('.popin').popover({trigger: 'hover'});
  19433. });
  19434. </script>
  19435. </body>
  19436. </html>
  19437. body {
  19438. padding-top: 10px;
  19439. }
  19440. .popover {
  19441. max-width: none;
  19442. }
  19443. .glyphicon {
  19444. margin-right:.25em;
  19445. }
  19446. .table-bordered>thead>tr>td {
  19447. border-bottom-width: 1px;
  19448. }
  19449. .table tbody>tr>td, .table thead>tr>td {
  19450. padding-top: 3px;
  19451. padding-bottom: 3px;
  19452. }
  19453. .table-condensed tbody>tr>td {
  19454. padding-top: 0;
  19455. padding-bottom: 0;
  19456. }
  19457. .table .progress {
  19458. margin-bottom: inherit;
  19459. }
  19460. .table-borderless th, .table-borderless td {
  19461. border: 0 !important;
  19462. }
  19463. .table tbody tr.covered-by-large-tests, li.covered-by-large-tests, tr.success, td.success, li.success, span.success {
  19464. background-color: #dff0d8;
  19465. }
  19466. .table tbody tr.covered-by-medium-tests, li.covered-by-medium-tests {
  19467. background-color: #c3e3b5;
  19468. }
  19469. .table tbody tr.covered-by-small-tests, li.covered-by-small-tests {
  19470. background-color: #99cb84;
  19471. }
  19472. .table tbody tr.danger, .table tbody td.danger, li.danger, span.danger {
  19473. background-color: #f2dede;
  19474. }
  19475. .table tbody td.warning, li.warning, span.warning {
  19476. background-color: #fcf8e3;
  19477. }
  19478. .table tbody td.info {
  19479. background-color: #d9edf7;
  19480. }
  19481. td.big {
  19482. width: 117px;
  19483. }
  19484. td.small {
  19485. }
  19486. td.codeLine {
  19487. font-family: monospace;
  19488. white-space: pre;
  19489. }
  19490. td span.comment {
  19491. color: #888a85;
  19492. }
  19493. td span.default {
  19494. color: #2e3436;
  19495. }
  19496. td span.html {
  19497. color: #888a85;
  19498. }
  19499. td span.keyword {
  19500. color: #2e3436;
  19501. font-weight: bold;
  19502. }
  19503. pre span.string {
  19504. color: #2e3436;
  19505. }
  19506. span.success, span.warning, span.danger {
  19507. margin-right: 2px;
  19508. padding-left: 10px;
  19509. padding-right: 10px;
  19510. text-align: center;
  19511. }
  19512. #classCoverageDistribution, #classComplexity {
  19513. height: 200px;
  19514. width: 475px;
  19515. }
  19516. #toplink {
  19517. position: fixed;
  19518. left: 5px;
  19519. bottom: 5px;
  19520. outline: 0;
  19521. }
  19522. svg text {
  19523. font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif;
  19524. font-size: 11px;
  19525. color: #666;
  19526. fill: #666;
  19527. }
  19528. .scrollbox {
  19529. height:245px;
  19530. overflow-x:hidden;
  19531. overflow-y:scroll;
  19532. }
  19533. .nvd3 .nv-axis{pointer-events:none;opacity:1}.nvd3 .nv-axis path{fill:none;stroke:#000;stroke-opacity:.75;shape-rendering:crispEdges}.nvd3 .nv-axis path.domain{stroke-opacity:.75}.nvd3 .nv-axis.nv-x path.domain{stroke-opacity:0}.nvd3 .nv-axis line{fill:none;stroke:#e5e5e5;shape-rendering:crispEdges}.nvd3 .nv-axis .zero line,.nvd3 .nv-axis line.zero{stroke-opacity:.75}.nvd3 .nv-axis .nv-axisMaxMin text{font-weight:700}.nvd3 .x .nv-axis .nv-axisMaxMin text,.nvd3 .x2 .nv-axis .nv-axisMaxMin text,.nvd3 .x3 .nv-axis .nv-axisMaxMin text{text-anchor:middle}.nvd3 .nv-axis.nv-disabled{opacity:0}.nvd3 .nv-bars rect{fill-opacity:.75;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-bars rect.hover{fill-opacity:1}.nvd3 .nv-bars .hover rect{fill:#add8e6}.nvd3 .nv-bars text{fill:rgba(0,0,0,0)}.nvd3 .nv-bars .hover text{fill:rgba(0,0,0,1)}.nvd3 .nv-multibar .nv-groups rect,.nvd3 .nv-multibarHorizontal .nv-groups rect,.nvd3 .nv-discretebar .nv-groups rect{stroke-opacity:0;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-multibar .nv-groups rect:hover,.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,.nvd3 .nv-candlestickBar .nv-ticks rect:hover,.nvd3 .nv-discretebar .nv-groups rect:hover{fill-opacity:1}.nvd3 .nv-discretebar .nv-groups text,.nvd3 .nv-multibarHorizontal .nv-groups text{font-weight:700;fill:rgba(0,0,0,1);stroke:rgba(0,0,0,0)}.nvd3 .nv-boxplot circle{fill-opacity:.5}.nvd3 .nv-boxplot circle:hover{fill-opacity:1}.nvd3 .nv-boxplot rect:hover{fill-opacity:1}.nvd3 line.nv-boxplot-median{stroke:#000}.nv-boxplot-tick:hover{stroke-width:2.5px}.nvd3.nv-bullet{font:10px sans-serif}.nvd3.nv-bullet .nv-measure{fill-opacity:.8}.nvd3.nv-bullet .nv-measure:hover{fill-opacity:1}.nvd3.nv-bullet .nv-marker{stroke:#000;stroke-width:2px}.nvd3.nv-bullet .nv-markerTriangle{stroke:#000;fill:#fff;stroke-width:1.5px}.nvd3.nv-bullet .nv-tick line{stroke:#666;stroke-width:.5px}.nvd3.nv-bullet .nv-range.nv-s0{fill:#eee}.nvd3.nv-bullet .nv-range.nv-s1{fill:#ddd}.nvd3.nv-bullet .nv-range.nv-s2{fill:#ccc}.nvd3.nv-bullet .nv-title{font-size:14px;font-weight:700}.nvd3.nv-bullet .nv-subtitle{fill:#999}.nvd3.nv-bullet .nv-range{fill:#bababa;fill-opacity:.4}.nvd3.nv-bullet .nv-range:hover{fill-opacity:.7}.nvd3.nv-candlestickBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect{stroke:#d62728;fill:#d62728}.with-transitions .nv-candlestickBar .nv-ticks .nv-tick{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-candlestickBar .nv-ticks line{stroke:#333}.nvd3 .nv-legend .nv-disabled rect{}.nvd3 .nv-check-box .nv-box{fill-opacity:0;stroke-width:2}.nvd3 .nv-check-box .nv-check{fill-opacity:0;stroke-width:4}.nvd3 .nv-series.nv-disabled .nv-check-box .nv-check{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check{opacity:0}.nvd3.nv-linePlusBar .nv-bar rect{fill-opacity:.75}.nvd3.nv-linePlusBar .nv-bar rect:hover{fill-opacity:1}.nvd3 .nv-groups path.nv-line{fill:none}.nvd3 .nv-groups path.nv-area{stroke:none}.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point{fill-opacity:0;stroke-opacity:0}.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point{fill-opacity:.5!important;stroke-opacity:.5!important}.with-transitions .nvd3 .nv-groups .nv-point{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-scatter .nv-groups .nv-point.hover,.nvd3 .nv-groups .nv-point.hover{stroke-width:7px;fill-opacity:.95!important;stroke-opacity:.95!important}.nvd3 .nv-point-paths path{stroke:#aaa;stroke-opacity:0;fill:#eee;fill-opacity:0}.nvd3 .nv-indexLine{cursor:ew-resize}svg.nvd3-svg{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;display:block;width:100%;height:100%}.nvtooltip.with-3d-shadow,.with-3d-shadow .nvtooltip{-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nvd3 text{font:400 12px Arial}.nvd3 .title{font:700 14px Arial}.nvd3 .nv-background{fill:#fff;fill-opacity:0}.nvd3.nv-noData{font-size:18px;font-weight:700}.nv-brush .extent{fill-opacity:.125;shape-rendering:crispEdges}.nv-brush .resize path{fill:#eee;stroke:#666}.nvd3 .nv-legend .nv-series{cursor:pointer}.nvd3 .nv-legend .nv-disabled circle{fill-opacity:0}.nvd3 .nv-brush .extent{fill-opacity:0!important}.nvd3 .nv-brushBackground rect{stroke:#000;stroke-width:.4;fill:#fff;fill-opacity:.7}.nvd3.nv-ohlcBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive{stroke:#2ca02c}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative{stroke:#d62728}.nvd3 .background path{fill:none;stroke:#EEE;stroke-opacity:.4;shape-rendering:crispEdges}.nvd3 .foreground path{fill:none;stroke-opacity:.7}.nvd3 .nv-parallelCoordinates-brush .extent{fill:#fff;fill-opacity:.6;stroke:gray;shape-rendering:crispEdges}.nvd3 .nv-parallelCoordinates .hover{fill-opacity:1;stroke-width:3px}.nvd3 .missingValuesline line{fill:none;stroke:#000;stroke-width:1;stroke-opacity:1;stroke-dasharray:5,5}.nvd3.nv-pie path{stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-pie .nv-pie-title{font-size:24px;fill:rgba(19,196,249,.59)}.nvd3.nv-pie .nv-slice text{stroke:#000;stroke-width:0}.nvd3.nv-pie path{stroke:#fff;stroke-width:1px;stroke-opacity:1}.nvd3.nv-pie .hover path{fill-opacity:.7}.nvd3.nv-pie .nv-label{pointer-events:none}.nvd3.nv-pie .nv-label rect{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-groups .nv-point.hover{stroke-width:20px;stroke-opacity:.5}.nvd3 .nv-scatter .nv-point.hover{fill-opacity:1}.nv-noninteractive{pointer-events:none}.nv-distx,.nv-disty{pointer-events:none}.nvd3.nv-sparkline path{fill:none}.nvd3.nv-sparklineplus g.nv-hoverValue{pointer-events:none}.nvd3.nv-sparklineplus .nv-hoverValue line{stroke:#333;stroke-width:1.5px}.nvd3.nv-sparklineplus,.nvd3.nv-sparklineplus g{pointer-events:all}.nvd3 .nv-hoverArea{fill-opacity:0;stroke-opacity:0}.nvd3.nv-sparklineplus .nv-xValue,.nvd3.nv-sparklineplus .nv-yValue{stroke-width:0;font-size:.9em;font-weight:400}.nvd3.nv-sparklineplus .nv-yValue{stroke:#f66}.nvd3.nv-sparklineplus .nv-maxValue{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-sparklineplus .nv-minValue{stroke:#d62728;fill:#d62728}.nvd3.nv-sparklineplus .nv-currentValue{font-weight:700;font-size:1.1em}.nvd3.nv-stackedarea path.nv-area{fill-opacity:.7;stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-stackedarea path.nv-area.hover{fill-opacity:.9}.nvd3.nv-stackedarea .nv-groups .nv-point{stroke-opacity:0;fill-opacity:0}.nvtooltip{position:absolute;background-color:rgba(255,255,255,1);color:rgba(0,0,0,1);padding:1px;border:1px solid rgba(0,0,0,.2);z-index:10000;display:block;font-family:Arial;font-size:13px;text-align:left;pointer-events:none;white-space:nowrap;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.nvtooltip{background:rgba(255,255,255,.8);border:1px solid rgba(0,0,0,.5);border-radius:4px}.nvtooltip.with-transitions,.with-transitions .nvtooltip{transition:opacity 50ms linear;-moz-transition:opacity 50ms linear;-webkit-transition:opacity 50ms linear;transition-delay:200ms;-moz-transition-delay:200ms;-webkit-transition-delay:200ms}.nvtooltip.x-nvtooltip,.nvtooltip.y-nvtooltip{padding:8px}.nvtooltip h3{margin:0;padding:4px 14px;line-height:18px;font-weight:400;background-color:rgba(247,247,247,.75);color:rgba(0,0,0,1);text-align:center;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.nvtooltip p{margin:0;padding:5px 14px;text-align:center}.nvtooltip span{display:inline-block;margin:2px 0}.nvtooltip table{margin:6px;border-spacing:0}.nvtooltip table td{padding:2px 9px 2px 0;vertical-align:middle}.nvtooltip table td.key{font-weight:400}.nvtooltip table td.value{text-align:right;font-weight:700}.nvtooltip table tr.highlight td{padding:1px 9px 1px 0;border-bottom-style:solid;border-bottom-width:1px;border-top-style:solid;border-top-width:1px}.nvtooltip table td.legend-color-guide div{width:8px;height:8px;vertical-align:middle}.nvtooltip table td.legend-color-guide div{width:12px;height:12px;border:1px solid #999}.nvtooltip .footer{padding:3px;text-align:center}.nvtooltip-pending-removal{pointer-events:none;display:none}.nvd3 .nv-interactiveGuideLine{pointer-events:none}.nvd3 line.nv-guideline{stroke:#ccc}/*!
  19534. * Bootstrap v3.3.4 (http://getbootstrap.com)
  19535. * Copyright 2011-2015 Twitter, Inc.
  19536. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  19537. *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px \9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.form-group-sm .form-control{height:30px;line-height:30px}select[multiple].form-group-sm .form-control,textarea.form-group-sm .form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:5px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.form-group-lg .form-control{height:46px;line-height:46px}select[multiple].form-group-lg .form-control,textarea.form-group-lg .form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:10px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.active,.btn-default.focus,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px)and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;margin-top:-10px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px)and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px)and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px)and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px)and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px)and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px)and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}�����€��pFFTMm*—Ü���ü���GDEFD������ OS/2g¹k‰��8���`cmapÚ­ã���˜��rcvt �(ø�� ���gaspÿÿ������glyf}]Âo����”¤headM/Ø��œ¼���6hhea
  19538. D��œô���$hmtxÒÇ `�����tlocaoû•Î�� Œ��0maxpj�Ø��¢¼��� name³, ›��¢Ü��¢postº£å5��¦€��
  19539. ÑwebfÃTP��±T����������Ì=¢Ï����Ðv�u����Ðvs—����������������������‹��� Ð���Z Ð��¤�2¸��������������������������UKWN�@� ÿÿÀÿ���{�������������� ����������,���
  19540. �������h�����,��
  19541. ��Ü�°���h�@��(� �+� �¥
  19542. / _ ¬ ½"#%ü&&ú' 'àà àà)à9àIàYà`àiàyà‰à—á áá)á9áFáIáYáiáyá‰á•á™ââ âââ!â'â9âIâYâ`øÿÿÿ��� �*� �¥ � / _ ¬ ½"#%ü&&ú' 'àààà à0à@àPà`àbàpà€à�ááá á0á@áHáPá`ápá€á�á—â�â âââ!â#â0â@âPâ`øÿÿÿÿãÿÚÿfÿbàßäßµßißYÞÜýÚÚÙ!ÙÙ    
  19543. þø÷ñëå|vpjdc]WQKEDÞÜÖÕÎÍÅ¿¹³���������������������������������������������������������������������������������������������������������� ����Œ�������5��� ��� ������*���+������ ��� ������¥���¥����� ���
  19544. ����� /�� /����� _�� _����� ¬�� ¬����� ½�� ½�����"��"�����#��#�����%ü��%ü�����&��&�����&ú��&ú�����' ��' �����'��'�����à��à�����à��à ���!��à��à���&��à ��à)���0��à0��à9���:��à@��àI���D��àP��àY���N��à`��à`���X��àb��ài���Y��àp��ày���a��à€��à‰���k��à���à—���u��á��á ���}��á��á���†��á ��á)������á0��á9���š��á@��áF���¤��áH��áI���«��áP��áY���­��á`��ái���·��áp��áy���Á��á€��á‰���Ë��á���á•���Õ��á—��á™���Û��â���â���Þ��â ��â ���å��â��â���æ��â��â���í��â!��â!���ï��â#��â'���ð��â0��â9���õ��â@��âI���ÿ��âP��âY�� ��â`��â`����øÿ��øÿ���õ�õ���öª�öª���
  19545. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(ø���ÿÿ���(��h ���.±�/<²�í2±Ü<²�í2�±�/<²�í2²ü<²�í23!%3#(@þèðð üà(Ð��d�dLL�[��27>32+&/#"&/.=/&6?#"&'&546?>;'.?654676X&
  19546. žjžà
  19547. 
  19548. àžjž
  19549. )"&
  19550. žjžà
  19551. 
  19552. àžjž
  19553. )L
  19554. àžjž
  19555. )"&
  19556. žjžà
  19557. 
  19558. àžjž
  19559. )"&
  19560. žjžà
  19561. ��������LL�#��32!2#!+"&5!"&=463!46ÂÈ^þ¢Èþ¢^Lþ¢Èþ¢^È^�����p��@L�E��32!2+!2++"&=!"&?>;5!"&?>;&'&6;22?69ú
  19562. þ”
  19563. x
  19564. }
  19565. x
  19566. } ” þí
  19567. x
  19568. }þí
  19569. x
  19570. vþ”
  19571. ú¤¤L
  19572. þ”   d   ®  ®   d   l
  19573. ¤¤���d�Œ®�;��2#4.#"!!!!32>53#"'.'#7367#73>76èòp<µ#4@9+820{dþÔ–dþÔ 09B49@4#®bk§Îv$B ÙdpÚd†>u®½hi-K0! .O2d22dJtB+"0J+«kuž0ªwd/5dW…%����{��L°�>�G��!2+!2++"&=!"&?>;5!"&?>;4632654&#¬^CjB0  0BjC²
  19574. x
  19575. Š
  19576. þõ
  19577. x
  19578. uþõ
  19579. x
  19580. u¶Ë@--@°$?2O*$ $*P2@%d   ¯ 
  19581. ¯   d   Û
  19582. ÈþÔBVT@���È�L¼���!2#!"&=46ú üà¼ÈÈ����È��è°�%�A��+32!546;5467.=#"&=!54&'.467>=è2cQQc2üà2cQQc2ÈA7 7A�A7 7A°–d[•##•[––––[•##•[d–Èd<c 2<2 c<––<c 2<2 c<d���������������1��ÿò,ÂA���2632#!"&5467&546÷nµ,,.xªªxýOqUBØAwa­xy­rPEk ™×������d°¯�����32!546;'&>76!'ö
  19583. ˆÓûPÔ‡
  19584. $
  19585. op zy¶Ã³#»ý%**%ê·$ ”–üp�������d°L� ��#�7��!2"'&6&546 6'&4#!"&7622?62~
  19586. ýÌýÌþø
  19587. Œ
  19588. þø\l
  19589. û‚
  19590. l¤¤L
  19591. ýÉ7
  19592. Úþøþø
  19593. &
  19594. þð
  19595. ýÚ
  19596. €þ”
  19597. l¤¤���ÿðÿðºº� � ����2'7' à&™ cÖ_"ý™Öfþþ³nº ™&\Ö`þtýšÖfüjpO�������°°���32!546;!¼úüàúþ °ŠýÚ22&&�����Lœ���%6.676.67646p…'0SFOˆ$WOHBý¨XAOˆ$WOHBù£"üÁ7Q)mr ›ý¢*`)nq&*���� ÿø»§��)���2"'#'".4>"2>4&�ȶƒNN;)þíwŽd¶ƒNNƒr°”VV”°”VV§Nƒ¶d�yþî%:MNƒ¶È¶ƒ[V”°”VV”°”��d�X¯D���>.54>‰0{xuX6Cy„¨>>§…xC8ZvxyµDH-Sv@9y€²UU²€y9@vS-H���ÿÓ�^{”���62!2'%&7%&63—ƒ�¥þª‚þ©þª‚þ¥ aþŸ ùþo ö÷ �û �ÿÓ�^{”��"��62!2'%&7%&63#7'7#'—ƒ�¥þª‚þ©þª‚þ¥óðÅJÁÃJÀêN aþŸ ùþo ö÷ �û dŽâ‹ŒåŒÓ������°°�&��2##!"&=467%>="&=46X|°>& f 
  19598. û‚
  19599.  f &>°°°|ú.hK
  19600. æ
  19601. ]
  19602. 
  19603. ]
  19604. æ
  19605. Kh.ú|°��� ����°L���#�'�+�/�3�7�G�K�O�S�W��!2#!"&54635)"3!2654&33535!3535!35!"3!2654&35!3535!35~
  19606. 
  19607. û‚
  19608. Ud£ýÚ
  19609. 
  19610. &
  19611. sdüd düd dáýÚ
  19612. 
  19613. &
  19614. üïd düd dL
  19615. ûæ
  19616. 
  19617. 
  19618. ddd
  19619. þ¢
  19620. 
  19621. ^
  19622. ddÈddddÈddddd
  19623. þ¢
  19624. 
  19625. ^
  19626. dddddÈdddd������LL���/�?��!2#!"&546)2#!"&546!2#!"&546)2#!"&5462�þpm�þpý½�þpm�þpLþp�þp�ý¨þp�þp��� ����LL���/�?�O�_�o�����32+"&=46!32+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=462ÈÈ¥ÈÈ¥ÈÈüõÈÈ¥ÈÈ¥ÈÈüõÈÈ¥ÈÈ¥ÈÈLÈÈÈÈÈÈþpÈÈÈÈÈÈþpÈÈÈÈÈÈ�����°L���/�?�O�_��32+"&=46)2#!"&=4632+"&=46)2#!"&=4632+"&=46)2#!"&=462ÈÈ¥¼ýDþ…ÈÈ¥¼ýDþ…ÈÈ¥¼ýDLÈÈÈÈþpÈÈÈÈþpÈÈÈÈ�����&�,è ��� 62"'&4?622Ñ;±üñþ€±«Ý;±üð€±«��n�nBB�#�� "' "/&47 &4?62 62ˆ²þõ ²þôþô² þõ²  ;³þôþô² þõ²  ²þõ ��ÿëÅ™��%�I���2"'#".4>"2>4&3232++"&=#"&=46;546™Ä³‚MN,mþÔwŽb´�MM�o³˜XX˜³™XXþ¼–
  19627. K
  19628. 
  19629. K
  19630. K
  19631. 
  19632. K™M‚³b�yþÕl+MM�´Ä³‚MX™³˜XX˜³™#
  19633. K
  19634. K
  19635. 
  19636. K
  19637. K
  19638. ���ÿëÅ™��%�5���2"'#".4>"2>4&!2#!"&=46™Ä³‚MN,mþÔwŽb´�MM�o³˜XX˜³™XXþX^
  19639. 
  19640. þ¢
  19641. ™M‚³b�yþÕl+MM�´Ä³‚MX™³˜XX˜³™‡
  19642. 
  19643. ������™°��-��32+"&5465".5472>54&&dd§Ò[›ÖêÖ›[Ò§g|rÅèÅr|°þp�á¦>þÙ¸uÖ›[[›Öu¸'>¦7ÈxtÅrrÅtxÈ��d��°°���/�?��32+"&54632+"&54632+"&54632+"&=46–
  19644. 
  19645. þÞ–
  19646. 
  19647. þÞ–
  19648. 
  19649. þÞ–
  19650. 
  19651. °
  19652. û‚
  19653. 
  19654. ~
  19655. þp
  19656. ý
  19657. 
  19658. þÔ
  19659. þ>
  19660. 
  19661. È
  19662. ú
  19663. 
  19664. ú
  19665. ������––�G�O��27'#"/&/&'7'&/&54?6?'6776?6"264X!)&1-†=+P˜˜P08†,2&+!)&1-†<,P —— P/:…-1&+x²~~²~–˜P09†,1&+"(&1,†=,Q——Q09†-0&* !(&0-†=,P˜þ™~±~~±��d��°���!�%�)�-�1��!2!2!5463!546!5#!"&53333333ô,);
  19666. û´
  19667. ;),,;)ýD);dddddddd;)d
  19668. KK
  19669. d);dddþÔüà);;) dýD¼ýD¼ýD¼ýD¼�� ��Ñ���62++"&5!+"&5#"&l`
  19670. ¯
  19671. ú
  19672. þÔ
  19673. ú
  19674. j`ý 
  19675. ýÁ
  19676. 
  19677. wþ‰
  19678. 
  19679. ?
  19680. ��d��è°����3!#!"&5463#"&=X;),üàRú°þp);ývLþpú���™™���0���2".4>"2>4&3232+"&546ãêÖ›[[›ÖêÖ›[[›¿èÅrrÅèÅrrþ|2
  19681. 
  19682. ú
  19683. ™[›ÖêÖ›[[›ÖêÖ›;rÅèÅrrÅèÅ 
  19684. þí
  19685. 2
  19686. 
  19687. ^
  19688. ����ÿœ��°� ���)#!3333ýæ)ò)ýæ¯Ñ¢Ðþžà�þp°þÔ,þpþÔ,�����d��°°��/��3232"'&6;4632#!"&546;2!546&È¿ þ¹ & þ¹ ¿T2
  19689. 
  19690. ûæ
  19691. 
  19692. 2
  19693. „°þ>þp�Âüà
  19694. þ¢
  19695. 
  19696. ^
  19697. 
  19698. ¯¯
  19699. ���™™���1���2".4>"2>4&3232"'&6;46ãêÖ›[[›ÖêÖ›[[›¿èÅrrÅèÅrrþ|–
  19700. ‰
  19701. ß & ß
  19702. ‰™[›ÖêÖ›[[›ÖêÖ›;rÅèÅrrÅèÅ 
  19703. þíþí
  19704. �����™™���1���2".4>"2>4&%++"&5#"&762ãêÖ›[[›ÖêÖ›[[›¿èÅrrÅèÅrrþçß
  19705. ‰
  19706. ‰
  19707. ß &™[›ÖêÖ›[[›ÖêÖ›;rÅèÅrrÅèÅþíþí
  19708. 
  19709. ��������°°��9��!2#!"&'&547>!";2;26?>;26'.áî
  19710. º û´ ¹—ýÔ
  19711. W
  19712. &
  19713. ú
  19714. &
  19715. W°
  19716. ýtþW  ©Œ
  19717. È þ> 
  19718. ˜
  19719. 
  19720. ˜
  19721.   ���™™���'���2".4>"2>4&&546ãêÖ›[[›ÖêÖ›[[›¿èÅrrÅèÅrrþ‹ýý™[›ÖêÖ›[[›ÖêÖ›;rÅèÅrrÅèÅ]¾ $ ¾ � ���™°�(��76#!"&?&#"2>53".4>32³‡ 
  19722. þ– …m�tÅrrÅèÅr–[›ÖêÖ›[[›ÖuÀ$‡ þ–
  19723.  …LrÅèÅrrÅtuÖ›[[›ÖêÖ›[������™°��5��76#!"&?&#"#4>323#"'&5463!232>³‡  þ— †n�tÅr–[›ÖuÀë–[›ÖuÀœ†  h
  19724. …n‚tÅr$‡ þ—  †KrÅtuÖ›[ý¿uÖ›[v†
  19725. h  …LrÅ���
  19726. �d��°°���/�?�O�_�o����Ÿ��!2#!"&546!"3!2654&32+"&=463!2#!"&=4632+"&=463!2#!"&=4632+"&=463!2#!"&=4632+"&=463!2#!"&=46}
  19727. 
  19728. ûæ
  19729. Àü®
  19730. 
  19731. R
  19732. ý2
  19733. 
  19734. 2
  19735. ÒÂ
  19736. 
  19737. þ>
  19738. ¾2
  19739. 
  19740. 2
  19741. ÒÂ
  19742. 
  19743. þ>
  19744. ¾2
  19745. 
  19746. 2
  19747. ÒÂ
  19748. 
  19749. þ>
  19750. ¾2
  19751. 
  19752. 2
  19753. ÒÂ
  19754. 
  19755. þ>
  19756. °
  19757. û‚
  19758. 
  19759. ~
  19760. È
  19761. ü®
  19762. 
  19763. R
  19764. d
  19765. 2
  19766. 
  19767. 2
  19768. 
  19769. 2
  19770. 
  19771. 2
  19772. È
  19773. 2
  19774. 
  19775. 2
  19776. 
  19777. 2
  19778. 
  19779. 2
  19780. È
  19781. 2
  19782. 
  19783. 2
  19784. 
  19785. 2
  19786. 
  19787. 2
  19788. È
  19789. 2
  19790. 
  19791. 2
  19792. 
  19793. 2
  19794. 
  19795. 2
  19796. ��������L°��#��54&#!"#"3!2654&#!546;2„uSþÔRvd);;)„);;)ý¨È ÈSuvRÈ;)ý¨);;)X);––��d��LL� �7��32#462#".'.#"#"'&5>763276}2
  19797. dÀ!C@1?*'),GUKx;(.9)-EgPL
  19798. ûÍ3
  19799. 0þ[;P$ 9¶7W W������°—�!�1�A���2+"&54. +"&54>32+"&546!32+"&546äèÞ£c
  19800. 2
  19801. �äþúä�
  19802. 2
  19803. c£*    `    —c£ÞtþÔ
  19804. 
  19805. ,ÑrrÑþÔ
  19806. 
  19807. ,tÞ£ýÀ þ4 Ì þ4 Ì �������ÓGÝ��9��%6'%&+"&546;2762"/"/&4?'&4?62A þþú
  19808. 
  19809. úXx"xx"xx"ww".¬
  19810. ý
  19811. ¬
  19812. ^
  19813. „x"xx"ww"xx"�������ÓrÝ��/��%6'%&+"&546;2%3"/.7654'&6?6A þþú
  19814. 
  19815. úÒ
  19816. `Z  HN.¬
  19817. ý
  19818. ¬
  19819. ^
  19820. d �¡š g~„j�������Äbì��1�K��3#"/.7654&'&6?6%6'%&+"&546;2%3"/.7654'&6?6Ç ‡D@
  19821.  *o;7 *ý‚ þþú
  19822. 
  19823. úÒ
  19824. `Z  HNì ³ÙiËT "–²Z¬G !¾¬
  19825. ý
  19826. ¬
  19827. ^
  19828. d �¡š g~„j���� ����°°� ����!�%�-�;�?�C�G�K�O��3#!#!#3!##5!!!!#53#533!3533##5#535#5!!#53#53#53!5!ôddþpdô¼ÈÈþÔÈdXû´,�,üàdd¼ddýDÈþ ÈdôÈdÈddÈ,ýD,ddd„ddþ ddôþÔ,„dddXþ dÈ,,ÈdþÔ,þÔ,Èdddþ þ ôdþÔddddÈdÈþÔ,ÈdddþÔddd���� ����°°��� ������#��7#3#3#3#3#3!5!#53#53#53dddÈdd�ÈÈÈdd,ÈÈüàþÔ,ÈddÈdd,ÈÈÈèüèüèüèüèûPdd[[[[[�����
  19829. ¦°� ��� "'463&"26ôªþ0ýV
  19830. C;S;;S;°ýVþ0ªÛ
  19831. Í;;T;;�������
  19832. Ò°� ��!�� "'463!"/ &"26ôªþ0ýV
  19833. ªþ08¨ýDþÓ;S;;S;°ýVþ0ªÛ
  19834. ýVþ08ª¼Í;;T;;�����d��°°�&��!2&54&#!"3!2#!"&54?6,9K@
  19835. 
  19836. ýD@
  19837. 
  19838. ü®
  19839. ‹°Kü|@
  19840. @
  19841. 
  19842. üJ
  19843. 
  19844. Ï‹����ÈÿÿL°�
  19845. ��!2 46ú þ>þ>°û‚¼þC��������°°��E�U��!"3!26?6'.#"#!"&/.+";26=463!2;2654&!"3!26/.6þD N9
  19846. >SV–
  19847. N
  19848. ýÚ
  19849. N
  19850. 
  19851. 
  19852. 
  19853. þ±þ
  19854. &
  19855. X
  19856. &°
  19857. þÓl l-
  19858. þp œ œ 
  19859. ýv
  19860. 
  19861. 
  19862. 
  19863. ý¨
  19864. ˜
  19865. 
  19866. ˜
  19867. �������d°L��!�)�1��3232#!"&546;>35"264$2"&4ôÈ8]4$–);;)ü);;)– '3]ÈdþϾ‡‡¾‡þïV<<V<L);;;)ý¨);;)X);E5+þÔddF‡¾‡‡¾<V<<V�����5��°¯� �#�� !526/!3!567>?!©�(%
  19868. þ_5,Rþy:" *2þ“8 �¬T¢¯ü2*BBW-Þ‘Y". BB % îýZÉ�����d��ð°�'�2�;��#!5>54.'52%32654.+32654&+ñ50;*7Xml0þ ); !×9uc>--þ�‹Ni*S>vØPR}^Ÿ�3:R.CuN7Y3(;  G)IsC3[:+ 1aJ);4ü®ePZ����È��o°���!56764.'&'5mSB„ ,Jþ º­  °95(ü¹1(aaR@ 9����ÿµ��°�%�/��#4.+!52>5#"#!#3'3#72 &È2þp"È& 2èû›KK}}KK}„ ü®dd R ,Èüà§§ §��!ÿµ�°�%�/��#4.+!52>5#"#!5!'7!5L2 &È2þp"È& 2èC§üà§§ „ ývdd Š ,û‚}KK}}KK�����°L���/�?��!2#!"&=46!2#!"&=46!2#!"&=46!2#!"&=462Xý¨èü üàLû´LddþÔddþÔddþÔdd�����°L���/�?��!2#!"&=46!2#!"&=46!2#!"&=46!2#!"&=46ú¼ýD³Lû´Ý¼ýD³Lû´LddþÔddþÔddþÔdd�����°L���/�?��5463!2#!"&5463!2#!"&5463!2#!"&5463!2#!"&ôXý¨þpèüÈ üàþÔLû´¶ddþéddþéddþédd������°L���/�?��!2#!"&=46!2#!"&=46!2#!"&=46!2#!"&=462Lû´Lû´Lû´Lû´LddþÔddþÔddþÔdd�����°L���/�?�O�_�o���32+"&=46)2#!"&=4632+"&=46)2#!"&=4632+"&=46)2#!"&=4632+"&=46)2#!"&=462ddA üàþéddA üàþéddA üàþéddA üàLddddþÔddddþÔddddþÔdddd��ÿœ��°L���#�*�:�J��!#;2+"&=46!2#!"&=465#535!2#!"&=46!2#!"&=46�dd–ddôþ þú§ÈÈÂ,þÔXý¨LddþÔddú}KdK¯ddþÔdd�������L���#�*�:�J��32+"&=46#3!2#!"&=463#'7!2#!"&=46!2#!"&=462ddgddü®ôþ /Èȧ§ûæ,þÔXý¨Lddû´LþÔddÈdK}}¯ddþÔdd�������Ȱè����!2#!"&546 Kî,,ý,,„þÔ,è,ýv,,Š,ýD,,�����°L�����!2#!"&5467'2"&4,Xû¨J÷*J%ìüÒpNNpNLü ôdý¶ƒœ>þàôtNoOOo�����Û�6‘����2.'&54>"264ˆuÆsFE²66 !^Xm)<DsŸ··‚‚·‚‘xÊus�mé?>!fh˜H„uX£yH¸��¸�����™™�����2".4>"ãêÖ›[[›ÖêÖ›[[›KtÅrrÅ™[›ÖêÖ›[[›ÖêÖ›üoVrÅèÅr���u�ß��5��.54>6?6&'.'&76#&*IOWN>%3Vp}?T›|J$?LWPI¼)(!1 )  H�uwsu‡EG€^F&:c—YE‡vsxv�ýþ!K‚:%A'# "
  19869. A)Y¶ �������Ël� �*�/��7>%!2!"3!26=7#!"&546 7èl
  19870. lý�27»þ�);;)ô);È»£þp¥¹¹8þ–¡7cõs*
  19871. sÈ »;)þ );;)¶Èþ´¥¹¹¥�¥¹þ×þ–2ªc�����“L��6��!#"3!2657#!"&546&'5&>75>^i¤4Ã);;)ô);ȹ¥þp¥¹¹Sþ¬ 9dTX
  19872. .9I@F* L’6;)þ );;)™g¥¹¹¥�¥¹þÓþÎ Ë 0!;bA4Ò
  19873. ���������L��5��!2!"3!26=7#!"&546 62"/&4?622^^<C²þ£);;)ô);ȹ¥þp¥¹¹Ê‹eýíøeoL±;)þ );;)EÈÛ¥¹¹¥�¥¹þ3‹eýìøeo����
  19874. ¦¦�;�� 62+3546&=#32"'&6;5#'&47635#"&>
  19875. ªÈ
  19876. þø
  19877. Ȫ
  19878. þüþø
  19879. ¯È
  19880. þø
  19881. ȯ
  19882. –þø
  19883. È­
  19884. þüþ÷
  19885. ­È
  19886. þø
  19887. È­
  19888.  
  19889. ­È
  19890. ��È��„L���326'+"&546údÐþ0dLþJÅüÅþJè�������°L�#��3266''+"&5462dÐÐþ0þ0dLþJÅþJÅüÅþJÅþJè������°3���''&4766°þ0þìÐüÅþJà*àþJÅ����È�36� ��&546ó.üÒ2þ  þ è��È�d„è����32+"&546!32+"&546úÈÈ¥ÈÈèüà üà ���È�dLè���#!"&5463!2Lüà ¶üà �������3���46&5&546ôìþþ0d¶þ *þ ¶þ;è��ÿþ�³O�#��72#"&5&5&5464646ddþ1þ2ÒÒNüµþ: µþ9 è þ>¶ þ=¶��,��èL���32+"&5&54646Rddþ0ÐLü¶þ;èþ;¶���d�ȰH� ��� #!"&762!2#!"&=46®õ ûî õ*ý÷èü9ýäýHdd��ˆÿüuJ���  uþ `ÅýØ(„þŸþŸÆ(&����;ÿü(J��� ' 7(ýÙÆaþŸÆ#ýÙÆaaÆ���™™��3���2".4>#"#";;26=326=4&+54&ãêÖ›[[›ÖêÖ›[[›}d––d––™[›ÖêÖ›[[›ÖêÖ›º–d––d–������™™�����2".4>!"3!26=4&ãêÖ›[[›ÖêÖ›[[›Eþ ô™[›ÖêÖ›[[›ÖêÖ›þ~dd���™™��3���2".4>"'&"2?2?64/764/ãêÖ›[[›ÖêÖ›[[›å xx  � xx �  xx  � xx �™[›ÖêÖ›[[›ÖêÖ›­ xx �  xx  � xx �  xx  ����™™��$���2".4>'&"2764/&"ãêÖ›[[›ÖêÖ›[[›T‹òw‹™[›ÖêÖ›[[›ÖêÖ›þ1U‹ñw‹������™™��;�K���2".4>";7>32";2>54.#";26=4&ãêÖ›[[›ÖêÖ›[[›?<B2!ƒ  ­(#"3D<:–
  19891. 
  19892. ™[›ÖêÖ›[[›ÖêÖ›‘ /O2*(8\6/H* ýã
  19893. 
  19894. ����™™���>���2".4>#";26=4&#";#"3!26=4&+4&ãêÖ›[[›ÖêÖ›[[›––
  19895. 
  19896. 
  19897. ú
  19898. 
  19899. KK
  19900. 
  19901. ^
  19902. 
  19903. K™[›ÖêÖ›[[›ÖêÖ›V
  19904. 
  19905. þÔ
  19906. 2
  19907. È
  19908. 2
  19909. 
  19910. 2
  19911. 
  19912. �����°°�/�_��3232++"&=.'#"&=46;>7546+"&=32+546;2>7#"&=46;. –
  19913. g—Â
  19914. 
  19915. —g
  19916. g—Â
  19917. 
  19918. —g¹
  19919. Df¨
  19920. 
  19921. ¨fD
  19922. Df¨
  19923. 
  19924. ¨f°
  19925. —g
  19926. g—Â
  19927. 
  19928. —g
  19929. g—Â
  19930. þͨ
  19931. 
  19932. ¨fD
  19933. Df¨
  19934. 
  19935. ¨fD
  19936. Df���™™���?���2".4>"2>4&"/"/&4?'&4?62762ãêÖ›[[›ÖêÖ›[[›¿èÅrrÅèÅrrš@||@||@||@||™[›ÖêÖ›[[›ÖêÖ›;rÅèÅrrÅèÅZ@||@||@||@||�����™™���0���2".4>"2>4&"/&4?62762ãêÖ›[[›ÖêÖ›[[›¿èÅrrÅèÅrrƒjþÀÊjOÅ™[›ÖêÖ›[[›ÖêÖ›;rÅèÅrrÅèÅ}jþ¿ËjOÅ�����™™���!���2".4>"&32>54ãêÖ›[[›ÖêÖ›[[›KtÅrAKiõý¸hstÅr™[›ÖêÖ›[[›ÖêÖ›;rÅtxiKAÐý¸>rÅts������S°ù���6!2#!'&4'
  19937. &ýÚýöF«
  19938. þÝÈþÝ
  19939. « &�������S™ù��� &5!"&=463!46
  19940. ýöýÚ&ñþU & þU
  19941. #È#
  19942. ����·��]™��� #!+"&5!"&762ª«
  19943. þÝÈþÝ
  19944. « &‰ýöýÚ&
  19945. ����·�]°���32!2"'&63!46&È#
  19946. þU & þU
  19947. #°ýÚýö
  19948. &�����·™]��� &5>746
  19949. ýö^°¥�$,[‡Ç~UþU & þU
  19950. #$DuMi±�qF
  19951. �����°°��+��!2/"/&4?'&6!"&546762R,^ùjù^þ!þÔ^ùjù^°þÔ^ùjù^ûP,^ùjù^����I�Igg��+��#!"&546762!2/"/&4?'&6öjù^þÔ^ùý ,^ùjù^`jù^,^ùýñþÔ^ùjù^������™™���/���2".4>#";2676&#";26=4&ãêÖ›[[›ÖêÖ›[[›³Ð:#6#:1–
  19952. 
  19953. ™[›ÖêÖ›[[›ÖêÖ›ºþÒ.þ 
  19954. 
  19955. ��������°°�I�U�a�h�o��276?67632;2+"!#!54&+"&=46;2654?67>;26/.'&;26!"&5)#! Ä &Ä0 
  19956. =
  19957. 
  19958. 2
  19959. þpÈþp
  19960. 2
  19961. 
  19962. =  �¦
  19963. Û
  19964. 3þ5±3
  19965. ç þ‰
  19966. �X
  19967. þ‰°
  19968. v  v
  19969. !{, 
  19970. 2
  19971. 
  19972. ¯,þÔ¯
  19973. 
  19974. 2
  19975. 0€y¢
  19976. 
  19977. ª�
  19978. 
  19979. ür
  19980. wþ‰
  19981. �������� ¯¦�+�I��6.'&&&547>7>'.>7>&67>7>7>�-Bla‹bŽD8=3™*U  :1'Ra\‡{À%&¢=>8\tYR-!Šq[Fak[)¦²þÝÈ•X1 ™"@&J<7_…?3J5%#/D &/q!!6ROg58<'([@1%@_U2��]�rÏ�O��.>7'&767>.'&'.'&>77>.'&>�'
  19982. '8GB 
  19983. 
  19984.  `ŠH  >JS>H7 '+" NA
  19985. 5M[`/Pg!;('2"&"IbYÏC€e\D9$ 886#1%)*ƒ‘§—J7gG:    8G\au9hªoK$œ]54<<E"5cQ8 .@AU!U™hQ)����ÿÜ�jÔF��?�Q���2".4>&"&5476&2>76&'&6?6&'&'.¤�{nO9:On{�¢�{nO:9On{°ø°FZ  2Z_ƒˆƒ_Z2  Zýÿ# %8-#,- "F-I\b\I*I\b\I--I\b\I*I\b\IÜ9>|°°|;7Es1$F^D10E^E$1u$/D0 "%,I���ÿÜ��Ô°��'�;�L��!#7.54>327377>76&'&%7.5476&6?'&'.P”[©vY,9On{�R=A ”&/l‰'Pj˜R.Mv&  6ýQFZ  *HLh5)k�|# %8- ,- "xatzbI\b\I-yþRµUÖ4Zrnc­1ˆ?1FrEs1<QA9 š§n;7p$/D0  V,I���ÿž��«� ��(��'6#!"&%!546;2!32+"&/&6Z‚8‚%úò%
  19986. Y
  19987. YþChÐ:#6#:d*!ûà GD„K
  19988. 
  19989. KÓßüü����d�°°�(���2'%/&=47&=4674L|Xkþ™dÍÍdþ™k°X>þ­þ»1) ùþù]@ €€ @]ù )1ES>�������L°��'�+�/�3�7�;�?�C�G�K�O�S�W�[�_�c��3232!546;546;2!546#!"&5353353353353353533533533533535335335335335Rd2û´2dôüddddddddddü|dddddddddü|ddddddddd°2––222þpýîÈddddddddddÈddddddddddÈdddddddddd������w—��%�7��&=#!"&=46;3546'#"&=463!&=#'73546oùùŸý¨þÝÑXñý©�zÑ#ùùñµ�zŸ�æ*æ–ý¨dX–þ˜�zdþMæ*æ–µ�z–�������°L���!2#!#"&546dè);;)ý¬þÐd);;L;)ý¨);þÔ,;)X);����d��L°� ��?��32!546!32!546".5!2>&54=–ÈþÔÑÈþÔ(LfœÀœfL(, '6B6'°úúúúþpþÔ)IjV\>((>\VjI),ú +'%! !%'*ú���ÿÿ�ÔLÂ��� 'LÆþŸþŸÅ'›ÇaþŸÇ'����îMÜ��� 7 MýÚýÙÆaaýÙ'ÇþŸa����ÿQ�d_è��)��!232"/&6;!%+!!"&5#"&?62”ê–æ*æ–þƒþæ–�×ý–æ*èýÙùù‘¸ùþpÈ&ù�����ž°�0��32!2#!!2+"&=!"&=#"&/#"&468^&€d,!ý‡02*þÔ*É6°¢%þ%+È*2222
  19990. Á*��������°L� ���!53463!2!!°ûPÈ;),);ýD°ûPèdd);;)Èüà�����ÜL� ���3463!2!!ÈÈÈ;),*:ô,þÔûP, þpX);;)ÈdýD¼�E��k¯���+32"/&6;#"&?62{æ––æ*æ––æ* ùý§ùùYù����D¯k���&=!/&4?6!546¨ùùý¨ùùX`å)å —— å)å •• �������°°� ���!��.#!"!"3!26=4&53353‘¬$ý`$¬-ü);;)è);;þ«ddd�Ü-(ýd;)d);;)d);Èdddd���ÿœ�d°L� �#�1���2"&54%##"+"&'=454>;%".=4>7i**dý]&/T7 È£ü" Lü®Rü™ÈþìQú úþÔú )2( ����J��f°�,�5��3232#"./.46;7>7'&6327"&)^Sz?vdjŸO9t\U>/ v?zS$2451 7F8°%Mþ¹­)( 
  19991. ()­GM~ û¾1==���œœ���7'''7'7'7'77 àNê´´êNà-››-àNê´´êNà-››²Nà-››-àNê´´êNà-››-àNê´´����d°°�!�-�=��32!2+"&/#"&54?>335!7532+"&546Š2(<H(<î,úF=-7‘` 1d–dˆÖúþ>2ývdd°Q,–}Q,d-þ¨!2$'�$ÄÆ(dÔÕþ‰dw}á¯þÔþ ô��������°L� �0�<��32#!+"&/&546;632+"&546!#35'!5Xú,î<(þ¸<(21 `‘7-=|ýédd_ˆd–d22ÂúL!þ¨-d,Qv–,Q(ÆÄ$�'$ddþ ôdþ‰ÕÔ¯á}w����dO��7�G��%6!2+#!"&5467!>;26&#!*.'&?'32+"&546dkn  T.TlnTjƒþª¦:d%ƒËþ8
  19992.   ’VýOddiæp &yL�Nþ­(¢  %
  19993. Hþ YS(22·Säþ ô���ÿœ�d°O��6�F��#!"&'#"&463!'&6?6*#!32!7%32+"&546Ûn ¬þªƒjUmlT.U  nJ’  
  19994. þ%Ý‚&jþªPddOæ ýó ¢(SN�Ly& p®·d(þ­Y÷ìäþ ô����a��L��7�G���2#!"&/&?>454&/!7%.!2#!"&=46Þ�NS(¢ ýó%
  19995. æp &yÆ22·Sì÷Yþ­(–ôþ nTjƒþª¦kn  T.TÖËþ8
  19996.   ’Vþ­d%ƒý dd�ÿý�è��-�I��!26=4&#!""&5&/&7>3!2766=467%'^ôþ N�Ly& pæ  ¢(ý‰ìS·22(SYLddüæjTnlT.T  nk ¦þªÏþ­V’  
  19997. þ8˃%d���šš��%���2".4>%&!"3!7%64âìÖ›[[›ÖìÖ›[[›†þíþí
  19998. 
  19999. š[›ÖìÖ›[[›ÖìÖ›þ9ß
  20000. ‰
  20001. ‰
  20002. ß &����šš��%���2".4> 6=!26=4&#!54&âìÖ›[[›ÖìÖ›[[›%þí
  20003. 
  20004. þíš[›ÖìÖ›[[›ÖìÖ›èß & ß
  20005. ‰
  20006. ‰
  20007. �����šš��%���2".4>&";;265326âìÖ›[[›ÖìÖ›[[›Kß & ß
  20008. ‰
  20009. ‰
  20010. š[›ÖìÖ›[[›ÖìÖ›þ@þíþí
  20011. 
  20012. ����šš��%���2".4>#"#"276&+4&âìÖ›[[›ÖìÖ›[[›—–
  20013. ‰
  20014. ß & ß
  20015. ‰š[›ÖìÖ›[[›ÖìÖ›»
  20016. þíþí
  20017. ����˜˜��–�¦���2".4>%&277>7.'.'"'&65.'6.'&767>'&>7>7&72267.'4>&'?6.'.'>72>äèÕ›\\›ÕèÕ›\\›d+:
  20018. =?1 " "/ ?9 #hu!$ 0 E.(,3)  (    
  20019. *!A 7 ,8 !?*
  20020. 
  20021. ˜\›ÕèÕ›\\›ÕèÕ›  ' "r"v G
  20022.  .&*
  20023. r$>   #1 
  20024.   %  *
  20025.  '"  $  g2( %
  20026. �������¯…���67'"/&47&6ô¤Žþý‘ûPM<†;ý¬+oX"O…\eŠè~Y‡+" ý¬n+WeÉ����`°¬���#�'�7�;��!2#!"&=46#3!2#!"&=46!!!2#!"&=46!!dè);;)ü);;ÈÈüè);;)ü);;þ ôüè);;)ü);;þÔ,¬;)d);;)d);ddÈ;)d);;)d);ddÈ;)d);;)d);dd����d��L°� ���!2#!"&46!–„ü|;Èþ¢„°**ýDþÔÈôô������d°°���%��32!2!5#!463!54635#!"&=ôÈ);,);þ Èþ ;),;)Èô;)ü);°;)d;)þpdd�);d);dddýDÈ);;)È�������°°��+�A�W��!2"/&546)2/"/&4?'&6#!"&54676276#!"&?'&4?622,^ÇjÇ^5,^ÇjÇ^þ/jÇ^þÔ^ÇË^þÔ^Çj°^ÇjÇ^,þÔ^ÇjÇ^ý&jÇ^,^ÇÎ^þÔ^Çj�������¨¨���#�;�C�K���2".4>"2>4&$2"&4$2#"'"&546?&542"&4$2"&4ÛòÝŸ__ŸÝòÝ ^^ Æà¿oo¿à¿ooþ-- - L- 73H3)z þ‡- - - - ¨_ŸÝòÝ ^^ ÝòÝŸWo¿à¿oo¿à¿ -!!- -!
  20027. ‘$33$ 1~¤ - - - -�ÿØ�Z¹¼�[��%676&'&#"�3276'.#"&47�7>32#"&'&6767632'."Õ[v_"A0?! þˆ-  Y7J3$$ þ«)G"#A.,= # (wn‹kV8@Fv"0DÿG([kPHNg8Bþ*­Ö[eb›2!þ‰5(7>B3$$' þ®)M"#!7)/c# *xn‰fL@9N¾DÿH7!$†W]µBþ$&����d�X¯D��D��>.54>"".#"2>767>54&‰0{xuX6Cy„¨>>§…xC8Zvxy#!?2-*!')-?"CoA23:+1! "3)@ +)?jµDH-Sv@9y€²UU²€y9@vS-H-&65&&56&oM8J41<*.0(@  )*D*2Om��9ÿòw¾��.���2&/7'/&477"/&4?«»B�B8"._÷þ{Ôi�BBi
  20028. �BBþåBºB�BB7._÷…¾B�B^*k"5._øþ{Ôj�BºBþFi �BºBþåBB�B»B77/_ø…�����È��è°������2#!"&54>!�"264ªšd:;)ý¨);<f>XþÿV==V=°.2üG);;)¹3-ªýD¼ý=V==V�����°°��� "/''!'&462†*$þéÔþÌþèË3Ò, #*¡þæ*#þõþÔÒþÍË4Ô$*����'� à�2�@�K��#.'#5&'.'3'.54>75>4.¼&ER<,Ÿ 3'@"<P7(²›d–W(‹WJ.BN0 2Uh:**& h)1"37àN,?iB$.,þÍ -<d>‹ª MOW(kVMbO/9X6FpH*Mþ6&+ÐþÊ  4C4%����d�f”­�J��2#4.#"3#>36327#".'>7>'#53&'.>761T™^™'<;%T)ñÅ-6"b Œ"S5268 jt&'V7  0 $ݦ
  20029. -$a­P‹N(?",9J0* d2‚>2
  20030. "“" ‘ 
  20031. 7�Gd/9+DAL!X����ÿÿ—°����32"/&6;3+##"&?62�–æ*æ–Èæ–È–æ*,úú„ùü|„ù���ÿÿè°����%��#5##!32"/&6;3353!57#5!èddd,ý¨–æ*æ–È‘dcÈÈþÔÈÈ,¼ddôü|úú„dÈÈýúd–úd�����ÿÿè°���!�%��32"/&6;33!57#5!#5##!35�–æ*æ–ÈXÈÈþÔÈÈ,ddd,Çd,úú„–úd–údûPddôdÈÈ����ÿÿL°������32"/&6;3##53#5#!35�–æ*æ–ÈXddÈddÈ,Çd,úú„þ �dûPd�dÈÈ�����ÿÿL°������32"/&6;3#5#!35##53�–æ*æ–ȼdÈ,ÇdddÈ,úú„þ d�dÈÈû´�d�����ÿÿ°°�������32"/&6;3#53!5!!5!!5!�–æ*æ–ÈôÈÈdþÔ,dþp�dþ ô,úú„ÈÈþ Èþ Èþ È��ÿÿ°°�������32"/&6;3!5!!5!!5!#53�–æ*æ–È þ ôdþp�dþÔ,dÈÈ,úú„ÈÈþ Èþ Èþ È�����LL����!2#!"&546!"3!2654&^�¢¼»£þp¥¹¹gþ );;)ô);;L»£þp¥¹¹¥�¥¹È;)þ );;)ô);��������LL���+��!2#!"&546!"3!2654&&546^�¥¹¹¥þp£»¼dþ );;)ô);;þoýýL¹¥þp¥¹¹¥�£»È;)þ );;)ô);‚¾ $ ¾ � ��������LL���+��!2#!"&546!"3!2654&!2"/&6^�£»¹¥þp¥¹¹gþ );;)ô);;þ� ¾ $ ¾ L¼¢þp¥¹¹¥�£»È;)þ );;)ô);Èýý�������LL���+��!2#!"&546!"3!2654&#!"&?62^�¥¹¹¥þp£»¹gþ );;)ô);;þû¾ þp ¾ $L¹¥þp£»¼¢�¥¹È;)þ );;)ô);Ïýý��������L��5��!2#!"&=463!2654&#!"&=46&=#"&=46;546&�¥¹¹¥þpÂ);;)þ>¿Dþ¼úúL¹¥þp¥¹d;)ô);déþä&þä
  20032. –È–
  20033. ���Ù�מ�#��%2"+'&7>?!"'&76�6763 ˜,þ÷þó  P''þÒ
  20034. K » ž
  20035.  þS#þÊþÅ  ånnV/Ó�������þL��5��!2#!"3!2#!"&546&=#"&=46;546^�þ>);;)Âþp¥¹¹ñDþ¼úúLd;)þ );d¹¥�¥¹éþä&þä
  20036. –È–
  20037. �����°°��1��!2/"/&47'&6#"3!26=7#!"&5463!î�mþÈ)�8mþïœ);;)ô);È»£þp¥¹¹¥,°þpmþÈ�)8mþÔ;)þ );;)”ÈþÖ¥¹¹¥�¥¹����¢¢���#���2".4>"2>4&2"&4áîÙ�]]�ÙîÙ�]]�ÃæÂqqÂæÂqqþ{ rr r¢]�ÙîÙ�]]�ÙîÙ�GqÂæÂqqÂæÂsr rr ������L°���#��3232"'&6;46!2!54635ÂÈõ
  20038. þ�' þ… úþ…èû´gd°þ¢þVª^ü|úúd22�������L¬���#�� ++"&=#"&7>!2!54635Gz
  20039. ô"Èú 'ýùèû´gdžþM úú!¯üúúd22�����LK���"�� 62"'&4?62!2!54635Œq‹ýóþÜ‹Ôèû´gdÓq‹ýó#‹ýÒúúd22�����L›� ��#�'��762'&476#"&?'7!2!54635‡Ž*MÔMÒý«КÔþ=èû´gdÿŽMÔL*šÒý©ЛÔý:úúd22�������L°���#�'��/'7'&6"/&4?!2!54635^WЛԛÒÃL*ŽMþúèû´gd°ý«КԚÒýPMŽ*MþXúúd22��ÿì°¯����% ! °þþÆþq¬ý3«gþq§üùæ¹�������dL°����+!#"&546;!3#53L–ýD–úôdÈddèü®�þpèþÔ,ÈÈ�����Eݰ���/��'&"!#"&546;!3#53"/&4?6262LþÕ_  •þÈ–úôdÈdd°jþ\ÊjO)è•þÕ_ “þpèþÔ,ÈÈýÎjþ[ËjO)���� °���>��'.!#"&546;!3#53"/"/&4?'&4?62762Lg†%þöþ·–úôdÈddöFƒƒF)ƒƒ)FƒƒF)ƒƒ)èþóg†þöþpèþÔ,ÈÈýŒF)ƒƒ)FƒƒF)ƒƒ)Fƒƒ�����—°���/��!"!#"&546;!3#533232"/&6;546Lþ¢þ –úôdÈdd–d–æ*æ–èþÔ–þpèþÔ,ÈÈý¨úææú��������—°���/��'&"!#"&546;!3#53++"&=#"&?62L¥*þùþn–úôdÈddëæ–d–æ*èþp¥þ÷þpèþÔ,ÈÈý…åúúå����ȰL� ����!2!546#!"&5!52LûP“û´d�L––þÔýÚ&þÔÈÈ����}­—����-�1�;��&=!5!546#"&=46;#5376!!/&4#5;2+§øøþp�ý/22Èddþ‚÷�þp÷�ddd33�æ*æ–È–þ…dÈÈýËæ–È–æ*yÈd�����d��°°��Q��%6+"&5.546%2+"&5.54>323<>3234>^%È"%þá
  20040. È"
  20041.  d d 1tû®�5gD‘ þ>?1) þA¿..@  þ¢^  þ¢^ ��d��°L�3��"!5265!3!52>54&/5!"!4&#5°"2þpKþ Kþp"2�KôKL8
  20042. üˆ88 %Šþv% 88
  20043. x88 %þvŠ% 8�������LL� �� �$�(�4��!2#5'!7!!2#!"&546!55%!5#!!'!73£wiþÙÈþpdwþ%,);;)þÔ);;),¼þp�ü,¼þ‰dþ‰d�Èiè–bbÈdÈ;)þ );;)ô);dÈÈþ÷…£…ÆÈÈføddÈ���ŸŸ�&��767>".'.7¢.‹wfü�w3À£ .1LOefx;JwF2 ï¢Â1vŽüevˆ/¢ 5Cc;J™|sU@�������°L�#�A���2/.=& &=>2#!"&=46754>ü¸¦ud?, Ê�þÂ�Ê 1;ftÊpR&mû´m&L!(("
  20044. È""’’""È '$+ þä
  20045. 2þÑ2ÔÔ2/2 !������°°� ��'��!'3353353!2+!7#"&46!2!546LÈý¨ÈÈÈÈÈÈü®¼ ‰üJ‰ ³LûP¼ÈÈôÈÈÈÈüà*dd*þÔ22����d��°L� ����#"!4&#"!4&!46;2¼d);,;gd);,;ýþÔ;)d);L;)üè);þÔ;)ýD¼);üà�);;)����ÿœ��°L����%�)��!2#!"&546!#3!535#!#33ȼ|°°|ýD|°°„þ ÈÈþÔÈÈ,�dÈÈddL°|þ |°°|ô|°ÈýD¼ÈdþÔdd,dþÔdôdþÔ,���ÿœ��°L����%�)��!2#!"&546!#5##3353#33ȼ|°°|ýD|°°„þ dddddd�dÈÈddL°|þ |°°|ô|°ÈýD¼ý¨ÈÈôÈÈdþÔdôdþÔ,�ÿœ��°L����#��!2#!"&546!#3!!#3!!ȼ|°°|ýD|°°„þ ÈÈþÔ,�ÈÈþÔ,L°|þ |°°|ô|°ÈýD¼ÈþÔdôdþÔdô���ÿœ��°L������!2#!"&546!- ȼ|°°|ýD|°°„þ þÔ,�þÔL°|þ |°°|ô|°ÈýD¼þ ––––,���ÿœ��°L���� �)��!2#!"&546!!!#";32654&#ȼ|°°|ýD|°°„dýD¼d‚&96)‚þ ‚)69&L°|þ |°°|ô|°ÈýD¼ý¨ôdVAAT,þÔTAAV���ÿœ��°L����%�)��!2#!"&546!#3!535#!##53#53ȼ|°°|ýD|°°„þ ÈÈþÔÈÈ,�ddÈÈddL°|þ |°°|ô|°ÈýD¼ÈdþÔdd,þ �dþ d�ÿœ��°L�����#�'��!2#!"&546!3!3##5335#53ȼ|°°|ýD|°°„ýDÈþÔdXddÈý¨d,ddL°|þ |°°|ô|°ÈýD¼Èþpôþ �dÈÈÈþÔd�ÿœ��°L����"�&��!2#!"&546!#575#5!##53#53ȼ|°°|ýD|°°„þ ÇdÇÈ,�ddÈÇddL°|þ |°°|ô|°ÈýD¼þpÈ2È–dþ �dþ d���� � §§���%���2".4>"2>4&!!!'57!àðÛž^^žÛðÛž^^žÅäÂqqÂäÂqqlþÔ,þÔdd,§^žÛðÛž^^žÛðÛžLqÂäÂqqÂäÂÐÈddÈd����� � §§���'�+���2".4>"2>4&#'##!35àðÛž^^žÛðÛž^^žÅäÂqqÂäÂqql2ddd–d,Èȧ^žÛðÛž^^žÛðÛžLqÂäÂqqÂäÂÐd2d2dd�ddd��ÿòÿ�ÂA� �6��2632+54&#!"#"&5467&54>3232"/&6;46÷nµ,,.xªªx€þÔÞPpVAbªz–
  20046. ‰
  20047. ß & ß
  20048. ‰Awa­ñ­úúsOEkdªbý³
  20049. þíôô
  20050. ����ÿòÿœÃA��3��2632&"#"&5467&54>++"&5#"&76762ön¶,+.yªxZþ† % þƒ OqVAb©æß
  20051. ‰
  20052. ‰
  20053. ÇAwa­xc¤hþ“sOEkd©cý’äþí
  20054. 
  20055. Ì����d��Lm���%5!33 33!#"!54&#¼�þòªþòªþÔþÔªþòªþò�2�dd,,Mþ³þÔþÔd22�����y��7›�/��2#"'2!54635#"&547.546324&546X^“Y{;2 iJ7-þÔ-7Ji/9iJ£›qYƒZ=gJiû22ûiJX5Jit£����'�‰œ��*�B�J�b�{��"&'&7>2"3276767>/&'&"327>7>/&'&&"267"327>76&/&"327>76&/&òoOOoSÙÜÙSoOOoSÙÜÙþ=y±" $GF`   Pu "Q9   ùcŒccŒcVQ:   Pu "�GF`   y±" $òoþÕþÕoSWWSo++oSWW"±y  `FG # ‘uP  :Q # úccŒcc:Q # uP  $`FG # "±y  ����d��è°� ����"��!#5!!463!#53'353!"&5+¼,´þ¬þ„
  20056. ?,Èd¢ÔÔ¢d´þu
  20057. „
  20058. Ã þ„ÈÈó
  20059. þÔÈüàÔÔÈþ 
  20060. ‹ÈÃ
  20061. �����d��è°� � ���!��! 463!#5##5#7!"&=)+5¼,þ¢ýÚ
  20062. ?,È>¢d¢Ôªþ�
  20063. |
  20064. › ýø^ýÚG
  20065. þÔÈü|ÈÈÔþd
  20066. 77
  20067. P��������°ô�����#3!#732!!34>3!!Š¢ddþÔ¢ÔýÈ!,ý¨Èd!sððüà,ô Èd,ÔÔ+$dþ¢Â$+þpþpô�������LL��2�9��3232#!"&=46;54652#!"'74633!265#535Šd2þÔ2s);;)ý¨öþº;)X>,>Xý´ÔÈÈL2dd2ú–;)üà);öFD);–>XXýæÔ¢d¢��d��¼L��6�=��3232#!"&=46;54652#3#!"&54633!265#535Âd2þÔ2s);ÈÈ!ý¨);;)X>,>XœÔÈÈL2dd2ú–;)þ þÔ$+;) );–>XXýæÔ¢d¢���ÿ¢��Ô� ���� #!"&762#";2676&35’} ,û, }@DÐ:#6#:àÈ­û°&77&P'þLþÒ.þ dd���� ����LL���/�?�O�_�o�����32+"&=4632+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=46©ú
  20068. 
  20069. ú
  20070. 
  20071. ú
  20072. 
  20073. ú
  20074. šú
  20075. 
  20076. ú
  20077. üêú
  20078. 
  20079. ú
  20080. šú
  20081. 
  20082. ú
  20083. šú
  20084. 
  20085. ú
  20086. üêú
  20087. 
  20088. ú
  20089. šú
  20090. 
  20091. ú
  20092. šú
  20093. 
  20094. ú
  20095. L
  20096. 
  20097. þÔ
  20098. 
  20099. 
  20100. 
  20101. þÔ
  20102. 
  20103. 
  20104. 
  20105. 
  20106. 
  20107. þÔ
  20108. 
  20109. 
  20110. 
  20111. 
  20112. 
  20113. �������°��)�3��3#!2!&/&63!5#5353!2+!7#"&46!2!546¼dd^>1B)(üü()B1>^ddÈþ>¼ ‰üJŠ ³LûP°ÈdO7„S33S„7OdÈdü|*dd*þÔ22������°���+�5���2#4!!2!'&63!&54!2+!%5#"&46!2!5460P9Â<:H)"¯ýZ²"
  20114. )H¯¼–üJ–³LûP;))�%&!‘‘!&þ•*ÈÈÈÈ*ý¨22�����°����$�.���2"&432!65463!2+!7#"&46!2!546 –jj–j·."+'þ¼'+#þͼ ŠüJ‰ ³LûP�j–jj–þë9:LkkL:9þr*dd*þÔ22�����°���,�6��2"&5477'632!65463!2+!7#"&46!2!546X/[3oœo"�o£"."+'þ¼'+#þͼ ŠüJ‰ ³LûPk‹6NooN>Q�o£þ
  20115. 9:LkkL:9þr*dd*þÔ22�������°��"�,��!!.54>7!2+!7#"&46!2!546X,þÔ%??Mýî<=Bm�Jþ¢¼ ŠüJ‰ ³LûP°¡‹9fQ?HS½TT¡vKü~*dd*þÔ22��È��è��)���2!546754!2#3#3#3#!"&546/R;.6þp6.d�6\¬ÈÈÈÈÈuSþpSuu;)N\6226\N)þG6.dddddSuuS�Su���dÿÿLL��/�3��!2#!"&546!2#!"/!"&4?!"&=46!'–„ü|¶
  20116. 
  20117. þåà % XýôW & àþß
  20118. ªdDdLþ ôýD
  20119. 2
  20120. à % XX % à
  20121. 2
  20122. ddd��������°L��#�-�7��!2#4&+"#4&+"#546!2!46+"&=!+"&=È Sud;)ú);d;)ú);duè);ûP;ñdèdLuSÈ);;));;)ÈSuþ ;)þÔ,);þ 2222����©¬� ���� !&4762 !2!546ઃþýû 'Yþ¬V/þ«¢ ü|�ýUYƒY(þnþª0Uü22��������!°��/��.#!"3!26=326!546;546;33232!½'þp'½q*}¨ý­20È/2‡úþ––ýŒ22,þÔ2������°°� ���"��!#!5463!#5!#!"&5463!#5„,
  20123. þ‰þÔ
  20124. w,Èý¨,
  20125. ýv
  20126. 
  20127. w,È ýÁ
  20128. O,T
  20129. þÔÈþ ýÁ
  20130. 
  20131. þÔÈ�ÿœ�dG�F�V��32676'&7>++"&?+"'+"&?&/.=46;67'&6;6#";26=4&äÃKŽjI C
  20132. 
  20133.  )V=>8'"d 1*Ã) "dT,Ÿ| -oËtEú
  20134. 
  20135. ú
  20136. GAkŠI
  20137. ! "% ,=?W7|&êF@�Je5&2WO_e_
  20138. 2
  20139. 
  20140. 2
  20141. �ÿœÿæ~� �$�4�<�R�b��%6%32!2&'&#!"&=46#";2654&'&"2647>?&/&6%?6'.'.�§. ‹ü+jCHf7ý" *:þÔ>XX¹P*† €@--@-þ˜ -?0 !3P/|)‚( )f!% = „÷ &* xÈ"6Ô2&„CX>È>X¬83 DÉ-@--@þÛ‚
  20142. # ³=I+E( /—/}X&+ 5!H �����d��9°�Q�`�o��322#+"&=#+"&=#"&=46;#"&=46;546;23546!2>574.#!2>574.#q–
  20143. Oh ..40:*"6-@#
  20144. d
  20145. 
  20146. KK
  20147. 
  20148. ¯
  20149. d×)  )þùk)  )°
  20150. m!mJ.M-(2N-;]<* K
  20151. 
  20152. KK
  20153. 
  20154. K
  20155. X
  20156. K
  20157. 
  20158. KK
  20159. þÔÈ
  20160. "þpÈ
  20161. "����°®��)�,��!2#!"&'.546"!7.#Ô Vz$�RýÄR‚(z Œ}VG+œ0œ )IU!�îzVþ`3·BBWwvXZÅ3 Vz™&--% óó,(1#þÂ��È��„����32#!"&546+"&=Û–g¬T)þ>)T¬H6–6¬gþ )TT)ôg¬üá66á���È��„����33#!"&546+"&=Û`³–T)þ>)T¬H6–6–³þB)TT)ôg¬üá66á��������� %'5754&>?' %5%ý‚þ†Nd––d/“‚\þ¢þ¢^^ÿþåª<à–Ç”•È–ú 
  20162. (Aýb¦¦“¥¥���dô° �����2"&4$2"&4$2"&4¼|XX|Xè|XX|Xè|XX|X X|XX|XX|XX|XX|XX|�������¼L������2"&42"&42"&4è|XX|XX|XX|XX|XX|XLX|XX|þÈX|XX|þÈX|XX|����d�dLL���/��!2#!"&=46!2#!"&=46!2#!"&=46}¶
  20163. 
  20164. üJ
  20165. 
  20166. 
  20167. üJ
  20168. 
  20169. 
  20170. üJ
  20171. L
  20172. 
  20173. þp
  20174. 
  20175. þp
  20176. 
  20177. �������°°���/�3��!2#!"&546!"3!2654&!2#!"&546!5^ô¢¼»£þ ¥¹¹Ëý¨);;)X);;ý±ôþ G�°»£þ ¥¹¹¥ô¥¹È;)ý¨);;)X);dþÔ,dÈÈ�����d�d°L�;��!2+32+32+32#!"&46;5#"&46;5#"&46;5#"&46–è222222ü222222L*È*È*È**È*È*È*���,�è£�� ����*��.62"&%#462"&%#46"&=32ŠW??WW??þù|°|°¼°|°ýÀ|°|°¼°|°°*(£C²²BB²²þÀ°|°||°|°þÔ°|°||°|°þÓ�Ž��ÿµ�È”��B��76+2+"47&"+".543#"&'&676/!'.6éE*  '?)’¸
  20178. T ¸Ž0I' *L
  20179. #3¶{¶,#
  20180. nþÙ  6F82 þà*<SC# 
  20181. (#( ÁÁ (#��������°°�%�C��#4.+!52>5#"#!#4.+3#525#"#5!°2 &È2þp"È& 2èýD
  20182. d È2d
  20183. ô„ ü®dd R ,ý
  20184. þW 22©
  20185. –��������L®�� �0��5"'./#!5"&?!##!"&=463!2èþßEþÔ  1;E%= !'þì†y±üè,2 "
  20186. ëý# 22+.°¦"A2‡Vþªýãdd�����°°��G�J��!2#!"&546#"3!26=4&#"'&?!#"3!26=4&'"'&'#&#2Lû´FF þÕ&  7
  20187. ?
  20188. 9   9 þàÅg°û´LR ý  2 2 £™ 2 2 $ì þ������°°���#�'��!5!!2#!"&546)2#!"&546!°ûP°û‚�þpm�þpG,LdÈü|„þp�dþÔ,�����°°���#�'��!2#!"&546!2#!"&546!!5!2�þpm�þpG,ÈûP°°ü|„þ þp�dþÔ,ý¨d�������d°è�'�+��!235463!23##!"&=##!"&546!2�d�ddþpdþpŸ,èþ¢––d––þ¢ þÔþÔ,������°°����'��3#3!2#!"&546!!2#!"&546ddd–�þpG,þ¢„ü|°dþp�dþÔ,þ þp������d��L°�'�+��32+!2#!"&5463!5#"&546;53!X––Âü|^––dÈ,Lþpdþp�d�dÈþÔ,�������°°����'��!#3!2#!"&546!!2#!"&546°ddýv�þpG,ü®„ü|°dþp�dþÔ,þ þp���,�0o€��� #"&54632aþî5þèþ*����A�2„~� �� 6'&4Oî**þ{î)ü)î*�����2A~„� ��!2"'&6dè)þ*þ„*þî*�����2,~o� �� #!"&762{î)ü)î*aþ**î�������°(��
  20189. ��5-5!5!¼ýL�þc¨üà å¶þ½ÝÁÁÝûØÈ�������d°°� �1��#3!35#5!34>;!5".5323!°ÈÈþÔÈÈ,ûP2 &d2�"d& 2üà„dd,ddþ  ýÚdd & ,������Lè�%�1��#4.+!52>5#"#!#3!35#5! 2 &d2þp"d& 2 ,ÈÈþÔÈÈ,¼ ýÚdd & ,üàdd,dd���È�frJ���32 +"'&476½ 
  20190. þ0Ð
  20191. þ)×
  20192. J þ0þ0  ×× ��>�fèJ���32+"&7 &6S 
  20193. ×þ)
  20194.  
  20195. Ðþ0
  20196. J þ)þ)  ÐÐ ���f�ÈJr����"'&=46 4 þ)þ)  ÐÐw
  20197. þ)×
  20198.  
  20199. þ0Ð����f>Jè��� ' &=4762j×  þ0þ0  ×áþ)
  20200.  
  20201. Ðþ0
  20202. ×����Ùÿù=°��:��#463267>"&#""'./.>'&6è°|°þVd&O "(P3G*+*3M, :I G79_7&%*>7F1“ °|°|°ÈÂ5KmCKG\JBktl$#?hI7 À�����È�„°����!2+&5#"&546!5úX–ÿ–«,°þpþ ² Š�ddd����È�L°����!2%!#4675úî'=ýDXýDd d°Q,ü[u¶}ü4ý]dd����MoÃ__<õ�°����Ðvs—����Ðvs—ÿQÿœÜ�������������ÿ…��ÿQþÔÜ����������������£¸�(�������°��°�d°��°��°�pŠ����Š����±��E���Ø���Ø���¢�����H����E��°�d°�{°�Ȱ�Èô��°ÿò°��°��°ÿð°��°�°� °�d°ÿÓ°ÿÓ°��°��°��°��°��°�&°�n°�°�°�°�d°�°�d°� °�d°�°ÿœ°�d°�°�°��°�°�°�°�d°��°�d°��°��°��°��°��°��°��°��°�d°�Ȱ��°��°�5°�d°�Ȱÿµ°�!°��°��°��°��°��°ÿœ°��°��°��°�Û°�°�u°��°��°��°�
  20203. °�Ȱ��°��°�Ȱ�Ȱ�Ȱ��°ÿþ°,°�d°�ˆ°;°�°�°�°�°�°�°��°�°�°�°�°��°�·°�·°��°��°�I°�°��°��°�]°ÿܰÿܰÿŸ°�d°��°��°��°�d°ÿÿ°��°ÿQ°�°��°��°E°�°��°ÿœ°�J°�°��°��°��°ÿœ°�a°ÿý°�°�°�°�°�°��Ä��°�d������ÿØ�d�9�È��'�d������������������Ù������������������������������d�d��������dÿœÿœÿœÿœÿœÿœÿœÿœ� � ÿòÿò�d�y�'�d�d�����dÿ¢�������������È�d�������ÿœÿœ�d��È�È���d��d���d,ÿµ���������������d��,A�2�2������È>�f�f�Ù�È�È���*�*�*�*�²�è�èNNNNNNNNNNNNNN¤"~†¬äFnŒÄ2b¢Ü\ºrô bÊb¾ 6 „ ¶ Þ
  20204. (
  20205. L
  20206. â 0 Š Ê  X * ^ °h´(¦æT�ª*v¶
  20207. 8|ÀtÐ*Ô<¨Ì6`°þR¦.j–°àþ(h”ÄÚî6h¸ö^´2”âDl”¼æ.vÀbÒ F ¾!2!v!¸"@"–"¸##"#8#z#Â#à$$0$^$–$â%4%`%¼&&~&æ'P'¼'ø(4(p(¬) )Ì*&*J*„+
  20208. +z,,h,º,ì--ˆ-ô.(.f.¢.Ø//F/~/²/ø0>0„0Ò11`1®1è2$2^2š2Þ3"3>3h3¶44`4¨4Ò5,5ž5è6>6|6Ü77N7’7Ô88B8†8È9
  20209. 9J9ˆ9Ì::l:š:Þ; ;Ü<<P<¢<ø=2=ì>:>Œ>Ô?(?n?ª?ú@H@€@ÆAA~BB¨BîCCBCvC CÊDD`D®DöEZE¶FFtF´FöG6GvG¶GöHH2HNHjH†HÌII8I^I„IªJJ.JR����§�������������@�.��������Æ����������� ���j��� ��(�|�� ���¤�� ��L�²�� ��8�þ�� ��x6�� ��6®�� ��ä�� � �ú�� � �$�� � �$4�� ��$X�� �È�|�� �É�0’�� Ù�Âwww.glyphicons.com�C�o�p�y�r�i�g�h�t� �©� �2�0�1�4� �b�y� �J�a�n� �K�o�v�a�r�i�k�.� �A�l�l� �r�i�g�h�t�s� �r�e�s�e�r�v�e�d�.�G�L�Y�P�H�I�C�O�N�S� �H�a�l�f�l�i�n�g�s�R�e�g�u�l�a�r�1�.�0�0�9�;�U�K�W�N�;�G�L�Y�P�H�I�C�O�N�S�H�a�l�f�l�i�n�g�s�-�R�e�g�u�l�a�r�G�L�Y�P�H�I�C�O�N�S� �H�a�l�f�l�i�n�g�s� �R�e�g�u�l�a�r�V�e�r�s�i�o�n� �1�.�0�0�9�;�P�S� �0�0�1�.�0�0�9�;�h�o�t�c�o�n�v� �1�.�0�.�7�0�;�m�a�k�e�o�t�f�.�l�i�b�2�.�5�.�5�8�3�2�9�G�L�Y�P�H�I�C�O�N�S�H�a�l�f�l�i�n�g�s�-�R�e�g�u�l�a�r�J�a�n� �K�o�v�a�r�i�k�J�a�n� �K�o�v�a�r�i�k�w�w�w�.�g�l�y�p�h�i�c�o�n�s�.�c�o�m�w�w�w�.�g�l�y�p�h�i�c�o�n�s�.�c�o�m�w�w�w�.�g�l�y�p�h�i�c�o�n�s�.�c�o�m�W�e�b�f�o�n�t� �1�.�0�W�e�d� �O�c�t� �2�9� �0�6�:�3�6�:�0�7� �2�0�1�4�F�o�n�t� �S�q�u�i�r�r�e�l���������ÿµ�2������������������������ ��– 
  20210.    �ï !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ� 
  20211.    glyph1glyph2uni00A0uni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni202Funi205FEurouni20BDuni231Buni25FCuni2601uni26FAuni2709uni270FuniE001uniE002uniE003uniE005uniE006uniE007uniE008uniE009uniE010uniE011uniE012uniE013uniE014uniE015uniE016uniE017uniE018uniE019uniE020uniE021uniE022uniE023uniE024uniE025uniE026uniE027uniE028uniE029uniE030uniE031uniE032uniE033uniE034uniE035uniE036uniE037uniE038uniE039uniE040uniE041uniE042uniE043uniE044uniE045uniE046uniE047uniE048uniE049uniE050uniE051uniE052uniE053uniE054uniE055uniE056uniE057uniE058uniE059uniE060uniE062uniE063uniE064uniE065uniE066uniE067uniE068uniE069uniE070uniE071uniE072uniE073uniE074uniE075uniE076uniE077uniE078uniE079uniE080uniE081uniE082uniE083uniE084uniE085uniE086uniE087uniE088uniE089uniE090uniE091uniE092uniE093uniE094uniE095uniE096uniE097uniE101uniE102uniE103uniE104uniE105uniE106uniE107uniE108uniE109uniE110uniE111uniE112uniE113uniE114uniE115uniE116uniE117uniE118uniE119uniE120uniE121uniE122uniE123uniE124uniE125uniE126uniE127uniE128uniE129uniE130uniE131uniE132uniE133uniE134uniE135uniE136uniE137uniE138uniE139uniE140uniE141uniE142uniE143uniE144uniE145uniE146uniE148uniE149uniE150uniE151uniE152uniE153uniE154uniE155uniE156uniE157uniE158uniE159uniE160uniE161uniE162uniE163uniE164uniE165uniE166uniE167uniE168uniE169uniE170uniE171uniE172uniE173uniE174uniE175uniE176uniE177uniE178uniE179uniE180uniE181uniE182uniE183uniE184uniE185uniE186uniE187uniE188uniE189uniE190uniE191uniE192uniE193uniE194uniE195uniE197uniE198uniE199uniE200uniE201uniE202uniE203uniE204uniE205uniE206uniE209uniE210uniE211uniE212uniE213uniE214uniE215uniE216uniE218uniE219uniE221uniE223uniE224uniE225uniE226uniE227uniE230uniE231uniE232uniE233uniE234uniE235uniE236uniE237uniE238uniE239uniE240uniE241uniE242uniE243uniE244uniE245uniE246uniE247uniE248uniE249uniE250uniE251uniE252uniE253uniE254uniE255uniE256uniE257uniE258uniE259uniE260uniF8FFu1F511u1F6AA����TPÃ��wOF2�����Fl�����±\��F �M��������������������?FFTM `�Œr
  20212. ‚©$�åe6$†t „0� ‡"•Q?webfeŒ5ì˜�€ó@ Â?þ¾
  20213. Úöˆ ¬töÿŸ” †ŒÁ“ÇØÜ,3+2q ËF®YOì&>±é±bÒm¤5�ZŽæH$±ªYŠœ½{ìH jd† Õ‰ ü²%÷¹Ù§y"§÷ö×+�@¹Œ]½«eŸû{úÒûv� Nc‹)»nù“É?~?è�¤hò�ÿž_ç&iÆÊÈÑ�Á¤‹?º>üå^K ûv´-cÛ�1íô€‰2K áy·õ,'nä«à�(ð3EwiàB‚ &©ÿ éÎT´lhØ0MÒØÚÒ†dåYØrñﲬ³ntiÞ]Ýyur•´¼®û™îVXsj¡¢žågMnªÓ™H�W•©ÃÔ r2ô>iT`V7¸ÍR(±¨ÉÏàÿ+ o6ó'cÅÈB°�æë4ç·Öι݇ƒ‹ã¿š®T ]a[Qd<3wq8,Ž…îrTI¡8áŽ0>E¸?ù*E¨ç—¦•#Ïú7'�ìÝý†S ocûÊ·í_‹7&#*Ñ+)½³ Ð+4a°A6¶cŒçy±Ù£†f(bFéæäÿé´$;{ YAÃ1vP-tGøÿŒáÀ±Í"û°•ÛCÂf- W‚÷®šÔ™ÎuKÖ°Kã#­íä¬Ö*K†<Ûü (ÑßëÔ÷×ÿZþ`Ù« åµ[—%êYTЬ{%¯ÉŠ$ˆ­ s{oïíœòˆƒÕ»ïvt"pàœ4`Èêß©ŠÏ¤}o `ã³Ýú'neÜ>
  20214. äG5s�zó_Nó
  20215. ’PKÓ¦vmUÞ É¾{z½ÜòîóÿŸøøŒ‡"3`l ’–W#Ô�½^@+�,c¹Éko©�AOpnuµ§Ôzó–zJ)õÜÎ¥÷˜Û1Ç}ááÿO=Þ­¶€x¾RÆÄ`ÁJ‰`§qƒ¥‚Us/¿+økÒvÇ1xlÝßçjl–Elì\nDŒÈÃÆ¶¯V†±æÿÐjg›{Zdå‰z7� 5ÿß!xmÂ5oÂ[½¿uïû&·¯1Ú‚HBkAâìqrêÎR�Ä £·°�(\ghôÈ7‰ìÒŠy�=†HµZóUPhéÐ$8RgÓÄ€zÂgÍ­ÉN:‹à�1u¬$Ü…¯¤¡ž>Rý]åú—¦¬"Ÿôf7¼— õK¯^'˜ªë½3“+E/¼Ä^‰YU5]¨NB.ÞÊ‹¥Ò8ßÅ+ÎÍ�8�ù,|‰{M|ŒAŠåua|Ðaˆ’ìŽÕÞË…Õ�%�
  20216. lKG¢Pí,NuæÜÔkþcï8mX@ÚÓdÿ̘?ñüÚó¢çYÓ&Ïþ{êö”ø³ÇÏ?ÛPÜ(®GŠ]¶¿ÏÆä¯äOä�ä·ä×ä—är-¹’\LFÉ9—,&§“yä8r¬û´û3÷ÜŸ¸?p¿ï>ê~Ûýºûsèäÿ‹žÐ¢ÓDǤzó1ú¡?\U5q=­ÙtÑzÔ’†&Z�nj¢%émM´"}¼‰ÖtkÞDºwh¢-=ÿm¢½Bíéõ76ñô®ƒ&:Ò»Éqt" Ö1:“¬ëЕ¬©u;ô"K_¡/JdÖc0–l²õ0²Å'^B¶ù8VC¶Õzg°²½¬[ ;Êúdì
  20217. ÙYÖbȃu‡¼©u;œ@ž*}y‰| .©¬'C>\g=ò9àVëÅ�¯·[o†|gð õ^� ž¶>Šüd¼
  20218. 9­ÏÇûäîØÅø”
  20219. *E|A¥�ã*M­[ã[*mOÜßQéz?PénÝ?R)Y�ÁoT&[ÏU*‹•5ÀSÙ MB þì¡¥ð[³
  20220. ­„ßoYDh­Õ{ìÑ,}1<f�&6h¤†'��Ê¥U#V¨Þ­¼¡¥EûD"TÁ¥Þ©Ð¢AD9ƒÿeB¹:©Ä%OœÁ ÒÐñ‚‡ØFuŠn 7?%RG4"„¸f©gÇÁFêº� a=‚‘-³ÕQ—á½y+B½,ÄøÐ2ÃËÖ…5¢•‡ð™„Œxn¡Ϊf*!¡³æëlâ|GXQø ÞƒUp”ä
  20221. ÅEu Â@ž�¦å-ð€Do.6YZö‚-&a>f?›�«“N�Nœ¢ ]ÔO/^;\ÚÂJÊ ÏBÇEsJrª� ÄšõÆ'ò…g/ããÑB%Ÿ¡o Cõêºn•7‹Ü:|õyƒKt²&÷$§Øs¯|¹õwPˆùÄ\i]¾$Z@+Í ¶¶Õ€90x]»r¸­%¾ÈÕ+öRU¬Em‡+ܰª£;w u¬À9/I¼Ô7È7Õ¦¹Qþlu\¦yÐW‹N)ë8‰Ü°vYî*u´m”¡±¿éâ©âºm( fÊE½òÿG8² ¢j#I¬½RŽÌùz #q¸ß·ß „)Y ×$‹ áЛ†c_%¿m-{!0-` ;áå…¬ñhyVõäÁ]Hv! Ïta½\KïÅ¥[Ì1{"çj 6@ì–3T0%¥¿éΘ"ÇÔ™ÆZI†Gä›S“÷�‚.³ÄΣp�ÆÓ¬SÆ1eéûÙ“ÄØ›�ù YÁÿv»8d±\±B¡l¡SûþR)ÒÓ†çù¯–®€ {IŠÓ†ôÒ%�”¯>û0ÐŽÚ¦³\ð'”cg½2%4 QŽD¡
  20222. 0Í’3B²"ÉMŽÕŽ&€ÛŠhIÇÂÚ§ÒRg·ME¤¡©¡¶š I½Î(©ÞÕ5U–D] }ò™bí8$—‡ì8¨>óáX ²h•"lµÎ€âj�.%ˆÛ€HHÇ- Iš¦Ý¸#1’C4õÞYÞ7„íî®íYÝ–¡V o>PÊ]¡6¿·˜ö™O4ÿ7f ½~�AJdYFÕ€Ê.–ÞoõÃþy) Æ8lÆ ¶22ŽeŠœ¦Ò1H¡[t‰°@!È… 2\€@¸5ÄÙ“Ê%Z×îüÛkÞ’aõ�®Ü@ú.`n¨3ÊOFŒ¢R(ó…¥¶÷ÿ½ZkLkF íHWjY I¤ê5×ç*ñ6ÚÎeµSbk.¤¼5F,ì.•N0ßÔ™’¹€|”†V¦€||~Nô‡( 4·�ìÚ],ìJp|~ùxeÓÉA¨Ô¡¯5ˆˆ/»Ú»S¤ýäô”Ðvò×Üy?›ù²'_v|rê„ËXÜøîHéQʰµÄ“B@= ÝX¬ßú¬B9Ë4³˜«ÃT©ØB‰B©c ­Á«H‘P£Î+‚ò‰�_““ÕYHÙ#¬$ªËÊ` ìFø£ñB;ãµÂ+Û”…BPR°4̼ t­:tõ"ZEºJ^!XÂÇ“à¬q4_dTW(5äÜ€§åÿä¸ÚI±”UŇÒAÍzþ@U6ÿn.WGXýÀÁèHìRKÀÛ&'swM±jŠÊŽ˜‹±<Ÿ”±˜3¦)€–�`#F@  F Ô¢àþØv�oÍb$x ï+²à¼uû&´}‰|ÊX&[Ùª�8F‹-¹E&/>Š/ÑGÅ.aêz^ŠÞ/ƒÔþ})œ²’ó'“x©‘$O=<ÇÂz™¤oä§áA9MØ�&ò~î¡™¹3rµ3gŸœ¦'¿8Ò£\°-¶MDzÈè˜økºÍ5†ù±´A
  20223. ÝÂýªG9©ä|1-Ø! Ç87û[œô¤,mRîu|¦57®
  20224. =Xþ‘¤,˜aJ§Ù›¸^t´N›4ÓØ\fЄ]AzH^7·ªF•èþ•™„&k"LU>}ì>çrBåX(Û‚ªë‚Tš%¿« Jª¿„­dhKÄ”ó¶P“²KÁTFaA‡3HH†C[r;a›À¶d·™‡•54ÈÌ ‰—lL„kjG{¡ì8Ÿh~ä� fR@Ðìü9wàB¨¤àÐ0ë zSõô°âÿ'— a7‚@Ý@N›±ŠÝƹl‘bj3hNî²Xö‹F/Éíe¢s£Ù'úŠDsQ«ñ<þk^Óíò×¼²ýˆZASO¨idºSJãxN4D½³ÀKÓ!´¹Ôù !Ù«v‰¬hA`ÛE–·X�•�¼Ê- ¢P íÄ:Ÿ‚ÛѤCê:ÂÂWÍzS½sÄdO :¶_¿«ÔË`Š:tÁaηБ ¥†²Íسú¢�® ¼IYð4Ç # �ø*ÒÍ+<êq�n°oÔ�¸u
  20225. UÌcww�óx$dµ³ðÆ¿�}Ï�ûÖÁ94Ìýšíü9p¬*T:ú%GQæ…^aŸ‹‡äÝË'¨çeƒôbö¨Šl-ÕÜ*XÝLç%*ź¸.…ÚŠÈ\Š@pR$Tå*KÖͽ¸hp‡ÀˆÈèÁ‚ßã¦múÁ‘â-/“oSÚ3ŽßÂE�àÏÎto¸ž}çжV‡oõeJ `<™$öÙtíØ½ßü ª]g*ßZ›„µ6q°Àùl’ø~÷E¯«
  20226. †Sú¸/Š’ùi£ÄTÆtÍk‚Ç®à²WÝþ Ü=?j¹�G¢ÒÌÔUUAJÆõý›`†ÒbÔË‘—ƒGˆõQÍAÏ«©�ñÖÎÆÚìcƒûê½WËï©èWSmÝÀ­g³ºÚFËñª‘&©^õúؘԡˆ6;C1:=ÛˆP‰äºÕ`ÊÚœ�VVÿ“ÔE�Æ5"´hO«Xà~«ÞØN3_5Ó�]ºz-þ­ä’CWÓÝtÔ¥�‚Óˆ´ÐËeÜ]°\¶”©¿V¯–‹ÿcÔ#m[ÆkuÞ—­_ʱ"©Éös�H³ô<}xï±…m0båxHÓqb‘a3tfçMTÛÑÏ*]I»
  20227. Þ}×(ú¾œ,M”„�–=Š Ý@ŒJAÛÆÐd‰� ¬Ë?§6PV±ö[ dVãvôæ4jžÒß›‘lH\â÷ÔŒÅè{˜ØòMôå½È˜\º��åYþÜ�€�`9MÃ`Db‡<Á;a#zò†‘<Šx"ó,¨d‚gCi¿`‘c’›:ÁÈâI´â>jw·Ì}JÈÉz§�^:V.ý:×þÚ‹{¿Í¼(ȲB÷æËɦ’ÉóxŽ<Db#"S£¡{ô’PùHu½N�/ë{r6;wU¶æÐòsÖPО“<¤çXÀàYâsÔÄ÷ÞMxu°‡\šb�‘Ús¸$Ž˜xŽÊ(¢‰/^|^*0j~mà¬;#·%J„ÞM4�Çp˜QM׬ð::b\C2gf°°]½zÒP8T™ Uª“QbÖètºƒC½TŸ>
  20228. p 8+6g_2–lΡ6§Hò ÚÎ�džH�:÷ d›<æCÍé6³¯Ø¤ê/«¿6ãE:ÂK‹”"Ë`kJ©<›ÏÆ¢ä=ùvž7„¥âN5·µ`°ò›¶Jt‹Ù\j¹6Í…%Ëž7ô*¥'¥•U•Ù4±:âX+ ä\b�ü’E
  20229. äìôÞaf®ŠxŒ“}Á‰1+p™‹B¥Ë0î6òâ”åýž3rõA$Nš~¶ô#³dª}ÇפŸP7h÷H7b£FªžÂ§…‚¬8ð ³P>øBtGNÐŽ¢ðmä‚xô@�j …‘¸|{Às9à»=þwRÙ/­«oDJs5z>“;Š'xÝñEÐq^ré^=G?½…9Aê¡æ–ÇAä_—£íK%µDÉ®:uikjkîIeÉæ½¬GúÕ�#*¡†)µjm‘á|½t£¹}`Jæ©Z؈éÖ÷H=4î�{gß�¢¾)¡qXˆMA,šHøŒ7û1‰ëV"¥Ùo,çY#hýü÷ݨSò_ê;‹Ía_Ô—Z^cn4¢­� ‚H¸E«®?‰«°}Ñ
  20230. È�¡»­Üî¼Ù¤=}BžWvÞªUeðåhšƒÚ�GŠ“F�…‰‘æ;�@2S¥Øœ€@Ëf þÂËünÍâ2Ð#�Žæ¹ñfÝY:]¿JyåH]­•-·˜G׌wgv'¡â|ˆÄ0eñ
  20231. Ã_7ˆðÒ�«n+fßÙ¸âàY<«ç(Í
  20232. ª?öì’©‘yòù¡%wm¬+jƒ&&!è¢c“^¡u'�bü&ñhŸm6¤šÎû¹*2 ?´AÇI«¶Æ²5FW¾Ø™[âÆœ¨BõUzïIÎE”“!’m:‹ÒûœxhÔe—ÝÇ®n¼z|]% ��mÙrÁU¸F�Ú¯�”ù®1Æ ‰};!n F¾& gòÚñÿP‰†Ý¯¯;&×ö©œøï$$¸éF«).t›BíQ¨3¦Ž½(žC=ú·Óä¦XÀÎØesÔ;Ýiû«¶­ÙŠ@¼Ñ~üNíÉΡEë ÔSR‹¡ˆh�\éè£úÁBeñoº†½œ ´¹ÎbTÑ„nÎ’ju¹¾À g@ä÷'qQ딎nx.u6bVU&Ô ›]¹;Ûïª!C_ „ ž�5Æ*Þz¹ɺûm€RQu‘ªq‚’঱PüÚZ0ƒ¶}mñ¼¡ÌÊõn½¦^nÕOrÉT¦âÁ‘µÎ:ŸUã'×hÀæ§0nZ¡p^Ré|DFª_b\ò@–Öm�‚èDEë8��Æ{oèGM‰á œq¸ÝÏ}ÜîSd ®C,ûiÀÜšEêŠé/°ÞË[d8]Ž×,MCIšÎÐó_u—,]V™�cñ"—ä¤p°g@ì`"y)‹,;B³^e­žlÚ¡ª2'€.(�ÍÐĘây>à-|Îh­ÜÓÄwšúþê;©jå¥è’íÕ�ÑÒiÔ½±ä¯ê_o|!@ö)ɢݪÄ=ÙÌŒSPz�—éˆ*!z})¼|ƧT}½j‘†E£tC¬Zå¡nŒ�½ýœ*ÕžõÉ4ۆ׽[¹©± ¾9»Ð®¨Žèˆ‘’Ý“õŒz`Wmeôo‚‹|j8j­ï5á�9¼öµ@.úšE¿VÌ/ÌZW@|—�f_ç\"${ᜑv¡àòƒóœÀÈ/¸ò¶;a×:Se¦i3TäGË*ëÎýƒ]¸Æ¡/ÌhÀ2C32$¿Óô¿ü1}¿ŒD¤ÍNXÉøþtì?FÏ�í~n,Pj9.î–>×£ü¨Í{
  20233. 9ýÉEN-v|3h†ò‘CÅиE”•‡ XTàâË;P–$Ã=�JÖ-ÝÕgÝ•ýùigz~q—(Aé<:h1±9³3áNì̽õQ‰‹ãÇ}CLØ�Wùß§Â׎Ü~ƒá Úb™¥"†�‡Í|Ç4u}îð­×Ùc™y€à‹È6°¡2ÿ[ ¥ØÖ\d¸,µÒŽÕ³b�kù¤ÌDåä¾%0TÜx­®{=;öÔ·‹†(„i‡ �ØLS·øß1½˜øý©Ñ3ÿNÏh/¤6?æ'E^ö~ÿÆÔP®{sZì™ZÓK”ÄžB{’DÌtø&‰½Ôz’Ó÷)µUoaù5Q¦3�‘È—ˆr~¿Ž‘¾
  20234. ¦ôÙùF] $º<èútm(š} ûÃÏMB@‡ž[œGxìÎFÓh8�›#}ˆô,£#À˜u ýLaz(ÞQh±4%Óxm`Uà•Õ¹.E¨ãv1a’ž4_'/[¨d±{Fx¨IÊ59žŒ ƒDõ<êì&�8VˆEóFgÉÈ٠芘#õI‘äŸ�2S²Íîÿ_ã©]QqAšnˆÑ_ðQç>bÞ˜4g¡¨­±-®0&E#c¦Üi8¿ vR/Õ4ÿržŠëšP7•£KsOWµN3Õ�vE\bq†ûQß5�Z¹Ú½Vy5]�½Ööàh/ i)Åû�¦Ž-/´°ã¡kµN¬Ñ޾ÈÄ#eì)"Píñü {ýKSQ�x‰²¸�¦>aã&µí¶Ž<a,릌HEHÏòó‰ ]”%,eDž³U~W»lý�Ú›«;c¾á˜“÷`þ�? ¡¾p‘M ² lëê.‚P²W7õ¡Ù£È./ôWœ#;Wõd*–:z;E2†¨Ÿîöãúj¡ø9yÉÜAÇS�S8èuÀŒ¶à¬;fY8»m KѯèìÔ„Ô¶‰Í¡>,„  _èg¥´ñ-mác<×n]Ч-®5‘2c¨¹¡®ñz ¬7d Pœzóåµàòð²V„ö“û¥OPvf¼Rþ R¤ÓÆà°“9†Z -ŸÁÞd†÷®šˆ¿C›šñóÇ`,öatÁ=‡k?v¢í4#P è¤BÌ¡šØ¥¸/[õs.<a0eÆ{�´&Ž¢vþò¡a~eÐó8‹è)fä±Ûny’êfäBPLùuñ³Iy²H=Sø2öÑ”Ò"[ÃÈ(Ù¼O@íz*I¸º@Åö0—äª#˜ãÜà,Ð�­ôÅI$Q¡Ïy côÑžF ëa�ßžv"²ï|RÇܘ 'WœF  x?þ+aNƒMö®�KÎ`ÆDÞ/è·nf:X¸I8:H ±IRm]›Kôº6i ü@UÏH*NíÐoF¬àý;–±©›á‡�"W�q£¾d\“‰‘Ð�*C=#ã2Ï6x”7ì<TÏÕ
  20235. 7yˆÔrU>-bH)ɺzï '}¶×¶Ýîwœ!rÁXÎZе ´.:’Vn×;î-î>Š:á
  20236. 6àrÿ½‡UÁcsÕ4k¬VW¬{’ú‰ð#­˜5ß‘0ÁBÝãìÇ`Ü�ÿ0ušÑ".QÊÆ¬›dB´˜0£”õ˜CžÐrõ]íïà#íºQ9lqœàN^ôÖ³�¯éôh~ NU\´ ¼16š
  20237. ~éè“á”S‘n‡Tòl¢‘\þTHÒ²Ú›-ÙÉ~ªG~)$…oQ7-ë¯Cï°ÌÈì}q%/a™¦³vO°ª|[q4–‚Š’³~Bc-$NÜ7<V…HE€i-™œèRÈF“ GNMà{Ð"3•� û49‡[„j< �ḬWÓ­ ÊãhÕø˜¿l‘nÛà üÈØQÒ¨Ú‰Gcq¨ï@w¯/e qÿ£ÌægήÈ<ˆ£ÍÆ:  êáaé’·¢‘u¯êÍñ”•_P‹` Ýùb{Eëá¦I(ÏÙOWGÝæ«fEyÀÜéABa_žß;O^ŽDQ£â'èµsóåç îÐìó`Dî#Ñši¯:Ñ´Û+ßY{©{Òpå&¶Å\ßRažšÀÁ—gþÏž0ÿÁgúïTùLÎi<'Ÿ7ö¦?ÀÒçX1¹ÀÏCïÖ
  20238. a¥¿éîn0o¹r1Ñ ™/U­¥‰�õ Îo�/?é•♯aùÓ_¬pê�HÖ± Gõì´ ¦Â8ŸÝ£?3F‰0ð˜€Ù`%Ã÷Ï‘ÄÓ<�
  20239. Gš]Ô½œ8blÍ�%-,Â)}%žJ”:¹Y­ÒjÐTÍ;Ыȶ5Å’>ž6½Ÿ�wÒ{œV餃.&£ö(†o¹©*õn<§Øn9¡ÁJ–
  20240. "a‡© ДÍÝ+¡† aÊ/»ýººð;7zDØZη{×t�M Mp—£ iØšk¼NPwˆØ‘ͺðH`T ö$23–†fÓöÀÐÚ0šzÆÈ;­¡¦žç"ð]Œòª‚*ŽY²¤é,äQ¡W�Øàô¸lS鵯ÅOŽrW$5]K¡VÙ»Bâ…Üš…I¸ŠkÚ|ß=²&Á[ÔèêÞÑÞÅ58EÓR¤0Þ‹Gk«sSîñÁnãònnuãúñExK�Ðrô¢¬Œ}‡~mñÙ`ŽG4u{ÐÑñ=]6f¤�÷âר
  20241. BoÖ&< ™Ã±c;2 ®P$Ãǃ{mW_cžõª'B6Њ?$½^z[�C—Y¹Ý­™é¥jÐNó~ þ¦Û®0¾»›út¢¯ú°Ûâ„6/)-‰1:p$Dꥅȗ
  20242. ®
  20243. ,'³†üyàõ±øÁv˜Ä …nœ‹F³T×Ñ�™['a¦MbÎJ]»%�&î¬lc6&ÂèIpFå�Ä ¨ÜoðŒiƒªÄÉþã5± ø'r¨äËår‘(q¼ïè�ú®ëî¾z6Á°öžîÉ(5óÐáEôàÉ¢ÕŸl\…Lñ�kº7«°1ÅY4^)bٗ¦8ù¼yøÆ�ªäÛ
  20244. NžØ=ƒ›9zT–^[T$‡dkœ QâiK%áˆ6޵�üqµéçõÌîfO|àÚàcÐ8$•ji^vrþ.QQR"âYárÄŠãâõ¸ ¨Ãkø’¥ÞrŸº¼Kˆ¢µ<QI‰"·@´ïêR9 öÀ/½«\&7Y}m‰gÒŠ7»œz6¸-Mùu=‚Àé,õþN3O\º6ŒÃaDAŽ»Þ®ðLd^rëÉ/.®>û æè
  20245. N·eíÏRiû4¦¾Õ!3Rù¢º�"�4¦ˆÈñúšn™bámÉ-y[X¦¦ÿÏñ."Æô!”øÜQK¯åE\N�ëµ4gÕ ×�ø§¿¦ƒï±aN¦p‚ >k)9ÁÁ0ˆB�ZêÌBs
  20246. ö¥yŠrŽšer«)v¯¢®Dóëtèrv�\ûvù[­ü>órµJmœ�–
  20247. aœò«µÌ¼›~uÝêêÕ�º>µrMZœ°˜cíB<øã`)\y×t|Û�ïÿr'<†ô˜à>ù×Öþã[æÃŽ—ï­èh7ëú­þZÅŒ8caI�!¹ ´p⢟ÍÌ®�,¶GÃí »k 5@ÈÙô÷ÿ`ôÉiw ˆÒnО8pŸv¿ çÉé*��²Â'O
  20248. ÝÔüв ÝA[È.¡¤r�hóT pR?+;Ëÿó\*H‹sLqÞæëUš¹f–â:ql-㤠ñ*6!…hç+ˬ�{h·‰ö- jg±kÉMMÉ×P#ã¶ä:¼}‘±¸{/ÝëîVËßŶC]옙ê·&[³W$Ú«^ß#àû¸¶4fWa\ ‹Á5ìð躺M[6ž½)T§3—•›~üÚέÉÔÀ
  20249. ã:. Z”¦¼¨`sÞi(ÍRô©Q…¼²Ì|/ú`ù
  20250. ilÏ^°L# §÷òf¤-ñ×;-C;_ÜÞù*ù{@EMCooÂ_¤œÆÃõ7¾TöãrqzÜFµ%ׯ|™šU<Z¤ÜoÁ[TA=Ž„Ð'DPJ]´;,U9¯µÊQ›±ÓpŠžkñ4~€êáÁâ_�Cª^™qE¢Å®�œb �SGsÚøßíY…�2N–A®Òuí®%ððSD„‚ ×hj
  20251. ÿy;9$ß´IA¨ÕhäEO�Ì„á²Ë}
  20252. ¨g‰³¬…—/+ ùÕƒ“ï5�JYÊ @äGúø��ü¾‚ê®f2�¢´—Y Äç/¸Âß¼™e„ß·¹±|vÞ/¸"ÞÿÕp倨~刋ñTãô8OKór*ÒžÝ* †ƒÀ4hià@Q›™3g"Ñj²Ÿ:ô$û•;:”ý¤fàÍü–÷Œ,d½®®zÍÈÈšÙÆÔŒêº³°«u%ç Ë£}Oõ&³¾‚i2Uè, @Íkêj%u?Ûã4§NœKmöÞùÐd?5ÉÝ“;Ê0™Yï�Úüe}sZô€‡ª>EÆ«Us^Ýœv{ ë¤¦fQ<Ä�¡‰VPüïÃÊTfͦî?¥�õmØpÙP*�È&¦÷ÐQ‡G‰ù{cœJïñEPe2)ŽxP½0AÑßÍûMɪZH¶j•"×»"ÙA¬ÐC+zq‰mVzá–žóU%ØCµ�:@1æãðW¹Š î[y)ÎJ@÷o±b% ÷j”A>)NÒÇ€Ôiç¼$’AóˆÀìt`>Ì?f0g�ÿH36pè6áÌD|ûM›ä áö4N�¡°
  20253. œ’ 4J½JÚƒ¯
  20254. µj¤ž˜Æ‡´ó\ íp 3ÓøŽ£8�À¦ªÑã–Яï”»­6p®ùV?:¬$‚sDùÀNúµƹ‘2ï’n’,¶„HÝO\‚[¸øÕ¸›öKÙ-)�«W~¹iém™?ÿ®ƒTÐ:°ÌðÞºUÖeYŒÓãŠ-#dJe)¯±ÚÏZªÕ5”?ø$»æ¡\d©W<·¹¹,Ɇ†š;¯Ø·¸Ã5ÍÍòS¸Õ¸¯¼—T«T–ñšÎÌ„f(�PY°v=Q ~DX*¼ßÝ8øè¾©s- Â˨®Î€55 ­ X¢R¥l QCÏá¤Î á“øÑÀl|òý5Î{ûÓ¦T\t꼕+éï£e»nÅÛ¸‹’ÂPsÓèlû3™�ùUO©[üÛîÇZ»ÉS3åÀ�îŸ�*èì,˜ª†ß:ÛZþ¾ÆÔL‰›¬†ÕS��ô'̵æã*õòŒ*@¨ø�ı~xgno2±¹áˆâ-
  20255. …Œ ³W³Š«½V�;äpZå9�?~„«$«6Ÿ<”µQr‚bQ8&óse•ÉEb¯ÚQ,·þ^|B²µï碘ïVd¬V-¶(Ü]ã .ïèËŽ8/qhV¡nR®ó®QÈD‰*ùU(*1hç1Ã`Ø�QL{…�Uj `àÒ"šo3�Ü»æ™V¨l…µ: ÑíêÂØÀ jaFaàžE­¶ÌžZˆ‹g1±·zü°Ì2Ö Õ:ÍAuÙZIf6–ƒ2Õtw+Љ‰f�§D�‹ïÉ誩CL-}g»µZ³0>Ò„óxJ¢ýÿÅ>\î�ÁëQ‰¸AÚ_C¶i‚hßÒbl] ‡6ÞÕÞÜ4*šA˯ɰüqX‰¤7„»YòX.€-¾ŠÚÕ¸•aɇÃVâh¬–iKg•ÔÏqN³RĆN(r'Á]¼à%Ù˜„�…­ô�ˆ@3ÔÍ€ÎÂ�j§Z¬÷J†.;üãnmÝú¯ÕÎ,SûûØ0x¯³ÃõøØÍ»£OF33­Ò§¶…«<$'Û»¸G—E+´Ú}¥¥Îóúó§…'1ðf3›ÆýÒyÐ5Ý/&¤Zœ\RBô7dmíô]æ¼8§§Â\Íý„3ß‚„Ȫ˜@÷ìo¿ûTé¿3eu^·W@Šªü”–ަe7l–!Bã,Às‚äæ1ÜÍß$šäò¯ÛZ§ã&Ù’ç?¯âdCéá �(YЦSm>‚J"&ptÞ܈ªP㇄BF¬ø´�Ú±àÙø4ŒGá5œ t^Ć$¯Þòj-aã �g^ÁÊ�C¤–…ƒAsÖT=k¡TS,|€ràåš9I·½BϘЬ†ö'ÂìvG�A¶Î@�ÍtÀÌhQÕNj†&€åT=Îxt;2]¯P¡|T- LÞƒ’Éç¿ñe1ãݽWÃZÅš*MrH5?„ñ‚=à�ýÑo°¬"ëÆ9ÑK5Îø=«'kÉ-*•„èA¦E| þ Þ qÒ”‘_?\£7%öŽ|M6°fª+““+’S*}çW�_Ü]3ª¨ú¶fmÜ®ØÒ˳ÒÜm w!–—î÷å.ÛR#‰é¬ª;Æíú¦±q qó71ŠÖä$•ݙկ_ÀóiKà&ìJ©Î¬M®Š¬öÞÇemåVÄ5PÏ0>¾¾ Q�çµ5ª†W•©H­Ih×åù&ù4Ò�IlÓE7}âsÈéÄm[cȾ좄|�d^ ¢ì÷%Uvé1¦D“²>“.èT¬Ò7*é=tƒZ¸_§ãŸ¾1Ð¥:=0pZûš6Ò‹ŠN„t�(åuíÆ�­; ÇBÒ]³‘$€k¡ÚŒ€Â.ó{ªFÄ*/UZ’ÆNüç ¦|oqŠÊK—G;^Ö侞9N§ûeÿíxK‹ ’¡¨\‡whþøñ~¡òòZpHÔb‘‹Í䉸 »ˆÛ[k¶8âÉÍÌk÷â.bX.Q¾Xp¸xYa^µÐ"˜Ñ#럙ãB³wnb¤¿óå�uÓð ém5žF²½~>ÇÐ8€­ÁbýúŽäN:Ýp4 µ[gv^
  20256. B½ÓFÐUzû)?œ¼60�ÐFÉÉ8˜‚�Â/2 ŒC8¨Œ®>�N8Gî�Í%ló%èÝ5ºFH˜{4„6h§Žï¸4Ž%Æ# 7¸è›ñŽÍúËx óoºÜN tª\•'ßȨ ¨ úæE£�Žæ½0#ƒïj¸NãVïÓ¹dà?WlcW��×ð‹ Äí
  20257. ž½Öµµuû-“»}2„2¨¶¥EN�¿}#‡äµµ2H^a3ðõ»¥r»Áqs§¤°ˆ„-�S3&Èïô„f´í‡£ÌëÎfwl.š=Wø8å„,õàÒcHá®jžcTê±W®‘× s�9ò0žî”ZàDÎM“ú¾C2’ZM’�Ýû�djµŒtŸ"8À:gí{.Ʊ°Ð1Fb6ƒ1Ç8"yÔ¦>˜õ¿ ’­WÀ9£ë ÓVšŠŠö ¯`×j¿ý®š�¿Tò””‘‘€<I£½MÔ±W'%­f&¸\yäZëdkÍ´èùRyÑjw˜æ}ùˆÐ€Ïß[8ÂÔ�†»£ÇbBí ©'d'müoû'<�ø|EÔÊÍ5êõ:³¹Ú‹o¼š©É>²µr,nƒ©iÀ­Á <Tª¸S¹¹Ÿ>¥d³… ÿôéqN§ªÝ .g+ ïSÂë¼ Qúù·�¾ë �áKaB¾ŒÛà?_í‹ÛQ�E ‡“µr¸†ÿj¤î‚h>ô•E¦�Ó›;�C�×­7…‹·^q¯
  20258. Æ`U¯eú#-Ÿ˜·;oJ˜Ä‹ãÒæŽÔ�>) Çý‚;Jgí£Ï×­9R;Ogí¢ÅýiI7ú}—â8K¡’œÛ�q¦j�¹ÑeØ“£+Ù—'nñÏ·k3‹Á­»üeFÏ�ûžì…0±šò¯ßV#©íÆp¥MAzb^PŽ÷VÏu¤Û~Þ1uº—Ò“•wnÈ ^›.II—¡Š_ÆÌÚvdW®Èö�óÎ[Q,ÍÞè+L¾b‚í¾É¥å„ÆÄ‡q¼þ 9«V}ï ”Î�VÑw4qUä3&jÛıHYb¼ ü¹ˆ ¿tt�Tœõˆ7Ï�ò’«ÙarBwP9?)Ûu•é‹T/Ùa£•ŽA19–±kªM
  20259. \ÓäPÝßs›<ØTaž�Ðã@‚<?Mâ (ê¼.¡,'%?,Ç%�a~eÎëŽÀ�ŽUá–0µÍ/zQÕö(Ѹý“÷¤a™¬ªp:.6«jÂÿdF@\V®4¦É{ÓRiìþ ˆÍ8é¯Éªnuý®Fï˜M_†§=¦½õZ8á¤HãîŠl‡sy5k%õÌ|(ði9 "Ù6äº}Ô‹~WK„ÛŸ‘hY©kŠÊö¤—\àû×l“RmŽ»´&Ò ºæ¦ñØò0¾ïÁbû]gÊ”µ¾"ÂçÞ€D^ý²æ¾ÞŒ¨jÿ±J*)žš6¨µ‹-YbÙhÖà÷òé
  20260. Zý¯éß=Þ‘¦A,ŽÊ(Ž�K#Ð –²OfÈJ:î;¾I†¾Ç!6Yi&ûdÙàÖ%m®86#ªö™Q�µÒÔÌW_‘öA›v}?+èGášÊú cc*ÿmûô’g`Ò>…õq±Ø+û£=Ù[5ÄÍ”·¶Ö×?²9£WÀÉ+^ýo¯^Eàã8s�)å�fç —2aôæ­QŸx¤·i‡é& NE>"^NaäaŸ;fŠÙÌ9]NE& t^°ÀCLz'âe…8ZRñs&6Þ²7_�üãcyJž‘1 Äþ@TZ°?S�D2û
  20261. ‡|ÔPõÔËOÓŒé\dªRïÞðû7zHÕøƒî±9iÈ�‹Q#µ¿¶‚zr³óc.ò4ö†GýR�4ÎÈqx¦ð¾<2~X’hµ÷náãੳ¨Å2ˆauB­NCÑ�+›¢k—Xó0Ñ aj5n>Þ‰¨õ²e3övÞ§Óôé<¥>�°_²Ÿ� Û uH: �XR�ÿ%~9á!4öüoÑѼ¦è�3…ºâ”8?¶‚ Î1d#ïÔÑü–šA&‹„„{A!i6 ‹ŒíÜ/Xa�Ÿ£á㇤=W‰;|ïðä)� Ðg¾~£ ?*¾æ‚½Ã }¿ãÚ§ˆKtÌ>5|­E޵ÐîÑÜÕ.§ýôAûš Qñ6üú ²€¾(6
  20262. 6Ñ”Æ7�–Ú÷<9ùù_ð•CÁ f1þëÐŽéi8¾®†å», V»4$ÀŸutÉøœø£ÆiÁ,.`v6r â£òŽP ¯½gFB�ÉŽÇ
  20263. tòÃçÚ C3½;˜ ,¼o“æãœx|
  20264. /KóMp©1S_¾‘X.f÷V�ª†#¼U>È’Èõˆ#Böñ]µ A�‘IVoÀÌІϵÀ‘¿üGTV1nr+£ÎOXÂS•% ‹›³¶™f§OZ[Û_ý9œû‘P­ß°÷ {Gln‘%ß#ÚÛhÀdw¿H ù=† ¸y©e/íªW¼³´¶>Ò,Óö¬°IP,*MV•ð„~ºK&ãe¢Ä‹»ûMì½£=ò)‹qF¿ S¶ß´"ÉGÑëTšF™�*¹LX,hŠ[—´º“§wŽw´íeñWQEÙxÚëº ?áè“{^Ú†EŽxïh»�iý»¢×‚�„J”³ÃÀH�¥|ó^ÙÍ“Š…Ée*^‰Ð¯.ãuÚxE™èëËb#î;›’ôÔ�<]z]\íƒ×�¨wÚN»ho¼chq¸E˜£=ºçâ4Q1¸7ýÝçWü½Ì“lÕ6�á§¿­HE_Ì£ ùqyÿ‰á YRŽ¤Û«<x=ÔcSßXy!=0û8Ç—óxÖ ˜�ôþ?±{}¢ÿÀîßF_„üáÇ ™zø¯‰kt©É±ðˆ7³ÊÚ‚|tû§+a®m¸<xe$‚ée–�ãÉ�ª×<[¹T÷¦ÿ�X[þáš žø£Ùö�¿s»VÃÌ‹«Þ§UžÉ*³áŒh—S©K=FeËsw uYéoÍßÙ¯nQ«³=NE:[Ò(t]å k×|ç@‘Ù¿uZ\9{h�±�v€Úܕӆ.Ú¡úsaƒ‰$u+Ÿq¹w:#ãæ?åeúT‰3=ЬлÐ!µpìPL`Í:…“ÝÐR; ØgÊ® �Fha�Î�;¯Ì†5Ie +–ÛØõ» �×bt06AW40TÍhJcc<&ÀmJccà
  20265. ¸ �ó¡OCn«W?üùNÂiþî¾o](XЄûŸ{÷Lzì˜ôÙ;¿ðØñg¹ï|Ç�ç>ä9~l4sæVyù­™`Š×Uß›,ùŸþñ×Å#_Êu´ù+Deêêí™àéMÙü¢~h³qªë²‡’·#YúÊæñzü$;Û 5ͯ9$µË z²>ÿ
  20266. ¾*jõOŸ�øŒñÛ$œÐ$O/¯ÀÃxRí½ƒÂtýf-}*žoïɦøÙÌ|3†M;xÞ¨¯U”•µl/.ñ~XÇŽ¯Yá¼4™x3&æë×x®";¤$�KIö’5ÛdÚ­ ½Êáüú‹~w[ÊÔM9OØã%4ÒáQ¨}éS^žìt–�è@ÑËæw[›Y;-Ýöÿ�Àºs;¢b¾ÍwH-* ï––Ãim½¶IÊ-¶1e/•~ø¨TNN®.òp²ßð)H$ûë«Wïß~�Îð�µÉƦí¼O
  20267. ( é9è†,Ù ]gM6rê+„#»%ƒà/süw¯Aœ$õŒqÆ4ËO>
  20268. d9}÷�+ðÑ$Œsôš³ý?0£™a,>�y‹¹Úˆs<ðþ=†,ð‹c_*\âƒDí¼Ü}È2Mí°ÍÌT8/í4ægæ'Ú¦ž�â8'û}"‹Câ*„\9½#Y�>z$ŽæöÔ7c[s“|"$}» ymÌïÕÀ«zQx 5·%å oùå“$j†kÐÎp)ñx½Äû-:º†Ð˜|?�˜oãøf§‡gFrÀžß2ŠS‘ÇZ÷Œq}qˆŠµ …o€,wyÅO¡gÊ�CF1Öl˜çŸ'íL5T3õò3ûÑðyª¦M‰9Ú2"s”˜ò5uD•‹6ÀÔ-Jì‰U†bsºÏ
  20269. «O)ƒÌw¸R -2æ/5fÜ<ªBQÌ4kŒ˜ê�­�G¹ )%ß¼ã<dÆàĪĞí¼3È2 `ŽaØÃ]©ªS{£K%ô\]¦3&�Šp„“®®Ú¸Úˆ”CÕ¸¢ ýœ©ë†¶“,÷À Úù^éTÐÙÛ7¿h¼5™uûlDÀ£xÚ·¶—ñL'D¶ð„rÃ6úv Õ·fc\þ£ý§µgAê‘Â�³ †²@�?¶½žÂØÁ‘ œ•GFæÁVA·l,¶µÄ:§¾ •i#~NUûæ“DV~7¾�k·K`!ˆP–ìMX³üRÍÆ$#îTiih¨ž®omÕ˜Å<.8UmÇ<’Î3ïÓéESä4 Ü«�úŸV9²ò'½™bvÒ{¿¡ø?îVVÞý£3�×;”U'Ö¬‘Àµ1RÙVé{BÇôÆîiŸëº4C RhÜéŠr6~˜Ó–�J”¥PàÍŽÕ÷M‡ 7GŒÐ�-,NLo¼ô<Ÿ²¶Ñ£zç÷••2H&|$³²’¼<{ ¦Úœ“Kä_œæÖÿmmSŒ)>r’Ï›f@=šâBF™‹ïCB�±©‰‰ƒ‡&'‡F}@©&ÓÈÿ„y×ubâÐÁÉÉC?'«êåñçSæ49+—Óä±Cø®³íIîð¤ÙŒ+×ç˜ëf/R«Uê ÌîC °Fu:C*£} †T:º¶}{ÂÜݽâ²·ÔuªÎ×ø•¬e[!®–>ú? ‹ÄåýÚ¸¸"ÇM
  20270. 8gzƒô0\HkƒÔZ³:Ähå­~™@ª+ô#«N�ê Öfj¾çyµîå‹ioÀ!„B÷ þñô·“±R'©5>Ú`Úò[!ÂÄTˆ`mCš� I…Ñ�Ã}¸n
  20271. �>Wßô!M}UËavõ¶4�€3)!§kcÈ‚²ómþ?’Ž Ýådïw•ãv«!×”;Xϡۨ}½8ívt•ëÐ"Ó¼# kÂvXŠJ™±[“l�¶[ZÝ™MÀ§ñÃXC3lê–[ ÃTa¼Vj‹¡…ÚÊ»¥åŒÑ¬"Å“Ñò t:‚(žêà¦ÈÁ<¾cZóve—ýQ›ÇîT…Ÿ qHá‘i{ Ò銀Q埓'Á“Ö»“i öPØöï¿­èüȯáímKÊAçIŠõ¤��BFƒ
  20272. £=‰‰µâÖTá…½¶à(âœ&TSŸ?/ïØ�A:Ö·¬»ÐžV§(ø÷@wïFa^ã¦]…Œµäo]*Óñ99¬R¿iáñ_Ôò˜À™þÎË2vM“€Ø`P§“ôf¦´{QYÏ«íH#V7vÅ7ÌÒ° q>@àó«~uɘ׆Ax°Ã/ƒ«xÙ°Bþà3£Ä Ùô‰�tƒÊÁy†b0ŒžnG`Á òEÚDìÙ�äA’Ô: ÆPØwIÓ7ÏìnWÓ÷2ED<hD�&Z˜ˆÃ Π7Í3á&úÍë)LDË4;Ü7èæÑ´?$­îËk@Ù"ö¿"L&~§ùö1ʺf«14ŠÊ±|îÚÙ7Os�Í}úÆL1;éÝ?Â{1$�ƒ¯w)™€1}Ðà0è~7„Ú# E5Šª`Òq&o ÇowÞÍ ËÓ_“…é´ŠªÔ8Q1Û�Gó»»óëùÓÉŠùêù08å×h¸äW¿e ˜+º²\êåÔ‰†R‹ÔÊ“ÃU?w®àeÙôïOÙ�ÝSx�AUÖÌž3˜| =WAµÍÝÅR�
  20273. Pñ°tO%Q"1Y×”!so%%­^�zÿ_hn,ý{?ÔÜø"L¬5±_D6©îì+êïÊËSbÆ<�à§ÌgfJËô¥0äbì_ç¡ÑxÔ-í £;‰H«âãââW‘:G˜MðiÄEeÌIuª®vJ]~mÈÙߨQHLKkì»ÊhbžA>}.(h•Ü"‚óãU]¢9Iíh_îV¯@‡›GZ0C
  20274. Üpb ó:ã™L 3�¡tN*ªN ½2¿Ó!¼3Œ� Ca³—yn.•ÊÝÉ‹Wâ`̳Ü}±QBÌC�ªÃi Á¡8*Ãï{57‰¹ìO#aT¢ËB½Ÿ‚½Uíoþi§0ç ó_ËðÑù^
  20275. ChrU}~rÈL 1òzÿ>..ö=%GÁš›GŒ£ ëüo ™�‡ ŒEéu‘P³Psؘ޸èó8­ðüþP¨Ÿu&;æÊ*Œëù|i&¤ÿPbÛÈ›°²˜hÒ;´[—€|y*cƒVšh†Ò¼Ò(ÿ”~Î_A•qU2·½ÿôGIQÇ3`®^Êvþ=î@¬ÜK'¤µÐ‡èËZ#4sJ=º¤:sY©è sÚ¥bÂyj ¯ë·S_E܃"Žª‹Š@ž~‚Ÿç¹>­86ºñ#Îy±Úäå[ïècòSï„¥ÙŬ–�”òò#­SJ”GZû®yvvÝßSùÑ�æ‰�p¸waTšžÏõÅ/,
  20276. 9'Jkv%%.†~oò[ÌóŸ è¡§üœÂR±Bj¢ŸSèÈ€*$'øè…�©pçS¥u� à+ç9\¬í_f+åòüù8õu\,¶Ê�ÓtæåðpžÑ�ÐkØ®J0hó(]N„QÈvó³W¬�ÇÌ7ó •8«ƒ6:ÜÖÝ£Ïâ ·ñWc“¯Y_i>ú¬ŒÝ"‘ßR¡çõ’â�(Óe]Þ6ø¹ªRA%U—6&´F]”½7@̳k3X h�?ŒÁKïà®Þ�Q¤2™Bk¾[<o¥-[ �s~Ÿî0¯�]Tœ°Ã2ÁÍä¯hÊñÝJÆqîK¹v§«Ÿ(32Jºþí//W…¼,ã¬ÃÎÛzï �d$2ÑcA´kP”¹— §”Kÿ+€î­Ec¥ ÛÂÜà[Qžùàóôùûiú—EdVÃõxR8šäBÐ5ÚÌÄa=:¢�KQ˜¶�çÓ\ °@ÆV»^;KrÌ —M{ü÷ñÆ{#þóC�w}{^,í§$0Rcÿ\o¾«Q½Ñ¼Á×¥PüÊ$é†YÊvpà®>?.ÿ€Ã.K¡ÈKAbŽÌ6ýÞÄ5¿·kò’eŽ+]²F<HËe"ª;{wN‰yx/Æ×å&f檄/XZ[Ÿ¤7»š¶c%ßÅ€5½d•Y_Ÿy"Ыߞ£2\37×
  20277. – k\Äë�²|FO Š’´68Ѝñð…‘œœÃïü½„�ÿnKðzR"�ƒý‡ –Ÿ?/7Ð32š:аá>ްeöWH©Uò«û0OÝ×§¾5…´øÿ ¤úîäe3H‡®coÇ>l]0¶2±ˆcý¹‡ÝHÊ9š{Z {sOõ–!¥A,þ7†?Å·3�w俎A
  20278. àFjÚÿ¸8¸Bí&8U$G…¡Â�µÙßé$µY5˜‚†FâL…5nÇì²Øò1–”> qóº2££.«6“e—é
  20279. î ì¼Úõ—œ+˜–@/¬¢ð™µkíb{à÷(�Å7Ði=¥É{lÍ�¬Ý‚­âÎæ¿¦ï 8«…1g�(»üè%ÎÓh/ëEf¶M¹Ò�ÝtŸ�5½Ÿ̼vg½oÚ ê~à©›WKi父U«ßأݖ­w¬RS‚EìFíßT¬²%ª `=í‹ø|*=1‚ò*Žù»ý·S§Xö¬€·Ø^êòÓw)l–ÃÖfQ�HãúŒ(YSþô„SËŒK�·æ1ÞØâíW]µf™Ÿ·°7ך³^&ýpô@T'.ìÀ%3�³•„à š�¯´ßÞò»ù5ÏzaTf6Ñë©A5ÜL•óXÌ¡æ·Á|ñL¸-Ÿå–ηêÄT×g{A)ªî­®FÑ•."hü“ùj¢ A;.ðâ~Âþ …oÞ%°è ýG#Ñ}&]Þ×¾cÜ`C»hH9xnN†·Y Îlð²cÞ¤\+v\EŸ¥«Æ§1¦D9K·Xá)2b.¿ó­“NôÚýW¢§ŽÜQש$¥/£”|6tð™Ã32Ô›£´7¡¡¦�–2¸ÑÛиyuü0e×ñ€)’NØuh'dœ¶Ãî„õ�~xY‰É ��‘´>ÄÚ# bˆ"k3Ó𠼃®Ì: 9¿º¢vˆú$ПCÝ:Ê)H¹Ë> Õ¦šzÇÛ;e“d\jmfŸäOÏa%ò9š‘ˆcK›xÓÐÛ¥Å!k©%H�ÞDn“ü{YÜ"“{n_Ö}
  20280. ß)9ƒ= _/û‡ZÎ(éù>lú¶­÷YžŸÖV÷‹gQ#§ß­:QÄ•ÈbwƒÇ÷Õ$¾zw±ðÙ®‹#¿»ãU˜?|ÅðïGÔ΄hÁzü{ùoº$wñ×Ïœ�´º)|Vh‰Ú?»Œ ZV�7¾%ŸüGûo/£×†‡ôéEÏ"¹KÓ²… ìµl¥p76Î�-z !Ál€4n>”¼$\á×zV?szûqejìQçëé]m‹›æ^æ=^µ ä§í­¥! ²ºl…ôHB4sL i9}Þ2¢^×ýKÐ5ÅOBú)èíO ­çv^~ªêµýïÝ€x¦“rm\KÚ&G^Ð5�CçÐL¼}&Fºò”ÀËâ¨B]K†¡n3††|ÍsGjyðkþO¯µÚbåsܽæaW?R6ð¡·²¾J�ÂÇfhãÚ2 ÄÊlBS§\=¢jÕÕV—Ê*”ôY¦“^¢¢Á™„˺^E)Õè*”\½Ÿ 
  20281. ‚rÔr(a¢@ø„6nÔŒ£?¥}ÚdL°©¦�šg¢IvqØNcÐÇa�‘Æ®kŒÍ÷mLŒöcÁA!¤±hd¸£±Vëðµ¹Îòwc=¢¦æ†–áæ–Õs_Ò:ŠÿÒ—•¢sLËí£g>‘œ—1Ü*4-%ð&Ëõ0Ubƒ)Eܬ�†*b¸ÔÖ51—Äï„ç ä+è+;˜Ž<…«†’`!q°fÍÎMù*Æ,[/GK+{×®�,>CâL�Œó�R%%cŒ³ÂÆÃ~‘’'EG�†A‰®GºÂ=‡hÂäŸ”Ž°8:IDìN)ÅWÌ»áAF)ucw'qhÍXè²L@a„¾~Œ6ÌPc2Lã"¥A…2bìÈU ™À&Œ€‹ÿ ¯9öA#ÓQLO¬:�E€9k§©’‘ÆfÞKF•b93tºL$c‰Ë¬pÿLzÿ ¿5ÔdÚp¢þðùÛ°>$`œ.÷ï«~Xó=¶�¡ã?„ N�Ͱ/ŠÄ©L®PªÔ­No0šÌ«ÍîpºÜ¯Ï ‚b8AR4Ãr¼ J²¢j¿}øŸÐ Ó²×óƒ0Š“4Ë‹²ª›¶ë‡qš—uÛ�óºŸ÷ûAFP 'HŠfXŽDIVTM7LËv\ÏÂ(NÒ,/ʪnÚ®Æi^Öm?Îë~Þï÷‡à ’¢–ãQ’UÓ Ó²×óƒ0Š“4Ë‹²ª›¶ë‡qš—uÛ�óºŸ÷÷ÿ�b$œ«tV&g®Ï–íÁr>¿<Ùyóå?�’“˜�ûfþ{�ç´·�£�‰µ›ž%îµïÇÌ~ßZûþaÅzW¾¿¼÷ÜõÝ2Ÿµsv�ïÀÌò�™ÙeW«�‰µ‘à����@DDDD$""""bffffÖ}�X ÓO„0ÆcDDDDD¬µÖZ›6Wò08BÖçI¥������������ƒ.H¬�W������
  20282. ¢ßˆÇÐ9 �‰u„*¥”R*J^}€Ä:M”´$I’$IÒF‚‹™™™™yÑŸžûÞóÀ_WÍÆý<G<þ��wOFF�����[€�����±\�����������������������FFTM��X������m*—ÜGDEF��t������ D�OS/2��”���E���`g¹k‰cmap��Ü��À��rÚ­ã�cvt ��œ�������(øgasp�� ������ÿÿ�glyf��¨��M��”¤}]Âohead��QÀ���4���6M/Øhhea��Qô������$
  20283. Dhmtx��R��O��tÒÇ `loca��S`��'��0oû•Îmaxp��Uˆ��� ��� j�Øname��U¨��ž��¢³, ›post��WH��-��
  20284. Ѻ£å5webf��[x������ÃTP�������Ì=¢Ï����Ðv�u����Ðvs—xÚc`d``àb `b`d`d’,`�H�J�xÚc`féfœÀÀÊÀÂÌÃt���!
  20285. B3.a0bÚ䥀 ‰êîÇàÀ ðÿ?ó�ÿ@u" Õ@aF$%
  20286. Œ�1– ���xÚí”?hSAÇ—¤iSÄÆþ‰�mß½44±­Ð,qÊPKƒ qÒ ÒXE]²(2 ‡.¥Ô©ƒ]´‚ "EœD·
  20287. ­¥¹ßi]DÔ¡ZJõù½\µº8ùà“Ïï½wïî›w¿„ˆšˆÈ�V"±F¦pUÔ¯û×â.Χ(ƒg’KÃ4O n«;âN¸‹îR{¼g`'!ÛÉP²MùUHEÕ J«¬Ê«‚*ª²ªªYq”9Ícœå<¹ÌUžá9Ô!ÑQÓI�ÖY�×…-Ïó°¢KCõ•è+ Õ¤ÂÊU)•Q9¬4©Jª¢¦Yp˜]Nq†Ç9Ç.q…§yVV
  20288. ën¬×)�Ñ9»’÷Ê[õÎ{“ª¥öºv¿V¬å×›Ö¾¬ö­FWb++{Ý>·×�¸a|ã€ü*·ägùQ¾•òм,Kò‚<'ÏÊÓò¤<!�É£rÔYwÖœβóÜyæ<q9�{-]öíþ“c�ùð]oœ®¿I‹Ùï!0l6Ì7‚…Í�áØ{j�G,ÔOX¨^´P¼d¡Q»…öÅ{,ÔM4°c¡(QBXè�¼m!ŒK†,Ô ·Y¨�Ha¬2Ù}«Ì˜˜�0B«AÔ)Ø�F}΀,êQ8ò¨�à �‚'A5î©(£>W@õExÌ¢¾DÄÈÃ&ÃUØd¸#› ËÈÀ&à x õMx˜<·aäa“çŒ,l2<€‘�M†Ç02°Éð6óΠ^†‘…çP¿$Ò�6{¸‡,´#›ÆžÐ{ MÎwpÌBïá8H¢þ�#³6™7adÖ&'~‰95r
  20289. 3wÁ"Ð[žEt’ØÜW‡:ýÓ­:$"ô™>2Íÿcÿ ò5*ß.ýlŸôÿäN þ/öÿøþhþ‹±Á]GtýéTè�ßß��Ñ�(ø���ÿÿ�xÚŽ |Õµ0>w�Öm#Y¶e[’%YÞ-YR'rö„ÄYÈj¶°D% �,@ØBØKZjHÙÚ¤@b¥¥¤-…RôÊë+¥nûhK›~¯åË룼–¦¥$Öä;çÎhµèëÿýþ^fîܹsï¹çnçœ{ι Ë´0 ¹Œkb8Fd:Ÿ%L×”Ã"Ïü1þ¬AøÕ”à AæY£Œ>,ÈØ”Ã㎀#œp„ZÈ4õØŸþÄ5�maßd“e²ü ?ÈœyÇ=�¤�øI:C‰Ç “DÜãõ(nI¤�xˆL ‘.1¢!„P'™JD‰t‘Hj€@L4’ì…P†ô“h' )ÈbÒ)vHŽX,fù1Ñc\'²âcGÍÖÀ±„u˜�>ëŒñ1Ù ~Âtüà?ññ„éø!x¡øÁT_qâ?qB‡ÛÐF‚‘¤#ŒL%½©DÀÑ›"¯ä?Y­øýŠºÇ¯ÀƒºÈj??8>NÑSkem„²¦AY³µ²Db¡4 ÙJ)¤•;•@¹j“ÅP$
  20290. ˜ï'qh®8`›ë;aŒê�XÍÃ6C�ùFâ*„dËYýcá±Ú"ÔŒ‚ù„Ïù£Ûø'?hÆL¬Vã—ŒÖ,½>c‘eË3eV¹Òh† =Cû‘Àš†éÇ~äõxC½�\((qb@ ¸4ð‰x†K&h×�Î ¥©4\2ºÇ±6N1|-Ô;­Ïëj›ï–É YuÔ@†ájêî›Ñ«xú¦õ†ži¸äЧþmKó ëÛÙ�DøEöw¦q3ÿÌ·.»¼cAw@¶4t.Žgãñìükg´Ér°{~ÛÓWl~¬{ÿÖlW2»êöð} Ã27Ð6a2Ì\€6o”z@³$´ñ¡ÞëHÄSÉÞHˆ «g®›Ñí±bõtÏX7ó0KštÔÞc1Á,«Õ7—Bò oLëè˜Æ�Ô6Ä·6[,–æÖ%ñiáZ ¿‡,’l>T†pòK³œSGg¬\> ñ�#»øAö#3Œ«ØEµŽy‚kÂî6v®ìÚçè…Áºç†;u3Ó!ZIÎ8ì˜M�†k?³8¶C˜£Wq{`ìC*‰Ðh>H��Ü1¿_söÙkâŠìh)œ›ž®ojªOO'»
  20291. !~dXñgÏûB(ô…ó†ýÊ0< kOYxÊe§¬©±Æ§Ä­5k¦ —=d ã²ðÓϧ> íü+ütÆCç-o
  20292. Ǫ†„/äÃõ_koïܶÿ¶¼sñÕ+f°ÿÎOßz±tpÛu7-™}…dõíþ9Å sàˆ©e Œ³\9.H4’!0�¥S\ ʱk2™ï"?ip7œ\2z§ÙÔÔlÞ°Ñt=¹î…Wùç\!ûKyOXimUÂì¾nov›ì ÛÇ6²:½èå 2Æ óLZkAýAÍ^âqCæ™Þ” &PæˆïaFÆê¥Iª0Üã>þ&ïù…Q �#F£Qý»Ñlæ> A³·q*˜O‚á­ýãÏÿ‹ÑȦ�æ_@27¦ÌlÄ,¨‚�sþø‰Ñè¾fÈ ¾6âp7üÜ©?�úÿMþ›Œ‰±1vˆA˜Ü2‰¦]$j"‚‹;‘vÛlk~va0¿ûgì¥j£úÜzþ›¶ÝRD:ÿg©×濱cë6’ÅÅywú%ôgâ(þƒØ#'´ÎuBµò#ì=ù_@?ƒ>ÆFØýVbŒ0žaá!¬aL4tXv¼¡ü:ÅFööh÷²9‹ïj^µxÞŒü¾¡ézÐÏ}´WnŽ}7}¶×»j“¯ÆÎšÎïi½H©�­¿º¶ÆÁÞi¥ýÅtêïüKüSŒŸ‰aÍXEôºEºbbBQ1ØÉöf”t‘x†ôF騆 ·-"dqA÷ׯ\ê·~F`³»è6²iä�•+À ÿÔ¢Û^ȲÂ}שï׆k&»ÝĹ¾»íÈà<- \èœ;Äâg1>¨w†0Ü0ßvòÉ^x ìÝÝ7lÛ<”šyÝÎ}™ÌS·o›9éÜ-Û®ã¾6kžÐ±lË´¾ën¹ùðЇo¾åº¾i[–uó—§~¬æoà`jàÁ•Š{i×\C4,"iW8’J�oñVò„bp¨ûwˆ²Cýªºß!‹;Ô'7×D.v¹ÔÇÖ�Ô n‹õoZ-n²ë¤ÕÁ°eùÏP‚òŠio4Š~LYä/zmþw_�ÿò�¾ØìgþϽŸþý§RÞÏ"tÞ Ó&NoN€¥)4ÆÉM ³CÛG2«‰\j²Ê8�d-É@>#ÛOt^¶Àì5¼+x͘e.^á]ƒ×¼à²ÎÛG 8›^æ ômŒ÷(ÓÆt1 ÷s™Ìbf³J›°ßÒ —%‘Œ‘ â<‰�¬4ŽÞHâø”ÝÅ@ešê÷8CÈÔòŠ,»5<Â(—åk²c5Y®I¿þ¶ìÍØ—âùAøú]|Åךål6+›Õ=øHVãcb´KÕ‹B´6ßi4• #´‹_Û©|&ó>NvQŠk#®pW•=ä¿uº7”ÛHɰR$ ç÷�î ³[5ì‹™ ™ ÌÍÌg¡ ­µé%ð1Ïä9}¼°ÐûÉÇþúÏ&@$&¸¨ÿ¹÷Œ¡l¬”ð=Ó1RIñ�ò}9æØ#ÎÏ‚«zû??1z&®ôı_aÚùc|PŒI[íÝ:uÐ; ¯þäÇl¿Ñ->k4ŽýæGõ£ñYÑm|Zô�wà }û“ÑHnÑR=-B¾ë™õü ~åm¼�§‰.Ù�± .ÀÃõ¦Mz^,—»ë0�%£ñ°Ê8®‰Eý«G¬Ä**|ÿsg|oÔò±ŠÀ¹zOýÿ¿Ö¬0s–¾zâÚé.¬�ãWN�¶^± ‹„yHk<J­’Ýß{nÇÂE¤Ýh¼
  20293. TG·~æ’ço]¸ðV²á¹‡††zn÷Ð�zdØ,/À)j�l.ùÝ w<w ¬¶?5*F qH|ö<f7´[ÿ6Tõ‰dªê“ü„õ©¢×?ìC8­êSì'€øN
  20294. #½0”fñ2^~7¥¯:
  20295. œm�ŸíM I�ˆ`Mö:ÓŠH¦À­ÏF²Ø9ñBä§Þ:ïáŸýágŸ÷ÖSk·ozíØk›¶ó#åSæoŸÌ¨oc3¤€„›¿A¢™'Ó¹m×¾¶iÓk×nËÁZ�-ÒyúZP ËÇ= Uc™'…ŠÊê¯?&È�èK¡—Eu£lÎ;éª÷><�v3t{8-Ù|Ã'
  20296. ø«eêøa~ÖìÅH94²Èx¼¢×AÅ-³@üy bT4@0ìb#]DŒDÓÑ“½lj€DSio:AgÐàöÄS½ìP z:„;¦¶-á|yH"r ·¤{ÒB{\ˆ´5RLi‡6öAƒáAÖæã–tM¾]èè�ÛßtÓá›øaøRò±KºûàËC¤­!Ø1ô´CÞígCÞ샂ð +ù¸³1EG·!ÒÚ€ÝXzû––®î¾éÙ›nz–µvÜ@±x™�ôíô›Ê-#i^ Ïxñ*�$)®ÎÀWü’ã¤=ÖO\fùäó€[WŒ´“öþX~V¬?«ÿîþÐ `Lei¬::v4Öß$?‹=Rþó˜•a#ÿc¤÷]8YåÝFJâ™b&'{%LCìEÀÏ¢­‰Í ·Cf�]Ç^$Šù/ÍùïÒfߪÞM;ÀÚ;«óÉœ… ¥°Ê�„6ù°CX�ÕV¸¥À§ð#êÆX~ FðƒÚ<ç :þvC¿¯cºµyBpLvŠ£¬�Ó1ðÐF”v#ß9†
  20297. /êö8VFë©01Óà­_Kôí?Êæx�>£}úÔ#€G7ÔÑ‚\WŒp!.@ü¸îü»±bùwÉ¡+{Üoª�Õ­#»Ô�PÃQÒ®nÄ«66
  20298. cZ�­�çD‰¡¥â’Â(. °Ÿº�uï;n‹M}ÑÁ‹Åý?»œ‚ªžävÊtžÉxíêF»�ì²{É+È–�²ù`¢
  20299. ×=Ÿ×" rPÏ€l˜DîV̶ß�¤¿±™•»?ã�íZ@ë¢Hÿä°…]�º[˜¥3Àö5€Ì%O ¨¼ê)Þ\^„�Ñå Z;ú˜>�F÷ºtf›-IºzÓ® €ç�Œyúu�1Üu™o<å:Éoa:uqß�‚Õwòykk ⋜‹}0?jv²«X+ÀèæÝ}V»›­ïäG$sþÚŸº
  20300. ?2ò6ùª¯†ý´YÊI5c‘$óCfýb!¯X¤*|FÏÔÖ^º$Üpº7ïpäí55§ÅÝß¶6[¿mµàjg�¹¨°®¢l>�*öñ KO&
  20301. ±‰8÷Ü�¢:ǰ…o¿êÖkõ¢‡Kåm~™o¾Sä-*4¥E¼}P/ûÚÍ%  k:¡e×"å1AéJˆ–èÂâCAX𴹋Š8= �LƒÅ¢>°Ü±a¦åÿ—v{ä|K.3 ÆÛ×:\B¬xǤüwðºå˜bÉeb€Ï<n­/ñN��ç…jN¶j�OTQMâÿòû‘ßÕ§ îå±gð�[
  20302. ×¼1®ÏJò[H*èd÷ÿéØJê(�R¡Y}äþ¹ÈÒ˜¤c¹hC;øay«hŒ�&ŒC q;7/SG—nÉÒõy'^óûÜ9w×”[¶yËÒF`4;ëÆupX_#��6Qy'�xCØêq/öQâ€P&ÑNè§t�ºî 4pÞèÁéÔ�qD÷2/عÀÌi=õµ­ÑXû܆ D£A�<Ûú½-�®>>Ö1Û¿v‰HÅ?äf¹›58Ôó †þ%Í6›$ɲÜ'p¢L^H¯âXÎbpI’VqnÖæ¿�ÞéAé8¥åK”g'i‚!Uz†áSEšªI×ßûõÞ5Ù÷ýN=ñ»ûhpÍÞVÜ?¡›(ìEÅ ÿàš½¿¾V¥³rûÍ?Þ´éÇ7ž®ýõÞüËV£Ú‹‰É¿âµ.´ãOø¹Ü;°÷•¤ Ñp¤� 4ž�NéRZm.–OÔø> Mu¾�L'¬Éj5©ªâÓ`;´Mt‹AQܶM„›ïôyëVí™ë<`‘’ $m)Þyš¤Ú³ÑX„™ÛDaî:ÌáÝ�ªšq»1�JöFq³15¤ä-Þl¸è\ƒ…3‰~X¡æ-2pFÿDðe‰éÖ/ñf!¯è2®½iç:à“=Ãhýà{ü%Ü{t…^€�¶ *ÄPˆˆ…ðBͽ]îÎYÓD3ÀØjd úÓÖÔ*æw|âê¼GLϽ}ùË‘k7¸�ÇÏ=0×ä6„o¢z*­ž¶âzo‚ð1~Jçw0ý0SÏÔe“Pw%¤”�#@BJB À  %Ùø+„’ ü'¸½œÀ;¤%!&©§ )ðHÈq î7fÉqöH.§Žæ²ìÐÉç�!ØEÚÇŽf³ì‘,ü9Õšƒ$9” æH{~iž€Û ŸZ³ð)O|‚�!"‡üD.K‰ÒQ a2Õ
  20303. %©£š2WŒ¥É‚\ëŽ{é*™õB{7â,˜9.ø'ew U^¨ƒW¯�&Þ$»r9¼µçrcGõBôçwl¬¦òÿä’lö<üÑú¾™Ê·îSQÂã‚…ˆ�hì! i¿Ñ¨vãîÎJ :³Y?üñ#ù•¸_Óm4²ûq[ð‡ýýËûû }×,¼EóõA{VåПºˆ‰œ®ÎP|žDöåg©?9M©ÅÇId?{¤)®ûÊ/ÂðÐ /\[ ˆ«JùÒ�ƒ¹�ë[àœf4G>ËÁÌÁQ€K ó^  Œm×â¹ †¦›O—Çù -7wê]ËÌê„ô<ÝU3jÆ�,ÄÉäˆ:“¿Y“µqÅ~ 0³™/¥m‘¬Åµ@CŠ—CÜF€q<·é’y¤xËhúŒõÄ\ôЦ0=—RgYìd‘(õ¼(_ð2’¸ŒØÉÊa³‡_Ä{p·M …T*¡‹0žU­”T¶˜Ù!³if$ÔŸÔ(Wâ¤q¥RC:P a3=b²Ñ rK1'-»{ Íö•HèʽHý1Êá'`Ùkϯex¢$’¼.¹hŽ{܆`¤Fé¤ z›EÃ0®øc5xfMÑĆä�¾}ç�ß¾Sýï•S¦¬œÂÂKÅ]Nëf'ÛpPιS§`BmmHÒv9Ä4ሄ^ìm �D $¡˜Š�,€'Ü„ „ pìWÉ­îgØdV/L¶;–ª×MZL­ñõó“ê­µ¢H>{€,ßë�·ºÂΘ±ªã×÷Ÿ쬷ΘQSo ÛlÜûùsÉ¿hýùÿ?A¿ˆ2qªÓÐ`ÀÝ5 ƒ€œZ€�&*ê“X1L5:Ù6¢ë´öÏ‚+ÙÝßêO]ue·j�õƒÅ¨%?ïÛ¼&ÓØÑaW?{ï¢Ë­Ë2[þ}ÉÒW?ÎÞJÄbòÒΙ›¥kÏ-\�»Þb7‰sIì¬kf&ΛÜfê¹x~¬¿·nì™O-9÷VÚçÎ ”~cˆW"È—y)b\)„2MrW±Ëfˆ;MíóUë7¥ƒ'[¯ÍÀ�ô¹’-c/ö´.¾Ø¾”›æ¨uÙMèþlŸ&øš.Óõ9ÔÛ) GêÑÚ!Ã!W* ¸60CŠÑ„#”Üq£ÅçŠÔørqŸOÝÈKÁZOÎWqù,Æ8Ì�/Xpã�ðÏíTšÉÈ‘±g<>¤)˜‰[J8£o`
  20304. ;úÔS\ÓSЧ¾Æö“Àá“%š†h~ðÌpÌ|J˾F~Kì=E0Nî¸QƒXßÇ©ÞÇ*çþÑç8;D7öQñÑ1ªµQCÃ% *E‚yëy}ƒ¡ �UG?>üI`æ>Æê÷'Ê6<ž+ƒí�ÓÄÿ3IVògÕÏ®�yOŽû•ªQ$WBv®ÛH vî…¢è[ýÏ� 2ÿ+ý£ �Ê'ÿø6N¸ß†<úÿúžÛÇîÉ•¶¦— ‡2”ÿSñ娚9ÿ³X†1 \•┣ûý­Ìdf>ÃBŽ~¶²ÊÕÍ-ˆ”t>¦W�]Ùìp©PrœîZ[±²'žÊåÈ+¤�ÆŒâµl†9]ï8qã‚ì‚C§é!Œ¶' ë@AA¯OuÿШäª
  20305. !?M\…JMÍ­ÍfÇž)«ß•Ë=õÔÉw?A•N>Ï–ƒžË¼}újQ<Ç�pÇ ^Îñò(»€}¿±½½1ï„+¿“2Çàq F²÷4R¾„´iHÄ�—îITër8ÒÐß^§™Úù!gm­óä>¸Îÿ�´Î'á÷ÆÞÚ¸hÑÆEü`­sÌŠo¹ãÎÚl¾ñ…Û!õ(9~í¢ ‹oÐàþ%#ð)þ~ƃúj$Þ@€Õ”ˆLp½GåOa{é®Íß¿fÎìé”)°zèªØ”Y×<þõ¯ïØñõüýÛ~°ùšÏ^õŸcàÒËš·sóÐÞëæ½ºã·Þú�²ýÂÝ´N•RUâЛÕRÔT”Y%8ÛÀ­¤òKÌs3Ãq¿d]^©QTb' œÄzx¯)îH´“�FÒ©P„mUÎZ¼jQ&œX¹ñÆ�åoŸß<0¸jÉYG¼±ŽÔzê]ЇþÙ$8cÖÚ&ÖhäyŸÝ¼õšÍwΞ{Ëê9^˜¼æÁsfß¹åšm[våÕÀ‚“ÃÓ£!É(ZíAs�ÈÛ§ÇÎyÁBмÀü•Œú8RiÔ£B­g6ˆ{ËUm¦’tyW!bšpÇ®d nÅ/yÌ‚áʼ@vÅÓ/©»�Ô%Çcý¹—öªŸxñEn’:üå4YÃýõ²¼,yZ-ækr¶—úcH&öÇ^È©ÏCº'È®'^T®Ç÷“5ºœîóÐÇê˜r)(Š(IèÒJ™U׌&#€ÝŒ! +YM.ÿJï«EX^|‚ÂÂÞL–«w@´�Ú¾ìò¡ZsgßYÓæ´ºˆ…ü\ª�ÑîµxêÔŸ ²Á¿xÓ„µyºý—LïõCyo™…’<ñQÊO$)÷W�6¥m%݆®r݆Õdõ”™‡Õ½Õð’�{¡üO‰bþ�pÿ»AE܀ʌÞg ÐÎÎý²ˆ¾¤§iòï‰�œ~ºA¤¼¢™òßO"mo*î!ƒÓ[TÀœŠ�òm¬dHÑT1Ó$…
  20306. ÉPÔ�4^ÌûsfcA3·ß,ˆêXA­òPŽêbâksî�Yà†‹ šyHˆhýPäÍËâ+b‚W�=}¥Óû;¿¾‚µ¨"Z&x<SySVYíÖ&=ªþ4Ÿ¼&‘è1Jä5u~�è,Ó¿¤zïeù–g^QB\/¡PÊ„%�+p‚re|Pn¥ ¤T’†cZ>?¢çï–eòžV"_[‘çQ©/…5Y�ãá|бàqI£ö/\§Ó9ö–Óçããªdi°ÀEBh$ª�åvÒõ ±€…Ó wOL¤ …êÐúfp�a ¦,?HógHùf2¬ˆµRbî…²L
  20307. v >ÞUÀSo™–°^1/,šˆÄ“¢vc«°Yò GmôÀŨ�Ô~¸Am�êzª Ë?Ç/¦’ÿ4ÔÎ0‰�‡yj̸pák²î�¶2«öH
  20308. «ÆeE€RßbéÅÏ/"M 7ò5u²lÂ[ŸdrC‘&YÍ�Ü&I�
  20309. `!>pû˜;¦õåJ-�b�àÂ--.à´VäMÚÅ4>©¼Fj¿–/î5ÀºÎσ¶¯£²ƒ¢Þt5}Â>Cþ*›<'ß÷˜dµæ?,cÂø¾üïd�Gfëåü¼2Ò�0w�ã6óó˜òL¬h"ÜfõKä¢×òÿζp;ÕÇÕǿ϶PÕd¨cÿ©1¾EO‹šÑi¾%ÿö÷ÉŘ(DCäâïW¬·‰ªõVé2š„I)ˆ�TöiÃM›êµøF�TÛz¡0ëÁªµù›U¯õ Sµþ7V¯ÿ mBW6;›nYZU¢zSÏTg>(“h……îF"âÞ½Të½·‹¤ñR]çßûLÛ¶™|¦ûLx‡[Õs,'NU|®€¯¹Eà<ñ4)«R–‹Š pß*ЏvU#¤gÄÃ*ñg˜ò·jÉ™*=�~܃¨ìA‰SÜýÄ“ÎÍîA J‚Hwä3@Nur®bw™°�ȀʌxÀ}[ƒ`ð7º½’‹ø¤Z§ËÊ›tPlh Õ³¦L.)NU‚}¿¥¡kqÜ'ØÝvÅéõˆFQr×·úŒ{ˤóS]óZëLùÿ(×@ã*úSfÂ^‚–+uöPe_k#Žñ•.É8éÎÉ‚%��Õ ¯,�…ª@•›£TK£¤Ñ…º§Ÿ
  20310. t`‘ß‘ˆXÔAD;¦‚b†¤�|pßAºâ7ð}qÒ¿é2
  20311. @Yû`Ý~¥îÁµ¶ŠˆiÔ¬K½û0jŸ÷ÒYÕ( žøÛR„úÃÓ~^ˆ¨Ò§8ƒ>…è=ãF"šËœA[å‹ÓDqûvQœCîŠXõ|Zõ‹sO÷…þ<NǦûcêPI|žèÛÖ‰¢ú2 Ö�ë Äů�Ð1…úQ|îëŒFH\[ îÏT�k˜Þ½$âÕÔ3’½ñXÓÙ—ÿ5ÿ�Ë®A…ŒqÅ_»írvÁô7óßÈ@ø�vð2Ë€Ïýi%«Êm‘ØŠ²f»—�P¶ú^{þovvyÚfVÔw4eåw³ ""Zd¿[ËÏT¤CÊ­"Ù›!CÌÆ›ÿåØ#^îÏê
  20312. ÔïZ¹’�fRÌ4¿¯Ãx»�p¢VërSK\·ÙýBÃß]Q„
  20313. ÕóóB~#”V*ØpÈx ¾ˆ^¼­(ÜÒëo/`D«ïסÍ.Ðô± õEæŠOWTvõÈ·6 íçÝùúM^~EyÖló¬Í /öÑ«çÀÇŠ¹lŽQ˜6M«©ŸŠq”":}H»eaãÞÀ-EYˆ"­þz"ôÈ�VKF5€’‘Ê8ª/7
  20314. tÑê�Dè€n#D*'—ÀÂÜ^I×û³˜³øµüZ}pITmdL%÷7½@¥CÞ:Fþ¢By%òž�Æêõå’ã× ¯KS<K»ReëÅÄ«ÝsoºkøÉ|È�r‡à^Ósºuí›~·ú–Ûïw“N·_µVêP Å6;‹YÁ\Ì\ÆlÐm¦ñÏëI£ì"�†ˆÃRð
  20315. 2�·Îts¨0÷ã^~’áõµ›î
  20316. ÑÝ;ÄgELc„7¹Áãùž"û�–È÷<^‡âí¶Ù$Þg$²yª¾ˆ©s¨ÙL×´©Éä$Ö �D�> \ä/Íf.ÁÙÕä³F;ÌæÿkáPñ•ìb‡d³z7Ô�eͶ-6‹b²y¶ØÌbÀaWjnh7YôLáFû!½4ƒÀwßâssF�Cºn�h–Ì_0óû…’> á±M½Z²« °ò‡€ïnC휌 ¬ÄÃ*#5/OöUÑN\(3oÄ@…[7`‹Mg8xÏßg¬e;f\yñ½—|fÖ¤©Þ‘¨Û]ëi5®¨q5q&Ö>¹'ºôâóï¼áå°ÑßÙ353éükÏYê­‘œß=WŸ7çâ+΋yxþIÎe<¬¾“ûÂP�Ãh±X aëêv׸‚Ó"ÆùŠcJcú›oHÌO†Cu]³L5‘®«�†ÔÒÅk““¦ðÑ–†ó¦õ„§]xóЏæŠ ˜~ÿ#ª;!‘ÞÛ)B58¨/P¬í õõHšÑF#0‰°B(ôÊpì}ÑFstÒÜM|�¹ÆlçˆÉ)]tϼ&ƒÝ–™¿,ã™—nt,¶h[ÐäY4ݬ$žwQ×’µ,Ë ž@‹Ñà�Ækåš`D”ƒg]rÿ£™·|êüY}ÍVq’wRC*ÔŽ9[o»ÿ©ç§×Î�ÜdðX 6Žš&Í=ÿâÍ}—íß°À/*Í�\�Ë”)³ƒÉ5gOò˜l�Ó¦¯¬Ø}ÙÙ1:>OýŠYÇ�òs(•p6Ÿ‚[‚�B/tçˆ�*Ì -n:±½ <Цð�øè)Èú ¬á+�Þ°~q_}ýäÅëoxt>L®¯ïƒV– FßÈßG¼@dÎ9ׯ[<ñs/¼í®Û.<7î±ðÖsó§B²Éždï�B'·wX‚üœŽ³Î¿äü³Zéµ£üáW²ÁÕ—Ù>2²½?í2ȳ¯±÷8›ç¬žÕÓ={õìfg�csC³ÜåœÕmãå –ÛÏrâ¾õe ¾#Œ›‰E>ˆòü45µqo:áJ£Öì¼X«°^ioº“P,x‹µfµ:/y ñ¼¯n9§�VóÑ¥S§7=éºòîè’u-í\¸%•KåϦUv¶Î¼,»â³€„íÅêZ=Öv›ûâk¯¿¤NÑ*+_§.ýÚŠŸõÖž»iýšÚƒ=w @¥æl¢m˜röô>Û�O­ÇÊo,VÔ²’×ëÉ�z &:'ÿ4ðÎ5¨Ó…!êÕ9èpI 0@I[ÍPU""©sÙîInv‡R>ñA¸Ž˜É9tæ$ç¨3/«š³|k£8y´iî¬�šE û“ßøÝc8óÂE×!Qè\Û‚} %Aš�f4ì s*®A8�¦‚A³Ø΀Ü>D®�=5uw¶Öõúj³ênG �z?2”Qª/I=î˜ÛfýHýè÷4Ånºå“]™æ¾€ˆYmðªG"³É2äPEÝH™Íf¹vZnž<š—PiA_Òq/³ŽPÉDÕ¿ð ã¨$$Ž~%NyhrÜOdM\‘-þŒmŸ(ˆä@\³º�#½„ÔêÆ¼“ÒNïçJŸOÔåã>a+ÿ µuJ¨*(%�¢FP„JÄW””¥Š¦½ø–ßð‘,$)�ç÷)åÿ˜ú³’ÿê}×ÿ˜
  20317. B\­–àÏ_»ïúÇþ¾w¥Vé] 0†ÑT¥OCÊQ}è¾ë5±ÐÂâ{Ho*ä™;;õ葞ÉrǨâêõMÔcå5­ÜãÑ4S
  20318. : ´ýMŒ‹îæ›7�(kY:멪¸•zÒ`ˆgp ›J†stˉý±v'²¡¦eðÒG^~äÒÁ–içD›»1šš‘Š6ºdA Ø@'N ðŠæ±³Ö­<?ÓÒ’9庳b¤ý„É©´EÃ�:�Ýh²{ëáh«â0ž vÛ§˜Q~�{©"šH”ðƒßGQÔkl”<ü:Ê›^g£/ïó ¹_i²«´‰ð ó¿ÐÅPœ’›�¾®>N.Öô?Îf²Â…Ü1˜ób•ŽzJý¡±D ì¥V
  20319. o@7R@6Š<Àþ%IF©Ø0êmj= �[Ž}N‰âÒüÛŠ¤57¹ÿpò©yŒÄv4@<mЭá¿Á9TÅòp?�ÚR7ú�ú¥Š0Ò›š´ÚQÏG¸[j„¬ÐÈßÙÍziß÷·b“´ú�~ƒð/)wC?â±ï רa¥-/ŠC®n“™û.Ä•ÛH j63¨€’иŠpø‘“KrhëÏÏÂîX–êIçÆŽjß
  20320. ¿‚o­è1ÁÅ9
  20321. ŸfÔ\Ž~Ú:-¦ÔÑ“K �4©±7BYÍö‰Ì†Žy%›DC~e“èmÀÞ@Ñ]Ñúÿ%Àrþ©ÖÙs4T® ™Åâ®ÐóÖG-âUg�õ>ÏíûH‚OpVÖBì�Â]ô{9&ÿ^6¹|Ðm’õå _PLLI7Ç’¦iÊ®õé "'T }Æãï? 4»ó¹›…|‡¦[FÇ­útu/Ù_y;Z”¼?Û£H†K®0W�z¤èc#¤ÙÙÐ)€Ž~.rÁŠÄ¥+ÊB‰°Š±&J°“ƒG 0ùË[ýÐäÙü‘.Ρìr·ŸO³kŽÝ;VC•‰ oX¨ úÍöKÛ�Sß³ër¶t‚åí²í„:z‚X\±úxm‹ÛJhÿ™x¸ðÐN÷ÇhÛ5¯ ¥Kè`…;ydp.Ec›4²XžD<-´llµÛip.»^ØâpÕ×:� Ùu�/î»öü™.«ÅY[ïrl�¯_æ4¸šã½ÉkzÎ$~Dq…]7/T_<è�µˆ¼¥Þã4K§$ðÆ–˜ÿ ™»ð&w“«öä· †ž©S¡¸7ÿÿµ|K‹^ü�Šø›Žâ¯7íMsMGýáùçÿ°èhÇÃw”…¹Ã㢴0]?²´˜fjaÍ5aŽi�–Цè6C¼2ôno• ¤“Õf ì=ñ–)õd^Ëÿûövï qNcãÔŽ´ûþ‹l=uÙáì]?;¡fâù-EÕ~äìöáÏnÏvøÕ}5�¸Ï×%»šë¾÷ýú–ìèOÕ»³dë�¿=„Z%v¹Žè ӳРn¯K— u ÐÌ“*J¦„ê�#1äh„u1HrìÐ o»ý}ÿ”õõSZâu=¶‹îw§;¦nÏ—UØ ï‚Äãä•ü` FÝçïȶŸ½En?»¥þûß«k&»¢ÍÙl9 Yõúí�d«†gAâÃ8NSGáê³ÊDŸ09M‘AK{Þ€K3ÝŠ„­ª�[_]’%W4zÖÛˆu9é\~åúåën3ÔÉê~ñÉzir–„ñé Ååô¨“X3kâ`PsÄêøÜÊüâ’nÇåïÚ=mùºÁ]‹ÔƒJËks„ÍóTÓ9d™ÒõeYN`}ž¯/û]U#Æób˜;R̨“ÐÀt,¢ÚlŸh*ö¢×#JB+
  20322. (´¡iGx\}~IÖ³F·Ýv@T÷Ëu†ÛÖ­¸êJ¨Ú
  20323. ±­÷ÌÿœÃ
  20324. �@-Lœ™¨áwäzÃY§îg—”úÓâw‰`wx-ù¿Øö´(dÙ¢]ƒ×ÉÛFÏ3_÷øX�cY’mQÔƒç�ßWæb¤-©ÐF ¡�êKõ5Õd-0bƒâ¨ç�ƒ—֨“T+æ‘_ïZ„xÜcËÿÐj*`ûûåˆ}�|xâ~¸LÇF�*ÚS*oêŸMتêA­Íó–²ýîTž1pÇ7µ1?‹R t>éó»¶R'"ú�‹ÀäÆÁEÂyÓ)oƒP�7ž”æ‚Å%«ËÀ$rÃvõ¬ QŸ¿û½eE”ÇãØç”+�½»nùzlÝåVlÝFrktÉÖ'µ¦'?R®„'ZƒCEÕI§Ky» gaÎö0þ‹ü¡^áê} pE;…õKq{ÒáT/ù?ïi"%íÆÞ1ÎÞ’ÿbñ-ÞÔ¾qÆ›Ì˵ƒÛ+ ¢Š8Æ]ÀÊrI¸Üú”Ú£V•{¬dȪÍœ¹\è•AÍôÓQÐvOÄSÕõ]0.ÛêúN¨ìX9s¹Õv¡b?OE~ÚFPU}ož[YîKårÀéÖðñA¹ÃÌ“U%‡�§7D€w ýêöˆqÔ bá/í‘hÈ íáAÙ±‘hPbQØ“JB8ÕI ºä?áI%=ÅX‘tÜO¥;¹(P‘hºLìd£Ñ S •'hÿݱŸ>|þùÿT»‘¬ÜV?Ù,O•Ýç"\�`ª7‰ÕãíÁ.‹2ÐçÝ>Îæ¹Dá²Í �fÎÖm•g;œ�-íö„ÌCŒ'œ¥Öéu¹,»¡¥Î z—A`-ÇÙ¼¼Á$Öx vc“Ãk2·¦[x–p\cÚbüí“l΀ÝihµsµœÙivðaÛÃêM,gĨlñŠÁMžà–zÓܳ›7JvÞÔÙÀË‘V‡RWÏ‹N³•ÝäoÎ4‰(Ú-„µXB^ÒCl&Vnô±nŸ¿¾Án D4[k6ž³†›ìN�×&µº}f§“3Y¼QwÐ@$“U$(Ǫo¶:-üZG¼…#&‹Å†/…} –?ÄßN}Æ¥¼‚7íA!M´àühöøW>£æï?iX²pÊýùr›¼A–Ù¡àbþöó?uϱ›Î¹³-hñäØíëå6;»êSÿBõ#/‚µé@Ñ¿J Æéþ
  20325. !%Q­)”ÀDq:{JI^Þ‘Ë¡õPY7UGçÊ(ÂÀ¼Ÿö¡h³?Hmÿ¬ÈÑŠævREˆíHŽôçÔ=ÜN`P)QœŸ¥Žæ€G9®ÓFM‡ÖSáMG§õ@2¤E‰$Q
  20326. µ$Çs±~ä’TkNµ"×9®Õ†8ûcêF¤ñ^ê"?+GÙ 
  20327. ^÷*¦¼gUlFVx�ªÚU™poC¨°ž.XCƵ�Š×µÍ‰×qï‚Kê[¯k[¯ãöK—(l�À;ö ºÓ¡ínè�%^ñ�RÔj­,$)§ ø·Êì1‹‚n.¿�ßG÷:CÐïfŽÓ(ßñ,˜íÐ;š„Ä´©ôR—¿Fëž_~ðÎã^øø;¼ó¥Õ«¿D¾ô;6|/jGGSSG„›G’ӎļD¬ñzbRï¤/X?½ñûŠÃíñUÚÇp14u˜$`¾ß[ßœH47õ7Iò~¥‰~Iÿrêß™sùù#èŸ6ŒÛ+‘h„ºe€Wò6@wK“̸h6, ‡1Cµ"à�‡·æ©Ú=­mÎèñ�e°AòÓóŒâ– =¾àôî�@“z—ÜÐÐá² ¦sÒóls³]ô;kklµêÓr¬^"sƒ¡é�’Ü>Õ&Õ„¬-[×ß{ÅJiÒ´9[‚ݵ³È©¹-ç]±dÞ¢µ²cÒ µAnµÛ¹ƒägç}ê’‡¼»6hTï–ëüÉ–´?3s�ÚÝ^k­úŒLêcY ˆ1ëZ²´n[÷¥ƒbÝ´¾E߆ŒçÕ¤Íw¬ºàk3Ôf™•åˆ>† þÿfMäÕD‚è…Õ ¸aåñDðé �~}&ö¬Á@¼£5�u gn¨›OÈ¢<¹­'` &bÓ¬¼±-6à÷®;ƒÁX÷"‘d*²a¡wÒüÞY”¦´vÖÔt·L³ð¦Xë¬Ö¸kñU�ß©ø­ü·aîèÔ=HR_Ã@¦£Ä+j“2—öT*‰Â£è%ìÓ/͸oƤ ¿±Óyá‡ê £—»î›1ƒÔ9/7›  þ~Æ7áýŒ´_“ÛùoÃÓêÖ+‚þ$DüÒ¯sÞIH�:çr£ ƒð ¤yiF:Ýå¸ðïäv�÷ËýÀ(Œ¿d®O":¦ omØÿÅìdM”8åÒ ;¤žZ9uêÊ©üHCg\›K/*‰ŽýÔ™�g*¾-óIèÑö—±¢ˆ_ÁE¢œ‹RqîR'û[¥fõ?GÕU�½Ao‘vb A$ÿeõ]¹Õ/‡Ô¿ª£o©?|ƒÔ�ÞQâm–4™G¢Œƒ7ñG™83�Ú3+ ¼74‡z*)¡$Ý‹JÀØpDµî“Núj5pÐq¾·“e�Df/�ÒÎ>ÎÛü‰è´à”%é–Ãg‡Wµø¸{…Uóë:g,ênН¸l²¿µU‘\ŸÏt™'Ö¬ñ%ÒüÑE‚«}àòÍ�íu¢úC›èꘒÍܻߺp±}UË+^b'‹�’¯«o(5gã¼VÃBÕIœ¼äOEüm>·ÑÀ½©þ€5yšzgö†}úÁ¥ÜüA”©P-øP/ú€�Þ«�ì„ò Õ6Ì)¡x5/t;1šp“1”L º9õAܳ|÷êÝÑ)ýµáåîX]m��ûókFEéH/ñ4}:¸,oLMªoò®»6]YãMó5¢Ëê0u[›ßyÒ«ˆfVêh¾˜?¸äÞE-A§_iï«�ßÝj²ñ Ô.
  20328. 6|Þå5’`#ÏÕZ-÷svÁfq˜ÓŸ�›íês·Íš>¢ãÚwêÿ î7C—å{ A“ú…ŠÒÖ]B¾ëÕîz,i÷H'dù„äávÚ?’`E‡•�
  20329. üx,‡öm±¸z‡`ÍF[ïê2aõv‰hp™%(ÔÌ’öü¾Ê‚ÉýÙ5Ô¦;GÚÑŽh”í¥²³¹\Þy";|"«Ù�Ê–©�rx‚zËsèP‰HCT×v¨P$…éõly}‡iyhvMŽCù…r)Ý#Ãx®›¿-Ü.(ót%fu»ôÊ€(Û…eÁ•UU–oâ²
  20330. ¥p´ÔqeÑˡ啗¥sòy¸iº X–æk¥`É>£X¯@2Pø¯. ¨2ÍŒ>«n„|‘Ê,/4—£Ôþ}Âò  ®ð?Aí¸&ÍJŸ†Åær§+�­ðÃÉ��ñCV“]{ŽèìZÍ0�- úùA=–ä
  20331. Fø®$ë+”Óöñ%U¸Z�y¢­ÂÞ—Ž°Ù²RÕ ·Bƒº)¿÷¥ŠâwT8úÁ(áaÙûRÁΣ*-Àª—ÆÙs€r5v êÿ!^tZ:/ÇK,'±ÂêF  9€»=ãÚæGˆ<�§¸CíÑu“"$º-¾î²F÷óS2ç(óÉF
  20332. 0Q©Ü+X�š�ðwÈ,»]=b÷h[qžB‹QI’ þ§ú;)"ÁÅŒšÓ9ÜÒ2ãšô6Ãr?çÓ}lŠV Ç=b¸[˜µ£j¯¢4€Az”ó™Œ÷KÚkQ?TÿÂ[%“É$°K¢Qõ-¯Ñl_@l/ &;ÿ˜Éì°¨ËDrª?P_d£E1ý~ýz—â^Iº~b°÷§ÔrÜè¼e¡uмf¹­P•/ÍÕº#Ü Eÿ+šS\ìG‡-ØR4¨�« ‘S®óÖS®óVä¿‘; �ÎÈ*`ßG¸é*5'Çäûd™Lº
  20333. ˜¯ÿ~¤ÚÆê à…5¯”FšÒÆhb` 
  20334. ½ê�œú³Â4€ý[b$~¿Gç£NÏAX$òÛ÷ß~ô‚ }[»‘Wß}åê«_Á‹z×6múÒ&~Oñ%Þæj/árÍ&|_Sˆ�ÆÒyã<ç�-â*LÏ›ø«Û,©·JQ›z»Í¤œð«·£ÙÂÉçÑ|’V|�GVW~öË<mbl»¶©œ�ÇËÆò�B¹&Íö©Ì­jš šy¹ì\r=´æñ 'ç®9á¶Häf)šÿ¨¬ÜÇÔ…rÓ w�É!;;vs©ÔB™ 7Ó€ž¿'òkëå*«úirµ¨ˆ÷Šbþ/¨Kû+Ô”WÄÑR™ìO �ÌÿÅh$!`‹1õ[¥r ¾§¦ûŽ(›a\T™R²šòü¸"Pž?]Yã;? ÕÂÑ…ëyKRXâWòOCzó‹£êÔÜ©ÏH�jPnýâ[°¨å¿Š‚;é͇Gó“ËqÎÛZ.ÀA¥ý.*�@/¡)WQHQÕâ«ÙU…L†2^…²$,T=QÞêå�(J~ÉBI¢UP‡J�° ê=êWC@Ûï°‰8&¢~Dõ«ßW¯æäìÓk‰[½š<ÅÕ�}ô.÷"S<#Aë«>Íz ·ý ê¨
  20335. àH ¯œ†ó³¨EÉ ¤º²Yîn‘¢çH4ûr7P?99­Îæß¡|O-µ·5³Š ²%ã4µ dzêO/4ùL_Pså’TÔ>¿LQ›ÄD(ú ˜ÚôùJ8òÿFµÏ+)jCb
  20336. ›MuØ2Xc8$ñt°}œ&<?¸ö9lWÿ¦~½Ò¿Í‘åÛn“å90AÁ=&W=sÇÔ¿À—œ_V‚ýéÓ}¢?køU(�m†øutEÔê*¸
  20337. ÚK%ò õtñÜÕZñp¶J³Ã ŽB›W�·¾P üA lµž(ZÍL�·zF íýZ²}¤®/‡è¿40”l™V ¬² ‹i%L·ÿ^V`‚jpŸPäßËžÝ×5QV—ØVêk¹ÐÅzX8¹ÄÏ^s³�Å£W4U*u´ }ŽLÊã8æFþ ÿ ç~ê3·¿B›"Ió/.·èO
  20338. =7B¹JAÓèô’§�î©¿KÒßQ-¿|—¦’ÕVw|()8¨éC™»¸ŸªÏ%Ê´¥�To×lásù7*ØÂërevðÙ¢üáì’6m«´“Ç– £â�ÖC™T¾ÉpT'Ç‘pL!èjR C4·š¸}aºöSm‰°ú[��%¨4a.ÅÑì²¹},—LŠìõBý¯ð=×:Ý�'©b¹�ë“ dmã¬û}V›š©è‰Y,êtúö;¼ÜÙ9­ž¼ÂŠ›ßï� ³:\ôI5ˆ–fDAû©¢™uìIœÉôFºH2  @:2 ß!°Ô�ÌŸjõ-ÐýÉ@ ÙµÀGŽûðƒ“ˆ`vKcw¡™I“lar�º%l›¤EsÛ
  20339. ÑêrDe·ƒT¨žib𙦷@³…„d4�¦›•ÇB’DH†¸ Tœ. ]‚ÝK¶*þËÕ·sè\m«Fá:�:£”4v»ÏX †€<¸;‹Ú»r—£þÕð%—ä²Ä6ðaꇷï½ýû¹Ü¥GÍÂàÏÎØùÇùÇѧ¬ í|°â¥g…уÁ‚�†h§�vìqtJ÷JÇÖKÇîÛêH¸^v‰Ž½œ­³gpñ§.ÝÖ?뜸ËB¸ÿÞã0¸^q÷8¶|fìS[¼t—ÔåØCx£Ò”œ¹¦þîí׬˜f¯Ð¹
  20340. é^ùFB‡
  20341. žPi©ÐWFpRßU
  20342. ©:̓ D‹Œ}ãÉÍÙ�v“Éïþ�ÛŸúÊ}4ÀÙzú/½ö—F<„�«P莣\‘ÈU¬'c?ÐÒ4›sJ ä‚Êçjj>§@€«Qr¼-ÚÜÖ¤þÎU_o6ÇÕËq7õP1êŽË¤+ÎÛ¾rc6ªI
  20343. ë\ ê(*v´2¼�4Uc(Aü Ì£9ú3öŒæ]Çz÷Øü»­;0'¡=äÛÑ*,e5Õ6ª»VÔa,ÌqhÌ*ôë²P@wȬ°G²¸/ÓOÖj÷|ÌFImÇ #Pzë;J¨wÊŽ}ž < ‘ú ŸÀz TŽ�út‡ˆ~£`ÂȱGP%;? ®5(Þ(u¨”# ”ÇÈvÕŠIÈñí#9,?G�ù¡¬b4K]ýQgÔŸ]ÒE[à phʯ§‡ÛG›¡à+` ÜÄĘp ?Å@á>!Ú}"
  20344. ÍÒ½¸Êr=ÔCÀD5ï 62¾¦ZYêèå��?à× ³ÖiðËA�¨‹
  20345. T(øE U•Ju³;"}©ØÕº#–ê‹Lˆc¨äÊéÓ—£VäòéÓWþOû›&ÙCIÔ™úÛÇu8*烞QæçaðQ^*z(¨L­|JÓ�‡½^Žf©p1¿ûõ„0À4~œ�Cˆ³Ux¨Î*ršV²*�N9Ï€„׳¯Pðú„Å«sñÜp¶ˆœ_LŒ‰ŠŠòÍá3ÙZ"}ˆ&ÓrôO¿|lõêÇ~©ÝÈk¿C¾/Wj><ËüSÅxÔÀåMêbS“¯–—�úg(]½J(Z#Ÿ†x©\$OC6¿8-àf:{êƒS�ҳ蚨oý4:œÓËÜ)Ž¥ËWb¼"uÅiu·hŽŽ~½dãÊéì%û¯¯ÕB�±ûóAM
  20346. sÍâÙWH.gvÿ%ùç4ý–ãvø+¸œ§ð=¿
  20347. ðÕSêG‡Ï‹jWHWÀæçu>…–[ÿB{[çuûɶsÕ;la›z›iñÕÝWß­Ô\z½ÆåCðäƒÛÖ|¥ž\f·«Ÿ×�te¿º&ÿ¹ß•+Býk�«è/t�¿
  20348. Ï CM�„ /@SÃ>Tm
  20349. ±G`vú`?þ�ª£ôþÙGÆ(Ù,zb" Õçðe¶¸üAÞ×AÞiàÿ»´š7ÐÓéQ�Á¨R<Æ"i X ¶:¸IÜ‹(a‡V¾öœúã¦Ëç§;4Réù—ó]}—Ïœì^þá«Ï1ÜvîÔµ�þÚù—7œÔÊ=Ùpù|§[Jοœeíµ{)­eÜüÝü#Œƒief0ó™KðJâq²"*öF#¬(©¸GjJF�hŒ¸‡Xè#ш·âµ�£ñÝ�kš¾—5EÔR¤PÍ΋ㆠ^p C©eoÿêíe…€:•ç¯{6ÈÛ¬Íï5ÔÍ�s‘ÅÆ™8‹XÏ K6×ðV[�ç=çÙ}V+�ÿhͧ×ÀßJŒ›lÑâŒZZ›5ÈßW‘‰±”;®þTýé†e«V-Û@ÚH†êIðÙë¬ÎD<Í™[Ç)Ö�ÍÀßÏÖl^bÃXeòÙNN±„¬"K]£@Œƒ×bŠ©šË?.æH÷H
  20350. gzXaÆðÐÙ’Aîˆ}MO¦eýXÂüH§N�r ÐóÚŸW¨;ñhtñ»gttOöyu3=–Âü*פîÌåØ¿ C ÂFGsh9JîͽZ°-”k‚’]L-Õ~hÎii¡.ê49ÍQr5¦ñ½I,VÝ“ÿ…^jf”»_}Ô,“í¬Q6?Ì5åÿNVçÁÏÕ
  20351. ÞžË�ªYÙœN›å%ezËÜqƨï>ÁZè  “NtñŠÓ1š �a Õ%þž=è yÏhÞ™«« H¸Á—ËJ�Zöš?ý h½vrœkÊÁ@åmÍY`®^insðêF\”*ö|Lœz!/?·)(“0 Éâ
  20352. MS4(šÈ—hðØ{²º™’æñ-î'×hŽæ‰ëoê7ûcCÒžÊ?‹6²âñ’²'|ubˆÕ£@´þ�Ì!³býÙ¡¡ü»Ðf{tzø…1UÒA?=Œ@œáá t%˜ä•‰ÀÌå�iuš“[ NòÈiáD ±ˆGÝT@Š:Ïp<ü(õcÓXéÉÆUm�2Úϱ7z›ÚOòíM^öFÏ´YUfwGsüÁ“#‘t:Â/‰ªƒ•¶Îå~±OsÞ]µÇF×ÿÏçÝ‘¯ž(úü(^È‹Á±?Lû�$ÀSʽ… WzT>mì'_§‚údŒ®ÐÔç:¥Ä�5®Lh;¯H7ÜWgzêgÄZÆÆZb3ê{2d5�Jj¦Ä9Þc+ãù‘\vqzç²DbÙÎôb ©Æ¶�g ù"l@צ�pæQB½b�ýÛS Qí>€“+d �p²¾î%}¯L!“�™ƒ‡òçšcdwHo˜¸Ææ×p€x(Tì¾pÄèxî¿ßp#ê�:dvQ qŸdAðQFdÜL³¦K¤mÒPRËí ¤pU?òlÃëÖ ¯ûzg°-ª‰¶…ÔjPÙî©b·ùG×aRõ¿ú&^qÅàä>uÓ8¤•p&ÃӮф ¤`íMGSŸ®¡®óÙܵao°ñã¡ÜWÜ›Z´aâÌٟݰ·V5ŸÊR¿s2NX ÛqGB  ¾O “ÊKÒg éôðÀÀBWþý)Sg\õÙùêžÓ¡läË÷ö]zöÀ<ß²o-_þå- ø±›ÆA£ŸKMqÓ­!´Ã¦Si­gyñüý¿ÄÛ°]Kû;SêÆT'�ã©ókPqÉæeêÆe›7cZT{~*‡7‹bê\H…?ðjÙµl3•�P œïоwïT2²ðjŠY;Ö�)ºl DËueytOTøï�Újö¡üñU¶H­í¨úœXögɬ,õ�W´ÉÏ¢^ŽÚÂu¶¡![]Øv”Fèç”|
  20353. ã®QGá¬h`(¨# ƒR¼'5X©D§ÌQ ÊqMË6gûc'býúu³:'—ôÿ™®H( „?¸yÕµ¥ú¶Ë6£~.òe¨¬[n ¸ªŠÿ*€±U«yZsÃt 9ï‹›¸R!GÙý��·©�ù“MM$ÚxŽz€¬$]êÓ{ÐÃL<ü}ù�ç4ÞÆàJZÕõê~ÒMVŒÕ•hy× >@u�»Êí šå…î�+³¿Æèôõ]áß2FqO8jü–Ñ¥°WCÿ»Qqíˤërw®‹.Êì�ä„«¾Þ¥\õš_´úü§ãôöyš¶\O¿nÔ)IÍKGR§êHÅ�q”¸ÜIÚÑÅ.
  20354. d+u@Ï´õÓ ê¾k–ÙŤ}9¥êT«v6ö*x¤g¶e7?—™Ã¬Ô}õS§éÕ-ð íAUÛü‚í OMlJ ÕpÛíժݧüîÕŸYw–Õéhœi6û\fAöZc,·rjFœTå‚ÐMj8kOë«51‹þT»¼ýqW½_ÙnéØ`•7®%³K«èÜéWÜs–d0š‚á:»Ñ`´¶OX•ÞùÒs$ã4¼?:ÿSI1¢�¢W-¾Pr}ê²£Š §9õ.Ôû& Pš™^f
  20355. ³8(ºW¡I¢ÃÛ`¬¢`@5a}ˆzµêiþV ¾p„²PÔ½+:–£d\jÃ"=üa€j£Šð­ä)W§Ô$qö{ÇÚÖÍœ×p)—Vüõ®|£7hj�¬ŽÍöâ—³õ»¥Éâ$·Lëè˜Ö¡Ê9›\öúŽÚ�n[ ±¤k{lG‹‰Ä.m „m~ÇT—ÀºE‹�Ûù¡Ñb�È­¶m¹`
  20356. »—wònyæP&—:P¯LJØí–YŽúéÀŒÕ_îp™NW¨‰ž›zVÛìS׃]7ÖÕEÚd“%i¸ç™¬|ñ ¾úèÙÌEÔWMÁ“™7râ ÀÞHB¨´Ë6þ`UG¹ZˆæÎ� ø9 N2l2ÝÛÉ…HY˜½(šÅ—ÒÔÙiwœ½Ý“[ýÞ`ªcZ¨–R;Yz=TrÒvH�þ9ëc. ¡Ö²êGäŠÒº6»*pÕüÎ…�'»[â‹:ú/˜ÒªXØ¥œ´CYÑ…Mñ˜ÖtÌÐ-'º]£n,{@üð cø˜Ob¸þæþÂIÑN‡.”xÁN� ¹F9ëÊë›�Nÿ­Kóß[º£ÞXÓr=ÛôéWÎmó �°Ý�°Æ¦ØY+�¾Ê?sýJõ¢Ä×gÌXµuËPý¹¯%È—V^¿Ûéè[­ù‹ ··ô„ÔWˆ ¯;éúWæ ³xv±iÈ/‡×XS3±åȼ”2¬¤÷Ô©Z¾<Fޝ=0Vó[%•R~ËŒÏx—ÓäyÑsÃÕy?§Î˜(O†q _ ”V-ÎøaQñ*Q1 ‹t$ŒjÔD„pR R~‡zÇ¢ìðp–"ð]Ÿgw�óÕ=¸%GV³§ÔßïŸrtøõ¾�>ÁÛ f×2�Ôå/yòÉÏ?ñí»ä8ð®M@ÓQÔÎ*Ë„ÂýÈö¡¡íCäXù�k¢÷²?MzT�y?±àÕZËÃYu׳)ÿãé]Í•ßô1–-ã—þa�ÿ7jô‚~”ÍÄá
  20357. .dãÄá
  20358. » –Ä'Ó·½¸š§º“VÔøz£tXKþÙ2k̹d?¢§z‚§úz¥´ÙKŒ.º>,¡¸BZ¦¿`q„—'ºk–Hèqy¢û°æ¤5¯¾j>aÇÅÅ\CÙÕ#ÊçH;#pÇø½Ð7lº4¿}” ÖIR¸7Œ„°ÞŠ0§ûœð$âì=«VÁ¿úÑö‘í#ì¸ä_.Ñvª…sð{g><cÆáÃê˹_«£ÅÐO¨ÚÝgxôçñ5&Ç?ÀÝÊÌ ';zº„ÇaÎæaØ:zÓ‘ èQìFꉢ‘ ®^éÂMFÑ�°³ÿ9Ûç&­£A¨•�„·ÕEbŸû†Ù½\±|ã3ÝgE}"+Ê>ƒÁh!­îÚA·b¹/p7¼Ðî™=Üz—Á©¾mi”%—ÍŸš3)^Ošj¼<_ãU�¶NY63dsIr£™´8E—jñ¬ßý®Uð´„*Ï 33Ï|v ¾ãè;ÔÛOÆéB@ñ�ù,—ü,ŸÑ\cwd}6k.žuØkÌF9þ±'Ìä�2Ð6D]e±‘xÜG¾J³K.×½}†ñS«†$ƒ@ t"š;2�É©�ê¹*¤Ž”ŒÛ4§Ü1_ƒäxõ7³ÕQ§bj´Xˆ£§ß9›„§ÚQõ½;®#Ï�{9†Ôe¼I
  20359. š-ìå¥�br B<ÞÖ9òdpzœÜIVªûóÿQ:l„+ëséi Õ#=ÑìT¬ð¬�+R˜Ñ(ªâMÞDC$â
  20360. ¹Êaç̱ êONgÄj1ž9˜¶›ÍÄÜgqXkè„}F«Åèðùd¢¤×ÖÒc¶ŠG“,µæå&—Ó.Øâ˜.^É·wwc�ƒ>ÀE´_]3ûžUˆ±|ãt{JÕfªçª‚u_ù.º\�ÿºþ*êö²W•=ÌÅ}ÔlNçÕ�o+^®ïßVÌ£îé‘ vØP£>~†‚s¢¦T¶jWz~_¶¤o‡gSÐ}-­üDñTd‚ Ý-TÀAaÈêYfµ²˜Ç3,PATcm²Ú Õ¼4gã¸}‚½•màE$BŽ„w¢�Ū8Ü>«¬9�–ä‘ì¸JWâ�©°O¥õ/9ÿPªJCÉXA{,™@c,tEJ¯ËTÈj½¾9ì�•8QÊñ•Óõ&¨ äHŸ þPÁl~K%Æžù1€¾Ñ»¹ ü-èeÈD zxN�›»Xuz�’Ý.9½ä}‰MÂc�&œ:¯ê”Z5¿ãÓ™8·ø% ÕµÕ½øm³˜¼ïomõCBö:ÐäÖá‡l´ï˜8™ÎßÄí¤~óËܦ¢E²¿j•T§ßÁí¤YH˜Yá»vønƒV^IN]]ÂŽåCXkg#Ås cÀSûˆB’$‰Ã�=’$�ªkø}cG¹&ö÷/¨ßzç»ß}çä¿çÊÆµ_îÑv6<�7¸½ý´IVGG™�úg*lôŸ\RXS²T‹‹®)ÙšEî¤Ê%Y uôóÁ~Q~>X¤¸ˆÏÐ…±Ö`9ÓW‚“k*‡@_ÕŠpM¸]0¦*ƒ�%ãaÀ“3XíŒ�K¹Mü|ô{†£FÔ”»ƒú‘
  20361. ì·¾d7[Õnò¦Õlÿ’ͬÆD‘üÜÌÏ÷@¤Úmõ˜ÈÏñ8‹Ÿ›°e ¯cżô#�gH›ÐÄdd@~.ŠjÌlÃlÉ›�äeRcxîEÌä�(( Íí™K�ž™Ïm¼êïGëX”A7¾×Sõ·µ@[lÚ×.%ÈëæÕ£nMDsˆ]n€_Qî·• Ú5Ài?zûÔGüTèG3²¦T�@e èi´�×,ˆƒ°r¸�
  20362. O2<°Ðè•éÒl+³À°/,Á–%‰¹­m²à ¼ÓÛšXØn›|–Eš›¶÷]˜Žˆ¢l�í™ôœžÆÏ[m<’|#¹z×+„5ˆ¢ 7&\5Sô-˜{þüAEß×^Ù¸ì¬t“Kä ÂËέßçMñ©^rq]‚îFmÞC%2þ„vJÒð)W-Î}OM"`Õ9l²+ì=…%"«çë£ó­Tò˜'8ÂzH3QÒ�ßûÑ©ùYìP~V¶‘زèNiì¼ÍÜ 7ŽÕðÄÛ›¿ ëÎþ?w1ê×�xÚc`d```dòÍ?ÌÏoó•AžeP„áBYñtý?ðÿÖ;¬"@.H�c èxÚc`d``ùß
  20363. &ÿ]a½Ã�A‹Š�_xÚ}S½JAžÕS<‘`ŒÚÙ‹« ‹€Úù�Âb)6â ˆ�>@DÈÄ"èX\o“ !‡­Žßìι{Çé,_¾Ùoçgg“˜gÚ ˜¹#J†VYp>uC4Ó&*Ù<=$Œìð¾g9ÓW@.0Ÿ¢qêò‡ú- õñüêñÛ;Æ:pt"H�Uåeèܾ5äÕçü Vg(÷[Aãx­9ÏÝ!ÖÞ´÷EMŸ�êß—ï4þN†&Óž×ðwj³tþ™³ÔžeσèLpŒ>†w‘ï†õ>GàÙpfz`Í|´Þâü^ªaÙżø>äŒÇð¶)Ço© o¥²‚MÜg+RŠm¹RqÑí,÷«‹RJ¹à1—ÔÕX‰TªäN7t‹{I–E—\îFÿë8ãU ºÉÌmbÍù:f—N±&’ýj9ÌY�xÚc``ЂÂM /^0úá�K˜Ø˜”˜ê˜Ú˜Ö0=avcÎcîa>ÂÂÁbĒIJˆåk ë.¶"¶/ì
  20364. ìIì§8ä8’8öqšq¶pnã¼Ç¥ÁåÃ5…ë·w÷)ž^-Þ8Þ ||||[ø5ø—ñ?˜ °JPK°Lp›—�…P�Ða)áá "Z"WDmDWˆžc3KÛ öO<H|™“„žD–Ä4‰ $þIjHfHN‘<"yKò�”™T†Ô©oÒqÒ[dŒd¦È<’•‘u‘Í‘�"»Gö™œž\™Üù$ùK
  20365. n
  20366. û�Ëw(9(MSڡ̧¬¤l¡\¥|Hù�
  20367. “Š�JœÊ4•Gª&ª ª{ÔDÔêÔž©¨ïQÿ¡a¢Q ±Fs�æ-5-/­m.í*� �]:otet;t¿èiè¥é-Ò»¡Ï§ï¦_§¿Iÿ‡��A‹Á%C!ÃÃu†/ŒTŒâŒfÝ3V2¶3Î0Þf"a’`²Âä’©Žé<Ófvf5fwÌ¥ÌýÌ'™_±°p²h³8aÉeéeÙayÆJÆ*Çj–Õ=ëÖwl$llÙü°5²}cge×cwÅ^Ã>Ï~•ý/‡‡cŽLŽuNN+œÞ9K8;9—9/p>å"à’à²Îå›k”ë676··-nßÜÍÜËÜ·¹óó0òðóÈòhó8ã)äiáçÙâ¹Ê‹ÉKÏ+�Ÿsª9�����§�������������@�.����xÚ­’½NAÇÿw ‘h ‘„Âê
  20368. /‡"‚TÆDñ#J$Š–ròqr|è!'‰Oá3ØØXøFÁÞ§°0þwY� …1Þfg;73;3»�Âx†ñE0C€ q=ç®Ëæq£XÇ4î°‹GÅA$ñ©x ×ZBñ8Úƒâ DµwÅ!ò‡âIÌéaÅSä¸âùXñ ¢úw¯°ôÛ.¿0«?ù¾o–ÝN³âØ�ºgÚ�ÖÑ@\ÂA´`àžsbˆ“
  20369. ük`§¨sÝ¡}›,ì«0©YƒËa Dðä®ÈµÈµMyFËMváYd°ÅS÷±‡í2Œå¢Äé0~™>´/ãŠqJŒžG
  20370. iòô<ýÒ#cýŒ´0ë·C~G²�ÿ²ƒ9ee Kv«¯­Ð²[Ú·{&V(Ó¨1j•1…M‰Zqr�7±,gKÜ¥þXåè›­õå0éíò–›ÌÛQY{Ô
  20371. ªý›MžY˜¹Ð¶z=ÉË×a°:[jEÝ¢Ÿ ¬² BZìZÿ=nôüs¸`Í+oÍýÔÌ����xÚmÕU”SgFá샧BÝ]óýÉ9Iê$uw÷-J;m©»»Pwwwwwwww˜lîšµ²Þ•‹³ó]<3)e¥®×¿7—Ré^ �üÎèVêVê_@÷Ò$zГ^ô¦ÓЗ~ôg�Ä`†0mé[¦czf`(3233 ³2³3s2s3ó2ó³� ² ³‹²‹³e‚D…*95ê4X’¥XšeX–åXž†1œ4i±+²+³
  20372. «²«³k²k³ë²ë³²³ ›²›³[²[³ Û²Û3’QŒfvd ;1–qŒgg&° »ÒÉnìÎLdOöboöa_öcà@â`áPãpŽàHŽâhŽáXŽãxNàDNâdNa§r§sgrgsçrçsrs —r—sWrWs ×r×s7r7s ·r·swrws÷r÷ó�òó�ò�óOòOó ÏòÏó/ò/ó
  20373. ¯ò¯óoòoóïòïóòó ŸòŸó_ò_ó ßòßó?ò?ó ¿ò¿óòóÿf¥Œ,˺eݳYϬWÖ;ë“M“õÍúeý³ÙÀlP68Òs䘉ãGE{R¯Î±£ËåŽò”MåòÔ 7¹·êænáÖܺÛp;Ú›ZíÍ[Ý›�Ƶ? ѵ•Öµykx×~yÑj?\3V+wEš×ô¸¦Ç5=ªéQM�jzTÓ£šå(»vÂN؉ªk/ì…½°ö’½d/ÙKö’½d/ÙKö’½d¯b¯b¯b¯b¯b¯b¯b¯b¯b¯b¯j¯j¯j¯j¯j¯j¯j¯j¯j¯j/·—ÛËíåör{¹½Ü^n/·—Û+ìv
  20374. ;…�ÂNa§°SØ)ìÔìÔ¼«f¯f¯f¯f¯f¯f¯f¯f¯n¯n¯n¯n¯n¯n¯n¯n¯n¯n¯a¯a¯a¯a¯a¯a¯a¯Ñî…îC÷¡ûhÿQNÞÜ-Ü©ÏÕÝö¡ÿÐè?ôúý‡þCÿ¡ÿÐè?ôúý‡þCÿ¡ÿÐè?ôúý‡þCÿ¡ÿÐè?ôúý‡þCÿ¡ÿÐè?ôú݇îC÷¡ûÐ}è>tº݇îC÷¡ûÐ}öôúý‡þCÿ¡ÿÐè?ôúý‡þCÿ¡ÿÐè?ôúý‡þCÿ¡ÿÐè?ôúý‡þCÿ¡ÿÐè?ôú�©îvíNjÿHMÞp“[q«nî®Ïë?é?é?é?é?é?é?é>é>é=é<é<é<é<é<é:é:é:é:é:é:é:U¦>ï÷ë:é:é:é:é:é:é:é:ù=é;é;é;é;é;é;é;é;é;é;é;é;µ}·ê­VÏÎhåS¦èèø·ªÙo����TPÃ��ŸN��AM���������������������LP����������������������',������������������(�G�L�Y�P�H�I�C�O�N�S� �H�a�l�f�l�i�n�g�s����R�e�g�u�l�a�r���x�V�e�r�s�i�o�n� �1�.�0�0�9�;�P�S� �0�0�1�.�0�0�9�;�h�o�t�c�o�n�v� �1�.�0�.�7�0�;�m�a�k�e�o�t�f�.�l�i�b�2�.�5�.�5�8�3�2�9���8�G�L�Y�P�H�I�C�O�N�S� �H�a�l�f�l�i�n�g�s� �R�e�g�u�l�a�r�����BSGP�����������������©Ü�M�M�FîÍéŒÏÒÙ£(uÊŒ<0DãB/X ïNï ˆ�CCê^Ç rmR2skÉËPJ"5+–gléW*iÕW–/EÓ4#¬Ô£U¦~²f‰‘UDÜĹ÷ˆ«±àJ·1á/!þþ/žºÊsª7’“kŠ•”(ºˆ¡hNøé8o�íd$yq޹1³âÖ9ƒ@-‰‚HG’ôµS"øFjôØ 6C3”¤&ž‡ÁøªW51ÁÓÜ×BŸ¯aËêQaR†U/õ¶{*¿‚Ëï�‚=–@dôøh$¡1ÉTÛ—nc+c’ÞA¡§¼ •ZÉ€¤@QÑc­a‡ÕÞl÷�2>ÊK°Èmó' “ËC‡HMĬfB‰X�,¾YòÂp¨e¢�
  20375. î�¸UøØ*Ò”zÿ
  20376. m‚ËËiO1nEÆ.›„ä hx!aC
  20377. XTÚV¢Å©Â‹– —éR¥š%¥|Iä Hð�ÅÕPƒ5"Åb’N²µ=âøƒrÙ/_åRŒ›”™_ à%Ò„�uzÉéÒ˜Ö5’2Ä¡ÒãPÚ)žÔþžÆÃFƒ7S‹q„FÀ{náia�·¸@DÐsˆ;š}9⬥?ź‘§Â R{¦Tkí;޵ǜ×U\NžZø›Q-»^Ôs�7òf 0˜ÊÆS3A Ü _n��`W7Pp˜»ôài«í³!ðgØ/à_p»ÁÒZ€-=Ã×¥~WZ#/á4 KF�`´ »ŒzßÒ0Û| D‚ѵ�ì�‚&däI‰´ŽüÃ�Á;·Mì”{'¶om†”m¢ I !wi9|H:§Û§À»ç÷Êþ¾{û~ö¹ýqº¸©Oøåôî© ú›,˜ ‚L]&„J0ñ•Ù9/í9&ÌYø è“°{;÷ú'À3`’e�@vH„yDZ$º�„3�ˈDx28 ƒW€ Cx5xw‚B`£$C$'ãÊEl…y Õh¿ëÔ€ DJ
  20378. $(p�½îQA”A܉A–@'Ç$ hpÊ0ÎV0 `�ºs¾ªeÒ$É4$"t2=f´˜4„A„{Tk–0|rH¤öÄУï`L&±´sÔh¦]”§A<£¡‹²`R´'£•!ƒ‹�1N¦;£_Št3Û#  âòëúØêVãê *veÑF`E O$Ž{)ÙW=p:®ÞÖF`о2ÆÄ2Ú“CëÁŒÒ^×.Êć˜¡ø–øGþ<<?¢éç~zк¢©å¥>û.pçNe2ê‹ïÖ´ºÞ+YìsÛl:ÂÃË¼ïµ Ü«u5©¦ÞîÐtÀu•^8¾Ì6èóÈ„TmyðQÉ%þu~ôòš%~1rÒ˜aýwßš^�ù_©Z£�Z�a¢ƒ²0!Ùè�¡·úNö`¥.Ž uqÀ±çêYB¥\™¨ó…„ÊᨀÔê…[eð‹îîþ:@ êJ'EÛ�,¯3ubj@�p¨ÁÆäð´f¨Éßóîµ·eW9( óºå ´Þ…‰³æ=‹l”G¦à7gj âSƒM6ư ô0ƒÿ9ò§–OË‘¨�üí�l§®B¼aªÝ�ò¯  ƒ<¦çžÇBÕ™(VRAp¡fù^°ú¯+g9 qÓݹ�ŠMÆt]»Øª�pëE�•r@]‡@ó©V�ŸkV¥
  20379. uêädé^ÑX �å–—R@?EÕöY2ô¨˜Éï]#àǼš4ÀJÞåKöÁäÖ'ÃÁ¾d²âPC|mãmånä#¾‚$+48u'…�çe&û¿€[n[LáÈù’ž±%{BCDÚL:^! ‹‚ÓbÆ™:&Éÿˆî‚g3“-3Ðøu´è­ÇæÐð¹ƒb iLZéÚ‚W‚FSÉäIdÍñ¡6.‘k5Pî„l7ž7üUz’T:NýN¡‘—.ý"€ªåü)‰Å—ì’['ß|U"Aƒ€³—‚I•�Ûv©wÐÛØpë™í­t¹dk‚ˆž9Ø›Šå««Í9�n¨D‹mq¹—7I|6›Kbcƒ]¶Mô“©²ÄÎ÷—è¶B�A�€BøÈª�_ôJºT Ùüq Ð 6@—§„¸F�—‡ƒžhd`G®�Tëñ·:MÅ7'à…L,éIh—ÆFP »Ê~j�½ŠŒíÄ ¬$¡„ Ä3™hAÝä��’-SŒ^ûÚ†�…Ðä-%qeÏìë~ÀÆQq«§¬ln"i¾ž&�‘æÑQe?FlKï¨"úAsÀ(Ý3Y;"¡LžÚÔe€tå'ÄRz<MW!¬ßSŠ3$rZ:ˆ’b¥-^Ç„/ƒ$Qý·qõJB'WdáGAO³¨Êã`.Í( ßž±o¤3öB0øÌÊÉ‘ø1å Ìp(®Äí(*–oõ^ÉǪk“†J`vñŒâ±[‘‹¡C|9œ=ðÙåé#„œAöÂQ˜‰ã# ¢òÉ7;.]L:î¿Äϸc®ç€ÐdŸÂêi€ˆEsr¯¡�âó6?æ}¯†eÇ@H-š�b»…ÑÆ–C¶1;®”™è. �v. ±É¾$`T‘ùöÂüù JW¼ÄÜÙ%BËZ¯I04ÄÙøÆ^:kU,èöC‰^êWVF©ÿ¥Ú`£F¬b‘¾(ñOÙÊO© È2<Åß@ÔX™u‘��ðg~ÖÉ‘ÎW št‘&1\ô1§LŒ:φ�„"‡!‘P¶Æ¢Ã è3/ØþÔ^¤øÇ°�q�ˆw`IA¼äD
  20380. ˜)°q£CÐfâ€ÑO“× ±é0õ2Y29®3N°‰fãpà„¨‰é\�˜CÐÃÆahö÷&°6åpË`âÚ�z³g‚B
  20381. hRf­�ž­]; ]Ì#pw_t(›p qê¿�Ù·,ÏÎíbdk‹R‰ÕBŽËèÚT?Ùì2¡Œ—À2¯cåF„y2˜™%¬ÍÏCÏnÁ9 ÐŒ…0›ñÜ÷9E&#×l’T__ÀSлg¶)eh/Ú·+÷#:FGot÷k5Gbr;CbË´Ü:ÄÊÒ#½¼Éœ &�Õã�QC ñwÿ’…™mxlN‡«qˆ ª€éPÇ´)�Í�3f-v5K‰¸¨hý·0A×›¢§Ðj»nSp¬ ÿœ^HªÐG·FŠÀfÝ�¾ó‚HŽ "%[Ñ»‰ßÍ @ � Ûèp ÉaÁ¦Î±�ì$$�œÍ‚Å*âÂ_Ü\Àï@>Mœª1 0¨{=æ�÷)ž€ ³K %�$C
  20382. Âø‘9ŠMðö¼ë¼4c ê€EotjÍÂV§GDŽ)lñ8“¯,˜\wÀ¥à !�%$¿×3tÉ TBz’žÒ´ iUJÒÝ[¢Çxgd„Brï$Å!eqˆ�’"J>࣠)\�~¡‚Љ3�(^ â R€8#>Öb›äH€âG'7_ fÓ«cκtD�oAA߃†(q™B<ý`Ç­`VˆüøéΫ”©Ö˜Â*úbÞÏu‹P­4v@—+•Ê.�’îQåÔ¥$V‚¡•í@C0
  20383. íR¢ÓÜ�P[‘z:X¦H#eäÁ òs >?úEÈWO>@IØ$|s¬žiâ
  20384. ES¥²)0AŒ?£9•ab,¶�@KšñÌ©o&îþüˆ¬Q´%¬ ÏžLu+›
  20385. Â+�H|ÌÆ�?´NKÌ4ŒÆ’ÓCnPtè³ 'OTòœÒ.j5àÄ´8ÈÜv¶wÖœ�«I¥&•+ß`¼ŠyS��caO[#¡g°§Q§œ€¸Údª[îK½I矗`ôÄŒLPýÓ¸ #°Áœ½ ©)2Ò7aTƒäëi@c\Þ�‘î ÂâÈ0nêC»pòß–é�‹4͵Ž�xö*ñËÐR”zÕYâ„b‡ÀúÛT[\úkU™vìHʈÜq’p঄IÂíIëÅ—) ‹bB X”PºN´…štzí 2 Iæ==¤ ¦³ˆý¨Ã;}†bŠœàqþÓjiÞ†§a²#" ¬Ÿ>1¼‚�°1äA›£p1ÖíÝP‚§OÇèO—ux÷Qôù°¹Î
  20386. Fϲ(úhÝ„©O'MDxÊLíK$ȵœhæ& ù‹¦Ð�1ŒïÄ4››Si ÜãrHJ’P°t�DMË;rMã‚+”ö—
  20387. *–àŸíØ—5u2$ªf3’K ß<ùP²LçrÑc‹I)�˜Öå^ëda>
  20388. %Åàѳb (Ÿú–@,‘2f,~"¦7ÛR;®EÑŽ;¬­”HXå(ú¹Ÿ4Š2ZäÝ'�TªÛ¿ö‹�„”½2J+ÿ^!#oŽ„›”Y~4Ø-׃òGW*ð!ßÃA•0&8€fä{`¼½øàWö=’DP8’'ÿ= ÖR¦ g©}ôiP>“Ê#¹Ëå¹4ÃÒEÐBRY®Æ^4eó�ý‚§N8¸�V,[B‹†ĨîD#�X†ø]²,Öèâ«LBsNC> +¢íoÍê^x¨ì§
  20389.  ÷•�újCì.4ÀYa‰_{e¦A2=rŽðØ+�‰­´Öî§¡9PO»A!!
  20390. ×}´YÊPJe„—çGnš±%xü�1¬/}RgHØša Ž^3-Š© ‹5
  20391. ¶|‹qS§ÐðaWK{ 1al`IÀ1Ó ™ÆQé¾ëf_yyCZ)ÄL3X±] W6@DM™Tø<.„«uëGÎKŒì8ÙDsôÚбWæ‘r…Ý\ß7Z\ÕËÿòVÓ"I¦¢ŒõS¡§®dµ‰>CަÈU�j�ßÉežÉÈÓD ®3MÇtWcP﯆–òÓ‰6#3Qךnቩ…°J\º¡Ã7ž#磱`Ø€Këë¤ ©×lV6 &ÓTŽ’ Þ~îÚl.’�¾¡ <˜˜BP
  20392. £*´!zRZÄäeÑ™»¾¾Ù·T±#£CéLH±¬ÈªWÅ)ÚD›†÷“p®YU#ÉÊ51{WJ€Ž¤4^Äf³Ì¼Z°öÌÑy6–Ó‘T2™dÎ4H=êB„Ҋɬ}œ&݃êÂ,aPçv+:2æ~òÁ*0¼°¢ˆd¦É“ÂõÖƒd ‚øáË!"A+‰r��Hn ¡ÇàsAäÁÈÚ—U €ýø¤b H“ÛN6þ$.ÐlÀ};½@£¡âiKà \¬Ò‚:v‰QEÇ�:,|ýªQ  Y0|Ç%Ö@í° Ü�äqcçÓÑdqh¯«è«¹vÜCÍGV†°©¸¯-(шm…’1»®âq89KF–Öä
  20393. "2±ò}RrzóŽ,j^¥ÀqË\…Ý–#pƒ»+õ`flš³½�â:k ´t–5E„OaIÃJ¬P @ps­E™j1ä4;6öô/aHÎ.¼ÏÓ°T�X¤p“L‹¸ÄL8¤½Fç„Üši¨lí1–²YØŠ8É %�!/Áù{­¨ÒÅñ éœ‹ÙåÆXœ€ºbˆ•½…�NÉÂxp»ºäPWê½ÛíèÄcI9g²*þº¿î�ƒ¹œ%:Ö»LËÞuŠ‚CAOÂŒ­™%¬/Å“´(Y¢³^ï? Þã�&I'ˆÈuh[x‹´–Qô$ÇzҵŽø‚ ß³ž�‚(=V×€Ÿê ¾mð­ÅU) »ílΠΒ¾Ìiœ•d㦈™¨½~f¦ùjGíµÖR{D€%>®¥�@”…”6‚¥¤1‚œ`Æ!Î ` ņ¶wYó§‰Õà�k/a�0A†«Â¹ŸÔ�´ÊYh²¯—µòˆdìæxš‘k:fšƒÿ漣<ÕØÙWL4�`8IYMBÁSlcäÖßÈà™-»EÒ‚'ÎÚŒÅ:,ÿD¬°�çÑÙøÆ©84Ó)~÷ÿ2·j€Ÿ–Ç i¶·B(Lãµ| "a©š¦¯4,¦b8§”¥Ô“i 94¦åÔŒÒjWщ° ©6*�ÐTð£†c4gŠÌ“¢×UMÉb³RÇE�²þª‹ò…C5‘Æ)jäÈ´ ‘­1�6pbÃëÛÆŽH÷§ªFxòˆñ¹¿—¯«Ä£�%4âòQÙÄC‰Êˆ§Å $9Ò:ÅM>òEÖÝaÜÆo«�ÌŸ^ÂØ<IwÞ�Ygq�7s[†ð’ð -yÐ1ع5†äaÄãMKš×�æRBÇY€†óFq}¹âç±ô8ïÀ²*ÈNtå�'.Yb„”›¤ÍðZÍûvÅK
  20394. (Ê]&ÉœŠ( Õ™¥ý2¯:0Õ €äo¤Î�Ñ…PKiBH4Uð¹X,Ž¢�[ˆð$
  20395. 0­mX±å»Ø´�‚ ò¥fë5ð0± VR ©8ê%ÙÑñÊÞ§§Dt°ÃUŒ‘s`ô·-BP�ÈzôP”së°Á¦vIë¶8z-¥t1DiB
  20396. ÒÝ"˶ÜÈYTJ ƒÄ.š?Ô0Ç7à€jL¢ÃNžú[2ÿtÈÂĮ̎†�æ� ù#þ6?E×»†”Œ×¡®ˆ:ÉžÎY;ƒç¬A&q…êSØIRÈ)Éss
  20397. 9*xÒß0Bj)mìáH§A¾öhyÐ�hòMm¤&4ÅŠ…4€ €‡ÜÚg¸ŸVæ&tYóÚ¦ÏOCS0³Y²ô‚d7Mv�Nïj)wë÷AÉ(¬âo "Í¢É[¦Ö
  20398. E`›”þŠë7ez¸Ä�†�»Þ-·QÀ]¦6Û+BcaÍ@^IÂ:²Ò»´Þþ¾=ƒ—š­ˆsSŸäÏncÇùÓ 6 ‚ÍçOã¡B„4½ˆŸç L¥¨ÀGpãB‰q/<•zAãÓCÁ¥» €ÔA~¹ÉxÐ0 6rih£Íh¤IìØ·O‚N,:oÇÁkìçÚöÅ/ó¸{H°,ÛzЂgÚfÈ»z—¯Ó΀5ý�Fõ²TrÀn/ät``l†Á™*H6jT¡tG/xøË@P@(„ÄIèp Òeº!ùê`wv,:A쑜¹N£ 4}09zÇqC�ìä$r�ìüM`Y†Q”’ øMää•«³÷Ä(|éB!í>¢ÁØ>«O pwj A*@›�ªŸJäC[h&3�üëB QbýÏ©8 …:ñ“%f~�v/‹lâSäÐèÒ0ÝèþÐð0a“·¶"<TX§@Ç&°ôà°Jg€ 3Ï•ì¤éHF ÕÐoï–éI8«¡{þ¸:YTèób( ˆ°Pëjþ<za{¸…wX¥oa•04 ž3ƒÌlÊøGȶN’à0>ŽBæ8(f úuGoÇšÈgyñÅ×t£_Ãy~ÀÍ”Ž
  20399. Ã%ä…°ûm�†L
  20400. èà!I$äX<T+Ê3­œdqó
  20401. DöMåÔtÌõ2|fEV([â]‘Ndb�œD3Sp'RŸG¬m—K¢›<œT�äÙ°�}½5iÜ·µʹ—àÌp¸ˆ«¿#Ä&jF ôZµ'”®’2ï%y9¡Q#2ñH]w¬Aˆ}Ævf§âØÐ¶è%ú³éòöX¡Óš·ì)”X_ S0åt£(±¤“-Ôî€â°“jHpÔ÷Ó–vœï/—Îô詵 ,9®w<`øE“ˆ
  20402. íìF°agAÐÙ“ Ð‰t©´)lœe
  20403. ›øÌ;é ¶ö$9ºŸ×ñ{æCù¨‰�œú()ªÇ?¯ñžÃpƒ¿¼IFã’ø¬‡‹¬¦—žb3”Òñl[):˜drr]Ÿ?†ŸÕ–˜ö?¸ÉBdÀiå¶DÕåÖÅõñ7ýühJ¤Ñ:
  20404. ½ÀU%næ3aƬJ.Ì>t0ƒÏ€~ÀeŒPˆzËÍ]¢Uìg Ð�=_±?ñºµº.j#+`li‘¡ BŠñâM5›Ò º¿Å‘GÒpŒž7«a
  20405. †Ö’�%Y[UG9æ™òÆÓ@\bDêÐY…’{‰�{¤ðED0®—
  20406. Ö$� Qø+FvCð`ݨì3°ýQ¥ “î±E\àÐuC9ÍáÃ![€$êlïßõ šú�êù6ßD¨oÙDgÀGˆ*+�X!¸�%#‚C€q‘ ?é­8ZUB)U@o¢ÏpgÞ©¶ZØq…¡¡É8ŽÊ9øžÇ|ucácAÑœ¶­é°•W;©@á" €Ø>P‚Óïåh_™�Ç9}.6€„�V/ÇO:à3´}Ž¡ZS ±µœ{:ØÚ~’óþœÅyŠk¦cO6;OÎBá=—bVñ. R¿k‹
  20407. oñ ¤ÿ^±GV=áØ }ïoI"+ ô
  20408. ]w‡�×FªÁzÏ·ä®ö`<“Éõ²30�ûh÷ŒÅ3]êRfú—¿859s¼`K…M€¤8ñË
  20409. X»Uqˆ<‰˜¥\˜“ÆZOàssè¿M’·&j&Ï ÄÖ÷ .§%Ÿ ÒPÊBL~^äßÿùGˆËˆ‘3páD‡¬•:í¸×£Z¿£Á¹¨©<\ñ«Ç i¯¨ÛW̆¨ÈÂ"(”ƒ:áÅâz‹©–X–~ê�Î0PG]8�ª¬ƒŒˆRQMNT�¦qfÝW~!Ý0”R%Õ‘�0ðxvGFy/Fø-›Ïwúu‚/ôî*ë+’Æ \õÂ8@ˆ6¢«Âþ©´‹»c<´àLƒ;c�[šû÷ŠÛÙº nr ŸQS'o£QuòT®{qÒ��_œÍ¿�ƒƒSdª»A*ð:mò8Yuz2ÿPB« ìHh`l´k’pèÿLLh
  20410. cEb6eÛ��Ò‹ ?!„™>| *=V�ü­»Kî@žë“rx‘0ÓG`%ryr[6êŠY3Œ7ŒÅ ‡f*—*n•à%9™ÚdfÃè1ó1Þ¢Ú�^'Ìý]‰š– RÍßèq�ÜÔ.Øê÷�,œö•‰Ó^%„¯lÂÚâ ã½eØØ#wWÂÑsó56!Ù=âå!q[ö°ÄØ Ã�%ÈÔ®]ó‹5^:€½m¨5©)?�V b|šuÀ7f“ºìw°œæÄð,:çYe æ†R%”
  20411. ò[À›�î Éo gæF«AzµFP¥›òŸÀÔx›¶î{Ïíöd‚xíÖwÃ8Ž˜–Ù”{{L> ®‚d¬�2Cä�L‘º¨äLÞ,œLÜè,„ò(àmSìø›ÃØåå$=Ñ|%�Ö�luè& Ä…”83ãÚ
  20412. N ¢XåŠx ë \VnõÍïžJ[)I›êwŒÄ/Ñé¹»²Ú ²| GÅºÙØY×Áð÷DHµ˜½*›Sýª�îè¤æ’p6®0Óc�J2ã@ÅW´%Ѧcï¼_^Ó$Ñç#*:G§®æ6Ž¡ïn>ÍD;úù¥�~¤`9ëhXB ñUŽ«JB_вˆ˜ùˈî%ªý’´w'¹$³èv|#T<68çªKM¶Ï‘-Ù5U+¾¶¡'íB
  20413. ËĪN…‘øŽbJìÃOv'Èì|‹„+*MŒ¼k(dˆ }›CÚ˱@ ³Áq°³¹&ùaR%}´
  20414. Ë!ÖVЃ‘s3w2¦ŽÑa²2²ÿŽawHæz¡/��Q0ðF¦ Ù]~;ž¥Ã¤�ËÖ NDùP
  20415. mü˜K3xÞŠke_™£  ñóþS¯!�¡V&=²²ª²ºvç_PÀ�L9؃Y£¡i¿
  20416. §NU­Ó_¶¬¯)–ƒ�J6Ý9‘f*ÊðS ± �1�7ÚF|¸BR$É·y,Ʊ.¿ÀÕ&=uqsáó¡ODÅòB›ÈôR„=çÙɳ—eøØ½É‡àB®¬ä¬ÖH­¡®ˆ
  20417. ª2lu'�h7^#ÿS…)£Xi2..P�e¡/@FÕKÉ‘$é](Ø%à|–2ÉðY1pC�±8tÁùIøã11N//+\»“p¥jÔÄïôd€”Îá�WÊmé›ÃI=ß½·ÓY“Zx¡ÔMЉPý8²“1/ JG«õÄ^U ,PÈd1O®ó^¬yßpq”l¿�£2hÝÑ$øjvñø‹þª­ÌõžIšö%‡Š¨§áèÔ]VæÎÖ
  20418. .�'[+WU8Á­[Žå†Dê’³è,ß»¾-=[ÀåÙ O
  20419. wÿƒ ¿Eê)å3±ø¬äó¿J&¥dïقݶR¡¬—S–\.° •5J$I�&ó‘Ýoª·Hȳ~› l‡½Îz>€
  20420. Ux/õHñÐu;š?Gt®{?à³;óT¡ŒªH äLþ|Fú8á†ð²}ˆ¡{ú˜p:ß2tì͆<L¤CA`²¼ÓʘÆâÇë“�§„+' ‰—‰‚¹ªoR0D?AûClIþç¯Z1¬¶›F?já§´ùõä{^�œEµdGIœµT°º¡&#eJ} ÖÄ É£_m¦Ü�i’³ÐA3÷K["ošCÙTJEßž4Ëc$ô„jÝ�bYËnathY�„`YG�Èãei‚µ¨ñ(…aº#ps¼W�ò±Âi-1òÇÑb™«,ÊŽTécmªå bhv9jhÜô3«tè4Î@zöK±±æê™†fÑjÄ–Å\$5Pü…!¼hR¶“$Pé
  20421. M“Ñš`’³ÿªÀCôC^%2Ù]u Os•‡LTx“íÝp¦Y€Ü!›UÆœ{°Í'�Ð’á¤ÏyLð +ްlÈJé‹8ª�Êß)@öw„$F5t4ÕÛ¾­$Ã,£²34aTþ˜&‰†ÕÝ„¨UiõÚ+¿äì-಑-›ç,®ð{!/\ÅÂüÏ‚ŸÂŸ±'& ¿S¬Å�™Á0xkÀYÿ‘Å0I¶)«'Ýöíâ~¿Ö ´ê«•jƒõ#±m!–-TQ`•‹‰=¶=œKRÔèÕ,.is¡gI&jf‰-IÍ(ÿª~ ²Ž³o¨‹,èiž€©å‚Œt&Ú\í�èØ`Íž¹¹éÒ•,äY†çGÜ‘uÁ I(~[Á!2=ÊÍý âø¸“¤hÙåˆ&I™¤ê{8~4œŒ
  20422. ðj(*��aA…TîRþ?bÚ0„I“³Kë¾Pÿ
  20423. ¸¬ž€M ‹û^c³œ´Yf3Œâ-®¹J¸óºc±÷rø;þružêGuAÁT1?Q‚‰à8DŠpy‚y†+‘Òcž¦ìŠ@6!Ë[oËÄÔf£×Zp­�×âɲè`$ÆQõÈ!†²O­‚ á4«Š»|�¬ÇqiùŠL^·Ø_Ç€M+žÆ¾Qb²¹#7ÕƒØìX 5=žÚqQ¿çî¬!¼iëçùm~•‡ù÷Å÷ÔÜ÷‡u…Ý¢êçÓÜ r(48zrŒY;ã*1ÃyNkÖ$9jÖôÊip+ˆq] æ°gèi™f”ÑîùÒ¦f…Ô¥×¾ ¨¤×»‘>a·Ëѧp6ÑÏíÔû·¶øè5Y"LÚD“Œù.Šr¼ØV“ß‘²ßS_ ºÚÊkþÏ]»n&úH�¸z§~¦9‘æ
  20424. ¦p $§4Ù‚”�'¢{º& ¸«ÿËM\ŸÎ°éч¨®!ìq®i�à ÏÄ(.hš'Ë B± T­²Ÿ|ž{I„6cLò¡.¹ž£ë¹�iI¾ê«¿\!à;§àg`1â ᾕ˜j%C ¹o�3*60÷·EŒ˜ØŽž]tä‰.×-%0 Y‰KÇ_nft] ·*VFCÆtJ’°ÄTÔ+¤\WZ�8áòÄâ×gFвàÙ^
  20425. Þžf�¶ 5šI=¶×ù#6ö.@õ2zÒÃ;Wš`ÿB/Ä™QøŠgí°ühŠjyJ�Ó°€N²AX¤3ªÝ,õ¤›� Kä6è’ë6�Ú²ØM0®T@ Ž…O{¡£˜4kj£|"¬ftÑŸ”Û„Uü‚<-üÞa†®Õæ5b�ú)í^R±°8™„ÎÁž:†§il�¾­ÀKaÇ6@µæ”Ã!ÀÍÃ] buvÎ�$ ‡oUÇœ�~:.…Lût–èêe—ü Ç€¢JξP
  20426. l$S[z–�~Rq39é’ºô¶9ëQïË/�m"•%ʤ‰¯†¼7Ÿš Ãî5MKLŸé‘§"Iß�G„ èXTÞŽXL¿FðݧV j‘p^¡/MÃgÁÛ»{¶¹»wô
  20427. ì*øº€ž9ÿð—ÊO¾Êˆ<Ë"aôÁþ÷Aáîïˆq¿»¢†.M—�2@möë‡p¿^Ú'“wß•möÇkxO8 ü$[ó«&Áü|Y‚Zyý`2_|%r—“/åJ?¡QùÃṈl‰3ÞÎßK¡E$–wÿvCËh£û a@÷U€1©Mø¾%0?1*¥ –$GÓZÓ{!|ÇÊ¿À$ÃßÛ•Â-òÙªEv;�‹Í“:佋Ÿ`BlÏ˸ ìŒ§Çɬ›oQÝ0&‹•ûþñ,†F?¡ýÆä„^�s,‡c“™ÁhË•ÿ$ÃEücl0åºw`ýâ�º¹Åˆ©@/€r^l˜8cT·3™�Ük@›ÜúJÂÝ”´uPÐ&ʪNÉódùJjT�K¸ªi ·é*u§»éX–{t“j~½É¡}ùñi\BÈKenâ‹Èµ|NëÖê šu�’ï#Ã]@lõCZ$iPæa½ã¸©t04y20ü sØÖªâ,AuÆ!QÒØBäÏ–ö–^ìˆ@VsÉ‘€‚\ÞZßaã7©ì¾‰©¸âш³»6-Tïr±ÀäU˜� àu“Œ~ë°1HÂJ¨(<Î±Ž‚ò½�Ó³bRÔ–¸qi Ï鿢¬J?íeÿG�Á §*jVħ "áØã†:Y);�-Fådô!ðH£»ÙG~´•u¦x cb�6m•¼ø)&;ñ0‡ÏdU?‡8ÅX~ïŸ1Ñ2�šÛ¼¨t€ˆI�Øxè5ÄÀ{(ëz„ê
  20428. Ü'¿ûÿ[ ÅƒkŽèZÐ…ØìéÍi,ðÅb™1̇‹¢Íá`º±(ôªm�Há�Nðìüe‰K¤°ßÔ/
  20429. [à´(õö#Qô—GdÊuÎT©½^øm³¢¿%ù†ŒÅ!(˜7Kgé…P=èhøÏ•ákÉ�U+ŒÂÆ.[Òe¯‹Ïм³CÁ�ž�ÿå"GDÿΨ£›<*<ÖÏþéh «)¤` A˜U @O]hýlÅf2”…!HžçÏF#�QBÂé=uȾ9f´h€ó;"R„¥Ú�’KÜ3-‚(G )¼P±áø¡¨ž¦²T],7ÁecÞ
  20430. ë F4hH Ós³73á–Ÿ ¡² âÛ`àºR–¡Tíwfͳ;6Bó>Ř 9&ÈâÛÑÚÜ‚Î?’—÷ø)À\¨Œ€�<&Ŏ™ð5 LÃJu¥@YžÝÝ,�냲ھÛ_wÂ0˜^é17ñððöìpÞ»‡*>D”8㟘ü°_)$UźóÊR´!jOFôÖ>{ˆÐ’‘ »t,¯-…bPµ,m`D"/ŸzðAâ ͔إêßQZGÕ&U]�xejxæåLwvõ~²œ=)@ØB¯Ö6Ê?!;53/ps@tƒOZS7©”§Ø™®’nŸØlxèûîÿZ?áƒZù—j a²–{ýû6—¥ÿL4›Š«1Ÿ 2¹´ù¯‹Q‡iÜý&Ö¥lƒˆá½Åì]o= 7Äļ ofüЖür MEV@ƒâHõ¦èòû/èýaD¥Ù¦ëH•ƒ®®lK5)ÂŒZ OE´œ˜„3Á¦IG©'г;îD'¶zl(‘ ÷�EŸÏÑ$�Š.Ùœð-W R'\w+)Âw3æêº¾ù¸ @Û%RÔ)ÿ.ò~Š9;]ô.šg+)Ø%È�ökÕÎÀÒ‰³¨^ÒöN€W·>b1z:s†¨oD
  20431. K�ö²ºÂ2w[|>9â®vWMFâ¯uÞ`¹ëÍax‡chÕ«õU·�`*ʆeû]O V'6ý‡ÀƒxÔd?¼H]_rõA»£+zÀd­F›¯H ÄÊ‹<¤…Ç´£ÕÆkUsFzÀºòÏaHÖÇ9-³œ��˜ƒgv‚b‹=ÓëL/žE»)°Ä.˜½x9j%Bã) $—ŒéAËB¢�æì ƒÛŸt b.bÒAE¨žZ�RböH(‘£õJÿyaãˆÒ9Wj0f¤ßF'›°Xàz¾Ã ï$DQ­6´ëžqƒØ` oÊÐ i=�áÁ{#4¤©FYHù@ØJÐ3 3i~‘tYТÙhkH‡PÏñ×÷ý17ÓàॆYÜD—"Üp—Ħ;'³16€Æf—pu‹ ô¾>þF›oDÅQi¨náÌ’�-Ïç @P#äš«‡ ¦h“j Þ‚ˆÅ€f´¶C– –�ƒ7°”T5HVXÉpíöÉklÄ­Œ³®]™ÚyXrÆ)?ͺÓBNJš Bƒ÷øä½#Ë›9e”�&&»_0•Ó=®špZ�É6§ªh¤Ù)ð Ì—ƒa bÀŒí=(p)‡âÙåí¬;Š.N•,“ÃWí^ *hÔºŠC—îm}E™7�iõà‡6Á‚Ã÷aËIívͲxpƒ*Ac#4‚ÿýûŒ³Ç Nö&ð`)®Ä‰ˆ£H£We›ƒy7jl¡ï°�oÝEh_n3 ­ ‹jp?ª4èp2WÀE'kT_ã &£°!È–jVl˜HíÓ»_kÉšáÈâöʳùaYùŒ ¡ sÎ@ä[…G"ÊÓbYÕLÛÜ«X¦ªi� ÕC�˜q8ñ&úz��VaY{èÆ#I@µ§�­2˜Žmó!ôdŒ[1 …AàÆ¢šÿnKèðòÕÆe×�²å/>ßdƒm†uX:xÊ·\„âpòN‘ûý©l�+ƒH+cÇtSǶ‚æCÀ±[íà~3ŒÍeÀ}6° �\³,ÎñÉ„˜×|¤YòÝ§çø˜§v]¬'û|¿žŸë&í–ìMô2° dõ¬�dsàx-((76”©aX›½m=ÕîÓŠ¿ãQˆ—<$ªª�€üóQ†˜„º\�“
  20432. Ô ªqiéH阇¬‹‰i'i¤”$�"£{S*V�wF‹“/°t<ìÊÁáQ`Ê’Z¸š+ðpr)›(¹.jµé¸«Iük5õ <ä´ʆ±Ë®ÉÖ, kO‘‡œDTˆÊJ&^7º£‡ÄªQ�þ¤ËÏvße
  20433. &žZ�Ø’ ^4úÆ^s°ñD+`WHµ™®�bì6ÙÄ©˜ ¸®ÈL�˜W{ZZ ¦@°ämqáûv¦É·(DÁ\+Ôlåéû0*¥V¥ß‡°VmÕЧæhÆ�æØ/S`|³^\<-™„©Ã6ë¸2©N3�‚" ToŸóŒlräÅe ‚!õÅH2 ‹pƒA Ö›¨ ‡ÞÃÏ{›È¼þ/£òŸÑ�çœudU2*2ò"c«Ì"p…${©€y�, 饋ö&\àm¾&º`Ð|x ¦p…ˆCªÒw#ÂÉûW�9D­IiñÑ–Cˆ�›Ksï–ç‡�S¶“ã3ï ,¶‘–þM›’;j¨þBë§4š›P›2ÙÙiµîïf¶®�É¿íÁbA­]a¢idíÂðŠ­¨†"Äò×i!aQhÔCNO½±žŠï‚õYí
  20434. “xF$Äøg—9ž¥‘Z`W«°…VBâg¸± ìÚ#j\Ë‚—¨€eùGñû [³.à¾]‹ª0º~X{2›D©„? Šø"óŠ3ÄBáj,ÀK~Æ�b#„0¬É’L˜kcÍ(6 ¸ 
  20435. ±aüE7λ�/ÕŽ¯%�­ ü±œ·ï àÉÄ¡Rë^JûëÅCÏ�Z+71XÛ´ÐUO,Á„öá}#�-”�eÙ¤ 4ö3Å‚ðítÃ8§™Z7†Îià¬Ê<:iÑ?Ft‹Fk–C W'˜êf0i<âXdj—ùŒ”0ÛW#i‹‹š–eCÏ
  20436. zI7ˆÎB°s·¬˜.Kƒ  *ë�ÝV‘°�«dÿ‡ŸD�ljö@ì«ï%
  20437. ©Üˆ�å� ÎZˆÄsÝï®�sh̸%‡^ß
  20438. ýèøÍ÷@8†ò§¤øÎ?  Nº8gÔGøgr¨X°€Sƒ» üä• Ap ‘³º4‡z*ö¹4á�Ýà§,í¹Ät4GÙnÔè÷‘¼õdSå>fî”Q–CòÏWUZ{SÙ;N�xå½Ê}°ÇH&º¼* ­�9׸¯q‹šU1 Êó a `(M-aÈG}Õn¶Ì½è¢Ú0 –¼pÊÔÇmcnñŽ òð‚ɘÀ_ú\±ül¼ÞÛàþ»}Î È� Þ9÷FávžHþkƒJZüNO å´mZ�áÁQžíÒ¤ aSûëfú�
  20439. )QC+2
  20440. d’˜¡[¯ý» ÌïÁõH"t*Þ Ác*bÏÆÚ¢÷¯q°¨,µ™óã#S˜Ÿ#¢äu›'Ò¬õ:4©as¥©¾CDM�F§|ɸm©_Ã1L]öáY˜Ê\À§ý*¤XœŠ>tú–¯¸Ìg‹§ØD‰Ÿ£Šøèd@&[°)8ÃÎ;<œ{óÊ8<–È+VG\°H˜®¦^�¯a—‹a�eÝ-4”úsÚJÔA \à �hM[‚\`ð“¼#¿pD5Z97g;²÷BWâmÎä‰qTXX‘%0¹�vºžã†ù&ù·]E ¹Û4]ûFŸIJä¤ù–œ„&ÝSŽ_¦îƒ4ÈR‰0 ¯¥Dü+Ëme¹Ô¨Y ƒg÷ÐOøñ+M{”03Ïv�'Í…f…ÁÅt¯á�è :;ôØ±Ê Nô¦nà\Ç”^Ü,)1Þlãá’aBïZZÚ„[•à ¸� ûZSÒÒä¼UYhÜ߆ÏÊw€õ‹šS¸\®/¤*?zQЋÿ`�X4ïg¹ríÛ[§ŠCWæÛGû.§Y„ì0Q|ûRÔƒ‚E�[w¾¦î„yƒ)¸áï‘,шï$ËNK@c/b
  20441. -#Z¯I ¹G$Æ—¯™‹tmçÊH#êð)X£wPZAD|¢S oýf�ŠõT¤€ÝHÚë)¸ÎäÓçÇ>ªM1 b 7á°…ɆS‹uÐÃq×
  20442. ö·öjK4[sð„‡ •—×xL ›Ö¼Ç¢©ë]5 ú!M!A¾dƧN Ë><«:Ç»Z(°8�†ø�)e… „ß »¥™†/™WØÈÀ| ý°bªØéˆú<é÷œƒ®T?%à ²:@±äÔ,-àø€ecMPð8u¤m°VÐg�Œ9Héö6®Ëç‹}¾=³5�ƒ�—AbÒÄŽæýÏì°�¬Î™ÀV:’�…_ leɹß
  20443. ÏÊî–•v ý`Í0Žä!$`GÁéA"I;$ß^?ú�®Ší‰Ke O¢ Í÷³N(Õ½çö“YyÊ5Bç¡w¸ÐV¹%ˆju;)lFµoaåìË›7�óxéÿ’Ú¸Ø4-‰É%ë� †ð$ÏÖ¹/zskǘ(sh>»ÁDD©ÅƒÉt¥TÄ7örurÀœ¸0ÉÒ¢ `Ü´h5 5�Œ¦Éä¶�“Sá}¸ÑÝÈÿÒ4hrva¼éléc!ZjB]�¹Ž¦©ÎxâD¯¶ÿb–Tx�zYS‚ß6_ö)ƒÊo°Ôp>˜#�@P¢SÓ*ýbÜS\q Æ‹xñYfQ><"ó·²ã¢ Y6‘ÅòIE�r_7ñˆÒ° VÔHÃ!�³ÅIçrŒELçŽ6ž!N»�öq"'’d “aþqMvºÅ‹A‚%íõºº¾ ñv³í½Ž n<Eб‰;�Ã,Úw®ß2pO%¬r’‡X“Hö`˜uI#™/šK¹Å ò;‰56‡ßLL.œMI8ÔqÁ¤4U‘närÉ¡"s9¦(ûÜ@=¬ò}N¢¤)?S™ú‚….úr½0L3¯m7VÂýK HG°/®yQ¾Ãé2û/Ww«F)±Áãd)s•¬Fë 7|óŽÆºvQÌ´ËAÝIz`€\‰†¸¾åÜ–Ðä„›<>ð.;šëA/Ïç°ô2ʲ‰œa8D$ÿGWv…#Ì�û 9®kÅÅ'ü‰ËoØŸœo€@âýÌ (]gkí+}/ (nq‡ºìK(f¢ÍÖ ÝÆŸÐ¸žpüøÌ2ÔÈ3Y°ãÝéw�²pDþdG´q2$ÌÉ}‘KÓ¯A­"öE&N‚tg'NeýsÕó!Юð4qìœo}ì¿�¥Sµµë,oÕjr/s œTþMT—&öÐðQf\12¡h'&ctN¦ú'TÅx7¼�]2û ;GÍ Ê…ë¢ã|Tª++:%/ †è¦ûгÿ1T ‘ÅúÏ“ óË€Ÿ<ÔñÌ4ÂÓÔùŠÀÍ”×ÿ“Ë— É,0~áò�!¡W‹O©à'‰ áÍ:sñuÈÆÊÒ¦Ù†ù�(´^ﮎ µ¥œÂ)˜ø7èØ�fÁ€Ñml¥òÒ¹î1Å«tÜÒZƒèhÀ ÊL0 §£·–6ÒX"JÒ‚í
  20444. Œˆ4§9ØÑ �Ö©Bé}ƒÞÔ­`è`‘¥®ð„Ó’ç #¦JÞïnéäôÑ_‘F­ H|š¡$OÈKÎú=¡Å“i1÷¡¦7Œ”o-HËq¡ªûp[É«%%:ˆä€Éˆi3Û ú„G C—�LL‰4ŠSÐ:ždBòj|‰ˆpYÓöSþD�P>¶pÓv�Þ²5KLeè{t0®ò‘yÇEND$à*�;z»5šŠN’áBIóÙgnŒ€.NÉ|×¶àÑnÐ�”RÈaS¤Z×ÂJcH² mÍÑXøÜÊße�k;_ 6È,yÊÂb”�0#¦Z„¸A e|w‚ÔÌG U½1l¸ËLDØ7ÄV£q’Ýt[­xuÝE”QULˆïðPB�lZSh–’.áé1Q0UìÙ±8R„i�úp;¦ñ{óôH#–GON!?ë£èt>©Q |pÊk¤�Ûó¨q!çgT,öÕjÇÐ2ÃÈsÇ�4툊t”jä·nÆ›/IÉO˜E!Ë‹nFõ›4¨†·ˆM&Ô1„’—¾…xÓ$§ew+v™SðË
  20445.  bm]e%8 ²ä�PÌÂ
  20446. !úï³�ŒsÂó_06£ò)Â�Q´2JB†êØý „[t9®–ƒ'”§³Ôœ,§¢Ìô[½f�Æג¶]˜ÂBŠBÃ@š¦îr&B„s|•Qš °§™×g¨íOCˆž1‡ÜJ Dç<ÌÏâUÿ‡²Î¼Ó(o©!³�h¦�ÜK½Hüê 0q›ˆ’§AÑVˆ¼'p´fÌy"Q
  20447. O…Û 2ÇZ»¾ŸqÂà½#d"›@bQ»,®“ w)îPÍ\b`xŠß�Oþ)Þ¢ d¼MC€$[Ho¤�WÞ¦Ñva4{äDZ`52íýº‡³5;‚…X°ÿao�K†;˜6“%ÁR(À‚ŒÓÆÑ…x9Š8 À2rãDc÷¥@ÙˆŒæ¾É¤îF×<†d(ÈAN#F�I·ž›zmEþ‰»F=©±…Æš­å•S‚€f
  20448. 4Ê8§<'´„íj�êŽô-ª˜Ú'ǘ<ÒTbñ2Ýv€EÀt¸¿q¡Ò3qODd_íÐ{`/œhhê‚öÌ`Â’9_ü1hAY|/ùë «Þ·Uê-Í•ºÐÄAÞ”Õo(ñËê"“$r؆TÌ×PR;§.¸-w>&LJøiC`A£^±—Ó#‰€ÄX8—t—öâH?€dÁ¿aÃÄ–TSTÚa¨HŸ0@ÒîŠðóU)ˆ£æï^e}Jb7%×Ü”%:›ÓÆ¿@�—¯MŽ+ñ»y”sqŽ�ª¡ëLÌÒýø¿á ÊYª00Ô÷GüD¡ >Ä©êAW ˆ¶ð2�IÛ:ÄÙF žÈÇš3ãŸ2<k½}[{ç¼*™"A�z0…Î:@ÞÀ¢1¨A:�µðçŠíܤhÖXÃî£Cûñ““£9èˆ8ÈËèµÔE„ùòÉÅUÖØeu)[?©mt-5Ër”~J’ݪÓV2li)áÕž<¸Ò³?ò(D†¦î;)’�o (­¤˜ÊXI¿I$¦–’ñ$ª)À'i(Àª*’¦_µŸE K´ª*½4C‹kàýÏ÷wkOIð˜FfQ$8γ�;(0+.½9²ÃÂ9uÝ$áÂ0öì�t ‘170‰ìfȦ Ç’ûaOµ=T,èm;°€ôn™‘�¥øË¸ÅýΧ—cí<9ð0ú<êÆð _½=g ÀQV&ÞÅB±Ü€Á%fÒ3`5ÍF�ݶ–~‰§`6dÉ.ê2`?ÎÀé]„}ìO´0^­A¿K´N\Qç(I {ÉÆ Œïp[ꜪÒ4Å$6x§P&Õ :²'�7u„ÇêáßÔ æ§´&éõŸRó®®dÀ'Ä Í´#{*Wøµàâl ·DÆQ§ÕÌŽ.*ZEîÿ šcƒÝé7µ¼|4€ ã€Õ‚or\�*öí
  20449. HX¥³Ø'È#k?WRÀ‡‘mP�x Ù$Ù“]�©¯� ׄFKÁ ~È4; [ÒŠh2 ÇAÌɉf‰� ¨<P dg¶é’ ÷)—!b#Z¥?0o´Ôá[¯¯E hXÜ$ö¶ …ÓêSþí’Ø¾eþˆ½NÛì$�ò–æð“Œ=Ÿ8Ш"^ ‡VÙcFDÔïx˜Á§ýÑRX³CõX“ážÎ.:Fƒ¿q,†„æ1)b¡Bº1 ò§²+¡Qž)ò_ÆOyE£�³
  20450. ôŸü‰¾º¹nTp „š}1`î�#
  20451. ×£d-½Ö¥#„OñáℚtïÈ:5ЋŸ/<b0°'m�oqI£ßÁBâŒFW‰ü.‘\k¯cø5ߦ-v›T[Í‚àô�°êà± ôü›-4­:dÝ—u”†[ 8:P금ª£ªBT˜ûµUÌËçÆQð ,F24‚lÀEO÷?ªDþk£œ{ å±1¸k6)Rä̘GIÉË6§Yp^UÁ­!Aâ@é{xg�#^/ ‚×E‰Tz°ÇÄ’Ê»@:FŽ'\�Q6ƒt,æÔpT!iõ
  20452. N!¦dGÁBáÄ^
  20453. ó$@yn�ˆ_uœUüºCÒàíK¨_K62˜ìB|
  20454. ^‡�¢‚T²mr½Ž¡LDgÊ¿Ëf›)!-îúú�ÓoФ�ch»}Éí@oà[ràE] �ë/iÚWJ8ÁOgbêÓ�FÖe‚(/”ÂEΠçyOñ™LB�œ]IkTÚ‰aÌàbVŽÌÕ
  20455. ÏÎ
  20456. 2¼¹“™Ö�%Íb»ŠÂjúªÔg†Œ'‚Àñ‡2…-6µÿ˜Düí»¢òJZe' ·oBi2üû+]x;S¾Pσ¥{£{Ju¤m² „f^L
  20457. S0Ñ’ÍÄ~oÇÇëæü-ë÷ÐS¸Ecô*€vl��pOmó�@�öv -SãÿD;<U ÈC¯Y×à¾îûÖnA)¤pxOý@¥iåLŠ�Â7—E`K\‡J`ô9ÛU$ü pº'°Õ� Ý…ŒÓ3Áv +�“nœ˜%§lSŠ}܉AÅìNj0*±¦è׳48ØÏÎi%Ñ‡Š”Ò8ÑãP5Âc‰Œ#ÅèT$F»?$²—€L~ªIžQN_òMC
  20458. Tn‰LŠ`)e|È�‹!dšäóÚòìÜ‘[ìsû‘D”\Vo�‚gFûœŽG(1¨ ÆÌOJB™É�JÛFR%pá�Ž�3NðP CéSêóÒë@pM”�ÍÝvA�f,- +®HƒFt»,Ÿ¶‡ówfA¨€�©²‹æŽ)yÁóî^­Æ¸}ÈNÅ+s8Z‚$j‡NF³ñ×âi#ÚlÈÖâh�–´ÿP!9ge ]ði˨öhòïç€öf“v'ôƒláð!êèynÛOÛä]3ã�i†™Ñ�ÀFÍ ›€ÈPkcœ\çˆ
  20459. `çõÞ@Þ92Ä z¿µXãú;]Û©áiª%[5‹”€àp¬8Q c‹ÈådÛð\ÑLo±ä;jPÚ/Š­ønýg�¢ó[åÒqBÒQP;ö˜,V“eÙçÐ3ÜPr´'Ø·õ4Yÿ©† 8»÷[% Íö¦c“
  20460. ^ˆ`Õ÷° š‹PjL>Ê íq€÷À”:6S•—ŽÑ]KÎÏ" ¥®g[¦� åÏ‘H“˜âB¬5ÈVEqÛLJŒ•X{C¼ˆ¹§B½ÅÙÒ!¥P«Iá�q9»øLlx–®Êª7Ò>Ö¤–Û]@Õ!@9H”!ªíäÈpÀÉ™Õ$ â?ÞÕ)›«�ÜŽ¨l°/"±”ÀÌ�–¯+“@`}}:\÷•¯Ð 8•zQgS£¿+ò’¤¿Á’C„£}€R:ŸõHþUF\¡Xþ’göÀ/âë€AZ%c1ÕwlET�–wX  ZNh¥ …Äyf2DÆ €Ã¸‰&v®L“qî4Æ7•ñ§ûÊzúð\�iJyÀèJ-k¯NÄ3½ ë £-¼s‘ÑJ5‰—)ÙV0™N0ÝdÚ\Ó›d0d-©ãEÚ[mf£\£UmÁx²ÒÒC«R<(`ªÑ•æƒp4^!�hÔQè �`¢ù�!l“ ~Æ™ì:J‡É ñlüW±þ€9˸ÌZXB=ëÈl)`jžªeVJ³àU€³†G!®sØç1Ô?Ƽ3„¨ÃŠ.³}bIaÙê6àÊ• œt?èÀ€ÞSxZJ'Ãp
  20461. ië,¦.ˆ�ñ¬�ØR2T`5�˜-R
  20462. BxræWHö JP°e#Bb‰|“¯”-±þ�¡�ì‹[²„ ÆäPÂâý…¤¨Eh‹±³Â‹(5Sœ¢•fÕräÃ/]˰ÑIÆŠ ÌÖd”ÞE#ú¢O®Sú3—9Ó»]¸º³€e‚¿Û®Õɹ.9_Œbêe§æ¾MŒ´�9b#e�©(’¦-ˆ 0�§Ò×Ra±àÆ„9ùº–ˆ"þ‰±þýýU,áÂ%ú~¾XèÜ€ö—”ëz€Û½{'6[@„t[W%ýÑ* .d'vR {”ÒðhЦ!ÞAed’CªE}»x=E[|ïB$7J¡* B-á� ,=k7”[_¶ê-ÐIô– ¢«€’‡J5eÖ̶Ä´{ Èí( ´†;�WMw§`«°€Ë~pÜA °z 8‡îfæ))âŒâÂ(Þü@ ©ĪÙ……Ù<áî…ä.a%N òìné@bz­Ã‡ÈÑÀµ¿>À�ëô%…‡€T*?lgb¿döÈ<‚ĵãúÀw9Na¬Å¼8;<^*%�›yÒ:tD¥Ò•Z<@ü‰0ª¨«ä‚q4±äÐíl\ –†1†îÉŸÓ�`/ž$IJ Ò“sN)¼;:A;’)$ו
  20463. °Ww¢y%KrÞIv\b¶V™£\n­d{ÀÞôÈ6t»�v�í×/~¢�ü*OÖí
  20464. 7U>£8ûr‚AC<ºjéŠEâ¢-jçØç‰·¨üxsî)��ÌD¢›–1¼ÃŒ/ÏÊq“p**̸À$Ù‘�, Ûá ƒ³BõȼpÄúk MhpˆKê7ÆUè¤Ã]ðøáh&„-ž$ˆéŽ»�¯”“Yê�£;àqËé6w•zÝ÷ÖWûî˄֭A¦h²ìDœ‘^RöÞÉ"­Æs5�fýüîw ˆ¿ä+çQ&’/9È‚–œ¸wNbÇëéü��­ãü°Øz{娕ÓþYÅ>
  20465. ]NEÚÁ±c,ßž# BFý:0ÍØ/-EȾÆÂŒÇ׃ëF\êŒôäI§{tìäA»Z‰C™ORÃuk¥ iú”ô)…ytkd�N¸&›v§A±™ˆ P{ÍÖîôËP'šó’>ÈêàxàÆ†`.Üä%,;:Ô¿Ù:Ž©«­¿íaFñ§oTQ«}v#ôìš×£‘öÚQkèÆ'ÝsÄÔÓÖØ÷~…µÞÍz5hMÄQÊ’áY>C…èÊ�™�„è¾i·ÌU± ÓNF#J0uŒÎCðäð8k“!
  20466. f«éì§v ¹{Eñ/ÏëæIKIEË> ºp·yd†Ìe
  20467. ʾ”=zô†:@7ÖJà÷ijÌ|ÆÆ5g8Àîx Å3çO±Œªþ€ÄÜÜ
  20468. þ3€H1‹ó±Ø„F. y´fz´ìWIM ñÙƒÆj[�.wæ%„i?Ò†UÂè©f|}@+[8•k7Cx¤˜S�…íEOÞ¯p $ä—üáç¾Qæ»+™Ê:¸<á]�¶¸Kâ3�‹T-y²ÂÍ[NÑÖz´µ„;y³Š¤-HZþªY^¡Ô.¥M�*Ô'h8ÒíA….°Nï2r‰œLBœ 7:Or�’©}‘C‰SËšS9äJq#ì£WI}*8ËD!ˆ¸# g#Y�>8`•
  20469. ìÐ’Âñ ?a…�2H,^ñãÄ'ƒ�ï?¸ÿ�^¸ˆæ§nƒhãOÆ’­¿i<ѪæÝYa2É+™üÌ6a°F±âa<Ì!„Û0¬‰2½]�c:ïe¼K¤¬X˜X˜[UgéO¯u5iÔyPcVÙTºž5RIúŸA6òOÔ¸i ¤ýCŽ\‡ñ…—ãQZ�M„DÄÆƒÓÚ�ÏB!X–Ä:ôÐã\!Ç^Á…"{¡E Vax$P \$ ³DBBTÞÓFtèŸ~™Ã{O‡�¼ w�ïøž5a#ø`�«=�g�€Ð�°Yý2>‡±MG¯-G­k�èªÛ1T¾b¦ü…L
  20470. ¹`*Ù€«V¬X
  20471. ­Þ*¥xªe§֊�Z*c`ªVÁSÕb¥ºÅJUŠ’ªÐ*6 TK@¨zqPÄâ¶ÉÅh“ŠÇg†Ì*ß”U§(ªöQU4‚§9L’
  20472. ­cMÆ*�ŒT»©R!R,B£È…E°Šˆ ¾*C|TzøôpðôFèô@èô4èô*àôà÷õ±î±í…°–†Ø¬á±Xób°€L€.™�T2�y`�®ÀUpbàåÀë�
  20473. �ª�T�, �%@`äÀ è€��# �?@�t€�¤øGLˆëÅž�SÀ)öžÃ¿ z“ÿtϲFy׎� �14�Lh�ŒÐ�ဃ�f�™�°ÈeÀ(.)pK€@\âà —�X¸e@�Tb v•h˜DÀÅ&ù0-I�bD‰ d@�ZD1¤@ ‘�DàyÀ¸ó€Ñ§�CN| 9Ü4æØÓš#Nc lÂÀ°;�¸, �`c‹XâÀ³@�(„�2$0� "@- �˜$è�B@‰�<$�Ð�ÁÀø8p7C�¦ €àbè(�@¥
  20474. PA@…�F �¸0�Àõ�t‰üœÞ‹äG­éÔOR—‰éIJâIïTñyS�ÍMW52\TÆoRå¥KV•0ÈŽ¬à»‚Œ(
  20475. - $²€’š€” ¤!6¦„¢wˆêH¢©†£ùú�Gù­ O r~àe~/à]þ·àV~/àP~7 Szï Kú— Fv`;ö¯`9vÑ#
  20476. J¤Ü§BÍN‚,�ä×ÎÅÓ­²'°��`��¡'â�‚`\LTþðÙApBs�)r…!Õ
  20477. â(
  20478. Òi‚`<?xml version="1.0" standalone="no"?>
  20479. <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
  20480. <svg xmlns="http://www.w3.org/2000/svg">
  20481. <metadata></metadata>
  20482. <defs>
  20483. <font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
  20484. <font-face units-per-em="1200" ascent="960" descent="-240" />
  20485. <missing-glyph horiz-adv-x="500" />
  20486. <glyph horiz-adv-x="0" />
  20487. <glyph horiz-adv-x="400" />
  20488. <glyph unicode=" " />
  20489. <glyph unicode="*" d="M600 1100q15 0 34 -1.5t30 -3.5l11 -1q10 -2 17.5 -10.5t7.5 -18.5v-224l158 158q7 7 18 8t19 -6l106 -106q7 -8 6 -19t-8 -18l-158 -158h224q10 0 18.5 -7.5t10.5 -17.5q6 -41 6 -75q0 -15 -1.5 -34t-3.5 -30l-1 -11q-2 -10 -10.5 -17.5t-18.5 -7.5h-224l158 -158 q7 -7 8 -18t-6 -19l-106 -106q-8 -7 -19 -6t-18 8l-158 158v-224q0 -10 -7.5 -18.5t-17.5 -10.5q-41 -6 -75 -6q-15 0 -34 1.5t-30 3.5l-11 1q-10 2 -17.5 10.5t-7.5 18.5v224l-158 -158q-7 -7 -18 -8t-19 6l-106 106q-7 8 -6 19t8 18l158 158h-224q-10 0 -18.5 7.5 t-10.5 17.5q-6 41 -6 75q0 15 1.5 34t3.5 30l1 11q2 10 10.5 17.5t18.5 7.5h224l-158 158q-7 7 -8 18t6 19l106 106q8 7 19 6t18 -8l158 -158v224q0 10 7.5 18.5t17.5 10.5q41 6 75 6z" />
  20490. <glyph unicode="+" d="M450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-350h350q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-350v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v350h-350q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5 h350v350q0 21 14.5 35.5t35.5 14.5z" />
  20491. <glyph unicode="&#xa0;" />
  20492. <glyph unicode="&#xa5;" d="M825 1100h250q10 0 12.5 -5t-5.5 -13l-364 -364q-6 -6 -11 -18h268q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-100h275q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-174q0 -11 -7.5 -18.5t-18.5 -7.5h-148q-11 0 -18.5 7.5t-7.5 18.5v174 h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h125v100h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h118q-5 12 -11 18l-364 364q-8 8 -5.5 13t12.5 5h250q25 0 43 -18l164 -164q8 -8 18 -8t18 8l164 164q18 18 43 18z" />
  20493. <glyph unicode="&#x2000;" horiz-adv-x="650" />
  20494. <glyph unicode="&#x2001;" horiz-adv-x="1300" />
  20495. <glyph unicode="&#x2002;" horiz-adv-x="650" />
  20496. <glyph unicode="&#x2003;" horiz-adv-x="1300" />
  20497. <glyph unicode="&#x2004;" horiz-adv-x="433" />
  20498. <glyph unicode="&#x2005;" horiz-adv-x="325" />
  20499. <glyph unicode="&#x2006;" horiz-adv-x="216" />
  20500. <glyph unicode="&#x2007;" horiz-adv-x="216" />
  20501. <glyph unicode="&#x2008;" horiz-adv-x="162" />
  20502. <glyph unicode="&#x2009;" horiz-adv-x="260" />
  20503. <glyph unicode="&#x200a;" horiz-adv-x="72" />
  20504. <glyph unicode="&#x202f;" horiz-adv-x="260" />
  20505. <glyph unicode="&#x205f;" horiz-adv-x="325" />
  20506. <glyph unicode="&#x20ac;" d="M744 1198q242 0 354 -189q60 -104 66 -209h-181q0 45 -17.5 82.5t-43.5 61.5t-58 40.5t-60.5 24t-51.5 7.5q-19 0 -40.5 -5.5t-49.5 -20.5t-53 -38t-49 -62.5t-39 -89.5h379l-100 -100h-300q-6 -50 -6 -100h406l-100 -100h-300q9 -74 33 -132t52.5 -91t61.5 -54.5t59 -29 t47 -7.5q22 0 50.5 7.5t60.5 24.5t58 41t43.5 61t17.5 80h174q-30 -171 -128 -278q-107 -117 -274 -117q-206 0 -324 158q-36 48 -69 133t-45 204h-217l100 100h112q1 47 6 100h-218l100 100h134q20 87 51 153.5t62 103.5q117 141 297 141z" />
  20507. <glyph unicode="&#x20bd;" d="M428 1200h350q67 0 120 -13t86 -31t57 -49.5t35 -56.5t17 -64.5t6.5 -60.5t0.5 -57v-16.5v-16.5q0 -36 -0.5 -57t-6.5 -61t-17 -65t-35 -57t-57 -50.5t-86 -31.5t-120 -13h-178l-2 -100h288q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-138v-175q0 -11 -5.5 -18 t-15.5 -7h-149q-10 0 -17.5 7.5t-7.5 17.5v175h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v100h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v475q0 10 7.5 17.5t17.5 7.5zM600 1000v-300h203q64 0 86.5 33t22.5 119q0 84 -22.5 116t-86.5 32h-203z" />
  20508. <glyph unicode="&#x2212;" d="M250 700h800q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
  20509. <glyph unicode="&#x231b;" d="M1000 1200v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-50v-100q0 -91 -49.5 -165.5t-130.5 -109.5q81 -35 130.5 -109.5t49.5 -165.5v-150h50q21 0 35.5 -14.5t14.5 -35.5v-150h-800v150q0 21 14.5 35.5t35.5 14.5h50v150q0 91 49.5 165.5t130.5 109.5q-81 35 -130.5 109.5 t-49.5 165.5v100h-50q-21 0 -35.5 14.5t-14.5 35.5v150h800zM400 1000v-100q0 -60 32.5 -109.5t87.5 -73.5q28 -12 44 -37t16 -55t-16 -55t-44 -37q-55 -24 -87.5 -73.5t-32.5 -109.5v-150h400v150q0 60 -32.5 109.5t-87.5 73.5q-28 12 -44 37t-16 55t16 55t44 37 q55 24 87.5 73.5t32.5 109.5v100h-400z" />
  20510. <glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
  20511. <glyph unicode="&#x2601;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -206.5q0 -121 -85 -207.5t-205 -86.5h-750q-79 0 -135.5 57t-56.5 137q0 69 42.5 122.5t108.5 67.5q-2 12 -2 37q0 153 108 260.5t260 107.5z" />
  20512. <glyph unicode="&#x26fa;" d="M774 1193.5q16 -9.5 20.5 -27t-5.5 -33.5l-136 -187l467 -746h30q20 0 35 -18.5t15 -39.5v-42h-1200v42q0 21 15 39.5t35 18.5h30l468 746l-135 183q-10 16 -5.5 34t20.5 28t34 5.5t28 -20.5l111 -148l112 150q9 16 27 20.5t34 -5zM600 200h377l-182 112l-195 534v-646z " />
  20513. <glyph unicode="&#x2709;" d="M25 1100h1150q10 0 12.5 -5t-5.5 -13l-564 -567q-8 -8 -18 -8t-18 8l-564 567q-8 8 -5.5 13t12.5 5zM18 882l264 -264q8 -8 8 -18t-8 -18l-264 -264q-8 -8 -13 -5.5t-5 12.5v550q0 10 5 12.5t13 -5.5zM918 618l264 264q8 8 13 5.5t5 -12.5v-550q0 -10 -5 -12.5t-13 5.5 l-264 264q-8 8 -8 18t8 18zM818 482l364 -364q8 -8 5.5 -13t-12.5 -5h-1150q-10 0 -12.5 5t5.5 13l364 364q8 8 18 8t18 -8l164 -164q8 -8 18 -8t18 8l164 164q8 8 18 8t18 -8z" />
  20514. <glyph unicode="&#x270f;" d="M1011 1210q19 0 33 -13l153 -153q13 -14 13 -33t-13 -33l-99 -92l-214 214l95 96q13 14 32 14zM1013 800l-615 -614l-214 214l614 614zM317 96l-333 -112l110 335z" />
  20515. <glyph unicode="&#xe001;" d="M700 650v-550h250q21 0 35.5 -14.5t14.5 -35.5v-50h-800v50q0 21 14.5 35.5t35.5 14.5h250v550l-500 550h1200z" />
  20516. <glyph unicode="&#xe002;" d="M368 1017l645 163q39 15 63 0t24 -49v-831q0 -55 -41.5 -95.5t-111.5 -63.5q-79 -25 -147 -4.5t-86 75t25.5 111.5t122.5 82q72 24 138 8v521l-600 -155v-606q0 -42 -44 -90t-109 -69q-79 -26 -147 -5.5t-86 75.5t25.5 111.5t122.5 82.5q72 24 138 7v639q0 38 14.5 59 t53.5 34z" />
  20517. <glyph unicode="&#xe003;" d="M500 1191q100 0 191 -39t156.5 -104.5t104.5 -156.5t39 -191l-1 -2l1 -5q0 -141 -78 -262l275 -274q23 -26 22.5 -44.5t-22.5 -42.5l-59 -58q-26 -20 -46.5 -20t-39.5 20l-275 274q-119 -77 -261 -77l-5 1l-2 -1q-100 0 -191 39t-156.5 104.5t-104.5 156.5t-39 191 t39 191t104.5 156.5t156.5 104.5t191 39zM500 1022q-88 0 -162 -43t-117 -117t-43 -162t43 -162t117 -117t162 -43t162 43t117 117t43 162t-43 162t-117 117t-162 43z" />
  20518. <glyph unicode="&#xe005;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104z" />
  20519. <glyph unicode="&#xe006;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429z" />
  20520. <glyph unicode="&#xe007;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429zM477 700h-240l197 -142l-74 -226 l193 139l195 -140l-74 229l192 140h-234l-78 211z" />
  20521. <glyph unicode="&#xe008;" d="M600 1200q124 0 212 -88t88 -212v-250q0 -46 -31 -98t-69 -52v-75q0 -10 6 -21.5t15 -17.5l358 -230q9 -5 15 -16.5t6 -21.5v-93q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v93q0 10 6 21.5t15 16.5l358 230q9 6 15 17.5t6 21.5v75q-38 0 -69 52 t-31 98v250q0 124 88 212t212 88z" />
  20522. <glyph unicode="&#xe009;" d="M25 1100h1150q10 0 17.5 -7.5t7.5 -17.5v-1050q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v1050q0 10 7.5 17.5t17.5 7.5zM100 1000v-100h100v100h-100zM875 1000h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5t17.5 -7.5h550 q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM1000 1000v-100h100v100h-100zM100 800v-100h100v100h-100zM1000 800v-100h100v100h-100zM100 600v-100h100v100h-100zM1000 600v-100h100v100h-100zM875 500h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5 t17.5 -7.5h550q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM100 400v-100h100v100h-100zM1000 400v-100h100v100h-100zM100 200v-100h100v100h-100zM1000 200v-100h100v100h-100z" />
  20523. <glyph unicode="&#xe010;" d="M50 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM50 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
  20524. <glyph unicode="&#xe011;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM850 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 700h200q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5 t35.5 14.5z" />
  20525. <glyph unicode="&#xe012;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h700q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
  20526. <glyph unicode="&#xe013;" d="M465 477l571 571q8 8 18 8t17 -8l177 -177q8 -7 8 -17t-8 -18l-783 -784q-7 -8 -17.5 -8t-17.5 8l-384 384q-8 8 -8 18t8 17l177 177q7 8 17 8t18 -8l171 -171q7 -7 18 -7t18 7z" />
  20527. <glyph unicode="&#xe014;" d="M904 1083l178 -179q8 -8 8 -18.5t-8 -17.5l-267 -268l267 -268q8 -7 8 -17.5t-8 -18.5l-178 -178q-8 -8 -18.5 -8t-17.5 8l-268 267l-268 -267q-7 -8 -17.5 -8t-18.5 8l-178 178q-8 8 -8 18.5t8 17.5l267 268l-267 268q-8 7 -8 17.5t8 18.5l178 178q8 8 18.5 8t17.5 -8 l268 -267l268 268q7 7 17.5 7t18.5 -7z" />
  20528. <glyph unicode="&#xe015;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM425 900h150q10 0 17.5 -7.5t7.5 -17.5v-75h75q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5 t-17.5 -7.5h-75v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-75q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v75q0 10 7.5 17.5t17.5 7.5z" />
  20529. <glyph unicode="&#xe016;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM325 800h350q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-350q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
  20530. <glyph unicode="&#xe017;" d="M550 1200h100q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM800 975v166q167 -62 272 -209.5t105 -331.5q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5 t-184.5 123t-123 184.5t-45.5 224q0 184 105 331.5t272 209.5v-166q-103 -55 -165 -155t-62 -220q0 -116 57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5q0 120 -62 220t-165 155z" />
  20531. <glyph unicode="&#xe018;" d="M1025 1200h150q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM725 800h150q10 0 17.5 -7.5t7.5 -17.5v-750q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v750 q0 10 7.5 17.5t17.5 7.5zM425 500h150q10 0 17.5 -7.5t7.5 -17.5v-450q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v450q0 10 7.5 17.5t17.5 7.5zM125 300h150q10 0 17.5 -7.5t7.5 -17.5v-250q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5 v250q0 10 7.5 17.5t17.5 7.5z" />
  20532. <glyph unicode="&#xe019;" d="M600 1174q33 0 74 -5l38 -152l5 -1q49 -14 94 -39l5 -2l134 80q61 -48 104 -105l-80 -134l3 -5q25 -44 39 -93l1 -6l152 -38q5 -43 5 -73q0 -34 -5 -74l-152 -38l-1 -6q-15 -49 -39 -93l-3 -5l80 -134q-48 -61 -104 -105l-134 81l-5 -3q-44 -25 -94 -39l-5 -2l-38 -151 q-43 -5 -74 -5q-33 0 -74 5l-38 151l-5 2q-49 14 -94 39l-5 3l-134 -81q-60 48 -104 105l80 134l-3 5q-25 45 -38 93l-2 6l-151 38q-6 42 -6 74q0 33 6 73l151 38l2 6q13 48 38 93l3 5l-80 134q47 61 105 105l133 -80l5 2q45 25 94 39l5 1l38 152q43 5 74 5zM600 815 q-89 0 -152 -63t-63 -151.5t63 -151.5t152 -63t152 63t63 151.5t-63 151.5t-152 63z" />
  20533. <glyph unicode="&#xe020;" d="M500 1300h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-75h-1100v75q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5zM500 1200v-100h300v100h-300zM1100 900v-800q0 -41 -29.5 -70.5t-70.5 -29.5h-700q-41 0 -70.5 29.5t-29.5 70.5 v800h900zM300 800v-700h100v700h-100zM500 800v-700h100v700h-100zM700 800v-700h100v700h-100zM900 800v-700h100v700h-100z" />
  20534. <glyph unicode="&#xe021;" d="M18 618l620 608q8 7 18.5 7t17.5 -7l608 -608q8 -8 5.5 -13t-12.5 -5h-175v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v375h-300v-375q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v575h-175q-10 0 -12.5 5t5.5 13z" />
  20535. <glyph unicode="&#xe022;" d="M600 1200v-400q0 -41 29.5 -70.5t70.5 -29.5h300v-650q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5h450zM1000 800h-250q-21 0 -35.5 14.5t-14.5 35.5v250z" />
  20536. <glyph unicode="&#xe023;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h50q10 0 17.5 -7.5t7.5 -17.5v-275h175q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5z" />
  20537. <glyph unicode="&#xe024;" d="M1300 0h-538l-41 400h-242l-41 -400h-538l431 1200h209l-21 -300h162l-20 300h208zM515 800l-27 -300h224l-27 300h-170z" />
  20538. <glyph unicode="&#xe025;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-450h191q20 0 25.5 -11.5t-7.5 -27.5l-327 -400q-13 -16 -32 -16t-32 16l-327 400q-13 16 -7.5 27.5t25.5 11.5h191v450q0 21 14.5 35.5t35.5 14.5zM1125 400h50q10 0 17.5 -7.5t7.5 -17.5v-350q0 -10 -7.5 -17.5t-17.5 -7.5 h-1050q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h50q10 0 17.5 -7.5t7.5 -17.5v-175h900v175q0 10 7.5 17.5t17.5 7.5z" />
  20539. <glyph unicode="&#xe026;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -275q-13 -16 -32 -16t-32 16l-223 275q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z " />
  20540. <glyph unicode="&#xe027;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM632 914l223 -275q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5l223 275q13 16 32 16 t32 -16z" />
  20541. <glyph unicode="&#xe028;" d="M225 1200h750q10 0 19.5 -7t12.5 -17l186 -652q7 -24 7 -49v-425q0 -12 -4 -27t-9 -17q-12 -6 -37 -6h-1100q-12 0 -27 4t-17 8q-6 13 -6 38l1 425q0 25 7 49l185 652q3 10 12.5 17t19.5 7zM878 1000h-556q-10 0 -19 -7t-11 -18l-87 -450q-2 -11 4 -18t16 -7h150 q10 0 19.5 -7t11.5 -17l38 -152q2 -10 11.5 -17t19.5 -7h250q10 0 19.5 7t11.5 17l38 152q2 10 11.5 17t19.5 7h150q10 0 16 7t4 18l-87 450q-2 11 -11 18t-19 7z" />
  20542. <glyph unicode="&#xe029;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM540 820l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
  20543. <glyph unicode="&#xe030;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-362q0 -10 -7.5 -17.5t-17.5 -7.5h-362q-11 0 -13 5.5t5 12.5l133 133q-109 76 -238 76q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5h150q0 -117 -45.5 -224 t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117z" />
  20544. <glyph unicode="&#xe031;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-361q0 -11 -7.5 -18.5t-18.5 -7.5h-361q-11 0 -13 5.5t5 12.5l134 134q-110 75 -239 75q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5h-150q0 117 45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117zM1027 600h150 q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5q-192 0 -348 118l-134 -134q-7 -8 -12.5 -5.5t-5.5 12.5v360q0 11 7.5 18.5t18.5 7.5h360q10 0 12.5 -5.5t-5.5 -12.5l-133 -133q110 -76 240 -76q116 0 214.5 57t155.5 155.5t57 214.5z" />
  20545. <glyph unicode="&#xe032;" d="M125 1200h1050q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-1050q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM1075 1000h-850q-10 0 -17.5 -7.5t-7.5 -17.5v-850q0 -10 7.5 -17.5t17.5 -7.5h850q10 0 17.5 7.5t7.5 17.5v850 q0 10 -7.5 17.5t-17.5 7.5zM325 900h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 900h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 700h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 700h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 500h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 500h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 300h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 300h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5z" />
  20546. <glyph unicode="&#xe033;" d="M900 800v200q0 83 -58.5 141.5t-141.5 58.5h-300q-82 0 -141 -59t-59 -141v-200h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h900q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-100zM400 800v150q0 21 15 35.5t35 14.5h200 q20 0 35 -14.5t15 -35.5v-150h-300z" />
  20547. <glyph unicode="&#xe034;" d="M125 1100h50q10 0 17.5 -7.5t7.5 -17.5v-1075h-100v1075q0 10 7.5 17.5t17.5 7.5zM1075 1052q4 0 9 -2q16 -6 16 -23v-421q0 -6 -3 -12q-33 -59 -66.5 -99t-65.5 -58t-56.5 -24.5t-52.5 -6.5q-26 0 -57.5 6.5t-52.5 13.5t-60 21q-41 15 -63 22.5t-57.5 15t-65.5 7.5 q-85 0 -160 -57q-7 -5 -15 -5q-6 0 -11 3q-14 7 -14 22v438q22 55 82 98.5t119 46.5q23 2 43 0.5t43 -7t32.5 -8.5t38 -13t32.5 -11q41 -14 63.5 -21t57 -14t63.5 -7q103 0 183 87q7 8 18 8z" />
  20548. <glyph unicode="&#xe035;" d="M600 1175q116 0 227 -49.5t192.5 -131t131 -192.5t49.5 -227v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v300q0 127 -70.5 231.5t-184.5 161.5t-245 57t-245 -57t-184.5 -161.5t-70.5 -231.5v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50 q-10 0 -17.5 7.5t-7.5 17.5v300q0 116 49.5 227t131 192.5t192.5 131t227 49.5zM220 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460q0 8 6 14t14 6zM820 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460 q0 8 6 14t14 6z" />
  20549. <glyph unicode="&#xe036;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM900 668l120 120q7 7 17 7t17 -7l34 -34q7 -7 7 -17t-7 -17l-120 -120l120 -120q7 -7 7 -17 t-7 -17l-34 -34q-7 -7 -17 -7t-17 7l-120 119l-120 -119q-7 -7 -17 -7t-17 7l-34 34q-7 7 -7 17t7 17l119 120l-119 120q-7 7 -7 17t7 17l34 34q7 8 17 8t17 -8z" />
  20550. <glyph unicode="&#xe037;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6 l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238q-6 8 -4.5 18t9.5 17l29 22q7 5 15 5z" />
  20551. <glyph unicode="&#xe038;" d="M967 1004h3q11 -1 17 -10q135 -179 135 -396q0 -105 -34 -206.5t-98 -185.5q-7 -9 -17 -10h-3q-9 0 -16 6l-42 34q-8 6 -9 16t5 18q111 150 111 328q0 90 -29.5 176t-84.5 157q-6 9 -5 19t10 16l42 33q7 5 15 5zM321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5 t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238 q-6 8 -4.5 18.5t9.5 16.5l29 22q7 5 15 5z" />
  20552. <glyph unicode="&#xe039;" d="M500 900h100v-100h-100v-100h-400v-100h-100v600h500v-300zM1200 700h-200v-100h200v-200h-300v300h-200v300h-100v200h600v-500zM100 1100v-300h300v300h-300zM800 1100v-300h300v300h-300zM300 900h-100v100h100v-100zM1000 900h-100v100h100v-100zM300 500h200v-500 h-500v500h200v100h100v-100zM800 300h200v-100h-100v-100h-200v100h-100v100h100v200h-200v100h300v-300zM100 400v-300h300v300h-300zM300 200h-100v100h100v-100zM1200 200h-100v100h100v-100zM700 0h-100v100h100v-100zM1200 0h-300v100h300v-100z" />
  20553. <glyph unicode="&#xe040;" d="M100 200h-100v1000h100v-1000zM300 200h-100v1000h100v-1000zM700 200h-200v1000h200v-1000zM900 200h-100v1000h100v-1000zM1200 200h-200v1000h200v-1000zM400 0h-300v100h300v-100zM600 0h-100v91h100v-91zM800 0h-100v91h100v-91zM1100 0h-200v91h200v-91z" />
  20554. <glyph unicode="&#xe041;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
  20555. <glyph unicode="&#xe042;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM800 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-56 56l424 426l-700 700h150zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5 t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
  20556. <glyph unicode="&#xe043;" d="M300 1200h825q75 0 75 -75v-900q0 -25 -18 -43l-64 -64q-8 -8 -13 -5.5t-5 12.5v950q0 10 -7.5 17.5t-17.5 7.5h-700q-25 0 -43 -18l-64 -64q-8 -8 -5.5 -13t12.5 -5h700q10 0 17.5 -7.5t7.5 -17.5v-950q0 -10 -7.5 -17.5t-17.5 -7.5h-850q-10 0 -17.5 7.5t-7.5 17.5v975 q0 25 18 43l139 139q18 18 43 18z" />
  20557. <glyph unicode="&#xe044;" d="M250 1200h800q21 0 35.5 -14.5t14.5 -35.5v-1150l-450 444l-450 -445v1151q0 21 14.5 35.5t35.5 14.5z" />
  20558. <glyph unicode="&#xe045;" d="M822 1200h-444q-11 0 -19 -7.5t-9 -17.5l-78 -301q-7 -24 7 -45l57 -108q6 -9 17.5 -15t21.5 -6h450q10 0 21.5 6t17.5 15l62 108q14 21 7 45l-83 301q-1 10 -9 17.5t-19 7.5zM1175 800h-150q-10 0 -21 -6.5t-15 -15.5l-78 -156q-4 -9 -15 -15.5t-21 -6.5h-550 q-10 0 -21 6.5t-15 15.5l-78 156q-4 9 -15 15.5t-21 6.5h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-650q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h750q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5 t7.5 17.5v650q0 10 -7.5 17.5t-17.5 7.5zM850 200h-500q-10 0 -19.5 -7t-11.5 -17l-38 -152q-2 -10 3.5 -17t15.5 -7h600q10 0 15.5 7t3.5 17l-38 152q-2 10 -11.5 17t-19.5 7z" />
  20559. <glyph unicode="&#xe046;" d="M500 1100h200q56 0 102.5 -20.5t72.5 -50t44 -59t25 -50.5l6 -20h150q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5h150q2 8 6.5 21.5t24 48t45 61t72 48t102.5 21.5zM900 800v-100 h100v100h-100zM600 730q-95 0 -162.5 -67.5t-67.5 -162.5t67.5 -162.5t162.5 -67.5t162.5 67.5t67.5 162.5t-67.5 162.5t-162.5 67.5zM600 603q43 0 73 -30t30 -73t-30 -73t-73 -30t-73 30t-30 73t30 73t73 30z" />
  20560. <glyph unicode="&#xe047;" d="M681 1199l385 -998q20 -50 60 -92q18 -19 36.5 -29.5t27.5 -11.5l10 -2v-66h-417v66q53 0 75 43.5t5 88.5l-82 222h-391q-58 -145 -92 -234q-11 -34 -6.5 -57t25.5 -37t46 -20t55 -6v-66h-365v66q56 24 84 52q12 12 25 30.5t20 31.5l7 13l399 1006h93zM416 521h340 l-162 457z" />
  20561. <glyph unicode="&#xe048;" d="M753 641q5 -1 14.5 -4.5t36 -15.5t50.5 -26.5t53.5 -40t50.5 -54.5t35.5 -70t14.5 -87q0 -67 -27.5 -125.5t-71.5 -97.5t-98.5 -66.5t-108.5 -40.5t-102 -13h-500v89q41 7 70.5 32.5t29.5 65.5v827q0 24 -0.5 34t-3.5 24t-8.5 19.5t-17 13.5t-28 12.5t-42.5 11.5v71 l471 -1q57 0 115.5 -20.5t108 -57t80.5 -94t31 -124.5q0 -51 -15.5 -96.5t-38 -74.5t-45 -50.5t-38.5 -30.5zM400 700h139q78 0 130.5 48.5t52.5 122.5q0 41 -8.5 70.5t-29.5 55.5t-62.5 39.5t-103.5 13.5h-118v-350zM400 200h216q80 0 121 50.5t41 130.5q0 90 -62.5 154.5 t-156.5 64.5h-159v-400z" />
  20562. <glyph unicode="&#xe049;" d="M877 1200l2 -57q-83 -19 -116 -45.5t-40 -66.5l-132 -839q-9 -49 13 -69t96 -26v-97h-500v97q186 16 200 98l173 832q3 17 3 30t-1.5 22.5t-9 17.5t-13.5 12.5t-21.5 10t-26 8.5t-33.5 10q-13 3 -19 5v57h425z" />
  20563. <glyph unicode="&#xe050;" d="M1300 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM175 1000h-75v-800h75l-125 -167l-125 167h75v800h-75l125 167z" />
  20564. <glyph unicode="&#xe051;" d="M1100 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-650q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v650h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM1167 50l-167 -125v75h-800v-75l-167 125l167 125v-75h800v75z" />
  20565. <glyph unicode="&#xe052;" d="M50 1100h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
  20566. <glyph unicode="&#xe053;" d="M250 1100h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM250 500h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
  20567. <glyph unicode="&#xe054;" d="M500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000 q-21 0 -35.5 14.5t-14.5 35.5zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5zM0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5z" />
  20568. <glyph unicode="&#xe055;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
  20569. <glyph unicode="&#xe056;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 1100h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 800h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 500h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 500h800q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 200h800 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
  20570. <glyph unicode="&#xe057;" d="M400 0h-100v1100h100v-1100zM550 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM267 550l-167 -125v75h-200v100h200v75zM550 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
  20571. <glyph unicode="&#xe058;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM900 0h-100v1100h100v-1100zM50 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM1100 600h200v-100h-200v-75l-167 125l167 125v-75zM50 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
  20572. <glyph unicode="&#xe059;" d="M75 1000h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53v650q0 31 22 53t53 22zM1200 300l-300 300l300 300v-600z" />
  20573. <glyph unicode="&#xe060;" d="M44 1100h1112q18 0 31 -13t13 -31v-1012q0 -18 -13 -31t-31 -13h-1112q-18 0 -31 13t-13 31v1012q0 18 13 31t31 13zM100 1000v-737l247 182l298 -131l-74 156l293 318l236 -288v500h-1000zM342 884q56 0 95 -39t39 -94.5t-39 -95t-95 -39.5t-95 39.5t-39 95t39 94.5 t95 39z" />
  20574. <glyph unicode="&#xe062;" d="M648 1169q117 0 216 -60t156.5 -161t57.5 -218q0 -115 -70 -258q-69 -109 -158 -225.5t-143 -179.5l-54 -62q-9 8 -25.5 24.5t-63.5 67.5t-91 103t-98.5 128t-95.5 148q-60 132 -60 249q0 88 34 169.5t91.5 142t137 96.5t166.5 36zM652.5 974q-91.5 0 -156.5 -65 t-65 -157t65 -156.5t156.5 -64.5t156.5 64.5t65 156.5t-65 157t-156.5 65z" />
  20575. <glyph unicode="&#xe063;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 173v854q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57z" />
  20576. <glyph unicode="&#xe064;" d="M554 1295q21 -72 57.5 -143.5t76 -130t83 -118t82.5 -117t70 -116t49.5 -126t18.5 -136.5q0 -71 -25.5 -135t-68.5 -111t-99 -82t-118.5 -54t-125.5 -23q-84 5 -161.5 34t-139.5 78.5t-99 125t-37 164.5q0 69 18 136.5t49.5 126.5t69.5 116.5t81.5 117.5t83.5 119 t76.5 131t58.5 143zM344 710q-23 -33 -43.5 -70.5t-40.5 -102.5t-17 -123q1 -37 14.5 -69.5t30 -52t41 -37t38.5 -24.5t33 -15q21 -7 32 -1t13 22l6 34q2 10 -2.5 22t-13.5 19q-5 4 -14 12t-29.5 40.5t-32.5 73.5q-26 89 6 271q2 11 -6 11q-8 1 -15 -10z" />
  20577. <glyph unicode="&#xe065;" d="M1000 1013l108 115q2 1 5 2t13 2t20.5 -1t25 -9.5t28.5 -21.5q22 -22 27 -43t0 -32l-6 -10l-108 -115zM350 1100h400q50 0 105 -13l-187 -187h-368q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v182l200 200v-332 q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM1009 803l-362 -362l-161 -50l55 170l355 355z" />
  20578. <glyph unicode="&#xe066;" d="M350 1100h361q-164 -146 -216 -200h-195q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-103q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M824 1073l339 -301q8 -7 8 -17.5t-8 -17.5l-340 -306q-7 -6 -12.5 -4t-6.5 11v203q-26 1 -54.5 0t-78.5 -7.5t-92 -17.5t-86 -35t-70 -57q10 59 33 108t51.5 81.5t65 58.5t68.5 40.5t67 24.5t56 13.5t40 4.5v210q1 10 6.5 12.5t13.5 -4.5z" />
  20579. <glyph unicode="&#xe067;" d="M350 1100h350q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-219q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M643 639l395 395q7 7 17.5 7t17.5 -7l101 -101q7 -7 7 -17.5t-7 -17.5l-531 -532q-7 -7 -17.5 -7t-17.5 7l-248 248q-7 7 -7 17.5t7 17.5l101 101q7 7 17.5 7t17.5 -7l111 -111q8 -7 18 -7t18 7z" />
  20580. <glyph unicode="&#xe068;" d="M318 918l264 264q8 8 18 8t18 -8l260 -264q7 -8 4.5 -13t-12.5 -5h-170v-200h200v173q0 10 5 12t13 -5l264 -260q8 -7 8 -17.5t-8 -17.5l-264 -265q-8 -7 -13 -5t-5 12v173h-200v-200h170q10 0 12.5 -5t-4.5 -13l-260 -264q-8 -8 -18 -8t-18 8l-264 264q-8 8 -5.5 13 t12.5 5h175v200h-200v-173q0 -10 -5 -12t-13 5l-264 265q-8 7 -8 17.5t8 17.5l264 260q8 7 13 5t5 -12v-173h200v200h-175q-10 0 -12.5 5t5.5 13z" />
  20581. <glyph unicode="&#xe069;" d="M250 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
  20582. <glyph unicode="&#xe070;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5 t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
  20583. <glyph unicode="&#xe071;" d="M1200 1050v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-492 480q-15 14 -15 35t15 35l492 480q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25z" />
  20584. <glyph unicode="&#xe072;" d="M243 1074l814 -498q18 -11 18 -26t-18 -26l-814 -498q-18 -11 -30.5 -4t-12.5 28v1000q0 21 12.5 28t30.5 -4z" />
  20585. <glyph unicode="&#xe073;" d="M250 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM650 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800 q0 21 14.5 35.5t35.5 14.5z" />
  20586. <glyph unicode="&#xe074;" d="M1100 950v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5z" />
  20587. <glyph unicode="&#xe075;" d="M500 612v438q0 21 10.5 25t25.5 -10l492 -480q15 -14 15 -35t-15 -35l-492 -480q-15 -14 -25.5 -10t-10.5 25v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10z" />
  20588. <glyph unicode="&#xe076;" d="M1048 1102l100 1q20 0 35 -14.5t15 -35.5l5 -1000q0 -21 -14.5 -35.5t-35.5 -14.5l-100 -1q-21 0 -35.5 14.5t-14.5 35.5l-2 437l-463 -454q-14 -15 -24.5 -10.5t-10.5 25.5l-2 437l-462 -455q-15 -14 -25.5 -9.5t-10.5 24.5l-5 1000q0 21 10.5 25.5t25.5 -10.5l466 -450 l-2 438q0 20 10.5 24.5t25.5 -9.5l466 -451l-2 438q0 21 14.5 35.5t35.5 14.5z" />
  20589. <glyph unicode="&#xe077;" d="M850 1100h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10l464 -453v438q0 21 14.5 35.5t35.5 14.5z" />
  20590. <glyph unicode="&#xe078;" d="M686 1081l501 -540q15 -15 10.5 -26t-26.5 -11h-1042q-22 0 -26.5 11t10.5 26l501 540q15 15 36 15t36 -15zM150 400h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
  20591. <glyph unicode="&#xe079;" d="M885 900l-352 -353l352 -353l-197 -198l-552 552l552 550z" />
  20592. <glyph unicode="&#xe080;" d="M1064 547l-551 -551l-198 198l353 353l-353 353l198 198z" />
  20593. <glyph unicode="&#xe081;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM650 900h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-150 q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5h150v-150q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v150h150q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-150v150q0 21 -14.5 35.5t-35.5 14.5z" />
  20594. <glyph unicode="&#xe082;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM850 700h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5 t35.5 -14.5h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5z" />
  20595. <glyph unicode="&#xe083;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM741.5 913q-12.5 0 -21.5 -9l-120 -120l-120 120q-9 9 -21.5 9 t-21.5 -9l-141 -141q-9 -9 -9 -21.5t9 -21.5l120 -120l-120 -120q-9 -9 -9 -21.5t9 -21.5l141 -141q9 -9 21.5 -9t21.5 9l120 120l120 -120q9 -9 21.5 -9t21.5 9l141 141q9 9 9 21.5t-9 21.5l-120 120l120 120q9 9 9 21.5t-9 21.5l-141 141q-9 9 -21.5 9z" />
  20596. <glyph unicode="&#xe084;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM546 623l-84 85q-7 7 -17.5 7t-18.5 -7l-139 -139q-7 -8 -7 -18t7 -18 l242 -241q7 -8 17.5 -8t17.5 8l375 375q7 7 7 17.5t-7 18.5l-139 139q-7 7 -17.5 7t-17.5 -7z" />
  20597. <glyph unicode="&#xe085;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM588 941q-29 0 -59 -5.5t-63 -20.5t-58 -38.5t-41.5 -63t-16.5 -89.5 q0 -25 20 -25h131q30 -5 35 11q6 20 20.5 28t45.5 8q20 0 31.5 -10.5t11.5 -28.5q0 -23 -7 -34t-26 -18q-1 0 -13.5 -4t-19.5 -7.5t-20 -10.5t-22 -17t-18.5 -24t-15.5 -35t-8 -46q-1 -8 5.5 -16.5t20.5 -8.5h173q7 0 22 8t35 28t37.5 48t29.5 74t12 100q0 47 -17 83 t-42.5 57t-59.5 34.5t-64 18t-59 4.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
  20598. <glyph unicode="&#xe086;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM675 1000h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5 t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5zM675 700h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h75v-200h-75q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h350q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5 t-17.5 7.5h-75v275q0 10 -7.5 17.5t-17.5 7.5z" />
  20599. <glyph unicode="&#xe087;" d="M525 1200h150q10 0 17.5 -7.5t7.5 -17.5v-194q103 -27 178.5 -102.5t102.5 -178.5h194q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-194q-27 -103 -102.5 -178.5t-178.5 -102.5v-194q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v194 q-103 27 -178.5 102.5t-102.5 178.5h-194q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h194q27 103 102.5 178.5t178.5 102.5v194q0 10 7.5 17.5t17.5 7.5zM700 893v-168q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v168q-68 -23 -119 -74 t-74 -119h168q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-168q23 -68 74 -119t119 -74v168q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-168q68 23 119 74t74 119h-168q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h168 q-23 68 -74 119t-119 74z" />
  20600. <glyph unicode="&#xe088;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM759 823l64 -64q7 -7 7 -17.5t-7 -17.5l-124 -124l124 -124q7 -7 7 -17.5t-7 -17.5l-64 -64q-7 -7 -17.5 -7t-17.5 7l-124 124l-124 -124q-7 -7 -17.5 -7t-17.5 7l-64 64 q-7 7 -7 17.5t7 17.5l124 124l-124 124q-7 7 -7 17.5t7 17.5l64 64q7 7 17.5 7t17.5 -7l124 -124l124 124q7 7 17.5 7t17.5 -7z" />
  20601. <glyph unicode="&#xe089;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM782 788l106 -106q7 -7 7 -17.5t-7 -17.5l-320 -321q-8 -7 -18 -7t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l197 197q7 7 17.5 7t17.5 -7z" />
  20602. <glyph unicode="&#xe090;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5q0 -120 65 -225 l587 587q-105 65 -225 65zM965 819l-584 -584q104 -62 219 -62q116 0 214.5 57t155.5 155.5t57 214.5q0 115 -62 219z" />
  20603. <glyph unicode="&#xe091;" d="M39 582l522 427q16 13 27.5 8t11.5 -26v-291h550q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-550v-291q0 -21 -11.5 -26t-27.5 8l-522 427q-16 13 -16 32t16 32z" />
  20604. <glyph unicode="&#xe092;" d="M639 1009l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291h-550q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h550v291q0 21 11.5 26t27.5 -8z" />
  20605. <glyph unicode="&#xe093;" d="M682 1161l427 -522q13 -16 8 -27.5t-26 -11.5h-291v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v550h-291q-21 0 -26 11.5t8 27.5l427 522q13 16 32 16t32 -16z" />
  20606. <glyph unicode="&#xe094;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-550h291q21 0 26 -11.5t-8 -27.5l-427 -522q-13 -16 -32 -16t-32 16l-427 522q-13 16 -8 27.5t26 11.5h291v550q0 21 14.5 35.5t35.5 14.5z" />
  20607. <glyph unicode="&#xe095;" d="M639 1109l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291q-94 -2 -182 -20t-170.5 -52t-147 -92.5t-100.5 -135.5q5 105 27 193.5t67.5 167t113 135t167 91.5t225.5 42v262q0 21 11.5 26t27.5 -8z" />
  20608. <glyph unicode="&#xe096;" d="M850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5zM350 0h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249 q8 7 18 7t18 -7l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5z" />
  20609. <glyph unicode="&#xe097;" d="M1014 1120l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249q8 7 18 7t18 -7zM250 600h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5z" />
  20610. <glyph unicode="&#xe101;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM704 900h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5 t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
  20611. <glyph unicode="&#xe102;" d="M260 1200q9 0 19 -2t15 -4l5 -2q22 -10 44 -23l196 -118q21 -13 36 -24q29 -21 37 -12q11 13 49 35l196 118q22 13 45 23q17 7 38 7q23 0 47 -16.5t37 -33.5l13 -16q14 -21 18 -45l25 -123l8 -44q1 -9 8.5 -14.5t17.5 -5.5h61q10 0 17.5 -7.5t7.5 -17.5v-50 q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 -7.5t-7.5 -17.5v-175h-400v300h-200v-300h-400v175q0 10 -7.5 17.5t-17.5 7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5h61q11 0 18 3t7 8q0 4 9 52l25 128q5 25 19 45q2 3 5 7t13.5 15t21.5 19.5t26.5 15.5 t29.5 7zM915 1079l-166 -162q-7 -7 -5 -12t12 -5h219q10 0 15 7t2 17l-51 149q-3 10 -11 12t-15 -6zM463 917l-177 157q-8 7 -16 5t-11 -12l-51 -143q-3 -10 2 -17t15 -7h231q11 0 12.5 5t-5.5 12zM500 0h-375q-10 0 -17.5 7.5t-7.5 17.5v375h400v-400zM1100 400v-375 q0 -10 -7.5 -17.5t-17.5 -7.5h-375v400h400z" />
  20612. <glyph unicode="&#xe103;" d="M1165 1190q8 3 21 -6.5t13 -17.5q-2 -178 -24.5 -323.5t-55.5 -245.5t-87 -174.5t-102.5 -118.5t-118 -68.5t-118.5 -33t-120 -4.5t-105 9.5t-90 16.5q-61 12 -78 11q-4 1 -12.5 0t-34 -14.5t-52.5 -40.5l-153 -153q-26 -24 -37 -14.5t-11 43.5q0 64 42 102q8 8 50.5 45 t66.5 58q19 17 35 47t13 61q-9 55 -10 102.5t7 111t37 130t78 129.5q39 51 80 88t89.5 63.5t94.5 45t113.5 36t129 31t157.5 37t182 47.5zM1116 1098q-8 9 -22.5 -3t-45.5 -50q-38 -47 -119 -103.5t-142 -89.5l-62 -33q-56 -30 -102 -57t-104 -68t-102.5 -80.5t-85.5 -91 t-64 -104.5q-24 -56 -31 -86t2 -32t31.5 17.5t55.5 59.5q25 30 94 75.5t125.5 77.5t147.5 81q70 37 118.5 69t102 79.5t99 111t86.5 148.5q22 50 24 60t-6 19z" />
  20613. <glyph unicode="&#xe104;" d="M653 1231q-39 -67 -54.5 -131t-10.5 -114.5t24.5 -96.5t47.5 -80t63.5 -62.5t68.5 -46.5t65 -30q-4 7 -17.5 35t-18.5 39.5t-17 39.5t-17 43t-13 42t-9.5 44.5t-2 42t4 43t13.5 39t23 38.5q96 -42 165 -107.5t105 -138t52 -156t13 -159t-19 -149.5q-13 -55 -44 -106.5 t-68 -87t-78.5 -64.5t-72.5 -45t-53 -22q-72 -22 -127 -11q-31 6 -13 19q6 3 17 7q13 5 32.5 21t41 44t38.5 63.5t21.5 81.5t-6.5 94.5t-50 107t-104 115.5q10 -104 -0.5 -189t-37 -140.5t-65 -93t-84 -52t-93.5 -11t-95 24.5q-80 36 -131.5 114t-53.5 171q-2 23 0 49.5 t4.5 52.5t13.5 56t27.5 60t46 64.5t69.5 68.5q-8 -53 -5 -102.5t17.5 -90t34 -68.5t44.5 -39t49 -2q31 13 38.5 36t-4.5 55t-29 64.5t-36 75t-26 75.5q-15 85 2 161.5t53.5 128.5t85.5 92.5t93.5 61t81.5 25.5z" />
  20614. <glyph unicode="&#xe105;" d="M600 1094q82 0 160.5 -22.5t140 -59t116.5 -82.5t94.5 -95t68 -95t42.5 -82.5t14 -57.5t-14 -57.5t-43 -82.5t-68.5 -95t-94.5 -95t-116.5 -82.5t-140 -59t-159.5 -22.5t-159.5 22.5t-140 59t-116.5 82.5t-94.5 95t-68.5 95t-43 82.5t-14 57.5t14 57.5t42.5 82.5t68 95 t94.5 95t116.5 82.5t140 59t160.5 22.5zM888 829q-15 15 -18 12t5 -22q25 -57 25 -119q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 59 23 114q8 19 4.5 22t-17.5 -12q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q22 -36 47 -71t70 -82t92.5 -81t113 -58.5t133.5 -24.5 t133.5 24t113 58.5t92.5 81.5t70 81.5t47 70.5q11 18 9 42.5t-14 41.5q-90 117 -163 189zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l35 34q14 15 12.5 33.5t-16.5 33.5q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
  20615. <glyph unicode="&#xe106;" d="M592 0h-148l31 120q-91 20 -175.5 68.5t-143.5 106.5t-103.5 119t-66.5 110t-22 76q0 21 14 57.5t42.5 82.5t68 95t94.5 95t116.5 82.5t140 59t160.5 22.5q61 0 126 -15l32 121h148zM944 770l47 181q108 -85 176.5 -192t68.5 -159q0 -26 -19.5 -71t-59.5 -102t-93 -112 t-129 -104.5t-158 -75.5l46 173q77 49 136 117t97 131q11 18 9 42.5t-14 41.5q-54 70 -107 130zM310 824q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q18 -30 39 -60t57 -70.5t74 -73t90 -61t105 -41.5l41 154q-107 18 -178.5 101.5t-71.5 193.5q0 59 23 114q8 19 4.5 22 t-17.5 -12zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l12 11l22 86l-3 4q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
  20616. <glyph unicode="&#xe107;" d="M-90 100l642 1066q20 31 48 28.5t48 -35.5l642 -1056q21 -32 7.5 -67.5t-50.5 -35.5h-1294q-37 0 -50.5 34t7.5 66zM155 200h345v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h345l-445 723zM496 700h208q20 0 32 -14.5t8 -34.5l-58 -252 q-4 -20 -21.5 -34.5t-37.5 -14.5h-54q-20 0 -37.5 14.5t-21.5 34.5l-58 252q-4 20 8 34.5t32 14.5z" />
  20617. <glyph unicode="&#xe108;" d="M650 1200q62 0 106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -93 100 -113v-64q0 -21 -13 -29t-32 1l-205 128l-205 -128q-19 -9 -32 -1t-13 29v64q0 20 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5v41 q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44z" />
  20618. <glyph unicode="&#xe109;" d="M850 1200h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-150h-1100v150q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-50h500v50q0 21 14.5 35.5t35.5 14.5zM1100 800v-750q0 -21 -14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v750h1100zM100 600v-100h100v100h-100zM300 600v-100h100v100h-100zM500 600v-100h100v100h-100zM700 600v-100h100v100h-100zM900 600v-100h100v100h-100zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400 v-100h100v100h-100zM700 400v-100h100v100h-100zM900 400v-100h100v100h-100zM100 200v-100h100v100h-100zM300 200v-100h100v100h-100zM500 200v-100h100v100h-100zM700 200v-100h100v100h-100zM900 200v-100h100v100h-100z" />
  20619. <glyph unicode="&#xe110;" d="M1135 1165l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-159l-600 -600h-291q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h209l600 600h241v150q0 21 10.5 25t24.5 -10zM522 819l-141 -141l-122 122h-209q-21 0 -35.5 14.5 t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h291zM1135 565l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-241l-181 181l141 141l122 -122h159v150q0 21 10.5 25t24.5 -10z" />
  20620. <glyph unicode="&#xe111;" d="M100 1100h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5z" />
  20621. <glyph unicode="&#xe112;" d="M150 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM850 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM1100 800v-300q0 -41 -3 -77.5t-15 -89.5t-32 -96t-58 -89t-89 -77t-129 -51t-174 -20t-174 20 t-129 51t-89 77t-58 89t-32 96t-15 89.5t-3 77.5v300h300v-250v-27v-42.5t1.5 -41t5 -38t10 -35t16.5 -30t25.5 -24.5t35 -19t46.5 -12t60 -4t60 4.5t46.5 12.5t35 19.5t25 25.5t17 30.5t10 35t5 38t2 40.5t-0.5 42v25v250h300z" />
  20622. <glyph unicode="&#xe113;" d="M1100 411l-198 -199l-353 353l-353 -353l-197 199l551 551z" />
  20623. <glyph unicode="&#xe114;" d="M1101 789l-550 -551l-551 551l198 199l353 -353l353 353z" />
  20624. <glyph unicode="&#xe115;" d="M404 1000h746q21 0 35.5 -14.5t14.5 -35.5v-551h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v401h-381zM135 984l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-400h385l215 -200h-750q-21 0 -35.5 14.5 t-14.5 35.5v550h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
  20625. <glyph unicode="&#xe116;" d="M56 1200h94q17 0 31 -11t18 -27l38 -162h896q24 0 39 -18.5t10 -42.5l-100 -475q-5 -21 -27 -42.5t-55 -21.5h-633l48 -200h535q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-50q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-300v-50 q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-31q-18 0 -32.5 10t-20.5 19l-5 10l-201 961h-54q-20 0 -35 14.5t-15 35.5t15 35.5t35 14.5z" />
  20626. <glyph unicode="&#xe117;" d="M1200 1000v-100h-1200v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500zM0 800h1200v-800h-1200v800z" />
  20627. <glyph unicode="&#xe118;" d="M200 800l-200 -400v600h200q0 41 29.5 70.5t70.5 29.5h300q42 0 71 -29.5t29 -70.5h500v-200h-1000zM1500 700l-300 -700h-1200l300 700h1200z" />
  20628. <glyph unicode="&#xe119;" d="M635 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-601h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v601h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
  20629. <glyph unicode="&#xe120;" d="M936 864l249 -229q14 -15 14 -35.5t-14 -35.5l-249 -229q-15 -15 -25.5 -10.5t-10.5 24.5v151h-600v-151q0 -20 -10.5 -24.5t-25.5 10.5l-249 229q-14 15 -14 35.5t14 35.5l249 229q15 15 25.5 10.5t10.5 -25.5v-149h600v149q0 21 10.5 25.5t25.5 -10.5z" />
  20630. <glyph unicode="&#xe121;" d="M1169 400l-172 732q-5 23 -23 45.5t-38 22.5h-672q-20 0 -38 -20t-23 -41l-172 -739h1138zM1100 300h-1000q-41 0 -70.5 -29.5t-29.5 -70.5v-100q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v100q0 41 -29.5 70.5t-70.5 29.5zM800 100v100h100v-100h-100 zM1000 100v100h100v-100h-100z" />
  20631. <glyph unicode="&#xe122;" d="M1150 1100q21 0 35.5 -14.5t14.5 -35.5v-850q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v850q0 21 14.5 35.5t35.5 14.5zM1000 200l-675 200h-38l47 -276q3 -16 -5.5 -20t-29.5 -4h-7h-84q-20 0 -34.5 14t-18.5 35q-55 337 -55 351v250v6q0 16 1 23.5t6.5 14 t17.5 6.5h200l675 250v-850zM0 750v-250q-4 0 -11 0.5t-24 6t-30 15t-24 30t-11 48.5v50q0 26 10.5 46t25 30t29 16t25.5 7z" />
  20632. <glyph unicode="&#xe123;" d="M553 1200h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q19 0 33 -14.5t14 -35t-13 -40.5t-31 -27q-8 -4 -23 -9.5t-65 -19.5t-103 -25t-132.5 -20t-158.5 -9q-57 0 -115 5t-104 12t-88.5 15.5t-73.5 17.5t-54.5 16t-35.5 12l-11 4 q-18 8 -31 28t-13 40.5t14 35t33 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3.5 32t28.5 13zM498 110q50 -6 102 -6q53 0 102 6q-12 -49 -39.5 -79.5t-62.5 -30.5t-63 30.5t-39 79.5z" />
  20633. <glyph unicode="&#xe124;" d="M800 946l224 78l-78 -224l234 -45l-180 -155l180 -155l-234 -45l78 -224l-224 78l-45 -234l-155 180l-155 -180l-45 234l-224 -78l78 224l-234 45l180 155l-180 155l234 45l-78 224l224 -78l45 234l155 -180l155 180z" />
  20634. <glyph unicode="&#xe125;" d="M650 1200h50q40 0 70 -40.5t30 -84.5v-150l-28 -125h328q40 0 70 -40.5t30 -84.5v-100q0 -45 -29 -74l-238 -344q-16 -24 -38 -40.5t-45 -16.5h-250q-7 0 -42 25t-66 50l-31 25h-61q-45 0 -72.5 18t-27.5 57v400q0 36 20 63l145 196l96 198q13 28 37.5 48t51.5 20z M650 1100l-100 -212l-150 -213v-375h100l136 -100h214l250 375v125h-450l50 225v175h-50zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5z" />
  20635. <glyph unicode="&#xe126;" d="M600 1100h250q23 0 45 -16.5t38 -40.5l238 -344q29 -29 29 -74v-100q0 -44 -30 -84.5t-70 -40.5h-328q28 -118 28 -125v-150q0 -44 -30 -84.5t-70 -40.5h-50q-27 0 -51.5 20t-37.5 48l-96 198l-145 196q-20 27 -20 63v400q0 39 27.5 57t72.5 18h61q124 100 139 100z M50 1000h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM636 1000l-136 -100h-100v-375l150 -213l100 -212h50v175l-50 225h450v125l-250 375h-214z" />
  20636. <glyph unicode="&#xe127;" d="M356 873l363 230q31 16 53 -6l110 -112q13 -13 13.5 -32t-11.5 -34l-84 -121h302q84 0 138 -38t54 -110t-55 -111t-139 -39h-106l-131 -339q-6 -21 -19.5 -41t-28.5 -20h-342q-7 0 -90 81t-83 94v525q0 17 14 35.5t28 28.5zM400 792v-503l100 -89h293l131 339 q6 21 19.5 41t28.5 20h203q21 0 30.5 25t0.5 50t-31 25h-456h-7h-6h-5.5t-6 0.5t-5 1.5t-5 2t-4 2.5t-4 4t-2.5 4.5q-12 25 5 47l146 183l-86 83zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500 q0 21 14.5 35.5t35.5 14.5z" />
  20637. <glyph unicode="&#xe128;" d="M475 1103l366 -230q2 -1 6 -3.5t14 -10.5t18 -16.5t14.5 -20t6.5 -22.5v-525q0 -13 -86 -94t-93 -81h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-85 0 -139.5 39t-54.5 111t54 110t138 38h302l-85 121q-11 15 -10.5 34t13.5 32l110 112q22 22 53 6zM370 945l146 -183 q17 -22 5 -47q-2 -2 -3.5 -4.5t-4 -4t-4 -2.5t-5 -2t-5 -1.5t-6 -0.5h-6h-6.5h-6h-475v-100h221q15 0 29 -20t20 -41l130 -339h294l106 89v503l-342 236zM1050 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5 v500q0 21 14.5 35.5t35.5 14.5z" />
  20638. <glyph unicode="&#xe129;" d="M550 1294q72 0 111 -55t39 -139v-106l339 -131q21 -6 41 -19.5t20 -28.5v-342q0 -7 -81 -90t-94 -83h-525q-17 0 -35.5 14t-28.5 28l-9 14l-230 363q-16 31 6 53l112 110q13 13 32 13.5t34 -11.5l121 -84v302q0 84 38 138t110 54zM600 972v203q0 21 -25 30.5t-50 0.5 t-25 -31v-456v-7v-6v-5.5t-0.5 -6t-1.5 -5t-2 -5t-2.5 -4t-4 -4t-4.5 -2.5q-25 -12 -47 5l-183 146l-83 -86l236 -339h503l89 100v293l-339 131q-21 6 -41 19.5t-20 28.5zM450 200h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
  20639. <glyph unicode="&#xe130;" d="M350 1100h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5zM600 306v-106q0 -84 -39 -139t-111 -55t-110 54t-38 138v302l-121 -84q-15 -12 -34 -11.5t-32 13.5l-112 110 q-22 22 -6 53l230 363q1 2 3.5 6t10.5 13.5t16.5 17t20 13.5t22.5 6h525q13 0 94 -83t81 -90v-342q0 -15 -20 -28.5t-41 -19.5zM308 900l-236 -339l83 -86l183 146q22 17 47 5q2 -1 4.5 -2.5t4 -4t2.5 -4t2 -5t1.5 -5t0.5 -6v-5.5v-6v-7v-456q0 -22 25 -31t50 0.5t25 30.5 v203q0 15 20 28.5t41 19.5l339 131v293l-89 100h-503z" />
  20640. <glyph unicode="&#xe131;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM914 632l-275 223q-16 13 -27.5 8t-11.5 -26v-137h-275 q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h275v-137q0 -21 11.5 -26t27.5 8l275 223q16 13 16 32t-16 32z" />
  20641. <glyph unicode="&#xe132;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM561 855l-275 -223q-16 -13 -16 -32t16 -32l275 -223q16 -13 27.5 -8 t11.5 26v137h275q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5h-275v137q0 21 -11.5 26t-27.5 -8z" />
  20642. <glyph unicode="&#xe133;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM855 639l-223 275q-13 16 -32 16t-32 -16l-223 -275q-13 -16 -8 -27.5 t26 -11.5h137v-275q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v275h137q21 0 26 11.5t-8 27.5z" />
  20643. <glyph unicode="&#xe134;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM675 900h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-275h-137q-21 0 -26 -11.5 t8 -27.5l223 -275q13 -16 32 -16t32 16l223 275q13 16 8 27.5t-26 11.5h-137v275q0 10 -7.5 17.5t-17.5 7.5z" />
  20644. <glyph unicode="&#xe135;" d="M600 1176q116 0 222.5 -46t184 -123.5t123.5 -184t46 -222.5t-46 -222.5t-123.5 -184t-184 -123.5t-222.5 -46t-222.5 46t-184 123.5t-123.5 184t-46 222.5t46 222.5t123.5 184t184 123.5t222.5 46zM627 1101q-15 -12 -36.5 -20.5t-35.5 -12t-43 -8t-39 -6.5 q-15 -3 -45.5 0t-45.5 -2q-20 -7 -51.5 -26.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79q-9 -34 5 -93t8 -87q0 -9 17 -44.5t16 -59.5q12 0 23 -5t23.5 -15t19.5 -14q16 -8 33 -15t40.5 -15t34.5 -12q21 -9 52.5 -32t60 -38t57.5 -11 q7 -15 -3 -34t-22.5 -40t-9.5 -38q13 -21 23 -34.5t27.5 -27.5t36.5 -18q0 -7 -3.5 -16t-3.5 -14t5 -17q104 -2 221 112q30 29 46.5 47t34.5 49t21 63q-13 8 -37 8.5t-36 7.5q-15 7 -49.5 15t-51.5 19q-18 0 -41 -0.5t-43 -1.5t-42 -6.5t-38 -16.5q-51 -35 -66 -12 q-4 1 -3.5 25.5t0.5 25.5q-6 13 -26.5 17.5t-24.5 6.5q1 15 -0.5 30.5t-7 28t-18.5 11.5t-31 -21q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q7 -12 18 -24t21.5 -20.5t20 -15t15.5 -10.5l5 -3q2 12 7.5 30.5t8 34.5t-0.5 32q-3 18 3.5 29 t18 22.5t15.5 24.5q6 14 10.5 35t8 31t15.5 22.5t34 22.5q-6 18 10 36q8 0 24 -1.5t24.5 -1.5t20 4.5t20.5 15.5q-10 23 -31 42.5t-37.5 29.5t-49 27t-43.5 23q0 1 2 8t3 11.5t1.5 10.5t-1 9.5t-4.5 4.5q31 -13 58.5 -14.5t38.5 2.5l12 5q5 28 -9.5 46t-36.5 24t-50 15 t-41 20q-18 -4 -37 0zM613 994q0 -17 8 -42t17 -45t9 -23q-8 1 -39.5 5.5t-52.5 10t-37 16.5q3 11 16 29.5t16 25.5q10 -10 19 -10t14 6t13.5 14.5t16.5 12.5z" />
  20645. <glyph unicode="&#xe136;" d="M756 1157q164 92 306 -9l-259 -138l145 -232l251 126q6 -89 -34 -156.5t-117 -110.5q-60 -34 -127 -39.5t-126 16.5l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5t15 37.5l600 599q-34 101 5.5 201.5t135.5 154.5z" />
  20646. <glyph unicode="&#xe137;" horiz-adv-x="1220" d="M100 1196h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 1096h-200v-100h200v100zM100 796h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 696h-500v-100h500v100zM100 396h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 296h-300v-100h300v100z " />
  20647. <glyph unicode="&#xe138;" d="M150 1200h900q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM700 500v-300l-200 -200v500l-350 500h900z" />
  20648. <glyph unicode="&#xe139;" d="M500 1200h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5zM500 1100v-100h200v100h-200zM1200 400v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v200h1200z" />
  20649. <glyph unicode="&#xe140;" d="M50 1200h300q21 0 25 -10.5t-10 -24.5l-94 -94l199 -199q7 -8 7 -18t-7 -18l-106 -106q-8 -7 -18 -7t-18 7l-199 199l-94 -94q-14 -14 -24.5 -10t-10.5 25v300q0 21 14.5 35.5t35.5 14.5zM850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-199 -199q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l199 199l-94 94q-14 14 -10 24.5t25 10.5zM364 470l106 -106q7 -8 7 -18t-7 -18l-199 -199l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l199 199 q8 7 18 7t18 -7zM1071 271l94 94q14 14 24.5 10t10.5 -25v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -25 10.5t10 24.5l94 94l-199 199q-7 8 -7 18t7 18l106 106q8 7 18 7t18 -7z" />
  20650. <glyph unicode="&#xe141;" d="M596 1192q121 0 231.5 -47.5t190 -127t127 -190t47.5 -231.5t-47.5 -231.5t-127 -190.5t-190 -127t-231.5 -47t-231.5 47t-190.5 127t-127 190.5t-47 231.5t47 231.5t127 190t190.5 127t231.5 47.5zM596 1010q-112 0 -207.5 -55.5t-151 -151t-55.5 -207.5t55.5 -207.5 t151 -151t207.5 -55.5t207.5 55.5t151 151t55.5 207.5t-55.5 207.5t-151 151t-207.5 55.5zM454.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38.5 -16.5t-38.5 16.5t-16 39t16 38.5t38.5 16zM754.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38 -16.5q-14 0 -29 10l-55 -145 q17 -23 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 23 16 39t38.5 16zM345.5 709q22.5 0 38.5 -16t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16zM854.5 709q22.5 0 38.5 -16 t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16z" />
  20651. <glyph unicode="&#xe142;" d="M546 173l469 470q91 91 99 192q7 98 -52 175.5t-154 94.5q-22 4 -47 4q-34 0 -66.5 -10t-56.5 -23t-55.5 -38t-48 -41.5t-48.5 -47.5q-376 -375 -391 -390q-30 -27 -45 -41.5t-37.5 -41t-32 -46.5t-16 -47.5t-1.5 -56.5q9 -62 53.5 -95t99.5 -33q74 0 125 51l548 548 q36 36 20 75q-7 16 -21.5 26t-32.5 10q-26 0 -50 -23q-13 -12 -39 -38l-341 -338q-15 -15 -35.5 -15.5t-34.5 13.5t-14 34.5t14 34.5q327 333 361 367q35 35 67.5 51.5t78.5 16.5q14 0 29 -1q44 -8 74.5 -35.5t43.5 -68.5q14 -47 2 -96.5t-47 -84.5q-12 -11 -32 -32 t-79.5 -81t-114.5 -115t-124.5 -123.5t-123 -119.5t-96.5 -89t-57 -45q-56 -27 -120 -27q-70 0 -129 32t-93 89q-48 78 -35 173t81 163l511 511q71 72 111 96q91 55 198 55q80 0 152 -33q78 -36 129.5 -103t66.5 -154q17 -93 -11 -183.5t-94 -156.5l-482 -476 q-15 -15 -36 -16t-37 14t-17.5 34t14.5 35z" />
  20652. <glyph unicode="&#xe143;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104zM896 972q-33 0 -64.5 -19t-56.5 -46t-47.5 -53.5t-43.5 -45.5t-37.5 -19t-36 19t-40 45.5t-43 53.5t-54 46t-65.5 19q-67 0 -122.5 -55.5t-55.5 -132.5q0 -23 13.5 -51t46 -65t57.5 -63t76 -75l22 -22q15 -14 44 -44t50.5 -51t46 -44t41 -35t23 -12 t23.5 12t42.5 36t46 44t52.5 52t44 43q4 4 12 13q43 41 63.5 62t52 55t46 55t26 46t11.5 44q0 79 -53 133.5t-120 54.5z" />
  20653. <glyph unicode="&#xe144;" d="M776.5 1214q93.5 0 159.5 -66l141 -141q66 -66 66 -160q0 -42 -28 -95.5t-62 -87.5l-29 -29q-31 53 -77 99l-18 18l95 95l-247 248l-389 -389l212 -212l-105 -106l-19 18l-141 141q-66 66 -66 159t66 159l283 283q65 66 158.5 66zM600 706l105 105q10 -8 19 -17l141 -141 q66 -66 66 -159t-66 -159l-283 -283q-66 -66 -159 -66t-159 66l-141 141q-66 66 -66 159.5t66 159.5l55 55q29 -55 75 -102l18 -17l-95 -95l247 -248l389 389z" />
  20654. <glyph unicode="&#xe145;" d="M603 1200q85 0 162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5v953q0 21 30 46.5t81 48t129 37.5t163 15zM300 1000v-700h600v700h-600zM600 254q-43 0 -73.5 -30.5t-30.5 -73.5t30.5 -73.5t73.5 -30.5t73.5 30.5 t30.5 73.5t-30.5 73.5t-73.5 30.5z" />
  20655. <glyph unicode="&#xe146;" d="M902 1185l283 -282q15 -15 15 -36t-14.5 -35.5t-35.5 -14.5t-35 15l-36 35l-279 -267v-300l-212 210l-308 -307l-280 -203l203 280l307 308l-210 212h300l267 279l-35 36q-15 14 -15 35t14.5 35.5t35.5 14.5t35 -15z" />
  20656. <glyph unicode="&#xe148;" d="M700 1248v-78q38 -5 72.5 -14.5t75.5 -31.5t71 -53.5t52 -84t24 -118.5h-159q-4 36 -10.5 59t-21 45t-40 35.5t-64.5 20.5v-307l64 -13q34 -7 64 -16.5t70 -32t67.5 -52.5t47.5 -80t20 -112q0 -139 -89 -224t-244 -97v-77h-100v79q-150 16 -237 103q-40 40 -52.5 93.5 t-15.5 139.5h139q5 -77 48.5 -126t117.5 -65v335l-27 8q-46 14 -79 26.5t-72 36t-63 52t-40 72.5t-16 98q0 70 25 126t67.5 92t94.5 57t110 27v77h100zM600 754v274q-29 -4 -50 -11t-42 -21.5t-31.5 -41.5t-10.5 -65q0 -29 7 -50.5t16.5 -34t28.5 -22.5t31.5 -14t37.5 -10 q9 -3 13 -4zM700 547v-310q22 2 42.5 6.5t45 15.5t41.5 27t29 42t12 59.5t-12.5 59.5t-38 44.5t-53 31t-66.5 24.5z" />
  20657. <glyph unicode="&#xe149;" d="M561 1197q84 0 160.5 -40t123.5 -109.5t47 -147.5h-153q0 40 -19.5 71.5t-49.5 48.5t-59.5 26t-55.5 9q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -26 13.5 -63t26.5 -61t37 -66q6 -9 9 -14h241v-100h-197q8 -50 -2.5 -115t-31.5 -95q-45 -62 -99 -112 q34 10 83 17.5t71 7.5q32 1 102 -16t104 -17q83 0 136 30l50 -147q-31 -19 -58 -30.5t-55 -15.5t-42 -4.5t-46 -0.5q-23 0 -76 17t-111 32.5t-96 11.5q-39 -3 -82 -16t-67 -25l-23 -11l-55 145q4 3 16 11t15.5 10.5t13 9t15.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221v100h166q-23 47 -44 104q-7 20 -12 41.5t-6 55.5t6 66.5t29.5 70.5t58.5 71q97 88 263 88z" />
  20658. <glyph unicode="&#xe150;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM935 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-900h-200v900h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
  20659. <glyph unicode="&#xe151;" d="M1000 700h-100v100h-100v-100h-100v500h300v-500zM400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM801 1100v-200h100v200h-100zM1000 350l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150z " />
  20660. <glyph unicode="&#xe152;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 1050l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150zM1000 0h-100v100h-100v-100h-100v500h300v-500zM801 400v-200h100v200h-100z " />
  20661. <glyph unicode="&#xe153;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 700h-100v400h-100v100h200v-500zM1100 0h-100v100h-200v400h300v-500zM901 400v-200h100v200h-100z" />
  20662. <glyph unicode="&#xe154;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1100 700h-100v100h-200v400h300v-500zM901 1100v-200h100v200h-100zM1000 0h-100v400h-100v100h200v-500z" />
  20663. <glyph unicode="&#xe155;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM900 1000h-200v200h200v-200zM1000 700h-300v200h300v-200zM1100 400h-400v200h400v-200zM1200 100h-500v200h500v-200z" />
  20664. <glyph unicode="&#xe156;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1200 1000h-500v200h500v-200zM1100 700h-400v200h400v-200zM1000 400h-300v200h300v-200zM900 100h-200v200h200v-200z" />
  20665. <glyph unicode="&#xe157;" d="M350 1100h400q162 0 256 -93.5t94 -256.5v-400q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5z" />
  20666. <glyph unicode="&#xe158;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-163 0 -256.5 92.5t-93.5 257.5v400q0 163 94 256.5t256 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM440 770l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
  20667. <glyph unicode="&#xe159;" d="M350 1100h400q163 0 256.5 -94t93.5 -256v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 163 92.5 256.5t257.5 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM350 700h400q21 0 26.5 -12t-6.5 -28l-190 -253q-12 -17 -30 -17t-30 17l-190 253q-12 16 -6.5 28t26.5 12z" />
  20668. <glyph unicode="&#xe160;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -163 -92.5 -256.5t-257.5 -93.5h-400q-163 0 -256.5 94t-93.5 256v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM580 693l190 -253q12 -16 6.5 -28t-26.5 -12h-400q-21 0 -26.5 12t6.5 28l190 253q12 17 30 17t30 -17z" />
  20669. <glyph unicode="&#xe161;" d="M550 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h450q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-450q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM338 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
  20670. <glyph unicode="&#xe162;" d="M793 1182l9 -9q8 -10 5 -27q-3 -11 -79 -225.5t-78 -221.5l300 1q24 0 32.5 -17.5t-5.5 -35.5q-1 0 -133.5 -155t-267 -312.5t-138.5 -162.5q-12 -15 -26 -15h-9l-9 8q-9 11 -4 32q2 9 42 123.5t79 224.5l39 110h-302q-23 0 -31 19q-10 21 6 41q75 86 209.5 237.5 t228 257t98.5 111.5q9 16 25 16h9z" />
  20671. <glyph unicode="&#xe163;" d="M350 1100h400q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-450q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h450q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400 q0 165 92.5 257.5t257.5 92.5zM938 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
  20672. <glyph unicode="&#xe164;" d="M750 1200h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -10.5 -25t-24.5 10l-109 109l-312 -312q-15 -15 -35.5 -15t-35.5 15l-141 141q-15 15 -15 35.5t15 35.5l312 312l-109 109q-14 14 -10 24.5t25 10.5zM456 900h-156q-41 0 -70.5 -29.5t-29.5 -70.5v-500 q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v148l200 200v-298q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5h300z" />
  20673. <glyph unicode="&#xe165;" d="M600 1186q119 0 227.5 -46.5t187 -125t125 -187t46.5 -227.5t-46.5 -227.5t-125 -187t-187 -125t-227.5 -46.5t-227.5 46.5t-187 125t-125 187t-46.5 227.5t46.5 227.5t125 187t187 125t227.5 46.5zM600 1022q-115 0 -212 -56.5t-153.5 -153.5t-56.5 -212t56.5 -212 t153.5 -153.5t212 -56.5t212 56.5t153.5 153.5t56.5 212t-56.5 212t-153.5 153.5t-212 56.5zM600 794q80 0 137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137t57 137t137 57z" />
  20674. <glyph unicode="&#xe166;" d="M450 1200h200q21 0 35.5 -14.5t14.5 -35.5v-350h245q20 0 25 -11t-9 -26l-383 -426q-14 -15 -33.5 -15t-32.5 15l-379 426q-13 15 -8.5 26t25.5 11h250v350q0 21 14.5 35.5t35.5 14.5zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
  20675. <glyph unicode="&#xe167;" d="M583 1182l378 -435q14 -15 9 -31t-26 -16h-244v-250q0 -20 -17 -35t-39 -15h-200q-20 0 -32 14.5t-12 35.5v250h-250q-20 0 -25.5 16.5t8.5 31.5l383 431q14 16 33.5 17t33.5 -14zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
  20676. <glyph unicode="&#xe168;" d="M396 723l369 369q7 7 17.5 7t17.5 -7l139 -139q7 -8 7 -18.5t-7 -17.5l-525 -525q-7 -8 -17.5 -8t-17.5 8l-292 291q-7 8 -7 18t7 18l139 139q8 7 18.5 7t17.5 -7zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50 h-100z" />
  20677. <glyph unicode="&#xe169;" d="M135 1023l142 142q14 14 35 14t35 -14l77 -77l-212 -212l-77 76q-14 15 -14 36t14 35zM655 855l210 210q14 14 24.5 10t10.5 -25l-2 -599q-1 -20 -15.5 -35t-35.5 -15l-597 -1q-21 0 -25 10.5t10 24.5l208 208l-154 155l212 212zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5 v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
  20678. <glyph unicode="&#xe170;" d="M350 1200l599 -2q20 -1 35 -15.5t15 -35.5l1 -597q0 -21 -10.5 -25t-24.5 10l-208 208l-155 -154l-212 212l155 154l-210 210q-14 14 -10 24.5t25 10.5zM524 512l-76 -77q-15 -14 -36 -14t-35 14l-142 142q-14 14 -14 35t14 35l77 77zM50 300h1000q21 0 35.5 -14.5 t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
  20679. <glyph unicode="&#xe171;" d="M1200 103l-483 276l-314 -399v423h-399l1196 796v-1096zM483 424v-230l683 953z" />
  20680. <glyph unicode="&#xe172;" d="M1100 1000v-850q0 -21 -14.5 -35.5t-35.5 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200z" />
  20681. <glyph unicode="&#xe173;" d="M1100 1000l-2 -149l-299 -299l-95 95q-9 9 -21.5 9t-21.5 -9l-149 -147h-312v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1132 638l106 -106q7 -7 7 -17.5t-7 -17.5l-420 -421q-8 -7 -18 -7 t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l297 297q7 7 17.5 7t17.5 -7z" />
  20682. <glyph unicode="&#xe174;" d="M1100 1000v-269l-103 -103l-134 134q-15 15 -33.5 16.5t-34.5 -12.5l-266 -266h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1202 572l70 -70q15 -15 15 -35.5t-15 -35.5l-131 -131 l131 -131q15 -15 15 -35.5t-15 -35.5l-70 -70q-15 -15 -35.5 -15t-35.5 15l-131 131l-131 -131q-15 -15 -35.5 -15t-35.5 15l-70 70q-15 15 -15 35.5t15 35.5l131 131l-131 131q-15 15 -15 35.5t15 35.5l70 70q15 15 35.5 15t35.5 -15l131 -131l131 131q15 15 35.5 15 t35.5 -15z" />
  20683. <glyph unicode="&#xe175;" d="M1100 1000v-300h-350q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM850 600h100q21 0 35.5 -14.5t14.5 -35.5v-250h150q21 0 25 -10.5t-10 -24.5 l-230 -230q-14 -14 -35 -14t-35 14l-230 230q-14 14 -10 24.5t25 10.5h150v250q0 21 14.5 35.5t35.5 14.5z" />
  20684. <glyph unicode="&#xe176;" d="M1100 1000v-400l-165 165q-14 15 -35 15t-35 -15l-263 -265h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM935 565l230 -229q14 -15 10 -25.5t-25 -10.5h-150v-250q0 -20 -14.5 -35 t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35v250h-150q-21 0 -25 10.5t10 25.5l230 229q14 15 35 15t35 -15z" />
  20685. <glyph unicode="&#xe177;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-150h-1200v150q0 21 14.5 35.5t35.5 14.5zM1200 800v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v550h1200zM100 500v-200h400v200h-400z" />
  20686. <glyph unicode="&#xe178;" d="M935 1165l248 -230q14 -14 14 -35t-14 -35l-248 -230q-14 -14 -24.5 -10t-10.5 25v150h-400v200h400v150q0 21 10.5 25t24.5 -10zM200 800h-50q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v-200zM400 800h-100v200h100v-200zM18 435l247 230 q14 14 24.5 10t10.5 -25v-150h400v-200h-400v-150q0 -21 -10.5 -25t-24.5 10l-247 230q-15 14 -15 35t15 35zM900 300h-100v200h100v-200zM1000 500h51q20 0 34.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-34.5 -14.5h-51v200z" />
  20687. <glyph unicode="&#xe179;" d="M862 1073l276 116q25 18 43.5 8t18.5 -41v-1106q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v397q-4 1 -11 5t-24 17.5t-30 29t-24 42t-11 56.5v359q0 31 18.5 65t43.5 52zM550 1200q22 0 34.5 -12.5t14.5 -24.5l1 -13v-450q0 -28 -10.5 -59.5 t-25 -56t-29 -45t-25.5 -31.5l-10 -11v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447q-4 4 -11 11.5t-24 30.5t-30 46t-24 55t-11 60v450q0 2 0.5 5.5t4 12t8.5 15t14.5 12t22.5 5.5q20 0 32.5 -12.5t14.5 -24.5l3 -13v-350h100v350v5.5t2.5 12 t7 15t15 12t25.5 5.5q23 0 35.5 -12.5t13.5 -24.5l1 -13v-350h100v350q0 2 0.5 5.5t3 12t7 15t15 12t24.5 5.5z" />
  20688. <glyph unicode="&#xe180;" d="M1200 1100v-56q-4 0 -11 -0.5t-24 -3t-30 -7.5t-24 -15t-11 -24v-888q0 -22 25 -34.5t50 -13.5l25 -2v-56h-400v56q75 0 87.5 6.5t12.5 43.5v394h-500v-394q0 -37 12.5 -43.5t87.5 -6.5v-56h-400v56q4 0 11 0.5t24 3t30 7.5t24 15t11 24v888q0 22 -25 34.5t-50 13.5 l-25 2v56h400v-56q-75 0 -87.5 -6.5t-12.5 -43.5v-394h500v394q0 37 -12.5 43.5t-87.5 6.5v56h400z" />
  20689. <glyph unicode="&#xe181;" d="M675 1000h375q21 0 35.5 -14.5t14.5 -35.5v-150h-105l-295 -98v98l-200 200h-400l100 100h375zM100 900h300q41 0 70.5 -29.5t29.5 -70.5v-500q0 -41 -29.5 -70.5t-70.5 -29.5h-300q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5zM100 800v-200h300v200 h-300zM1100 535l-400 -133v163l400 133v-163zM100 500v-200h300v200h-300zM1100 398v-248q0 -21 -14.5 -35.5t-35.5 -14.5h-375l-100 -100h-375l-100 100h400l200 200h105z" />
  20690. <glyph unicode="&#xe182;" d="M17 1007l162 162q17 17 40 14t37 -22l139 -194q14 -20 11 -44.5t-20 -41.5l-119 -118q102 -142 228 -268t267 -227l119 118q17 17 42.5 19t44.5 -12l192 -136q19 -14 22.5 -37.5t-13.5 -40.5l-163 -162q-3 -1 -9.5 -1t-29.5 2t-47.5 6t-62.5 14.5t-77.5 26.5t-90 42.5 t-101.5 60t-111 83t-119 108.5q-74 74 -133.5 150.5t-94.5 138.5t-60 119.5t-34.5 100t-15 74.5t-4.5 48z" />
  20691. <glyph unicode="&#xe183;" d="M600 1100q92 0 175 -10.5t141.5 -27t108.5 -36.5t81.5 -40t53.5 -37t31 -27l9 -10v-200q0 -21 -14.5 -33t-34.5 -9l-202 34q-20 3 -34.5 20t-14.5 38v146q-141 24 -300 24t-300 -24v-146q0 -21 -14.5 -38t-34.5 -20l-202 -34q-20 -3 -34.5 9t-14.5 33v200q3 4 9.5 10.5 t31 26t54 37.5t80.5 39.5t109 37.5t141 26.5t175 10.5zM600 795q56 0 97 -9.5t60 -23.5t30 -28t12 -24l1 -10v-50l365 -303q14 -15 24.5 -40t10.5 -45v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v212q0 20 10.5 45t24.5 40l365 303v50 q0 4 1 10.5t12 23t30 29t60 22.5t97 10z" />
  20692. <glyph unicode="&#xe184;" d="M1100 700l-200 -200h-600l-200 200v500h200v-200h200v200h200v-200h200v200h200v-500zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5 t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
  20693. <glyph unicode="&#xe185;" d="M700 1100h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-1000h300v1000q0 41 -29.5 70.5t-70.5 29.5zM1100 800h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-700h300v700q0 41 -29.5 70.5t-70.5 29.5zM400 0h-300v400q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-400z " />
  20694. <glyph unicode="&#xe186;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
  20695. <glyph unicode="&#xe187;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 300h-100v200h-100v-200h-100v500h100v-200h100v200h100v-500zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
  20696. <glyph unicode="&#xe188;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-300h200v-100h-300v500h300v-100zM900 700h-200v-300h200v-100h-300v500h300v-100z" />
  20697. <glyph unicode="&#xe189;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 400l-300 150l300 150v-300zM900 550l-300 -150v300z" />
  20698. <glyph unicode="&#xe190;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM900 300h-700v500h700v-500zM800 700h-130q-38 0 -66.5 -43t-28.5 -108t27 -107t68 -42h130v300zM300 700v-300 h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130z" />
  20699. <glyph unicode="&#xe191;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 300h-100v400h-100v100h200v-500z M700 300h-100v100h100v-100z" />
  20700. <glyph unicode="&#xe192;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM300 700h200v-400h-300v500h100v-100zM900 300h-100v400h-100v100h200v-500zM300 600v-200h100v200h-100z M700 300h-100v100h100v-100z" />
  20701. <glyph unicode="&#xe193;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 500l-199 -200h-100v50l199 200v150h-200v100h300v-300zM900 300h-100v400h-100v100h200v-500zM701 300h-100 v100h100v-100z" />
  20702. <glyph unicode="&#xe194;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700h-300v-200h300v-100h-300l-100 100v200l100 100h300v-100z" />
  20703. <glyph unicode="&#xe195;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700v-100l-50 -50l100 -100v-50h-100l-100 100h-150v-100h-100v400h300zM500 700v-100h200v100h-200z" />
  20704. <glyph unicode="&#xe197;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -207t-85 -207t-205 -86.5h-128v250q0 21 -14.5 35.5t-35.5 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-250h-222q-80 0 -136 57.5t-56 136.5q0 69 43 122.5t108 67.5q-2 19 -2 37q0 100 49 185 t134 134t185 49zM525 500h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -244q-13 -16 -32 -16t-32 16l-223 244q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z" />
  20705. <glyph unicode="&#xe198;" d="M502 1089q110 0 201 -59.5t135 -156.5q43 15 89 15q121 0 206 -86.5t86 -206.5q0 -99 -60 -181t-150 -110l-378 360q-13 16 -31.5 16t-31.5 -16l-381 -365h-9q-79 0 -135.5 57.5t-56.5 136.5q0 69 43 122.5t108 67.5q-2 19 -2 38q0 100 49 184.5t133.5 134t184.5 49.5z M632 467l223 -228q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5q199 204 223 228q19 19 31.5 19t32.5 -19z" />
  20706. <glyph unicode="&#xe199;" d="M700 100v100h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170l-270 -300h400v-100h-50q-21 0 -35.5 -14.5t-14.5 -35.5v-50h400v50q0 21 -14.5 35.5t-35.5 14.5h-50z" />
  20707. <glyph unicode="&#xe200;" d="M600 1179q94 0 167.5 -56.5t99.5 -145.5q89 -6 150.5 -71.5t61.5 -155.5q0 -61 -29.5 -112.5t-79.5 -82.5q9 -29 9 -55q0 -74 -52.5 -126.5t-126.5 -52.5q-55 0 -100 30v-251q21 0 35.5 -14.5t14.5 -35.5v-50h-300v50q0 21 14.5 35.5t35.5 14.5v251q-45 -30 -100 -30 q-74 0 -126.5 52.5t-52.5 126.5q0 18 4 38q-47 21 -75.5 65t-28.5 97q0 74 52.5 126.5t126.5 52.5q5 0 23 -2q0 2 -1 10t-1 13q0 116 81.5 197.5t197.5 81.5z" />
  20708. <glyph unicode="&#xe201;" d="M1010 1010q111 -111 150.5 -260.5t0 -299t-150.5 -260.5q-83 -83 -191.5 -126.5t-218.5 -43.5t-218.5 43.5t-191.5 126.5q-111 111 -150.5 260.5t0 299t150.5 260.5q83 83 191.5 126.5t218.5 43.5t218.5 -43.5t191.5 -126.5zM476 1065q-4 0 -8 -1q-121 -34 -209.5 -122.5 t-122.5 -209.5q-4 -12 2.5 -23t18.5 -14l36 -9q3 -1 7 -1q23 0 29 22q27 96 98 166q70 71 166 98q11 3 17.5 13.5t3.5 22.5l-9 35q-3 13 -14 19q-7 4 -15 4zM512 920q-4 0 -9 -2q-80 -24 -138.5 -82.5t-82.5 -138.5q-4 -13 2 -24t19 -14l34 -9q4 -1 8 -1q22 0 28 21 q18 58 58.5 98.5t97.5 58.5q12 3 18 13.5t3 21.5l-9 35q-3 12 -14 19q-7 4 -15 4zM719.5 719.5q-49.5 49.5 -119.5 49.5t-119.5 -49.5t-49.5 -119.5t49.5 -119.5t119.5 -49.5t119.5 49.5t49.5 119.5t-49.5 119.5zM855 551q-22 0 -28 -21q-18 -58 -58.5 -98.5t-98.5 -57.5 q-11 -4 -17 -14.5t-3 -21.5l9 -35q3 -12 14 -19q7 -4 15 -4q4 0 9 2q80 24 138.5 82.5t82.5 138.5q4 13 -2.5 24t-18.5 14l-34 9q-4 1 -8 1zM1000 515q-23 0 -29 -22q-27 -96 -98 -166q-70 -71 -166 -98q-11 -3 -17.5 -13.5t-3.5 -22.5l9 -35q3 -13 14 -19q7 -4 15 -4 q4 0 8 1q121 34 209.5 122.5t122.5 209.5q4 12 -2.5 23t-18.5 14l-36 9q-3 1 -7 1z" />
  20709. <glyph unicode="&#xe202;" d="M700 800h300v-380h-180v200h-340v-200h-380v755q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM700 300h162l-212 -212l-212 212h162v200h100v-200zM520 0h-395q-10 0 -17.5 7.5t-7.5 17.5v395zM1000 220v-195q0 -10 -7.5 -17.5t-17.5 -7.5h-195z" />
  20710. <glyph unicode="&#xe203;" d="M700 800h300v-520l-350 350l-550 -550v1095q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM862 200h-162v-200h-100v200h-162l212 212zM480 0h-355q-10 0 -17.5 7.5t-7.5 17.5v55h380v-80zM1000 80v-55q0 -10 -7.5 -17.5t-17.5 -7.5h-155v80h180z" />
  20711. <glyph unicode="&#xe204;" d="M1162 800h-162v-200h100l100 -100h-300v300h-162l212 212zM200 800h200q27 0 40 -2t29.5 -10.5t23.5 -30t7 -57.5h300v-100h-600l-200 -350v450h100q0 36 7 57.5t23.5 30t29.5 10.5t40 2zM800 400h240l-240 -400h-800l300 500h500v-100z" />
  20712. <glyph unicode="&#xe205;" d="M650 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM1000 850v150q41 0 70.5 -29.5t29.5 -70.5v-800 q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-1 0 -20 4l246 246l-326 326v324q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM412 250l-212 -212v162h-200v100h200v162z" />
  20713. <glyph unicode="&#xe206;" d="M450 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM800 850v150q41 0 70.5 -29.5t29.5 -70.5v-500 h-200v-300h200q0 -36 -7 -57.5t-23.5 -30t-29.5 -10.5t-40 -2h-600q-41 0 -70.5 29.5t-29.5 70.5v800q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM1212 250l-212 -212v162h-200v100h200v162z" />
  20714. <glyph unicode="&#xe209;" d="M658 1197l637 -1104q23 -38 7 -65.5t-60 -27.5h-1276q-44 0 -60 27.5t7 65.5l637 1104q22 39 54 39t54 -39zM704 800h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM500 300v-100h200 v100h-200z" />
  20715. <glyph unicode="&#xe210;" d="M425 1100h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM825 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM25 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5zM425 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5 v150q0 10 7.5 17.5t17.5 7.5zM25 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
  20716. <glyph unicode="&#xe211;" d="M700 1200h100v-200h-100v-100h350q62 0 86.5 -39.5t-3.5 -94.5l-66 -132q-41 -83 -81 -134h-772q-40 51 -81 134l-66 132q-28 55 -3.5 94.5t86.5 39.5h350v100h-100v200h100v100h200v-100zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100 h-950l138 100h-13q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
  20717. <glyph unicode="&#xe212;" d="M600 1300q40 0 68.5 -29.5t28.5 -70.5h-194q0 41 28.5 70.5t68.5 29.5zM443 1100h314q18 -37 18 -75q0 -8 -3 -25h328q41 0 44.5 -16.5t-30.5 -38.5l-175 -145h-678l-178 145q-34 22 -29 38.5t46 16.5h328q-3 17 -3 25q0 38 18 75zM250 700h700q21 0 35.5 -14.5 t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-150v-200l275 -200h-950l275 200v200h-150q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
  20718. <glyph unicode="&#xe213;" d="M600 1181q75 0 128 -53t53 -128t-53 -128t-128 -53t-128 53t-53 128t53 128t128 53zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13 l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
  20719. <glyph unicode="&#xe214;" d="M600 1300q47 0 92.5 -53.5t71 -123t25.5 -123.5q0 -78 -55.5 -133.5t-133.5 -55.5t-133.5 55.5t-55.5 133.5q0 62 34 143l144 -143l111 111l-163 163q34 26 63 26zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45 zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
  20720. <glyph unicode="&#xe215;" d="M600 1200l300 -161v-139h-300q0 -57 18.5 -108t50 -91.5t63 -72t70 -67.5t57.5 -61h-530q-60 83 -90.5 177.5t-30.5 178.5t33 164.5t87.5 139.5t126 96.5t145.5 41.5v-98zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100 h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
  20721. <glyph unicode="&#xe216;" d="M600 1300q41 0 70.5 -29.5t29.5 -70.5v-78q46 -26 73 -72t27 -100v-50h-400v50q0 54 27 100t73 72v78q0 41 29.5 70.5t70.5 29.5zM400 800h400q54 0 100 -27t72 -73h-172v-100h200v-100h-200v-100h200v-100h-200v-100h200q0 -83 -58.5 -141.5t-141.5 -58.5h-400 q-83 0 -141.5 58.5t-58.5 141.5v400q0 83 58.5 141.5t141.5 58.5z" />
  20722. <glyph unicode="&#xe218;" d="M150 1100h900q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM125 400h950q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-283l224 -224q13 -13 13 -31.5t-13 -32 t-31.5 -13.5t-31.5 13l-88 88h-524l-87 -88q-13 -13 -32 -13t-32 13.5t-13 32t13 31.5l224 224h-289q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM541 300l-100 -100h324l-100 100h-124z" />
  20723. <glyph unicode="&#xe219;" d="M200 1100h800q83 0 141.5 -58.5t58.5 -141.5v-200h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100v200q0 83 58.5 141.5t141.5 58.5zM100 600h1000q41 0 70.5 -29.5 t29.5 -70.5v-300h-1200v300q0 41 29.5 70.5t70.5 29.5zM300 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200zM1100 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200z" />
  20724. <glyph unicode="&#xe221;" d="M480 1165l682 -683q31 -31 31 -75.5t-31 -75.5l-131 -131h-481l-517 518q-32 31 -32 75.5t32 75.5l295 296q31 31 75.5 31t76.5 -31zM108 794l342 -342l303 304l-341 341zM250 100h800q21 0 35.5 -14.5t14.5 -35.5v-50h-900v50q0 21 14.5 35.5t35.5 14.5z" />
  20725. <glyph unicode="&#xe223;" d="M1057 647l-189 506q-8 19 -27.5 33t-40.5 14h-400q-21 0 -40.5 -14t-27.5 -33l-189 -506q-8 -19 1.5 -33t30.5 -14h625v-150q0 -21 14.5 -35.5t35.5 -14.5t35.5 14.5t14.5 35.5v150h125q21 0 30.5 14t1.5 33zM897 0h-595v50q0 21 14.5 35.5t35.5 14.5h50v50 q0 21 14.5 35.5t35.5 14.5h48v300h200v-300h47q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-50z" />
  20726. <glyph unicode="&#xe224;" d="M900 800h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-375v591l-300 300v84q0 10 7.5 17.5t17.5 7.5h375v-400zM1200 900h-200v200zM400 600h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-650q-10 0 -17.5 7.5t-7.5 17.5v950q0 10 7.5 17.5t17.5 7.5h375v-400zM700 700h-200v200z " />
  20727. <glyph unicode="&#xe225;" d="M484 1095h195q75 0 146 -32.5t124 -86t89.5 -122.5t48.5 -142q18 -14 35 -20q31 -10 64.5 6.5t43.5 48.5q10 34 -15 71q-19 27 -9 43q5 8 12.5 11t19 -1t23.5 -16q41 -44 39 -105q-3 -63 -46 -106.5t-104 -43.5h-62q-7 -55 -35 -117t-56 -100l-39 -234q-3 -20 -20 -34.5 t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l12 70q-49 -14 -91 -14h-195q-24 0 -65 8l-11 -64q-3 -20 -20 -34.5t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l26 157q-84 74 -128 175l-159 53q-19 7 -33 26t-14 40v50q0 21 14.5 35.5t35.5 14.5h124q11 87 56 166l-111 95 q-16 14 -12.5 23.5t24.5 9.5h203q116 101 250 101zM675 1000h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h250q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5t-17.5 7.5z" />
  20728. <glyph unicode="&#xe226;" d="M641 900l423 247q19 8 42 2.5t37 -21.5l32 -38q14 -15 12.5 -36t-17.5 -34l-139 -120h-390zM50 1100h106q67 0 103 -17t66 -71l102 -212h823q21 0 35.5 -14.5t14.5 -35.5v-50q0 -21 -14 -40t-33 -26l-737 -132q-23 -4 -40 6t-26 25q-42 67 -100 67h-300q-62 0 -106 44 t-44 106v200q0 62 44 106t106 44zM173 928h-80q-19 0 -28 -14t-9 -35v-56q0 -51 42 -51h134q16 0 21.5 8t5.5 24q0 11 -16 45t-27 51q-18 28 -43 28zM550 727q-32 0 -54.5 -22.5t-22.5 -54.5t22.5 -54.5t54.5 -22.5t54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5zM130 389 l152 130q18 19 34 24t31 -3.5t24.5 -17.5t25.5 -28q28 -35 50.5 -51t48.5 -13l63 5l48 -179q13 -61 -3.5 -97.5t-67.5 -79.5l-80 -69q-47 -40 -109 -35.5t-103 51.5l-130 151q-40 47 -35.5 109.5t51.5 102.5zM380 377l-102 -88q-31 -27 2 -65l37 -43q13 -15 27.5 -19.5 t31.5 6.5l61 53q19 16 14 49q-2 20 -12 56t-17 45q-11 12 -19 14t-23 -8z" />
  20729. <glyph unicode="&#xe227;" d="M625 1200h150q10 0 17.5 -7.5t7.5 -17.5v-109q79 -33 131 -87.5t53 -128.5q1 -46 -15 -84.5t-39 -61t-46 -38t-39 -21.5l-17 -6q6 0 15 -1.5t35 -9t50 -17.5t53 -30t50 -45t35.5 -64t14.5 -84q0 -59 -11.5 -105.5t-28.5 -76.5t-44 -51t-49.5 -31.5t-54.5 -16t-49.5 -6.5 t-43.5 -1v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-100v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-175q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v600h-75q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5h175v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h100v75q0 10 7.5 17.5t17.5 7.5zM400 900v-200h263q28 0 48.5 10.5t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-263zM400 500v-200h363q28 0 48.5 10.5 t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-363z" />
  20730. <glyph unicode="&#xe230;" d="M212 1198h780q86 0 147 -61t61 -147v-416q0 -51 -18 -142.5t-36 -157.5l-18 -66q-29 -87 -93.5 -146.5t-146.5 -59.5h-572q-82 0 -147 59t-93 147q-8 28 -20 73t-32 143.5t-20 149.5v416q0 86 61 147t147 61zM600 1045q-70 0 -132.5 -11.5t-105.5 -30.5t-78.5 -41.5 t-57 -45t-36 -41t-20.5 -30.5l-6 -12l156 -243h560l156 243q-2 5 -6 12.5t-20 29.5t-36.5 42t-57 44.5t-79 42t-105 29.5t-132.5 12zM762 703h-157l195 261z" />
  20731. <glyph unicode="&#xe231;" d="M475 1300h150q103 0 189 -86t86 -189v-500q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
  20732. <glyph unicode="&#xe232;" d="M475 1300h96q0 -150 89.5 -239.5t239.5 -89.5v-446q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
  20733. <glyph unicode="&#xe233;" d="M1294 767l-638 -283l-378 170l-78 -60v-224l100 -150v-199l-150 148l-150 -149v200l100 150v250q0 4 -0.5 10.5t0 9.5t1 8t3 8t6.5 6l47 40l-147 65l642 283zM1000 380l-350 -166l-350 166v147l350 -165l350 165v-147z" />
  20734. <glyph unicode="&#xe234;" d="M250 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM650 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM1050 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
  20735. <glyph unicode="&#xe235;" d="M550 1100q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 700q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 300q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
  20736. <glyph unicode="&#xe236;" d="M125 1100h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM125 700h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM125 300h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
  20737. <glyph unicode="&#xe237;" d="M350 1200h500q162 0 256 -93.5t94 -256.5v-500q0 -165 -93.5 -257.5t-256.5 -92.5h-500q-165 0 -257.5 92.5t-92.5 257.5v500q0 165 92.5 257.5t257.5 92.5zM900 1000h-600q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h600q41 0 70.5 29.5 t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5zM350 900h500q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-500q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 14.5 35.5t35.5 14.5zM400 800v-200h400v200h-400z" />
  20738. <glyph unicode="&#xe238;" d="M150 1100h1000q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5z" />
  20739. <glyph unicode="&#xe239;" d="M650 1187q87 -67 118.5 -156t0 -178t-118.5 -155q-87 66 -118.5 155t0 178t118.5 156zM300 800q124 0 212 -88t88 -212q-124 0 -212 88t-88 212zM1000 800q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM300 500q124 0 212 -88t88 -212q-124 0 -212 88t-88 212z M1000 500q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM700 199v-144q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v142q40 -4 43 -4q17 0 57 6z" />
  20740. <glyph unicode="&#xe240;" d="M745 878l69 19q25 6 45 -12l298 -295q11 -11 15 -26.5t-2 -30.5q-5 -14 -18 -23.5t-28 -9.5h-8q1 0 1 -13q0 -29 -2 -56t-8.5 -62t-20 -63t-33 -53t-51 -39t-72.5 -14h-146q-184 0 -184 288q0 24 10 47q-20 4 -62 4t-63 -4q11 -24 11 -47q0 -288 -184 -288h-142 q-48 0 -84.5 21t-56 51t-32 71.5t-16 75t-3.5 68.5q0 13 2 13h-7q-15 0 -27.5 9.5t-18.5 23.5q-6 15 -2 30.5t15 25.5l298 296q20 18 46 11l76 -19q20 -5 30.5 -22.5t5.5 -37.5t-22.5 -31t-37.5 -5l-51 12l-182 -193h891l-182 193l-44 -12q-20 -5 -37.5 6t-22.5 31t6 37.5 t31 22.5z" />
  20741. <glyph unicode="&#xe241;" d="M1200 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM500 450h-25q0 15 -4 24.5t-9 14.5t-17 7.5t-20 3t-25 0.5h-100v-425q0 -11 12.5 -17.5t25.5 -7.5h12v-50h-200v50q50 0 50 25v425h-100q-17 0 -25 -0.5t-20 -3t-17 -7.5t-9 -14.5t-4 -24.5h-25v150h500v-150z" />
  20742. <glyph unicode="&#xe242;" d="M1000 300v50q-25 0 -55 32q-14 14 -25 31t-16 27l-4 11l-289 747h-69l-300 -754q-18 -35 -39 -56q-9 -9 -24.5 -18.5t-26.5 -14.5l-11 -5v-50h273v50q-49 0 -78.5 21.5t-11.5 67.5l69 176h293l61 -166q13 -34 -3.5 -66.5t-55.5 -32.5v-50h312zM412 691l134 342l121 -342 h-255zM1100 150v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5z" />
  20743. <glyph unicode="&#xe243;" d="M50 1200h1100q21 0 35.5 -14.5t14.5 -35.5v-1100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5zM611 1118h-70q-13 0 -18 -12l-299 -753q-17 -32 -35 -51q-18 -18 -56 -34q-12 -5 -12 -18v-50q0 -8 5.5 -14t14.5 -6 h273q8 0 14 6t6 14v50q0 8 -6 14t-14 6q-55 0 -71 23q-10 14 0 39l63 163h266l57 -153q11 -31 -6 -55q-12 -17 -36 -17q-8 0 -14 -6t-6 -14v-50q0 -8 6 -14t14 -6h313q8 0 14 6t6 14v50q0 7 -5.5 13t-13.5 7q-17 0 -42 25q-25 27 -40 63h-1l-288 748q-5 12 -19 12zM639 611 h-197l103 264z" />
  20744. <glyph unicode="&#xe244;" d="M1200 1100h-1200v100h1200v-100zM50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 1000h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM700 900v-300h300v300h-300z" />
  20745. <glyph unicode="&#xe245;" d="M50 1200h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 700h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM700 600v-300h300v300h-300zM1200 0h-1200v100h1200v-100z" />
  20746. <glyph unicode="&#xe246;" d="M50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-350h100v150q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-150h100v-100h-100v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v150h-100v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM700 700v-300h300v300h-300z" />
  20747. <glyph unicode="&#xe247;" d="M100 0h-100v1200h100v-1200zM250 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM300 1000v-300h300v300h-300zM250 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
  20748. <glyph unicode="&#xe248;" d="M600 1100h150q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-100h450q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h350v100h-150q-21 0 -35.5 14.5 t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h150v100h100v-100zM400 1000v-300h300v300h-300z" />
  20749. <glyph unicode="&#xe249;" d="M1200 0h-100v1200h100v-1200zM550 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM600 1000v-300h300v300h-300zM50 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
  20750. <glyph unicode="&#xe250;" d="M865 565l-494 -494q-23 -23 -41 -23q-14 0 -22 13.5t-8 38.5v1000q0 25 8 38.5t22 13.5q18 0 41 -23l494 -494q14 -14 14 -35t-14 -35z" />
  20751. <glyph unicode="&#xe251;" d="M335 635l494 494q29 29 50 20.5t21 -49.5v-1000q0 -41 -21 -49.5t-50 20.5l-494 494q-14 14 -14 35t14 35z" />
  20752. <glyph unicode="&#xe252;" d="M100 900h1000q41 0 49.5 -21t-20.5 -50l-494 -494q-14 -14 -35 -14t-35 14l-494 494q-29 29 -20.5 50t49.5 21z" />
  20753. <glyph unicode="&#xe253;" d="M635 865l494 -494q29 -29 20.5 -50t-49.5 -21h-1000q-41 0 -49.5 21t20.5 50l494 494q14 14 35 14t35 -14z" />
  20754. <glyph unicode="&#xe254;" d="M700 741v-182l-692 -323v221l413 193l-413 193v221zM1200 0h-800v200h800v-200z" />
  20755. <glyph unicode="&#xe255;" d="M1200 900h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300zM0 700h50q0 21 4 37t9.5 26.5t18 17.5t22 11t28.5 5.5t31 2t37 0.5h100v-550q0 -22 -25 -34.5t-50 -13.5l-25 -2v-100h400v100q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v550h100q25 0 37 -0.5t31 -2 t28.5 -5.5t22 -11t18 -17.5t9.5 -26.5t4 -37h50v300h-800v-300z" />
  20756. <glyph unicode="&#xe256;" d="M800 700h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-100v-550q0 -22 25 -34.5t50 -14.5l25 -1v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v550h-100q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h800v-300zM1100 200h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300z" />
  20757. <glyph unicode="&#xe257;" d="M701 1098h160q16 0 21 -11t-7 -23l-464 -464l464 -464q12 -12 7 -23t-21 -11h-160q-13 0 -23 9l-471 471q-7 8 -7 18t7 18l471 471q10 9 23 9z" />
  20758. <glyph unicode="&#xe258;" d="M339 1098h160q13 0 23 -9l471 -471q7 -8 7 -18t-7 -18l-471 -471q-10 -9 -23 -9h-160q-16 0 -21 11t7 23l464 464l-464 464q-12 12 -7 23t21 11z" />
  20759. <glyph unicode="&#xe259;" d="M1087 882q11 -5 11 -21v-160q0 -13 -9 -23l-471 -471q-8 -7 -18 -7t-18 7l-471 471q-9 10 -9 23v160q0 16 11 21t23 -7l464 -464l464 464q12 12 23 7z" />
  20760. <glyph unicode="&#xe260;" d="M618 993l471 -471q9 -10 9 -23v-160q0 -16 -11 -21t-23 7l-464 464l-464 -464q-12 -12 -23 -7t-11 21v160q0 13 9 23l471 471q8 7 18 7t18 -7z" />
  20761. <glyph unicode="&#xf8ff;" d="M1000 1200q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM450 1000h100q21 0 40 -14t26 -33l79 -194q5 1 16 3q34 6 54 9.5t60 7t65.5 1t61 -10t56.5 -23t42.5 -42t29 -64t5 -92t-19.5 -121.5q-1 -7 -3 -19.5t-11 -50t-20.5 -73t-32.5 -81.5t-46.5 -83t-64 -70 t-82.5 -50q-13 -5 -42 -5t-65.5 2.5t-47.5 2.5q-14 0 -49.5 -3.5t-63 -3.5t-43.5 7q-57 25 -104.5 78.5t-75 111.5t-46.5 112t-26 90l-7 35q-15 63 -18 115t4.5 88.5t26 64t39.5 43.5t52 25.5t58.5 13t62.5 2t59.5 -4.5t55.5 -8l-147 192q-12 18 -5.5 30t27.5 12z" />
  20762. <glyph unicode="&#x1f511;" d="M250 1200h600q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-500l-255 -178q-19 -9 -32 -1t-13 29v650h-150q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM400 1100v-100h300v100h-300z" />
  20763. <glyph unicode="&#x1f6aa;" d="M250 1200h750q39 0 69.5 -40.5t30.5 -84.5v-933l-700 -117v950l600 125h-700v-1000h-100v1025q0 23 15.5 49t34.5 26zM500 525v-100l100 20v100z" />
  20764. </font>
  20765. </defs></svg> <?php
  20766. /*
  20767. * This file is part of the PHP_CodeCoverage package.
  20768. *
  20769. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  20770. *
  20771. * For the full copyright and license information, please view the LICENSE
  20772. * file that was distributed with this source code.
  20773. */
  20774. /**
  20775. * Renders a PHP_CodeCoverage_Report_Node_Directory node.
  20776. *
  20777. * @since Class available since Release 1.1.0
  20778. */
  20779. class PHP_CodeCoverage_Report_HTML_Renderer_Directory extends PHP_CodeCoverage_Report_HTML_Renderer
  20780. {
  20781. /**
  20782. * @param PHP_CodeCoverage_Report_Node_Directory $node
  20783. * @param string $file
  20784. */
  20785. public function render(PHP_CodeCoverage_Report_Node_Directory $node, $file)
  20786. {
  20787. $template = new Text_Template($this->templatePath . 'directory.html', '{{', '}}');
  20788. $this->setCommonTemplateVariables($template, $node);
  20789. $items = $this->renderItem($node, true);
  20790. foreach ($node->getDirectories() as $item) {
  20791. $items .= $this->renderItem($item);
  20792. }
  20793. foreach ($node->getFiles() as $item) {
  20794. $items .= $this->renderItem($item);
  20795. }
  20796. $template->setVar(
  20797. array(
  20798. 'id' => $node->getId(),
  20799. 'items' => $items
  20800. )
  20801. );
  20802. $template->renderTo($file);
  20803. }
  20804. /**
  20805. * @param PHP_CodeCoverage_Report_Node $item
  20806. * @param bool $total
  20807. * @return string
  20808. */
  20809. protected function renderItem(PHP_CodeCoverage_Report_Node $item, $total = false)
  20810. {
  20811. $data = array(
  20812. 'numClasses' => $item->getNumClassesAndTraits(),
  20813. 'numTestedClasses' => $item->getNumTestedClassesAndTraits(),
  20814. 'numMethods' => $item->getNumMethods(),
  20815. 'numTestedMethods' => $item->getNumTestedMethods(),
  20816. 'linesExecutedPercent' => $item->getLineExecutedPercent(false),
  20817. 'linesExecutedPercentAsString' => $item->getLineExecutedPercent(),
  20818. 'numExecutedLines' => $item->getNumExecutedLines(),
  20819. 'numExecutableLines' => $item->getNumExecutableLines(),
  20820. 'testedMethodsPercent' => $item->getTestedMethodsPercent(false),
  20821. 'testedMethodsPercentAsString' => $item->getTestedMethodsPercent(),
  20822. 'testedClassesPercent' => $item->getTestedClassesAndTraitsPercent(false),
  20823. 'testedClassesPercentAsString' => $item->getTestedClassesAndTraitsPercent()
  20824. );
  20825. if ($total) {
  20826. $data['name'] = 'Total';
  20827. } else {
  20828. if ($item instanceof PHP_CodeCoverage_Report_Node_Directory) {
  20829. $data['name'] = sprintf(
  20830. '<a href="%s/index.html">%s</a>',
  20831. $item->getName(),
  20832. $item->getName()
  20833. );
  20834. $data['icon'] = '<span class="glyphicon glyphicon-folder-open"></span> ';
  20835. } else {
  20836. $data['name'] = sprintf(
  20837. '<a href="%s.html">%s</a>',
  20838. $item->getName(),
  20839. $item->getName()
  20840. );
  20841. $data['icon'] = '<span class="glyphicon glyphicon-file"></span> ';
  20842. }
  20843. }
  20844. return $this->renderItemTemplate(
  20845. new Text_Template($this->templatePath . 'directory_item.html', '{{', '}}'),
  20846. $data
  20847. );
  20848. }
  20849. }
  20850. <?php
  20851. /*
  20852. * This file is part of the PHP_CodeCoverage package.
  20853. *
  20854. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  20855. *
  20856. * For the full copyright and license information, please view the LICENSE
  20857. * file that was distributed with this source code.
  20858. */
  20859. /**
  20860. * @since Class available since Release 2.0.0
  20861. */
  20862. class PHP_CodeCoverage_Report_Crap4j
  20863. {
  20864. /**
  20865. * @var int
  20866. */
  20867. private $threshold;
  20868. /**
  20869. * @param int $threshold
  20870. */
  20871. public function __construct($threshold = 30)
  20872. {
  20873. if (!is_int($threshold)) {
  20874. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  20875. 1,
  20876. 'integer'
  20877. );
  20878. }
  20879. $this->threshold = $threshold;
  20880. }
  20881. /**
  20882. * @param PHP_CodeCoverage $coverage
  20883. * @param string $target
  20884. * @param string $name
  20885. * @return string
  20886. */
  20887. public function process(PHP_CodeCoverage $coverage, $target = null, $name = null)
  20888. {
  20889. $document = new DOMDocument('1.0', 'UTF-8');
  20890. $document->formatOutput = true;
  20891. $root = $document->createElement('crap_result');
  20892. $document->appendChild($root);
  20893. $project = $document->createElement('project', is_string($name) ? $name : '');
  20894. $root->appendChild($project);
  20895. $root->appendChild($document->createElement('timestamp', date('Y-m-d H:i:s', (int) $_SERVER['REQUEST_TIME'])));
  20896. $stats = $document->createElement('stats');
  20897. $methodsNode = $document->createElement('methods');
  20898. $report = $coverage->getReport();
  20899. unset($coverage);
  20900. $fullMethodCount = 0;
  20901. $fullCrapMethodCount = 0;
  20902. $fullCrapLoad = 0;
  20903. $fullCrap = 0;
  20904. foreach ($report as $item) {
  20905. $namespace = 'global';
  20906. if (!$item instanceof PHP_CodeCoverage_Report_Node_File) {
  20907. continue;
  20908. }
  20909. $file = $document->createElement('file');
  20910. $file->setAttribute('name', $item->getPath());
  20911. $classes = $item->getClassesAndTraits();
  20912. foreach ($classes as $className => $class) {
  20913. foreach ($class['methods'] as $methodName => $method) {
  20914. $crapLoad = $this->getCrapLoad($method['crap'], $method['ccn'], $method['coverage']);
  20915. $fullCrap += $method['crap'];
  20916. $fullCrapLoad += $crapLoad;
  20917. $fullMethodCount++;
  20918. if ($method['crap'] >= $this->threshold) {
  20919. $fullCrapMethodCount++;
  20920. }
  20921. $methodNode = $document->createElement('method');
  20922. if (!empty($class['package']['namespace'])) {
  20923. $namespace = $class['package']['namespace'];
  20924. }
  20925. $methodNode->appendChild($document->createElement('package', $namespace));
  20926. $methodNode->appendChild($document->createElement('className', $className));
  20927. $methodNode->appendChild($document->createElement('methodName', $methodName));
  20928. $methodNode->appendChild($document->createElement('methodSignature', htmlspecialchars($method['signature'])));
  20929. $methodNode->appendChild($document->createElement('fullMethod', htmlspecialchars($method['signature'])));
  20930. $methodNode->appendChild($document->createElement('crap', $this->roundValue($method['crap'])));
  20931. $methodNode->appendChild($document->createElement('complexity', $method['ccn']));
  20932. $methodNode->appendChild($document->createElement('coverage', $this->roundValue($method['coverage'])));
  20933. $methodNode->appendChild($document->createElement('crapLoad', round($crapLoad)));
  20934. $methodsNode->appendChild($methodNode);
  20935. }
  20936. }
  20937. }
  20938. $stats->appendChild($document->createElement('name', 'Method Crap Stats'));
  20939. $stats->appendChild($document->createElement('methodCount', $fullMethodCount));
  20940. $stats->appendChild($document->createElement('crapMethodCount', $fullCrapMethodCount));
  20941. $stats->appendChild($document->createElement('crapLoad', round($fullCrapLoad)));
  20942. $stats->appendChild($document->createElement('totalCrap', $fullCrap));
  20943. if ($fullMethodCount > 0) {
  20944. $crapMethodPercent = $this->roundValue((100 * $fullCrapMethodCount) / $fullMethodCount);
  20945. } else {
  20946. $crapMethodPercent = '';
  20947. }
  20948. $stats->appendChild($document->createElement('crapMethodPercent', $crapMethodPercent));
  20949. $root->appendChild($stats);
  20950. $root->appendChild($methodsNode);
  20951. if ($target !== null) {
  20952. if (!is_dir(dirname($target))) {
  20953. mkdir(dirname($target), 0777, true);
  20954. }
  20955. return $document->save($target);
  20956. } else {
  20957. return $document->saveXML();
  20958. }
  20959. }
  20960. /**
  20961. * @param float $crapValue
  20962. * @param int $cyclomaticComplexity
  20963. * @param float $coveragePercent
  20964. * @return float
  20965. */
  20966. private function getCrapLoad($crapValue, $cyclomaticComplexity, $coveragePercent)
  20967. {
  20968. $crapLoad = 0;
  20969. if ($crapValue >= $this->threshold) {
  20970. $crapLoad += $cyclomaticComplexity * (1.0 - $coveragePercent / 100);
  20971. $crapLoad += $cyclomaticComplexity / $this->threshold;
  20972. }
  20973. return $crapLoad;
  20974. }
  20975. /**
  20976. * @param float $value
  20977. * @return float
  20978. */
  20979. private function roundValue($value)
  20980. {
  20981. return round($value, 2);
  20982. }
  20983. }
  20984. <?php
  20985. /*
  20986. * This file is part of the PHP_CodeCoverage package.
  20987. *
  20988. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  20989. *
  20990. * For the full copyright and license information, please view the LICENSE
  20991. * file that was distributed with this source code.
  20992. */
  20993. /**
  20994. * @since Class available since Release 2.0.0
  20995. */
  20996. class PHP_CodeCoverage_Report_XML_Tests
  20997. {
  20998. private $contextNode;
  20999. private $codeMap = array(
  21000. 0 => 'PASSED', // PHPUnit_Runner_BaseTestRunner::STATUS_PASSED
  21001. 1 => 'SKIPPED', // PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED
  21002. 2 => 'INCOMPLETE', // PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE
  21003. 3 => 'FAILURE', // PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE
  21004. 4 => 'ERROR', // PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
  21005. 5 => 'RISKY' // PHPUnit_Runner_BaseTestRunner::STATUS_RISKY
  21006. );
  21007. public function __construct(DOMElement $context)
  21008. {
  21009. $this->contextNode = $context;
  21010. }
  21011. public function addTest($test, array $result)
  21012. {
  21013. $node = $this->contextNode->appendChild(
  21014. $this->contextNode->ownerDocument->createElementNS(
  21015. 'http://schema.phpunit.de/coverage/1.0',
  21016. 'test'
  21017. )
  21018. );
  21019. $node->setAttribute('name', $test);
  21020. $node->setAttribute('size', $result['size']);
  21021. $node->setAttribute('result', (int) $result['status']);
  21022. $node->setAttribute('status', $this->codeMap[(int) $result['status']]);
  21023. }
  21024. }
  21025. <?php
  21026. /*
  21027. * This file is part of the PHP_CodeCoverage package.
  21028. *
  21029. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21030. *
  21031. * For the full copyright and license information, please view the LICENSE
  21032. * file that was distributed with this source code.
  21033. */
  21034. /**
  21035. * @since Class available since Release 2.0.0
  21036. */
  21037. class PHP_CodeCoverage_Report_XML_File
  21038. {
  21039. /**
  21040. * @var DOMDocument
  21041. */
  21042. protected $dom;
  21043. /**
  21044. * @var DOMElement
  21045. */
  21046. protected $contextNode;
  21047. public function __construct(DOMElement $context)
  21048. {
  21049. $this->dom = $context->ownerDocument;
  21050. $this->contextNode = $context;
  21051. }
  21052. public function getTotals()
  21053. {
  21054. $totalsContainer = $this->contextNode->firstChild;
  21055. if (!$totalsContainer) {
  21056. $totalsContainer = $this->contextNode->appendChild(
  21057. $this->dom->createElementNS(
  21058. 'http://schema.phpunit.de/coverage/1.0',
  21059. 'totals'
  21060. )
  21061. );
  21062. }
  21063. return new PHP_CodeCoverage_Report_XML_Totals($totalsContainer);
  21064. }
  21065. public function getLineCoverage($line)
  21066. {
  21067. $coverage = $this->contextNode->getElementsByTagNameNS(
  21068. 'http://schema.phpunit.de/coverage/1.0',
  21069. 'coverage'
  21070. )->item(0);
  21071. if (!$coverage) {
  21072. $coverage = $this->contextNode->appendChild(
  21073. $this->dom->createElementNS(
  21074. 'http://schema.phpunit.de/coverage/1.0',
  21075. 'coverage'
  21076. )
  21077. );
  21078. }
  21079. $lineNode = $coverage->appendChild(
  21080. $this->dom->createElementNS(
  21081. 'http://schema.phpunit.de/coverage/1.0',
  21082. 'line'
  21083. )
  21084. );
  21085. return new PHP_CodeCoverage_Report_XML_File_Coverage($lineNode, $line);
  21086. }
  21087. }
  21088. <?php
  21089. /*
  21090. * This file is part of the PHP_CodeCoverage package.
  21091. *
  21092. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21093. *
  21094. * For the full copyright and license information, please view the LICENSE
  21095. * file that was distributed with this source code.
  21096. */
  21097. /**
  21098. * @since Class available since Release 2.0.0
  21099. */
  21100. class PHP_CodeCoverage_Report_XML_Node
  21101. {
  21102. /**
  21103. * @var DOMDocument
  21104. */
  21105. private $dom;
  21106. /**
  21107. * @var DOMElement
  21108. */
  21109. private $contextNode;
  21110. public function __construct(DOMElement $context)
  21111. {
  21112. $this->setContextNode($context);
  21113. }
  21114. protected function setContextNode(DOMElement $context)
  21115. {
  21116. $this->dom = $context->ownerDocument;
  21117. $this->contextNode = $context;
  21118. }
  21119. public function getDom()
  21120. {
  21121. return $this->dom;
  21122. }
  21123. protected function getContextNode()
  21124. {
  21125. return $this->contextNode;
  21126. }
  21127. public function getTotals()
  21128. {
  21129. $totalsContainer = $this->getContextNode()->firstChild;
  21130. if (!$totalsContainer) {
  21131. $totalsContainer = $this->getContextNode()->appendChild(
  21132. $this->dom->createElementNS(
  21133. 'http://schema.phpunit.de/coverage/1.0',
  21134. 'totals'
  21135. )
  21136. );
  21137. }
  21138. return new PHP_CodeCoverage_Report_XML_Totals($totalsContainer);
  21139. }
  21140. public function addDirectory($name)
  21141. {
  21142. $dirNode = $this->getDom()->createElementNS(
  21143. 'http://schema.phpunit.de/coverage/1.0',
  21144. 'directory'
  21145. );
  21146. $dirNode->setAttribute('name', $name);
  21147. $this->getContextNode()->appendChild($dirNode);
  21148. return new PHP_CodeCoverage_Report_XML_Directory($dirNode);
  21149. }
  21150. public function addFile($name, $href)
  21151. {
  21152. $fileNode = $this->getDom()->createElementNS(
  21153. 'http://schema.phpunit.de/coverage/1.0',
  21154. 'file'
  21155. );
  21156. $fileNode->setAttribute('name', $name);
  21157. $fileNode->setAttribute('href', $href);
  21158. $this->getContextNode()->appendChild($fileNode);
  21159. return new PHP_CodeCoverage_Report_XML_File($fileNode);
  21160. }
  21161. }
  21162. <?php
  21163. /*
  21164. * This file is part of the PHP_CodeCoverage package.
  21165. *
  21166. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21167. *
  21168. * For the full copyright and license information, please view the LICENSE
  21169. * file that was distributed with this source code.
  21170. */
  21171. /**
  21172. * @since Class available since Release 2.0.0
  21173. */
  21174. class PHP_CodeCoverage_Report_XML_Project extends PHP_CodeCoverage_Report_XML_Node
  21175. {
  21176. public function __construct($name)
  21177. {
  21178. $this->init();
  21179. $this->setProjectName($name);
  21180. }
  21181. private function init()
  21182. {
  21183. $dom = new DOMDocument;
  21184. $dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="http://schema.phpunit.de/coverage/1.0"><project/></phpunit>');
  21185. $this->setContextNode(
  21186. $dom->getElementsByTagNameNS(
  21187. 'http://schema.phpunit.de/coverage/1.0',
  21188. 'project'
  21189. )->item(0)
  21190. );
  21191. }
  21192. private function setProjectName($name)
  21193. {
  21194. $this->getContextNode()->setAttribute('name', $name);
  21195. }
  21196. public function getTests()
  21197. {
  21198. $testsNode = $this->getContextNode()->getElementsByTagNameNS(
  21199. 'http://schema.phpunit.de/coverage/1.0',
  21200. 'tests'
  21201. )->item(0);
  21202. if (!$testsNode) {
  21203. $testsNode = $this->getContextNode()->appendChild(
  21204. $this->getDom()->createElementNS(
  21205. 'http://schema.phpunit.de/coverage/1.0',
  21206. 'tests'
  21207. )
  21208. );
  21209. }
  21210. return new PHP_CodeCoverage_Report_XML_Tests($testsNode);
  21211. }
  21212. public function asDom()
  21213. {
  21214. return $this->getDom();
  21215. }
  21216. }
  21217. <?php
  21218. /*
  21219. * This file is part of the PHP_CodeCoverage package.
  21220. *
  21221. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21222. *
  21223. * For the full copyright and license information, please view the LICENSE
  21224. * file that was distributed with this source code.
  21225. */
  21226. /**
  21227. * @since Class available since Release 2.0.0
  21228. */
  21229. class PHP_CodeCoverage_Report_XML_Totals
  21230. {
  21231. /**
  21232. * @var DOMNode
  21233. */
  21234. private $container;
  21235. /**
  21236. * @var DOMElement
  21237. */
  21238. private $linesNode;
  21239. /**
  21240. * @var DOMElement
  21241. */
  21242. private $methodsNode;
  21243. /**
  21244. * @var DOMElement
  21245. */
  21246. private $functionsNode;
  21247. /**
  21248. * @var DOMElement
  21249. */
  21250. private $classesNode;
  21251. /**
  21252. * @var DOMElement
  21253. */
  21254. private $traitsNode;
  21255. public function __construct(DOMElement $container)
  21256. {
  21257. $this->container = $container;
  21258. $dom = $container->ownerDocument;
  21259. $this->linesNode = $dom->createElementNS(
  21260. 'http://schema.phpunit.de/coverage/1.0',
  21261. 'lines'
  21262. );
  21263. $this->methodsNode = $dom->createElementNS(
  21264. 'http://schema.phpunit.de/coverage/1.0',
  21265. 'methods'
  21266. );
  21267. $this->functionsNode = $dom->createElementNS(
  21268. 'http://schema.phpunit.de/coverage/1.0',
  21269. 'functions'
  21270. );
  21271. $this->classesNode = $dom->createElementNS(
  21272. 'http://schema.phpunit.de/coverage/1.0',
  21273. 'classes'
  21274. );
  21275. $this->traitsNode = $dom->createElementNS(
  21276. 'http://schema.phpunit.de/coverage/1.0',
  21277. 'traits'
  21278. );
  21279. $container->appendChild($this->linesNode);
  21280. $container->appendChild($this->methodsNode);
  21281. $container->appendChild($this->functionsNode);
  21282. $container->appendChild($this->classesNode);
  21283. $container->appendChild($this->traitsNode);
  21284. }
  21285. public function getContainer()
  21286. {
  21287. return $this->container;
  21288. }
  21289. public function setNumLines($loc, $cloc, $ncloc, $executable, $executed)
  21290. {
  21291. $this->linesNode->setAttribute('total', $loc);
  21292. $this->linesNode->setAttribute('comments', $cloc);
  21293. $this->linesNode->setAttribute('code', $ncloc);
  21294. $this->linesNode->setAttribute('executable', $executable);
  21295. $this->linesNode->setAttribute('executed', $executed);
  21296. $this->linesNode->setAttribute(
  21297. 'percent',
  21298. PHP_CodeCoverage_Util::percent($executed, $executable, true)
  21299. );
  21300. }
  21301. public function setNumClasses($count, $tested)
  21302. {
  21303. $this->classesNode->setAttribute('count', $count);
  21304. $this->classesNode->setAttribute('tested', $tested);
  21305. $this->classesNode->setAttribute(
  21306. 'percent',
  21307. PHP_CodeCoverage_Util::percent($tested, $count, true)
  21308. );
  21309. }
  21310. public function setNumTraits($count, $tested)
  21311. {
  21312. $this->traitsNode->setAttribute('count', $count);
  21313. $this->traitsNode->setAttribute('tested', $tested);
  21314. $this->traitsNode->setAttribute(
  21315. 'percent',
  21316. PHP_CodeCoverage_Util::percent($tested, $count, true)
  21317. );
  21318. }
  21319. public function setNumMethods($count, $tested)
  21320. {
  21321. $this->methodsNode->setAttribute('count', $count);
  21322. $this->methodsNode->setAttribute('tested', $tested);
  21323. $this->methodsNode->setAttribute(
  21324. 'percent',
  21325. PHP_CodeCoverage_Util::percent($tested, $count, true)
  21326. );
  21327. }
  21328. public function setNumFunctions($count, $tested)
  21329. {
  21330. $this->functionsNode->setAttribute('count', $count);
  21331. $this->functionsNode->setAttribute('tested', $tested);
  21332. $this->functionsNode->setAttribute(
  21333. 'percent',
  21334. PHP_CodeCoverage_Util::percent($tested, $count, true)
  21335. );
  21336. }
  21337. }
  21338. <?php
  21339. /*
  21340. * This file is part of the PHP_CodeCoverage package.
  21341. *
  21342. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21343. *
  21344. * For the full copyright and license information, please view the LICENSE
  21345. * file that was distributed with this source code.
  21346. */
  21347. /**
  21348. * @since Class available since Release 2.0.0
  21349. */
  21350. class PHP_CodeCoverage_Report_XML_Directory extends PHP_CodeCoverage_Report_XML_Node
  21351. {
  21352. }
  21353. <?php
  21354. /*
  21355. * This file is part of the PHP_CodeCoverage package.
  21356. *
  21357. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21358. *
  21359. * For the full copyright and license information, please view the LICENSE
  21360. * file that was distributed with this source code.
  21361. */
  21362. /**
  21363. * @since Class available since Release 2.0.0
  21364. */
  21365. class PHP_CodeCoverage_Report_XML_File_Method
  21366. {
  21367. /**
  21368. * @var DOMElement
  21369. */
  21370. private $contextNode;
  21371. public function __construct(DOMElement $context, $name)
  21372. {
  21373. $this->contextNode = $context;
  21374. $this->setName($name);
  21375. }
  21376. private function setName($name)
  21377. {
  21378. $this->contextNode->setAttribute('name', $name);
  21379. }
  21380. public function setSignature($signature)
  21381. {
  21382. $this->contextNode->setAttribute('signature', $signature);
  21383. }
  21384. public function setLines($start, $end = null)
  21385. {
  21386. $this->contextNode->setAttribute('start', $start);
  21387. if ($end !== null) {
  21388. $this->contextNode->setAttribute('end', $end);
  21389. }
  21390. }
  21391. public function setTotals($executable, $executed, $coverage)
  21392. {
  21393. $this->contextNode->setAttribute('executable', $executable);
  21394. $this->contextNode->setAttribute('executed', $executed);
  21395. $this->contextNode->setAttribute('coverage', $coverage);
  21396. }
  21397. public function setCrap($crap)
  21398. {
  21399. $this->contextNode->setAttribute('crap', $crap);
  21400. }
  21401. }
  21402. <?php
  21403. /*
  21404. * This file is part of the PHP_CodeCoverage package.
  21405. *
  21406. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21407. *
  21408. * For the full copyright and license information, please view the LICENSE
  21409. * file that was distributed with this source code.
  21410. */
  21411. /**
  21412. * @since Class available since Release 2.0.0
  21413. */
  21414. class PHP_CodeCoverage_Report_XML_File_Report extends PHP_CodeCoverage_Report_XML_File
  21415. {
  21416. public function __construct($name)
  21417. {
  21418. $this->dom = new DOMDocument;
  21419. $this->dom->loadXML('<?xml version="1.0" ?><phpunit xmlns="http://schema.phpunit.de/coverage/1.0"><file /></phpunit>');
  21420. $this->contextNode = $this->dom->getElementsByTagNameNS(
  21421. 'http://schema.phpunit.de/coverage/1.0',
  21422. 'file'
  21423. )->item(0);
  21424. $this->setName($name);
  21425. }
  21426. private function setName($name)
  21427. {
  21428. $this->contextNode->setAttribute('name', $name);
  21429. }
  21430. public function asDom()
  21431. {
  21432. return $this->dom;
  21433. }
  21434. public function getFunctionObject($name)
  21435. {
  21436. $node = $this->contextNode->appendChild(
  21437. $this->dom->createElementNS(
  21438. 'http://schema.phpunit.de/coverage/1.0',
  21439. 'function'
  21440. )
  21441. );
  21442. return new PHP_CodeCoverage_Report_XML_File_Method($node, $name);
  21443. }
  21444. public function getClassObject($name)
  21445. {
  21446. return $this->getUnitObject('class', $name);
  21447. }
  21448. public function getTraitObject($name)
  21449. {
  21450. return $this->getUnitObject('trait', $name);
  21451. }
  21452. private function getUnitObject($tagName, $name)
  21453. {
  21454. $node = $this->contextNode->appendChild(
  21455. $this->dom->createElementNS(
  21456. 'http://schema.phpunit.de/coverage/1.0',
  21457. $tagName
  21458. )
  21459. );
  21460. return new PHP_CodeCoverage_Report_XML_File_Unit($node, $name);
  21461. }
  21462. }
  21463. <?php
  21464. /*
  21465. * This file is part of the PHP_CodeCoverage package.
  21466. *
  21467. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21468. *
  21469. * For the full copyright and license information, please view the LICENSE
  21470. * file that was distributed with this source code.
  21471. */
  21472. /**
  21473. * @since Class available since Release 2.0.0
  21474. */
  21475. class PHP_CodeCoverage_Report_XML_File_Coverage
  21476. {
  21477. /**
  21478. * @var XMLWriter
  21479. */
  21480. private $writer;
  21481. /**
  21482. * @var DOMElement
  21483. */
  21484. private $contextNode;
  21485. /**
  21486. * @var bool
  21487. */
  21488. private $finalized = false;
  21489. public function __construct(DOMElement $context, $line)
  21490. {
  21491. $this->contextNode = $context;
  21492. $this->writer = new XMLWriter();
  21493. $this->writer->openMemory();
  21494. $this->writer->startElementNs(null, $context->nodeName, 'http://schema.phpunit.de/coverage/1.0');
  21495. $this->writer->writeAttribute('nr', $line);
  21496. }
  21497. public function addTest($test)
  21498. {
  21499. if ($this->finalized) {
  21500. throw new PHP_CodeCoverage_Exception('Coverage Report already finalized');
  21501. }
  21502. $this->writer->startElement('covered');
  21503. $this->writer->writeAttribute('by', $test);
  21504. $this->writer->endElement();
  21505. }
  21506. public function finalize()
  21507. {
  21508. $this->writer->endElement();
  21509. $fragment = $this->contextNode->ownerDocument->createDocumentFragment();
  21510. $fragment->appendXML($this->writer->outputMemory());
  21511. $this->contextNode->parentNode->replaceChild(
  21512. $fragment,
  21513. $this->contextNode
  21514. );
  21515. $this->finalized = true;
  21516. }
  21517. }
  21518. <?php
  21519. /*
  21520. * This file is part of the PHP_CodeCoverage package.
  21521. *
  21522. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21523. *
  21524. * For the full copyright and license information, please view the LICENSE
  21525. * file that was distributed with this source code.
  21526. */
  21527. /**
  21528. * @since Class available since Release 2.0.0
  21529. */
  21530. class PHP_CodeCoverage_Report_XML_File_Unit
  21531. {
  21532. /**
  21533. * @var DOMElement
  21534. */
  21535. private $contextNode;
  21536. public function __construct(DOMElement $context, $name)
  21537. {
  21538. $this->contextNode = $context;
  21539. $this->setName($name);
  21540. }
  21541. private function setName($name)
  21542. {
  21543. $this->contextNode->setAttribute('name', $name);
  21544. }
  21545. public function setLines($start, $executable, $executed)
  21546. {
  21547. $this->contextNode->setAttribute('start', $start);
  21548. $this->contextNode->setAttribute('executable', $executable);
  21549. $this->contextNode->setAttribute('executed', $executed);
  21550. }
  21551. public function setCrap($crap)
  21552. {
  21553. $this->contextNode->setAttribute('crap', $crap);
  21554. }
  21555. public function setPackage($full, $package, $sub, $category)
  21556. {
  21557. $node = $this->contextNode->getElementsByTagNameNS(
  21558. 'http://schema.phpunit.de/coverage/1.0',
  21559. 'package'
  21560. )->item(0);
  21561. if (!$node) {
  21562. $node = $this->contextNode->appendChild(
  21563. $this->contextNode->ownerDocument->createElementNS(
  21564. 'http://schema.phpunit.de/coverage/1.0',
  21565. 'package'
  21566. )
  21567. );
  21568. }
  21569. $node->setAttribute('full', $full);
  21570. $node->setAttribute('name', $package);
  21571. $node->setAttribute('sub', $sub);
  21572. $node->setAttribute('category', $category);
  21573. }
  21574. public function setNamespace($namespace)
  21575. {
  21576. $node = $this->contextNode->getElementsByTagNameNS(
  21577. 'http://schema.phpunit.de/coverage/1.0',
  21578. 'namespace'
  21579. )->item(0);
  21580. if (!$node) {
  21581. $node = $this->contextNode->appendChild(
  21582. $this->contextNode->ownerDocument->createElementNS(
  21583. 'http://schema.phpunit.de/coverage/1.0',
  21584. 'namespace'
  21585. )
  21586. );
  21587. }
  21588. $node->setAttribute('name', $namespace);
  21589. }
  21590. public function addMethod($name)
  21591. {
  21592. $node = $this->contextNode->appendChild(
  21593. $this->contextNode->ownerDocument->createElementNS(
  21594. 'http://schema.phpunit.de/coverage/1.0',
  21595. 'method'
  21596. )
  21597. );
  21598. return new PHP_CodeCoverage_Report_XML_File_Method($node, $name);
  21599. }
  21600. }
  21601. <?php
  21602. /*
  21603. * This file is part of the PHP_CodeCoverage package.
  21604. *
  21605. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21606. *
  21607. * For the full copyright and license information, please view the LICENSE
  21608. * file that was distributed with this source code.
  21609. */
  21610. /**
  21611. * Base class for nodes in the code coverage information tree.
  21612. *
  21613. * @since Class available since Release 1.1.0
  21614. */
  21615. abstract class PHP_CodeCoverage_Report_Node implements Countable
  21616. {
  21617. /**
  21618. * @var string
  21619. */
  21620. protected $name;
  21621. /**
  21622. * @var string
  21623. */
  21624. protected $path;
  21625. /**
  21626. * @var array
  21627. */
  21628. protected $pathArray;
  21629. /**
  21630. * @var PHP_CodeCoverage_Report_Node
  21631. */
  21632. protected $parent;
  21633. /**
  21634. * @var string
  21635. */
  21636. protected $id;
  21637. /**
  21638. * Constructor.
  21639. *
  21640. * @param string $name
  21641. * @param PHP_CodeCoverage_Report_Node $parent
  21642. */
  21643. public function __construct($name, PHP_CodeCoverage_Report_Node $parent = null)
  21644. {
  21645. if (substr($name, -1) == '/') {
  21646. $name = substr($name, 0, -1);
  21647. }
  21648. $this->name = $name;
  21649. $this->parent = $parent;
  21650. }
  21651. /**
  21652. * @return string
  21653. */
  21654. public function getName()
  21655. {
  21656. return $this->name;
  21657. }
  21658. /**
  21659. * @return string
  21660. */
  21661. public function getId()
  21662. {
  21663. if ($this->id === null) {
  21664. $parent = $this->getParent();
  21665. if ($parent === null) {
  21666. $this->id = 'index';
  21667. } else {
  21668. $parentId = $parent->getId();
  21669. if ($parentId == 'index') {
  21670. $this->id = str_replace(':', '_', $this->name);
  21671. } else {
  21672. $this->id = $parentId . '/' . $this->name;
  21673. }
  21674. }
  21675. }
  21676. return $this->id;
  21677. }
  21678. /**
  21679. * @return string
  21680. */
  21681. public function getPath()
  21682. {
  21683. if ($this->path === null) {
  21684. if ($this->parent === null || $this->parent->getPath() === null || $this->parent->getPath() === false) {
  21685. $this->path = $this->name;
  21686. } else {
  21687. $this->path = $this->parent->getPath() . '/' . $this->name;
  21688. }
  21689. }
  21690. return $this->path;
  21691. }
  21692. /**
  21693. * @return array
  21694. */
  21695. public function getPathAsArray()
  21696. {
  21697. if ($this->pathArray === null) {
  21698. if ($this->parent === null) {
  21699. $this->pathArray = array();
  21700. } else {
  21701. $this->pathArray = $this->parent->getPathAsArray();
  21702. }
  21703. $this->pathArray[] = $this;
  21704. }
  21705. return $this->pathArray;
  21706. }
  21707. /**
  21708. * @return PHP_CodeCoverage_Report_Node
  21709. */
  21710. public function getParent()
  21711. {
  21712. return $this->parent;
  21713. }
  21714. /**
  21715. * Returns the percentage of classes that has been tested.
  21716. *
  21717. * @param bool $asString
  21718. * @return int
  21719. */
  21720. public function getTestedClassesPercent($asString = true)
  21721. {
  21722. return PHP_CodeCoverage_Util::percent(
  21723. $this->getNumTestedClasses(),
  21724. $this->getNumClasses(),
  21725. $asString
  21726. );
  21727. }
  21728. /**
  21729. * Returns the percentage of traits that has been tested.
  21730. *
  21731. * @param bool $asString
  21732. * @return int
  21733. */
  21734. public function getTestedTraitsPercent($asString = true)
  21735. {
  21736. return PHP_CodeCoverage_Util::percent(
  21737. $this->getNumTestedTraits(),
  21738. $this->getNumTraits(),
  21739. $asString
  21740. );
  21741. }
  21742. /**
  21743. * Returns the percentage of traits that has been tested.
  21744. *
  21745. * @param bool $asString
  21746. * @return int
  21747. * @since Method available since Release 1.2.0
  21748. */
  21749. public function getTestedClassesAndTraitsPercent($asString = true)
  21750. {
  21751. return PHP_CodeCoverage_Util::percent(
  21752. $this->getNumTestedClassesAndTraits(),
  21753. $this->getNumClassesAndTraits(),
  21754. $asString
  21755. );
  21756. }
  21757. /**
  21758. * Returns the percentage of methods that has been tested.
  21759. *
  21760. * @param bool $asString
  21761. * @return int
  21762. */
  21763. public function getTestedMethodsPercent($asString = true)
  21764. {
  21765. return PHP_CodeCoverage_Util::percent(
  21766. $this->getNumTestedMethods(),
  21767. $this->getNumMethods(),
  21768. $asString
  21769. );
  21770. }
  21771. /**
  21772. * Returns the percentage of executed lines.
  21773. *
  21774. * @param bool $asString
  21775. * @return int
  21776. */
  21777. public function getLineExecutedPercent($asString = true)
  21778. {
  21779. return PHP_CodeCoverage_Util::percent(
  21780. $this->getNumExecutedLines(),
  21781. $this->getNumExecutableLines(),
  21782. $asString
  21783. );
  21784. }
  21785. /**
  21786. * Returns the number of classes and traits.
  21787. *
  21788. * @return int
  21789. * @since Method available since Release 1.2.0
  21790. */
  21791. public function getNumClassesAndTraits()
  21792. {
  21793. return $this->getNumClasses() + $this->getNumTraits();
  21794. }
  21795. /**
  21796. * Returns the number of tested classes and traits.
  21797. *
  21798. * @return int
  21799. * @since Method available since Release 1.2.0
  21800. */
  21801. public function getNumTestedClassesAndTraits()
  21802. {
  21803. return $this->getNumTestedClasses() + $this->getNumTestedTraits();
  21804. }
  21805. /**
  21806. * Returns the classes and traits of this node.
  21807. *
  21808. * @return array
  21809. * @since Method available since Release 1.2.0
  21810. */
  21811. public function getClassesAndTraits()
  21812. {
  21813. return array_merge($this->getClasses(), $this->getTraits());
  21814. }
  21815. /**
  21816. * Returns the classes of this node.
  21817. *
  21818. * @return array
  21819. */
  21820. abstract public function getClasses();
  21821. /**
  21822. * Returns the traits of this node.
  21823. *
  21824. * @return array
  21825. */
  21826. abstract public function getTraits();
  21827. /**
  21828. * Returns the functions of this node.
  21829. *
  21830. * @return array
  21831. */
  21832. abstract public function getFunctions();
  21833. /**
  21834. * Returns the LOC/CLOC/NCLOC of this node.
  21835. *
  21836. * @return array
  21837. */
  21838. abstract public function getLinesOfCode();
  21839. /**
  21840. * Returns the number of executable lines.
  21841. *
  21842. * @return int
  21843. */
  21844. abstract public function getNumExecutableLines();
  21845. /**
  21846. * Returns the number of executed lines.
  21847. *
  21848. * @return int
  21849. */
  21850. abstract public function getNumExecutedLines();
  21851. /**
  21852. * Returns the number of classes.
  21853. *
  21854. * @return int
  21855. */
  21856. abstract public function getNumClasses();
  21857. /**
  21858. * Returns the number of tested classes.
  21859. *
  21860. * @return int
  21861. */
  21862. abstract public function getNumTestedClasses();
  21863. /**
  21864. * Returns the number of traits.
  21865. *
  21866. * @return int
  21867. */
  21868. abstract public function getNumTraits();
  21869. /**
  21870. * Returns the number of tested traits.
  21871. *
  21872. * @return int
  21873. */
  21874. abstract public function getNumTestedTraits();
  21875. /**
  21876. * Returns the number of methods.
  21877. *
  21878. * @return int
  21879. */
  21880. abstract public function getNumMethods();
  21881. /**
  21882. * Returns the number of tested methods.
  21883. *
  21884. * @return int
  21885. */
  21886. abstract public function getNumTestedMethods();
  21887. /**
  21888. * Returns the number of functions.
  21889. *
  21890. * @return int
  21891. */
  21892. abstract public function getNumFunctions();
  21893. /**
  21894. * Returns the number of tested functions.
  21895. *
  21896. * @return int
  21897. */
  21898. abstract public function getNumTestedFunctions();
  21899. }
  21900. <?php
  21901. /*
  21902. * This file is part of the PHP_CodeCoverage package.
  21903. *
  21904. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  21905. *
  21906. * For the full copyright and license information, please view the LICENSE
  21907. * file that was distributed with this source code.
  21908. */
  21909. /**
  21910. * Recursive iterator for PHP_CodeCoverage_Report_Node object graphs.
  21911. *
  21912. * @since Class available since Release 1.1.0
  21913. */
  21914. class PHP_CodeCoverage_Report_Node_Iterator implements RecursiveIterator
  21915. {
  21916. /**
  21917. * @var int
  21918. */
  21919. protected $position;
  21920. /**
  21921. * @var PHP_CodeCoverage_Report_Node[]
  21922. */
  21923. protected $nodes;
  21924. /**
  21925. * Constructor.
  21926. *
  21927. * @param PHP_CodeCoverage_Report_Node_Directory $node
  21928. */
  21929. public function __construct(PHP_CodeCoverage_Report_Node_Directory $node)
  21930. {
  21931. $this->nodes = $node->getChildNodes();
  21932. }
  21933. /**
  21934. * Rewinds the Iterator to the first element.
  21935. */
  21936. public function rewind()
  21937. {
  21938. $this->position = 0;
  21939. }
  21940. /**
  21941. * Checks if there is a current element after calls to rewind() or next().
  21942. *
  21943. * @return bool
  21944. */
  21945. public function valid()
  21946. {
  21947. return $this->position < count($this->nodes);
  21948. }
  21949. /**
  21950. * Returns the key of the current element.
  21951. *
  21952. * @return int
  21953. */
  21954. public function key()
  21955. {
  21956. return $this->position;
  21957. }
  21958. /**
  21959. * Returns the current element.
  21960. *
  21961. * @return PHPUnit_Framework_Test
  21962. */
  21963. public function current()
  21964. {
  21965. return $this->valid() ? $this->nodes[$this->position] : null;
  21966. }
  21967. /**
  21968. * Moves forward to next element.
  21969. */
  21970. public function next()
  21971. {
  21972. $this->position++;
  21973. }
  21974. /**
  21975. * Returns the sub iterator for the current element.
  21976. *
  21977. * @return PHP_CodeCoverage_Report_Node_Iterator
  21978. */
  21979. public function getChildren()
  21980. {
  21981. return new self(
  21982. $this->nodes[$this->position]
  21983. );
  21984. }
  21985. /**
  21986. * Checks whether the current element has children.
  21987. *
  21988. * @return bool
  21989. */
  21990. public function hasChildren()
  21991. {
  21992. return $this->nodes[$this->position] instanceof PHP_CodeCoverage_Report_Node_Directory;
  21993. }
  21994. }
  21995. <?php
  21996. /*
  21997. * This file is part of the PHP_CodeCoverage package.
  21998. *
  21999. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  22000. *
  22001. * For the full copyright and license information, please view the LICENSE
  22002. * file that was distributed with this source code.
  22003. */
  22004. /**
  22005. * Represents a file in the code coverage information tree.
  22006. *
  22007. * @since Class available since Release 1.1.0
  22008. */
  22009. class PHP_CodeCoverage_Report_Node_File extends PHP_CodeCoverage_Report_Node
  22010. {
  22011. /**
  22012. * @var array
  22013. */
  22014. protected $coverageData;
  22015. /**
  22016. * @var array
  22017. */
  22018. protected $testData;
  22019. /**
  22020. * @var int
  22021. */
  22022. protected $numExecutableLines = 0;
  22023. /**
  22024. * @var int
  22025. */
  22026. protected $numExecutedLines = 0;
  22027. /**
  22028. * @var array
  22029. */
  22030. protected $classes = array();
  22031. /**
  22032. * @var array
  22033. */
  22034. protected $traits = array();
  22035. /**
  22036. * @var array
  22037. */
  22038. protected $functions = array();
  22039. /**
  22040. * @var array
  22041. */
  22042. protected $linesOfCode = array();
  22043. /**
  22044. * @var int
  22045. */
  22046. protected $numTestedTraits = 0;
  22047. /**
  22048. * @var int
  22049. */
  22050. protected $numTestedClasses = 0;
  22051. /**
  22052. * @var int
  22053. */
  22054. protected $numMethods = null;
  22055. /**
  22056. * @var int
  22057. */
  22058. protected $numTestedMethods = null;
  22059. /**
  22060. * @var int
  22061. */
  22062. protected $numTestedFunctions = null;
  22063. /**
  22064. * @var array
  22065. */
  22066. protected $startLines = array();
  22067. /**
  22068. * @var array
  22069. */
  22070. protected $endLines = array();
  22071. /**
  22072. * @var bool
  22073. */
  22074. protected $cacheTokens;
  22075. /**
  22076. * Constructor.
  22077. *
  22078. * @param string $name
  22079. * @param PHP_CodeCoverage_Report_Node $parent
  22080. * @param array $coverageData
  22081. * @param array $testData
  22082. * @param bool $cacheTokens
  22083. * @throws PHP_CodeCoverage_Exception
  22084. */
  22085. public function __construct($name, PHP_CodeCoverage_Report_Node $parent, array $coverageData, array $testData, $cacheTokens)
  22086. {
  22087. if (!is_bool($cacheTokens)) {
  22088. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  22089. 1,
  22090. 'boolean'
  22091. );
  22092. }
  22093. parent::__construct($name, $parent);
  22094. $this->coverageData = $coverageData;
  22095. $this->testData = $testData;
  22096. $this->cacheTokens = $cacheTokens;
  22097. $this->calculateStatistics();
  22098. }
  22099. /**
  22100. * Returns the number of files in/under this node.
  22101. *
  22102. * @return int
  22103. */
  22104. public function count()
  22105. {
  22106. return 1;
  22107. }
  22108. /**
  22109. * Returns the code coverage data of this node.
  22110. *
  22111. * @return array
  22112. */
  22113. public function getCoverageData()
  22114. {
  22115. return $this->coverageData;
  22116. }
  22117. /**
  22118. * Returns the test data of this node.
  22119. *
  22120. * @return array
  22121. */
  22122. public function getTestData()
  22123. {
  22124. return $this->testData;
  22125. }
  22126. /**
  22127. * Returns the classes of this node.
  22128. *
  22129. * @return array
  22130. */
  22131. public function getClasses()
  22132. {
  22133. return $this->classes;
  22134. }
  22135. /**
  22136. * Returns the traits of this node.
  22137. *
  22138. * @return array
  22139. */
  22140. public function getTraits()
  22141. {
  22142. return $this->traits;
  22143. }
  22144. /**
  22145. * Returns the functions of this node.
  22146. *
  22147. * @return array
  22148. */
  22149. public function getFunctions()
  22150. {
  22151. return $this->functions;
  22152. }
  22153. /**
  22154. * Returns the LOC/CLOC/NCLOC of this node.
  22155. *
  22156. * @return array
  22157. */
  22158. public function getLinesOfCode()
  22159. {
  22160. return $this->linesOfCode;
  22161. }
  22162. /**
  22163. * Returns the number of executable lines.
  22164. *
  22165. * @return int
  22166. */
  22167. public function getNumExecutableLines()
  22168. {
  22169. return $this->numExecutableLines;
  22170. }
  22171. /**
  22172. * Returns the number of executed lines.
  22173. *
  22174. * @return int
  22175. */
  22176. public function getNumExecutedLines()
  22177. {
  22178. return $this->numExecutedLines;
  22179. }
  22180. /**
  22181. * Returns the number of classes.
  22182. *
  22183. * @return int
  22184. */
  22185. public function getNumClasses()
  22186. {
  22187. return count($this->classes);
  22188. }
  22189. /**
  22190. * Returns the number of tested classes.
  22191. *
  22192. * @return int
  22193. */
  22194. public function getNumTestedClasses()
  22195. {
  22196. return $this->numTestedClasses;
  22197. }
  22198. /**
  22199. * Returns the number of traits.
  22200. *
  22201. * @return int
  22202. */
  22203. public function getNumTraits()
  22204. {
  22205. return count($this->traits);
  22206. }
  22207. /**
  22208. * Returns the number of tested traits.
  22209. *
  22210. * @return int
  22211. */
  22212. public function getNumTestedTraits()
  22213. {
  22214. return $this->numTestedTraits;
  22215. }
  22216. /**
  22217. * Returns the number of methods.
  22218. *
  22219. * @return int
  22220. */
  22221. public function getNumMethods()
  22222. {
  22223. if ($this->numMethods === null) {
  22224. $this->numMethods = 0;
  22225. foreach ($this->classes as $class) {
  22226. foreach ($class['methods'] as $method) {
  22227. if ($method['executableLines'] > 0) {
  22228. $this->numMethods++;
  22229. }
  22230. }
  22231. }
  22232. foreach ($this->traits as $trait) {
  22233. foreach ($trait['methods'] as $method) {
  22234. if ($method['executableLines'] > 0) {
  22235. $this->numMethods++;
  22236. }
  22237. }
  22238. }
  22239. }
  22240. return $this->numMethods;
  22241. }
  22242. /**
  22243. * Returns the number of tested methods.
  22244. *
  22245. * @return int
  22246. */
  22247. public function getNumTestedMethods()
  22248. {
  22249. if ($this->numTestedMethods === null) {
  22250. $this->numTestedMethods = 0;
  22251. foreach ($this->classes as $class) {
  22252. foreach ($class['methods'] as $method) {
  22253. if ($method['executableLines'] > 0 &&
  22254. $method['coverage'] == 100) {
  22255. $this->numTestedMethods++;
  22256. }
  22257. }
  22258. }
  22259. foreach ($this->traits as $trait) {
  22260. foreach ($trait['methods'] as $method) {
  22261. if ($method['executableLines'] > 0 &&
  22262. $method['coverage'] == 100) {
  22263. $this->numTestedMethods++;
  22264. }
  22265. }
  22266. }
  22267. }
  22268. return $this->numTestedMethods;
  22269. }
  22270. /**
  22271. * Returns the number of functions.
  22272. *
  22273. * @return int
  22274. */
  22275. public function getNumFunctions()
  22276. {
  22277. return count($this->functions);
  22278. }
  22279. /**
  22280. * Returns the number of tested functions.
  22281. *
  22282. * @return int
  22283. */
  22284. public function getNumTestedFunctions()
  22285. {
  22286. if ($this->numTestedFunctions === null) {
  22287. $this->numTestedFunctions = 0;
  22288. foreach ($this->functions as $function) {
  22289. if ($function['executableLines'] > 0 &&
  22290. $function['coverage'] == 100) {
  22291. $this->numTestedFunctions++;
  22292. }
  22293. }
  22294. }
  22295. return $this->numTestedFunctions;
  22296. }
  22297. /**
  22298. * Calculates coverage statistics for the file.
  22299. */
  22300. protected function calculateStatistics()
  22301. {
  22302. if ($this->cacheTokens) {
  22303. $tokens = PHP_Token_Stream_CachingFactory::get($this->getPath());
  22304. } else {
  22305. $tokens = new PHP_Token_Stream($this->getPath());
  22306. }
  22307. $this->processClasses($tokens);
  22308. $this->processTraits($tokens);
  22309. $this->processFunctions($tokens);
  22310. $this->linesOfCode = $tokens->getLinesOfCode();
  22311. unset($tokens);
  22312. for ($lineNumber = 1; $lineNumber <= $this->linesOfCode['loc']; $lineNumber++) {
  22313. if (isset($this->startLines[$lineNumber])) {
  22314. // Start line of a class.
  22315. if (isset($this->startLines[$lineNumber]['className'])) {
  22316. $currentClass = &$this->startLines[$lineNumber];
  22317. } // Start line of a trait.
  22318. elseif (isset($this->startLines[$lineNumber]['traitName'])) {
  22319. $currentTrait = &$this->startLines[$lineNumber];
  22320. } // Start line of a method.
  22321. elseif (isset($this->startLines[$lineNumber]['methodName'])) {
  22322. $currentMethod = &$this->startLines[$lineNumber];
  22323. } // Start line of a function.
  22324. elseif (isset($this->startLines[$lineNumber]['functionName'])) {
  22325. $currentFunction = &$this->startLines[$lineNumber];
  22326. }
  22327. }
  22328. if (isset($this->coverageData[$lineNumber]) &&
  22329. $this->coverageData[$lineNumber] !== null) {
  22330. if (isset($currentClass)) {
  22331. $currentClass['executableLines']++;
  22332. }
  22333. if (isset($currentTrait)) {
  22334. $currentTrait['executableLines']++;
  22335. }
  22336. if (isset($currentMethod)) {
  22337. $currentMethod['executableLines']++;
  22338. }
  22339. if (isset($currentFunction)) {
  22340. $currentFunction['executableLines']++;
  22341. }
  22342. $this->numExecutableLines++;
  22343. if (count($this->coverageData[$lineNumber]) > 0) {
  22344. if (isset($currentClass)) {
  22345. $currentClass['executedLines']++;
  22346. }
  22347. if (isset($currentTrait)) {
  22348. $currentTrait['executedLines']++;
  22349. }
  22350. if (isset($currentMethod)) {
  22351. $currentMethod['executedLines']++;
  22352. }
  22353. if (isset($currentFunction)) {
  22354. $currentFunction['executedLines']++;
  22355. }
  22356. $this->numExecutedLines++;
  22357. }
  22358. }
  22359. if (isset($this->endLines[$lineNumber])) {
  22360. // End line of a class.
  22361. if (isset($this->endLines[$lineNumber]['className'])) {
  22362. unset($currentClass);
  22363. } // End line of a trait.
  22364. elseif (isset($this->endLines[$lineNumber]['traitName'])) {
  22365. unset($currentTrait);
  22366. } // End line of a method.
  22367. elseif (isset($this->endLines[$lineNumber]['methodName'])) {
  22368. unset($currentMethod);
  22369. } // End line of a function.
  22370. elseif (isset($this->endLines[$lineNumber]['functionName'])) {
  22371. unset($currentFunction);
  22372. }
  22373. }
  22374. }
  22375. foreach ($this->traits as &$trait) {
  22376. foreach ($trait['methods'] as &$method) {
  22377. if ($method['executableLines'] > 0) {
  22378. $method['coverage'] = ($method['executedLines'] /
  22379. $method['executableLines']) * 100;
  22380. } else {
  22381. $method['coverage'] = 100;
  22382. }
  22383. $method['crap'] = $this->crap(
  22384. $method['ccn'],
  22385. $method['coverage']
  22386. );
  22387. $trait['ccn'] += $method['ccn'];
  22388. }
  22389. if ($trait['executableLines'] > 0) {
  22390. $trait['coverage'] = ($trait['executedLines'] /
  22391. $trait['executableLines']) * 100;
  22392. } else {
  22393. $trait['coverage'] = 100;
  22394. }
  22395. if ($trait['coverage'] == 100) {
  22396. $this->numTestedClasses++;
  22397. }
  22398. $trait['crap'] = $this->crap(
  22399. $trait['ccn'],
  22400. $trait['coverage']
  22401. );
  22402. }
  22403. foreach ($this->classes as &$class) {
  22404. foreach ($class['methods'] as &$method) {
  22405. if ($method['executableLines'] > 0) {
  22406. $method['coverage'] = ($method['executedLines'] /
  22407. $method['executableLines']) * 100;
  22408. } else {
  22409. $method['coverage'] = 100;
  22410. }
  22411. $method['crap'] = $this->crap(
  22412. $method['ccn'],
  22413. $method['coverage']
  22414. );
  22415. $class['ccn'] += $method['ccn'];
  22416. }
  22417. if ($class['executableLines'] > 0) {
  22418. $class['coverage'] = ($class['executedLines'] /
  22419. $class['executableLines']) * 100;
  22420. } else {
  22421. $class['coverage'] = 100;
  22422. }
  22423. if ($class['coverage'] == 100) {
  22424. $this->numTestedClasses++;
  22425. }
  22426. $class['crap'] = $this->crap(
  22427. $class['ccn'],
  22428. $class['coverage']
  22429. );
  22430. }
  22431. }
  22432. /**
  22433. * @param PHP_Token_Stream $tokens
  22434. */
  22435. protected function processClasses(PHP_Token_Stream $tokens)
  22436. {
  22437. $classes = $tokens->getClasses();
  22438. unset($tokens);
  22439. $link = $this->getId() . '.html#';
  22440. foreach ($classes as $className => $class) {
  22441. $this->classes[$className] = array(
  22442. 'className' => $className,
  22443. 'methods' => array(),
  22444. 'startLine' => $class['startLine'],
  22445. 'executableLines' => 0,
  22446. 'executedLines' => 0,
  22447. 'ccn' => 0,
  22448. 'coverage' => 0,
  22449. 'crap' => 0,
  22450. 'package' => $class['package'],
  22451. 'link' => $link . $class['startLine']
  22452. );
  22453. $this->startLines[$class['startLine']] = &$this->classes[$className];
  22454. $this->endLines[$class['endLine']] = &$this->classes[$className];
  22455. foreach ($class['methods'] as $methodName => $method) {
  22456. $this->classes[$className]['methods'][$methodName] = array(
  22457. 'methodName' => $methodName,
  22458. 'signature' => $method['signature'],
  22459. 'startLine' => $method['startLine'],
  22460. 'endLine' => $method['endLine'],
  22461. 'executableLines' => 0,
  22462. 'executedLines' => 0,
  22463. 'ccn' => $method['ccn'],
  22464. 'coverage' => 0,
  22465. 'crap' => 0,
  22466. 'link' => $link . $method['startLine']
  22467. );
  22468. $this->startLines[$method['startLine']] = &$this->classes[$className]['methods'][$methodName];
  22469. $this->endLines[$method['endLine']] = &$this->classes[$className]['methods'][$methodName];
  22470. }
  22471. }
  22472. }
  22473. /**
  22474. * @param PHP_Token_Stream $tokens
  22475. */
  22476. protected function processTraits(PHP_Token_Stream $tokens)
  22477. {
  22478. $traits = $tokens->getTraits();
  22479. unset($tokens);
  22480. $link = $this->getId() . '.html#';
  22481. foreach ($traits as $traitName => $trait) {
  22482. $this->traits[$traitName] = array(
  22483. 'traitName' => $traitName,
  22484. 'methods' => array(),
  22485. 'startLine' => $trait['startLine'],
  22486. 'executableLines' => 0,
  22487. 'executedLines' => 0,
  22488. 'ccn' => 0,
  22489. 'coverage' => 0,
  22490. 'crap' => 0,
  22491. 'package' => $trait['package'],
  22492. 'link' => $link . $trait['startLine']
  22493. );
  22494. $this->startLines[$trait['startLine']] = &$this->traits[$traitName];
  22495. $this->endLines[$trait['endLine']] = &$this->traits[$traitName];
  22496. foreach ($trait['methods'] as $methodName => $method) {
  22497. $this->traits[$traitName]['methods'][$methodName] = array(
  22498. 'methodName' => $methodName,
  22499. 'signature' => $method['signature'],
  22500. 'startLine' => $method['startLine'],
  22501. 'endLine' => $method['endLine'],
  22502. 'executableLines' => 0,
  22503. 'executedLines' => 0,
  22504. 'ccn' => $method['ccn'],
  22505. 'coverage' => 0,
  22506. 'crap' => 0,
  22507. 'link' => $link . $method['startLine']
  22508. );
  22509. $this->startLines[$method['startLine']] = &$this->traits[$traitName]['methods'][$methodName];
  22510. $this->endLines[$method['endLine']] = &$this->traits[$traitName]['methods'][$methodName];
  22511. }
  22512. }
  22513. }
  22514. /**
  22515. * @param PHP_Token_Stream $tokens
  22516. */
  22517. protected function processFunctions(PHP_Token_Stream $tokens)
  22518. {
  22519. $functions = $tokens->getFunctions();
  22520. unset($tokens);
  22521. $link = $this->getId() . '.html#';
  22522. foreach ($functions as $functionName => $function) {
  22523. $this->functions[$functionName] = array(
  22524. 'functionName' => $functionName,
  22525. 'signature' => $function['signature'],
  22526. 'startLine' => $function['startLine'],
  22527. 'executableLines' => 0,
  22528. 'executedLines' => 0,
  22529. 'ccn' => $function['ccn'],
  22530. 'coverage' => 0,
  22531. 'crap' => 0,
  22532. 'link' => $link . $function['startLine']
  22533. );
  22534. $this->startLines[$function['startLine']] = &$this->functions[$functionName];
  22535. $this->endLines[$function['endLine']] = &$this->functions[$functionName];
  22536. }
  22537. }
  22538. /**
  22539. * Calculates the Change Risk Anti-Patterns (CRAP) index for a unit of code
  22540. * based on its cyclomatic complexity and percentage of code coverage.
  22541. *
  22542. * @param int $ccn
  22543. * @param float $coverage
  22544. * @return string
  22545. * @since Method available since Release 1.2.0
  22546. */
  22547. protected function crap($ccn, $coverage)
  22548. {
  22549. if ($coverage == 0) {
  22550. return (string) (pow($ccn, 2) + $ccn);
  22551. }
  22552. if ($coverage >= 95) {
  22553. return (string) $ccn;
  22554. }
  22555. return sprintf(
  22556. '%01.2F',
  22557. pow($ccn, 2) * pow(1 - $coverage/100, 3) + $ccn
  22558. );
  22559. }
  22560. }
  22561. <?php
  22562. /*
  22563. * This file is part of the PHP_CodeCoverage package.
  22564. *
  22565. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  22566. *
  22567. * For the full copyright and license information, please view the LICENSE
  22568. * file that was distributed with this source code.
  22569. */
  22570. /**
  22571. * Represents a directory in the code coverage information tree.
  22572. *
  22573. * @since Class available since Release 1.1.0
  22574. */
  22575. class PHP_CodeCoverage_Report_Node_Directory extends PHP_CodeCoverage_Report_Node implements IteratorAggregate
  22576. {
  22577. /**
  22578. * @var PHP_CodeCoverage_Report_Node[]
  22579. */
  22580. protected $children = array();
  22581. /**
  22582. * @var PHP_CodeCoverage_Report_Node_Directory[]
  22583. */
  22584. protected $directories = array();
  22585. /**
  22586. * @var PHP_CodeCoverage_Report_Node_File[]
  22587. */
  22588. protected $files = array();
  22589. /**
  22590. * @var array
  22591. */
  22592. protected $classes;
  22593. /**
  22594. * @var array
  22595. */
  22596. protected $traits;
  22597. /**
  22598. * @var array
  22599. */
  22600. protected $functions;
  22601. /**
  22602. * @var array
  22603. */
  22604. protected $linesOfCode = null;
  22605. /**
  22606. * @var int
  22607. */
  22608. protected $numFiles = -1;
  22609. /**
  22610. * @var int
  22611. */
  22612. protected $numExecutableLines = -1;
  22613. /**
  22614. * @var int
  22615. */
  22616. protected $numExecutedLines = -1;
  22617. /**
  22618. * @var int
  22619. */
  22620. protected $numClasses = -1;
  22621. /**
  22622. * @var int
  22623. */
  22624. protected $numTestedClasses = -1;
  22625. /**
  22626. * @var int
  22627. */
  22628. protected $numTraits = -1;
  22629. /**
  22630. * @var int
  22631. */
  22632. protected $numTestedTraits = -1;
  22633. /**
  22634. * @var int
  22635. */
  22636. protected $numMethods = -1;
  22637. /**
  22638. * @var int
  22639. */
  22640. protected $numTestedMethods = -1;
  22641. /**
  22642. * @var int
  22643. */
  22644. protected $numFunctions = -1;
  22645. /**
  22646. * @var int
  22647. */
  22648. protected $numTestedFunctions = -1;
  22649. /**
  22650. * Returns the number of files in/under this node.
  22651. *
  22652. * @return int
  22653. */
  22654. public function count()
  22655. {
  22656. if ($this->numFiles == -1) {
  22657. $this->numFiles = 0;
  22658. foreach ($this->children as $child) {
  22659. $this->numFiles += count($child);
  22660. }
  22661. }
  22662. return $this->numFiles;
  22663. }
  22664. /**
  22665. * Returns an iterator for this node.
  22666. *
  22667. * @return RecursiveIteratorIterator
  22668. */
  22669. public function getIterator()
  22670. {
  22671. return new RecursiveIteratorIterator(
  22672. new PHP_CodeCoverage_Report_Node_Iterator($this),
  22673. RecursiveIteratorIterator::SELF_FIRST
  22674. );
  22675. }
  22676. /**
  22677. * Adds a new directory.
  22678. *
  22679. * @param string $name
  22680. * @return PHP_CodeCoverage_Report_Node_Directory
  22681. */
  22682. public function addDirectory($name)
  22683. {
  22684. $directory = new self($name, $this);
  22685. $this->children[] = $directory;
  22686. $this->directories[] = &$this->children[count($this->children) - 1];
  22687. return $directory;
  22688. }
  22689. /**
  22690. * Adds a new file.
  22691. *
  22692. * @param string $name
  22693. * @param array $coverageData
  22694. * @param array $testData
  22695. * @param bool $cacheTokens
  22696. * @return PHP_CodeCoverage_Report_Node_File
  22697. * @throws PHP_CodeCoverage_Exception
  22698. */
  22699. public function addFile($name, array $coverageData, array $testData, $cacheTokens)
  22700. {
  22701. $file = new PHP_CodeCoverage_Report_Node_File(
  22702. $name,
  22703. $this,
  22704. $coverageData,
  22705. $testData,
  22706. $cacheTokens
  22707. );
  22708. $this->children[] = $file;
  22709. $this->files[] = &$this->children[count($this->children) - 1];
  22710. $this->numExecutableLines = -1;
  22711. $this->numExecutedLines = -1;
  22712. return $file;
  22713. }
  22714. /**
  22715. * Returns the directories in this directory.
  22716. *
  22717. * @return array
  22718. */
  22719. public function getDirectories()
  22720. {
  22721. return $this->directories;
  22722. }
  22723. /**
  22724. * Returns the files in this directory.
  22725. *
  22726. * @return array
  22727. */
  22728. public function getFiles()
  22729. {
  22730. return $this->files;
  22731. }
  22732. /**
  22733. * Returns the child nodes of this node.
  22734. *
  22735. * @return array
  22736. */
  22737. public function getChildNodes()
  22738. {
  22739. return $this->children;
  22740. }
  22741. /**
  22742. * Returns the classes of this node.
  22743. *
  22744. * @return array
  22745. */
  22746. public function getClasses()
  22747. {
  22748. if ($this->classes === null) {
  22749. $this->classes = array();
  22750. foreach ($this->children as $child) {
  22751. $this->classes = array_merge(
  22752. $this->classes,
  22753. $child->getClasses()
  22754. );
  22755. }
  22756. }
  22757. return $this->classes;
  22758. }
  22759. /**
  22760. * Returns the traits of this node.
  22761. *
  22762. * @return array
  22763. */
  22764. public function getTraits()
  22765. {
  22766. if ($this->traits === null) {
  22767. $this->traits = array();
  22768. foreach ($this->children as $child) {
  22769. $this->traits = array_merge(
  22770. $this->traits,
  22771. $child->getTraits()
  22772. );
  22773. }
  22774. }
  22775. return $this->traits;
  22776. }
  22777. /**
  22778. * Returns the functions of this node.
  22779. *
  22780. * @return array
  22781. */
  22782. public function getFunctions()
  22783. {
  22784. if ($this->functions === null) {
  22785. $this->functions = array();
  22786. foreach ($this->children as $child) {
  22787. $this->functions = array_merge(
  22788. $this->functions,
  22789. $child->getFunctions()
  22790. );
  22791. }
  22792. }
  22793. return $this->functions;
  22794. }
  22795. /**
  22796. * Returns the LOC/CLOC/NCLOC of this node.
  22797. *
  22798. * @return array
  22799. */
  22800. public function getLinesOfCode()
  22801. {
  22802. if ($this->linesOfCode === null) {
  22803. $this->linesOfCode = array('loc' => 0, 'cloc' => 0, 'ncloc' => 0);
  22804. foreach ($this->children as $child) {
  22805. $linesOfCode = $child->getLinesOfCode();
  22806. $this->linesOfCode['loc'] += $linesOfCode['loc'];
  22807. $this->linesOfCode['cloc'] += $linesOfCode['cloc'];
  22808. $this->linesOfCode['ncloc'] += $linesOfCode['ncloc'];
  22809. }
  22810. }
  22811. return $this->linesOfCode;
  22812. }
  22813. /**
  22814. * Returns the number of executable lines.
  22815. *
  22816. * @return int
  22817. */
  22818. public function getNumExecutableLines()
  22819. {
  22820. if ($this->numExecutableLines == -1) {
  22821. $this->numExecutableLines = 0;
  22822. foreach ($this->children as $child) {
  22823. $this->numExecutableLines += $child->getNumExecutableLines();
  22824. }
  22825. }
  22826. return $this->numExecutableLines;
  22827. }
  22828. /**
  22829. * Returns the number of executed lines.
  22830. *
  22831. * @return int
  22832. */
  22833. public function getNumExecutedLines()
  22834. {
  22835. if ($this->numExecutedLines == -1) {
  22836. $this->numExecutedLines = 0;
  22837. foreach ($this->children as $child) {
  22838. $this->numExecutedLines += $child->getNumExecutedLines();
  22839. }
  22840. }
  22841. return $this->numExecutedLines;
  22842. }
  22843. /**
  22844. * Returns the number of classes.
  22845. *
  22846. * @return int
  22847. */
  22848. public function getNumClasses()
  22849. {
  22850. if ($this->numClasses == -1) {
  22851. $this->numClasses = 0;
  22852. foreach ($this->children as $child) {
  22853. $this->numClasses += $child->getNumClasses();
  22854. }
  22855. }
  22856. return $this->numClasses;
  22857. }
  22858. /**
  22859. * Returns the number of tested classes.
  22860. *
  22861. * @return int
  22862. */
  22863. public function getNumTestedClasses()
  22864. {
  22865. if ($this->numTestedClasses == -1) {
  22866. $this->numTestedClasses = 0;
  22867. foreach ($this->children as $child) {
  22868. $this->numTestedClasses += $child->getNumTestedClasses();
  22869. }
  22870. }
  22871. return $this->numTestedClasses;
  22872. }
  22873. /**
  22874. * Returns the number of traits.
  22875. *
  22876. * @return int
  22877. */
  22878. public function getNumTraits()
  22879. {
  22880. if ($this->numTraits == -1) {
  22881. $this->numTraits = 0;
  22882. foreach ($this->children as $child) {
  22883. $this->numTraits += $child->getNumTraits();
  22884. }
  22885. }
  22886. return $this->numTraits;
  22887. }
  22888. /**
  22889. * Returns the number of tested traits.
  22890. *
  22891. * @return int
  22892. */
  22893. public function getNumTestedTraits()
  22894. {
  22895. if ($this->numTestedTraits == -1) {
  22896. $this->numTestedTraits = 0;
  22897. foreach ($this->children as $child) {
  22898. $this->numTestedTraits += $child->getNumTestedTraits();
  22899. }
  22900. }
  22901. return $this->numTestedTraits;
  22902. }
  22903. /**
  22904. * Returns the number of methods.
  22905. *
  22906. * @return int
  22907. */
  22908. public function getNumMethods()
  22909. {
  22910. if ($this->numMethods == -1) {
  22911. $this->numMethods = 0;
  22912. foreach ($this->children as $child) {
  22913. $this->numMethods += $child->getNumMethods();
  22914. }
  22915. }
  22916. return $this->numMethods;
  22917. }
  22918. /**
  22919. * Returns the number of tested methods.
  22920. *
  22921. * @return int
  22922. */
  22923. public function getNumTestedMethods()
  22924. {
  22925. if ($this->numTestedMethods == -1) {
  22926. $this->numTestedMethods = 0;
  22927. foreach ($this->children as $child) {
  22928. $this->numTestedMethods += $child->getNumTestedMethods();
  22929. }
  22930. }
  22931. return $this->numTestedMethods;
  22932. }
  22933. /**
  22934. * Returns the number of functions.
  22935. *
  22936. * @return int
  22937. */
  22938. public function getNumFunctions()
  22939. {
  22940. if ($this->numFunctions == -1) {
  22941. $this->numFunctions = 0;
  22942. foreach ($this->children as $child) {
  22943. $this->numFunctions += $child->getNumFunctions();
  22944. }
  22945. }
  22946. return $this->numFunctions;
  22947. }
  22948. /**
  22949. * Returns the number of tested functions.
  22950. *
  22951. * @return int
  22952. */
  22953. public function getNumTestedFunctions()
  22954. {
  22955. if ($this->numTestedFunctions == -1) {
  22956. $this->numTestedFunctions = 0;
  22957. foreach ($this->children as $child) {
  22958. $this->numTestedFunctions += $child->getNumTestedFunctions();
  22959. }
  22960. }
  22961. return $this->numTestedFunctions;
  22962. }
  22963. }
  22964. <?php
  22965. /*
  22966. * This file is part of the PHP_CodeCoverage package.
  22967. *
  22968. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  22969. *
  22970. * For the full copyright and license information, please view the LICENSE
  22971. * file that was distributed with this source code.
  22972. */
  22973. /**
  22974. * Generates a Clover XML logfile from an PHP_CodeCoverage object.
  22975. *
  22976. * @since Class available since Release 1.0.0
  22977. */
  22978. class PHP_CodeCoverage_Report_Clover
  22979. {
  22980. /**
  22981. * @param PHP_CodeCoverage $coverage
  22982. * @param string $target
  22983. * @param string $name
  22984. * @return string
  22985. */
  22986. public function process(PHP_CodeCoverage $coverage, $target = null, $name = null)
  22987. {
  22988. $xmlDocument = new DOMDocument('1.0', 'UTF-8');
  22989. $xmlDocument->formatOutput = true;
  22990. $xmlCoverage = $xmlDocument->createElement('coverage');
  22991. $xmlCoverage->setAttribute('generated', (int) $_SERVER['REQUEST_TIME']);
  22992. $xmlDocument->appendChild($xmlCoverage);
  22993. $xmlProject = $xmlDocument->createElement('project');
  22994. $xmlProject->setAttribute('timestamp', (int) $_SERVER['REQUEST_TIME']);
  22995. if (is_string($name)) {
  22996. $xmlProject->setAttribute('name', $name);
  22997. }
  22998. $xmlCoverage->appendChild($xmlProject);
  22999. $packages = array();
  23000. $report = $coverage->getReport();
  23001. unset($coverage);
  23002. foreach ($report as $item) {
  23003. $namespace = 'global';
  23004. if (!$item instanceof PHP_CodeCoverage_Report_Node_File) {
  23005. continue;
  23006. }
  23007. $xmlFile = $xmlDocument->createElement('file');
  23008. $xmlFile->setAttribute('name', $item->getPath());
  23009. $classes = $item->getClassesAndTraits();
  23010. $coverage = $item->getCoverageData();
  23011. $lines = array();
  23012. foreach ($classes as $className => $class) {
  23013. $classStatements = 0;
  23014. $coveredClassStatements = 0;
  23015. $coveredMethods = 0;
  23016. $classMethods = 0;
  23017. foreach ($class['methods'] as $methodName => $method) {
  23018. if ($method['executableLines'] == 0) {
  23019. continue;
  23020. }
  23021. $classMethods++;
  23022. $classStatements += $method['executableLines'];
  23023. $coveredClassStatements += $method['executedLines'];
  23024. if ($method['coverage'] == 100) {
  23025. $coveredMethods++;
  23026. }
  23027. $methodCount = 0;
  23028. for ($i = $method['startLine'];
  23029. $i <= $method['endLine'];
  23030. $i++) {
  23031. if (isset($coverage[$i]) && ($coverage[$i] !== null)) {
  23032. $methodCount = max($methodCount, count($coverage[$i]));
  23033. }
  23034. }
  23035. $lines[$method['startLine']] = array(
  23036. 'count' => $methodCount,
  23037. 'crap' => $method['crap'],
  23038. 'type' => 'method',
  23039. 'name' => $methodName
  23040. );
  23041. }
  23042. if (!empty($class['package']['namespace'])) {
  23043. $namespace = $class['package']['namespace'];
  23044. }
  23045. $xmlClass = $xmlDocument->createElement('class');
  23046. $xmlClass->setAttribute('name', $className);
  23047. $xmlClass->setAttribute('namespace', $namespace);
  23048. if (!empty($class['package']['fullPackage'])) {
  23049. $xmlClass->setAttribute(
  23050. 'fullPackage',
  23051. $class['package']['fullPackage']
  23052. );
  23053. }
  23054. if (!empty($class['package']['category'])) {
  23055. $xmlClass->setAttribute(
  23056. 'category',
  23057. $class['package']['category']
  23058. );
  23059. }
  23060. if (!empty($class['package']['package'])) {
  23061. $xmlClass->setAttribute(
  23062. 'package',
  23063. $class['package']['package']
  23064. );
  23065. }
  23066. if (!empty($class['package']['subpackage'])) {
  23067. $xmlClass->setAttribute(
  23068. 'subpackage',
  23069. $class['package']['subpackage']
  23070. );
  23071. }
  23072. $xmlFile->appendChild($xmlClass);
  23073. $xmlMetrics = $xmlDocument->createElement('metrics');
  23074. $xmlMetrics->setAttribute('methods', $classMethods);
  23075. $xmlMetrics->setAttribute('coveredmethods', $coveredMethods);
  23076. $xmlMetrics->setAttribute('conditionals', 0);
  23077. $xmlMetrics->setAttribute('coveredconditionals', 0);
  23078. $xmlMetrics->setAttribute('statements', $classStatements);
  23079. $xmlMetrics->setAttribute(
  23080. 'coveredstatements',
  23081. $coveredClassStatements
  23082. );
  23083. $xmlMetrics->setAttribute(
  23084. 'elements',
  23085. $classMethods +
  23086. $classStatements
  23087. /* + conditionals */
  23088. );
  23089. $xmlMetrics->setAttribute(
  23090. 'coveredelements',
  23091. $coveredMethods +
  23092. $coveredClassStatements
  23093. /* + coveredconditionals */
  23094. );
  23095. $xmlClass->appendChild($xmlMetrics);
  23096. }
  23097. foreach ($coverage as $line => $data) {
  23098. if ($data === null || isset($lines[$line])) {
  23099. continue;
  23100. }
  23101. $lines[$line] = array(
  23102. 'count' => count($data), 'type' => 'stmt'
  23103. );
  23104. }
  23105. ksort($lines);
  23106. foreach ($lines as $line => $data) {
  23107. $xmlLine = $xmlDocument->createElement('line');
  23108. $xmlLine->setAttribute('num', $line);
  23109. $xmlLine->setAttribute('type', $data['type']);
  23110. if (isset($data['name'])) {
  23111. $xmlLine->setAttribute('name', $data['name']);
  23112. }
  23113. if (isset($data['crap'])) {
  23114. $xmlLine->setAttribute('crap', $data['crap']);
  23115. }
  23116. $xmlLine->setAttribute('count', $data['count']);
  23117. $xmlFile->appendChild($xmlLine);
  23118. }
  23119. $linesOfCode = $item->getLinesOfCode();
  23120. $xmlMetrics = $xmlDocument->createElement('metrics');
  23121. $xmlMetrics->setAttribute('loc', $linesOfCode['loc']);
  23122. $xmlMetrics->setAttribute('ncloc', $linesOfCode['ncloc']);
  23123. $xmlMetrics->setAttribute('classes', $item->getNumClassesAndTraits());
  23124. $xmlMetrics->setAttribute('methods', $item->getNumMethods());
  23125. $xmlMetrics->setAttribute(
  23126. 'coveredmethods',
  23127. $item->getNumTestedMethods()
  23128. );
  23129. $xmlMetrics->setAttribute('conditionals', 0);
  23130. $xmlMetrics->setAttribute('coveredconditionals', 0);
  23131. $xmlMetrics->setAttribute(
  23132. 'statements',
  23133. $item->getNumExecutableLines()
  23134. );
  23135. $xmlMetrics->setAttribute(
  23136. 'coveredstatements',
  23137. $item->getNumExecutedLines()
  23138. );
  23139. $xmlMetrics->setAttribute(
  23140. 'elements',
  23141. $item->getNumMethods() + $item->getNumExecutableLines()
  23142. /* + conditionals */
  23143. );
  23144. $xmlMetrics->setAttribute(
  23145. 'coveredelements',
  23146. $item->getNumTestedMethods() + $item->getNumExecutedLines()
  23147. /* + coveredconditionals */
  23148. );
  23149. $xmlFile->appendChild($xmlMetrics);
  23150. if ($namespace == 'global') {
  23151. $xmlProject->appendChild($xmlFile);
  23152. } else {
  23153. if (!isset($packages[$namespace])) {
  23154. $packages[$namespace] = $xmlDocument->createElement(
  23155. 'package'
  23156. );
  23157. $packages[$namespace]->setAttribute('name', $namespace);
  23158. $xmlProject->appendChild($packages[$namespace]);
  23159. }
  23160. $packages[$namespace]->appendChild($xmlFile);
  23161. }
  23162. }
  23163. $linesOfCode = $report->getLinesOfCode();
  23164. $xmlMetrics = $xmlDocument->createElement('metrics');
  23165. $xmlMetrics->setAttribute('files', count($report));
  23166. $xmlMetrics->setAttribute('loc', $linesOfCode['loc']);
  23167. $xmlMetrics->setAttribute('ncloc', $linesOfCode['ncloc']);
  23168. $xmlMetrics->setAttribute(
  23169. 'classes',
  23170. $report->getNumClassesAndTraits()
  23171. );
  23172. $xmlMetrics->setAttribute('methods', $report->getNumMethods());
  23173. $xmlMetrics->setAttribute(
  23174. 'coveredmethods',
  23175. $report->getNumTestedMethods()
  23176. );
  23177. $xmlMetrics->setAttribute('conditionals', 0);
  23178. $xmlMetrics->setAttribute('coveredconditionals', 0);
  23179. $xmlMetrics->setAttribute(
  23180. 'statements',
  23181. $report->getNumExecutableLines()
  23182. );
  23183. $xmlMetrics->setAttribute(
  23184. 'coveredstatements',
  23185. $report->getNumExecutedLines()
  23186. );
  23187. $xmlMetrics->setAttribute(
  23188. 'elements',
  23189. $report->getNumMethods() + $report->getNumExecutableLines()
  23190. /* + conditionals */
  23191. );
  23192. $xmlMetrics->setAttribute(
  23193. 'coveredelements',
  23194. $report->getNumTestedMethods() + $report->getNumExecutedLines()
  23195. /* + coveredconditionals */
  23196. );
  23197. $xmlProject->appendChild($xmlMetrics);
  23198. if ($target !== null) {
  23199. if (!is_dir(dirname($target))) {
  23200. mkdir(dirname($target), 0777, true);
  23201. }
  23202. return $xmlDocument->save($target);
  23203. } else {
  23204. return $xmlDocument->saveXML();
  23205. }
  23206. }
  23207. }
  23208. <?php
  23209. /*
  23210. * This file is part of the PHP_CodeCoverage package.
  23211. *
  23212. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  23213. *
  23214. * For the full copyright and license information, please view the LICENSE
  23215. * file that was distributed with this source code.
  23216. */
  23217. /**
  23218. * Generates an HTML report from an PHP_CodeCoverage object.
  23219. *
  23220. * @since Class available since Release 1.0.0
  23221. */
  23222. class PHP_CodeCoverage_Report_HTML
  23223. {
  23224. /**
  23225. * @var string
  23226. */
  23227. private $templatePath;
  23228. /**
  23229. * @var string
  23230. */
  23231. private $generator;
  23232. /**
  23233. * @var int
  23234. */
  23235. private $lowUpperBound;
  23236. /**
  23237. * @var int
  23238. */
  23239. private $highLowerBound;
  23240. /**
  23241. * Constructor.
  23242. *
  23243. * @param int $lowUpperBound
  23244. * @param int $highLowerBound
  23245. * @param string $generator
  23246. */
  23247. public function __construct($lowUpperBound = 50, $highLowerBound = 90, $generator = '')
  23248. {
  23249. $this->generator = $generator;
  23250. $this->highLowerBound = $highLowerBound;
  23251. $this->lowUpperBound = $lowUpperBound;
  23252. $this->templatePath = sprintf(
  23253. '%s%sHTML%sRenderer%sTemplate%s',
  23254. dirname(__FILE__),
  23255. DIRECTORY_SEPARATOR,
  23256. DIRECTORY_SEPARATOR,
  23257. DIRECTORY_SEPARATOR,
  23258. DIRECTORY_SEPARATOR
  23259. );
  23260. }
  23261. /**
  23262. * @param PHP_CodeCoverage $coverage
  23263. * @param string $target
  23264. */
  23265. public function process(PHP_CodeCoverage $coverage, $target)
  23266. {
  23267. $target = $this->getDirectory($target);
  23268. $report = $coverage->getReport();
  23269. unset($coverage);
  23270. if (!isset($_SERVER['REQUEST_TIME'])) {
  23271. $_SERVER['REQUEST_TIME'] = time();
  23272. }
  23273. $date = date('D M j G:i:s T Y', $_SERVER['REQUEST_TIME']);
  23274. $dashboard = new PHP_CodeCoverage_Report_HTML_Renderer_Dashboard(
  23275. $this->templatePath,
  23276. $this->generator,
  23277. $date,
  23278. $this->lowUpperBound,
  23279. $this->highLowerBound
  23280. );
  23281. $directory = new PHP_CodeCoverage_Report_HTML_Renderer_Directory(
  23282. $this->templatePath,
  23283. $this->generator,
  23284. $date,
  23285. $this->lowUpperBound,
  23286. $this->highLowerBound
  23287. );
  23288. $file = new PHP_CodeCoverage_Report_HTML_Renderer_File(
  23289. $this->templatePath,
  23290. $this->generator,
  23291. $date,
  23292. $this->lowUpperBound,
  23293. $this->highLowerBound
  23294. );
  23295. $directory->render($report, $target . 'index.html');
  23296. $dashboard->render($report, $target . 'dashboard.html');
  23297. foreach ($report as $node) {
  23298. $id = $node->getId();
  23299. if ($node instanceof PHP_CodeCoverage_Report_Node_Directory) {
  23300. if (!file_exists($target . $id)) {
  23301. mkdir($target . $id, 0777, true);
  23302. }
  23303. $directory->render($node, $target . $id . '/index.html');
  23304. $dashboard->render($node, $target . $id . '/dashboard.html');
  23305. } else {
  23306. $dir = dirname($target . $id);
  23307. if (!file_exists($dir)) {
  23308. mkdir($dir, 0777, true);
  23309. }
  23310. $file->render($node, $target . $id . '.html');
  23311. }
  23312. }
  23313. $this->copyFiles($target);
  23314. }
  23315. /**
  23316. * @param string $target
  23317. */
  23318. private function copyFiles($target)
  23319. {
  23320. $dir = $this->getDirectory($target . 'css');
  23321. copy($this->templatePath . 'css/bootstrap.min.css', $dir . 'bootstrap.min.css');
  23322. copy($this->templatePath . 'css/nv.d3.min.css', $dir . 'nv.d3.min.css');
  23323. copy($this->templatePath . 'css/style.css', $dir . 'style.css');
  23324. $dir = $this->getDirectory($target . 'fonts');
  23325. copy($this->templatePath . 'fonts/glyphicons-halflings-regular.eot', $dir . 'glyphicons-halflings-regular.eot');
  23326. copy($this->templatePath . 'fonts/glyphicons-halflings-regular.svg', $dir . 'glyphicons-halflings-regular.svg');
  23327. copy($this->templatePath . 'fonts/glyphicons-halflings-regular.ttf', $dir . 'glyphicons-halflings-regular.ttf');
  23328. copy($this->templatePath . 'fonts/glyphicons-halflings-regular.woff', $dir . 'glyphicons-halflings-regular.woff');
  23329. copy($this->templatePath . 'fonts/glyphicons-halflings-regular.woff2', $dir . 'glyphicons-halflings-regular.woff2');
  23330. $dir = $this->getDirectory($target . 'js');
  23331. copy($this->templatePath . 'js/bootstrap.min.js', $dir . 'bootstrap.min.js');
  23332. copy($this->templatePath . 'js/d3.min.js', $dir . 'd3.min.js');
  23333. copy($this->templatePath . 'js/holder.min.js', $dir . 'holder.min.js');
  23334. copy($this->templatePath . 'js/html5shiv.min.js', $dir . 'html5shiv.min.js');
  23335. copy($this->templatePath . 'js/jquery.min.js', $dir . 'jquery.min.js');
  23336. copy($this->templatePath . 'js/nv.d3.min.js', $dir . 'nv.d3.min.js');
  23337. copy($this->templatePath . 'js/respond.min.js', $dir . 'respond.min.js');
  23338. }
  23339. /**
  23340. * @param string $directory
  23341. * @return string
  23342. * @throws PHP_CodeCoverage_Exception
  23343. * @since Method available since Release 1.2.0
  23344. */
  23345. private function getDirectory($directory)
  23346. {
  23347. if (substr($directory, -1, 1) != DIRECTORY_SEPARATOR) {
  23348. $directory .= DIRECTORY_SEPARATOR;
  23349. }
  23350. if (is_dir($directory)) {
  23351. return $directory;
  23352. }
  23353. if (@mkdir($directory, 0777, true)) {
  23354. return $directory;
  23355. }
  23356. throw new PHP_CodeCoverage_Exception(
  23357. sprintf(
  23358. 'Directory "%s" does not exist.',
  23359. $directory
  23360. )
  23361. );
  23362. }
  23363. }
  23364. <?php
  23365. /*
  23366. * This file is part of the PHP_CodeCoverage package.
  23367. *
  23368. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  23369. *
  23370. * For the full copyright and license information, please view the LICENSE
  23371. * file that was distributed with this source code.
  23372. */
  23373. /**
  23374. * Factory for PHP_CodeCoverage_Report_Node_* object graphs.
  23375. *
  23376. * @since Class available since Release 1.1.0
  23377. */
  23378. class PHP_CodeCoverage_Report_Factory
  23379. {
  23380. /**
  23381. * @param PHP_CodeCoverage $coverage
  23382. * @return PHP_CodeCoverage_Report_Node_Directory
  23383. */
  23384. public function create(PHP_CodeCoverage $coverage)
  23385. {
  23386. $files = $coverage->getData();
  23387. $commonPath = $this->reducePaths($files);
  23388. $root = new PHP_CodeCoverage_Report_Node_Directory(
  23389. $commonPath,
  23390. null
  23391. );
  23392. $this->addItems(
  23393. $root,
  23394. $this->buildDirectoryStructure($files),
  23395. $coverage->getTests(),
  23396. $coverage->getCacheTokens()
  23397. );
  23398. return $root;
  23399. }
  23400. /**
  23401. * @param PHP_CodeCoverage_Report_Node_Directory $root
  23402. * @param array $items
  23403. * @param array $tests
  23404. * @param bool $cacheTokens
  23405. */
  23406. private function addItems(PHP_CodeCoverage_Report_Node_Directory $root, array $items, array $tests, $cacheTokens)
  23407. {
  23408. foreach ($items as $key => $value) {
  23409. if (substr($key, -2) == '/f') {
  23410. $key = substr($key, 0, -2);
  23411. if (file_exists($root->getPath() . DIRECTORY_SEPARATOR . $key)) {
  23412. $root->addFile($key, $value, $tests, $cacheTokens);
  23413. }
  23414. } else {
  23415. $child = $root->addDirectory($key);
  23416. $this->addItems($child, $value, $tests, $cacheTokens);
  23417. }
  23418. }
  23419. }
  23420. /**
  23421. * Builds an array representation of the directory structure.
  23422. *
  23423. * For instance,
  23424. *
  23425. * <code>
  23426. * Array
  23427. * (
  23428. * [Money.php] => Array
  23429. * (
  23430. * ...
  23431. * )
  23432. *
  23433. * [MoneyBag.php] => Array
  23434. * (
  23435. * ...
  23436. * )
  23437. * )
  23438. * </code>
  23439. *
  23440. * is transformed into
  23441. *
  23442. * <code>
  23443. * Array
  23444. * (
  23445. * [.] => Array
  23446. * (
  23447. * [Money.php] => Array
  23448. * (
  23449. * ...
  23450. * )
  23451. *
  23452. * [MoneyBag.php] => Array
  23453. * (
  23454. * ...
  23455. * )
  23456. * )
  23457. * )
  23458. * </code>
  23459. *
  23460. * @param array $files
  23461. * @return array
  23462. */
  23463. private function buildDirectoryStructure($files)
  23464. {
  23465. $result = array();
  23466. foreach ($files as $path => $file) {
  23467. $path = explode('/', $path);
  23468. $pointer = &$result;
  23469. $max = count($path);
  23470. for ($i = 0; $i < $max; $i++) {
  23471. if ($i == ($max - 1)) {
  23472. $type = '/f';
  23473. } else {
  23474. $type = '';
  23475. }
  23476. $pointer = &$pointer[$path[$i] . $type];
  23477. }
  23478. $pointer = $file;
  23479. }
  23480. return $result;
  23481. }
  23482. /**
  23483. * Reduces the paths by cutting the longest common start path.
  23484. *
  23485. * For instance,
  23486. *
  23487. * <code>
  23488. * Array
  23489. * (
  23490. * [/home/sb/Money/Money.php] => Array
  23491. * (
  23492. * ...
  23493. * )
  23494. *
  23495. * [/home/sb/Money/MoneyBag.php] => Array
  23496. * (
  23497. * ...
  23498. * )
  23499. * )
  23500. * </code>
  23501. *
  23502. * is reduced to
  23503. *
  23504. * <code>
  23505. * Array
  23506. * (
  23507. * [Money.php] => Array
  23508. * (
  23509. * ...
  23510. * )
  23511. *
  23512. * [MoneyBag.php] => Array
  23513. * (
  23514. * ...
  23515. * )
  23516. * )
  23517. * </code>
  23518. *
  23519. * @param array $files
  23520. * @return string
  23521. */
  23522. private function reducePaths(&$files)
  23523. {
  23524. if (empty($files)) {
  23525. return '.';
  23526. }
  23527. $commonPath = '';
  23528. $paths = array_keys($files);
  23529. if (count($files) == 1) {
  23530. $commonPath = dirname($paths[0]) . '/';
  23531. $files[basename($paths[0])] = $files[$paths[0]];
  23532. unset($files[$paths[0]]);
  23533. return $commonPath;
  23534. }
  23535. $max = count($paths);
  23536. for ($i = 0; $i < $max; $i++) {
  23537. // strip phar:// prefixes
  23538. if (strpos($paths[$i], 'phar://') === 0) {
  23539. $paths[$i] = substr($paths[$i], 7);
  23540. $paths[$i] = strtr($paths[$i], '/', DIRECTORY_SEPARATOR);
  23541. }
  23542. $paths[$i] = explode(DIRECTORY_SEPARATOR, $paths[$i]);
  23543. if (empty($paths[$i][0])) {
  23544. $paths[$i][0] = DIRECTORY_SEPARATOR;
  23545. }
  23546. }
  23547. $done = false;
  23548. $max = count($paths);
  23549. while (!$done) {
  23550. for ($i = 0; $i < $max - 1; $i++) {
  23551. if (!isset($paths[$i][0]) ||
  23552. !isset($paths[$i+1][0]) ||
  23553. $paths[$i][0] != $paths[$i+1][0]) {
  23554. $done = true;
  23555. break;
  23556. }
  23557. }
  23558. if (!$done) {
  23559. $commonPath .= $paths[0][0];
  23560. if ($paths[0][0] != DIRECTORY_SEPARATOR) {
  23561. $commonPath .= DIRECTORY_SEPARATOR;
  23562. }
  23563. for ($i = 0; $i < $max; $i++) {
  23564. array_shift($paths[$i]);
  23565. }
  23566. }
  23567. }
  23568. $original = array_keys($files);
  23569. $max = count($original);
  23570. for ($i = 0; $i < $max; $i++) {
  23571. $files[implode('/', $paths[$i])] = $files[$original[$i]];
  23572. unset($files[$original[$i]]);
  23573. }
  23574. ksort($files);
  23575. return substr($commonPath, 0, -1);
  23576. }
  23577. }
  23578. <?php
  23579. /*
  23580. * This file is part of the PHP_CodeCoverage package.
  23581. *
  23582. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  23583. *
  23584. * For the full copyright and license information, please view the LICENSE
  23585. * file that was distributed with this source code.
  23586. */
  23587. /**
  23588. * @since Class available since Release 2.0.0
  23589. */
  23590. class PHP_CodeCoverage_Report_XML
  23591. {
  23592. /**
  23593. * @var string
  23594. */
  23595. private $target;
  23596. /**
  23597. * @var PHP_CodeCoverage_Report_XML_Project
  23598. */
  23599. private $project;
  23600. public function process(PHP_CodeCoverage $coverage, $target)
  23601. {
  23602. if (substr($target, -1, 1) != DIRECTORY_SEPARATOR) {
  23603. $target .= DIRECTORY_SEPARATOR;
  23604. }
  23605. $this->target = $target;
  23606. $this->initTargetDirectory($target);
  23607. $report = $coverage->getReport();
  23608. $this->project = new PHP_CodeCoverage_Report_XML_Project(
  23609. $coverage->getReport()->getName()
  23610. );
  23611. $this->processTests($coverage->getTests());
  23612. $this->processDirectory($report, $this->project);
  23613. $index = $this->project->asDom();
  23614. $index->formatOutput = true;
  23615. $index->preserveWhiteSpace = false;
  23616. $index->save($target . '/index.xml');
  23617. }
  23618. private function initTargetDirectory($dir)
  23619. {
  23620. if (file_exists($dir)) {
  23621. if (!is_dir($dir)) {
  23622. throw new PHP_CodeCoverage_Exception(
  23623. "'$dir' exists but is not a directory."
  23624. );
  23625. }
  23626. if (!is_writable($dir)) {
  23627. throw new PHP_CodeCoverage_Exception(
  23628. "'$dir' exists but is not writable."
  23629. );
  23630. }
  23631. } elseif (!@mkdir($dir, 0777, true)) {
  23632. throw new PHP_CodeCoverage_Exception(
  23633. "'$dir' could not be created."
  23634. );
  23635. }
  23636. }
  23637. private function processDirectory(PHP_CodeCoverage_Report_Node_Directory $directory, PHP_CodeCoverage_Report_XML_Node $context)
  23638. {
  23639. $dirObject = $context->addDirectory($directory->getName());
  23640. $this->setTotals($directory, $dirObject->getTotals());
  23641. foreach ($directory as $node) {
  23642. if ($node instanceof PHP_CodeCoverage_Report_Node_Directory) {
  23643. $this->processDirectory($node, $dirObject);
  23644. continue;
  23645. }
  23646. if ($node instanceof PHP_CodeCoverage_Report_Node_File) {
  23647. $this->processFile($node, $dirObject);
  23648. continue;
  23649. }
  23650. throw new PHP_CodeCoverage_Exception(
  23651. 'Unknown node type for XML report'
  23652. );
  23653. }
  23654. }
  23655. private function processFile(PHP_CodeCoverage_Report_Node_File $file, PHP_CodeCoverage_Report_XML_Directory $context)
  23656. {
  23657. $fileObject = $context->addFile(
  23658. $file->getName(),
  23659. $file->getId() . '.xml'
  23660. );
  23661. $this->setTotals($file, $fileObject->getTotals());
  23662. $fileReport = new PHP_CodeCoverage_Report_XML_File_Report(
  23663. $file->getName()
  23664. );
  23665. $this->setTotals($file, $fileReport->getTotals());
  23666. foreach ($file->getClassesAndTraits() as $unit) {
  23667. $this->processUnit($unit, $fileReport);
  23668. }
  23669. foreach ($file->getFunctions() as $function) {
  23670. $this->processFunction($function, $fileReport);
  23671. }
  23672. foreach ($file->getCoverageData() as $line => $tests) {
  23673. if (!is_array($tests) || count($tests) == 0) {
  23674. continue;
  23675. }
  23676. $coverage = $fileReport->getLineCoverage($line);
  23677. foreach ($tests as $test) {
  23678. $coverage->addTest($test);
  23679. }
  23680. $coverage->finalize();
  23681. }
  23682. $this->initTargetDirectory(
  23683. $this->target . dirname($file->getId()) . '/'
  23684. );
  23685. $fileDom = $fileReport->asDom();
  23686. $fileDom->formatOutput = true;
  23687. $fileDom->preserveWhiteSpace = false;
  23688. $fileDom->save($this->target . $file->getId() . '.xml');
  23689. }
  23690. private function processUnit($unit, PHP_CodeCoverage_Report_XML_File_Report $report)
  23691. {
  23692. if (isset($unit['className'])) {
  23693. $unitObject = $report->getClassObject($unit['className']);
  23694. } else {
  23695. $unitObject = $report->getTraitObject($unit['traitName']);
  23696. }
  23697. $unitObject->setLines(
  23698. $unit['startLine'],
  23699. $unit['executableLines'],
  23700. $unit['executedLines']
  23701. );
  23702. $unitObject->setCrap($unit['crap']);
  23703. $unitObject->setPackage(
  23704. $unit['package']['fullPackage'],
  23705. $unit['package']['package'],
  23706. $unit['package']['subpackage'],
  23707. $unit['package']['category']
  23708. );
  23709. $unitObject->setNamespace($unit['package']['namespace']);
  23710. foreach ($unit['methods'] as $method) {
  23711. $methodObject = $unitObject->addMethod($method['methodName']);
  23712. $methodObject->setSignature($method['signature']);
  23713. $methodObject->setLines($method['startLine'], $method['endLine']);
  23714. $methodObject->setCrap($method['crap']);
  23715. $methodObject->setTotals(
  23716. $method['executableLines'],
  23717. $method['executedLines'],
  23718. $method['coverage']
  23719. );
  23720. }
  23721. }
  23722. private function processFunction($function, PHP_CodeCoverage_Report_XML_File_Report $report)
  23723. {
  23724. $functionObject = $report->getFunctionObject($function['functionName']);
  23725. $functionObject->setSignature($function['signature']);
  23726. $functionObject->setLines($function['startLine']);
  23727. $functionObject->setCrap($function['crap']);
  23728. $functionObject->setTotals($function['executableLines'], $function['executedLines'], $function['coverage']);
  23729. }
  23730. private function processTests(array $tests)
  23731. {
  23732. $testsObject = $this->project->getTests();
  23733. foreach ($tests as $test => $result) {
  23734. if ($test == 'UNCOVERED_FILES_FROM_WHITELIST') {
  23735. continue;
  23736. }
  23737. $testsObject->addTest($test, $result);
  23738. }
  23739. }
  23740. private function setTotals(PHP_CodeCoverage_Report_Node $node, PHP_CodeCoverage_Report_XML_Totals $totals)
  23741. {
  23742. $loc = $node->getLinesOfCode();
  23743. $totals->setNumLines(
  23744. $loc['loc'],
  23745. $loc['cloc'],
  23746. $loc['ncloc'],
  23747. $node->getNumExecutableLines(),
  23748. $node->getNumExecutedLines()
  23749. );
  23750. $totals->setNumClasses(
  23751. $node->getNumClasses(),
  23752. $node->getNumTestedClasses()
  23753. );
  23754. $totals->setNumTraits(
  23755. $node->getNumTraits(),
  23756. $node->getNumTestedTraits()
  23757. );
  23758. $totals->setNumMethods(
  23759. $node->getNumMethods(),
  23760. $node->getNumTestedMethods()
  23761. );
  23762. $totals->setNumFunctions(
  23763. $node->getNumFunctions(),
  23764. $node->getNumTestedFunctions()
  23765. );
  23766. }
  23767. }
  23768. <?php
  23769. /*
  23770. * This file is part of the PHP_CodeCoverage package.
  23771. *
  23772. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  23773. *
  23774. * For the full copyright and license information, please view the LICENSE
  23775. * file that was distributed with this source code.
  23776. */
  23777. /**
  23778. * Uses var_export() to write a PHP_CodeCoverage object to a file.
  23779. *
  23780. * @since Class available since Release 1.1.0
  23781. */
  23782. class PHP_CodeCoverage_Report_PHP
  23783. {
  23784. /**
  23785. * @param PHP_CodeCoverage $coverage
  23786. * @param string $target
  23787. * @return string
  23788. */
  23789. public function process(PHP_CodeCoverage $coverage, $target = null)
  23790. {
  23791. $filter = $coverage->filter();
  23792. $output = sprintf(
  23793. '<?php
  23794. $coverage = new PHP_CodeCoverage;
  23795. $coverage->setData(%s);
  23796. $coverage->setTests(%s);
  23797. $filter = $coverage->filter();
  23798. $filter->setBlacklistedFiles(%s);
  23799. $filter->setWhitelistedFiles(%s);
  23800. return $coverage;',
  23801. var_export($coverage->getData(true), 1),
  23802. var_export($coverage->getTests(), 1),
  23803. var_export($filter->getBlacklistedFiles(), 1),
  23804. var_export($filter->getWhitelistedFiles(), 1)
  23805. );
  23806. if ($target !== null) {
  23807. return file_put_contents($target, $output);
  23808. } else {
  23809. return $output;
  23810. }
  23811. }
  23812. }
  23813. <?php
  23814. /*
  23815. * This file is part of the PHP_CodeCoverage package.
  23816. *
  23817. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  23818. *
  23819. * For the full copyright and license information, please view the LICENSE
  23820. * file that was distributed with this source code.
  23821. */
  23822. /**
  23823. * Generates human readable output from an PHP_CodeCoverage object.
  23824. *
  23825. * The output gets put into a text file our written to the CLI.
  23826. *
  23827. * @since Class available since Release 1.1.0
  23828. */
  23829. class PHP_CodeCoverage_Report_Text
  23830. {
  23831. protected $lowUpperBound;
  23832. protected $highLowerBound;
  23833. protected $showUncoveredFiles;
  23834. protected $showOnlySummary;
  23835. protected $colors = array(
  23836. 'green' => "\x1b[30;42m",
  23837. 'yellow' => "\x1b[30;43m",
  23838. 'red' => "\x1b[37;41m",
  23839. 'header' => "\x1b[1;37;40m",
  23840. 'reset' => "\x1b[0m",
  23841. 'eol' => "\x1b[2K",
  23842. );
  23843. public function __construct($lowUpperBound, $highLowerBound, $showUncoveredFiles, $showOnlySummary)
  23844. {
  23845. $this->lowUpperBound = $lowUpperBound;
  23846. $this->highLowerBound = $highLowerBound;
  23847. $this->showUncoveredFiles = $showUncoveredFiles;
  23848. $this->showOnlySummary = $showOnlySummary;
  23849. }
  23850. /**
  23851. * @param PHP_CodeCoverage $coverage
  23852. * @param bool $showColors
  23853. * @return string
  23854. */
  23855. public function process(PHP_CodeCoverage $coverage, $showColors = false)
  23856. {
  23857. $output = PHP_EOL . PHP_EOL;
  23858. $report = $coverage->getReport();
  23859. unset($coverage);
  23860. $colors = array(
  23861. 'header' => '',
  23862. 'classes' => '',
  23863. 'methods' => '',
  23864. 'lines' => '',
  23865. 'reset' => '',
  23866. 'eol' => ''
  23867. );
  23868. if ($showColors) {
  23869. $colors['classes'] = $this->getCoverageColor(
  23870. $report->getNumTestedClassesAndTraits(),
  23871. $report->getNumClassesAndTraits()
  23872. );
  23873. $colors['methods'] = $this->getCoverageColor(
  23874. $report->getNumTestedMethods(),
  23875. $report->getNumMethods()
  23876. );
  23877. $colors['lines'] = $this->getCoverageColor(
  23878. $report->getNumExecutedLines(),
  23879. $report->getNumExecutableLines()
  23880. );
  23881. $colors['reset'] = $this->colors['reset'];
  23882. $colors['header'] = $this->colors['header'];
  23883. $colors['eol'] = $this->colors['eol'];
  23884. }
  23885. $classes = sprintf(
  23886. ' Classes: %6s (%d/%d)',
  23887. PHP_CodeCoverage_Util::percent(
  23888. $report->getNumTestedClassesAndTraits(),
  23889. $report->getNumClassesAndTraits(),
  23890. true
  23891. ),
  23892. $report->getNumTestedClassesAndTraits(),
  23893. $report->getNumClassesAndTraits()
  23894. );
  23895. $methods = sprintf(
  23896. ' Methods: %6s (%d/%d)',
  23897. PHP_CodeCoverage_Util::percent(
  23898. $report->getNumTestedMethods(),
  23899. $report->getNumMethods(),
  23900. true
  23901. ),
  23902. $report->getNumTestedMethods(),
  23903. $report->getNumMethods()
  23904. );
  23905. $lines = sprintf(
  23906. ' Lines: %6s (%d/%d)',
  23907. PHP_CodeCoverage_Util::percent(
  23908. $report->getNumExecutedLines(),
  23909. $report->getNumExecutableLines(),
  23910. true
  23911. ),
  23912. $report->getNumExecutedLines(),
  23913. $report->getNumExecutableLines()
  23914. );
  23915. $padding = max(array_map('strlen', array($classes, $methods, $lines)));
  23916. if ($this->showOnlySummary) {
  23917. $title = 'Code Coverage Report Summary:';
  23918. $padding = max($padding, strlen($title));
  23919. $output .= $this->format($colors['header'], $padding, $title);
  23920. } else {
  23921. $date = date(' Y-m-d H:i:s', $_SERVER['REQUEST_TIME']);
  23922. $title = 'Code Coverage Report:';
  23923. $output .= $this->format($colors['header'], $padding, $title);
  23924. $output .= $this->format($colors['header'], $padding, $date);
  23925. $output .= $this->format($colors['header'], $padding, '');
  23926. $output .= $this->format($colors['header'], $padding, ' Summary:');
  23927. }
  23928. $output .= $this->format($colors['classes'], $padding, $classes);
  23929. $output .= $this->format($colors['methods'], $padding, $methods);
  23930. $output .= $this->format($colors['lines'], $padding, $lines);
  23931. if ($this->showOnlySummary) {
  23932. return $output . PHP_EOL;
  23933. }
  23934. $classCoverage = array();
  23935. foreach ($report as $item) {
  23936. if (!$item instanceof PHP_CodeCoverage_Report_Node_File) {
  23937. continue;
  23938. }
  23939. $classes = $item->getClassesAndTraits();
  23940. foreach ($classes as $className => $class) {
  23941. $classStatements = 0;
  23942. $coveredClassStatements = 0;
  23943. $coveredMethods = 0;
  23944. $classMethods = 0;
  23945. foreach ($class['methods'] as $method) {
  23946. if ($method['executableLines'] == 0) {
  23947. continue;
  23948. }
  23949. $classMethods++;
  23950. $classStatements += $method['executableLines'];
  23951. $coveredClassStatements += $method['executedLines'];
  23952. if ($method['coverage'] == 100) {
  23953. $coveredMethods++;
  23954. }
  23955. }
  23956. if (!empty($class['package']['namespace'])) {
  23957. $namespace = '\\' . $class['package']['namespace'] . '::';
  23958. } elseif (!empty($class['package']['fullPackage'])) {
  23959. $namespace = '@' . $class['package']['fullPackage'] . '::';
  23960. } else {
  23961. $namespace = '';
  23962. }
  23963. $classCoverage[$namespace . $className] = array(
  23964. 'namespace' => $namespace,
  23965. 'className ' => $className,
  23966. 'methodsCovered' => $coveredMethods,
  23967. 'methodCount' => $classMethods,
  23968. 'statementsCovered' => $coveredClassStatements,
  23969. 'statementCount' => $classStatements,
  23970. );
  23971. }
  23972. }
  23973. ksort($classCoverage);
  23974. $methodColor = '';
  23975. $linesColor = '';
  23976. $resetColor = '';
  23977. foreach ($classCoverage as $fullQualifiedPath => $classInfo) {
  23978. if ($classInfo['statementsCovered'] != 0 ||
  23979. $this->showUncoveredFiles) {
  23980. if ($showColors) {
  23981. $methodColor = $this->getCoverageColor($classInfo['methodsCovered'], $classInfo['methodCount']);
  23982. $linesColor = $this->getCoverageColor($classInfo['statementsCovered'], $classInfo['statementCount']);
  23983. $resetColor = $colors['reset'];
  23984. }
  23985. $output .= PHP_EOL . $fullQualifiedPath . PHP_EOL
  23986. . ' ' . $methodColor . 'Methods: ' . $this->printCoverageCounts($classInfo['methodsCovered'], $classInfo['methodCount'], 2) . $resetColor . ' '
  23987. . ' ' . $linesColor . 'Lines: ' . $this->printCoverageCounts($classInfo['statementsCovered'], $classInfo['statementCount'], 3) . $resetColor
  23988. ;
  23989. }
  23990. }
  23991. return $output . PHP_EOL;
  23992. }
  23993. protected function getCoverageColor($numberOfCoveredElements, $totalNumberOfElements)
  23994. {
  23995. $coverage = PHP_CodeCoverage_Util::percent(
  23996. $numberOfCoveredElements,
  23997. $totalNumberOfElements
  23998. );
  23999. if ($coverage >= $this->highLowerBound) {
  24000. return $this->colors['green'];
  24001. } elseif ($coverage > $this->lowUpperBound) {
  24002. return $this->colors['yellow'];
  24003. }
  24004. return $this->colors['red'];
  24005. }
  24006. protected function printCoverageCounts($numberOfCoveredElements, $totalNumberOfElements, $presicion)
  24007. {
  24008. $format = '%' . $presicion . 's';
  24009. return PHP_CodeCoverage_Util::percent(
  24010. $numberOfCoveredElements,
  24011. $totalNumberOfElements,
  24012. true,
  24013. true
  24014. ) .
  24015. ' (' . sprintf($format, $numberOfCoveredElements) . '/' .
  24016. sprintf($format, $totalNumberOfElements) . ')';
  24017. }
  24018. private function format($color, $padding, $string)
  24019. {
  24020. $reset = $color ? $this->colors['reset'] : '';
  24021. return $color . str_pad($string, $padding) . $reset . PHP_EOL;
  24022. }
  24023. }
  24024. <?php
  24025. /*
  24026. * This file is part of the PHP_CodeCoverage package.
  24027. *
  24028. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  24029. *
  24030. * For the full copyright and license information, please view the LICENSE
  24031. * file that was distributed with this source code.
  24032. */
  24033. /**
  24034. * Exception that is raised when code is unintentionally covered.
  24035. *
  24036. * @since Class available since Release 2.0.0
  24037. */
  24038. class PHP_CodeCoverage_Exception_UnintentionallyCoveredCode extends PHP_CodeCoverage_Exception
  24039. {
  24040. }
  24041. <?php
  24042. /*
  24043. * This file is part of the PHP_CodeCoverage package.
  24044. *
  24045. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  24046. *
  24047. * For the full copyright and license information, please view the LICENSE
  24048. * file that was distributed with this source code.
  24049. */
  24050. /**
  24051. * Interface for code coverage drivers.
  24052. *
  24053. * @since Class available since Release 1.0.0
  24054. */
  24055. interface PHP_CodeCoverage_Driver
  24056. {
  24057. /**
  24058. * Start collection of code coverage information.
  24059. */
  24060. public function start();
  24061. /**
  24062. * Stop collection of code coverage information.
  24063. *
  24064. * @return array
  24065. */
  24066. public function stop();
  24067. }
  24068. <?php
  24069. /*
  24070. * This file is part of the PHP_CodeCoverage package.
  24071. *
  24072. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  24073. *
  24074. * For the full copyright and license information, please view the LICENSE
  24075. * file that was distributed with this source code.
  24076. */
  24077. /**
  24078. * Filter for blacklisting and whitelisting of code coverage information.
  24079. *
  24080. * @since Class available since Release 1.0.0
  24081. */
  24082. class PHP_CodeCoverage_Filter
  24083. {
  24084. /**
  24085. * Source files that are blacklisted.
  24086. *
  24087. * @var array
  24088. */
  24089. private $blacklistedFiles = array();
  24090. /**
  24091. * Source files that are whitelisted.
  24092. *
  24093. * @var array
  24094. */
  24095. private $whitelistedFiles = array();
  24096. /**
  24097. * Adds a directory to the blacklist (recursively).
  24098. *
  24099. * @param string $directory
  24100. * @param string $suffix
  24101. * @param string $prefix
  24102. */
  24103. public function addDirectoryToBlacklist($directory, $suffix = '.php', $prefix = '')
  24104. {
  24105. $facade = new File_Iterator_Facade;
  24106. $files = $facade->getFilesAsArray($directory, $suffix, $prefix);
  24107. foreach ($files as $file) {
  24108. $this->addFileToBlacklist($file);
  24109. }
  24110. }
  24111. /**
  24112. * Adds a file to the blacklist.
  24113. *
  24114. * @param string $filename
  24115. */
  24116. public function addFileToBlacklist($filename)
  24117. {
  24118. $this->blacklistedFiles[realpath($filename)] = true;
  24119. }
  24120. /**
  24121. * Adds files to the blacklist.
  24122. *
  24123. * @param array $files
  24124. */
  24125. public function addFilesToBlacklist(array $files)
  24126. {
  24127. foreach ($files as $file) {
  24128. $this->addFileToBlacklist($file);
  24129. }
  24130. }
  24131. /**
  24132. * Removes a directory from the blacklist (recursively).
  24133. *
  24134. * @param string $directory
  24135. * @param string $suffix
  24136. * @param string $prefix
  24137. */
  24138. public function removeDirectoryFromBlacklist($directory, $suffix = '.php', $prefix = '')
  24139. {
  24140. $facade = new File_Iterator_Facade;
  24141. $files = $facade->getFilesAsArray($directory, $suffix, $prefix);
  24142. foreach ($files as $file) {
  24143. $this->removeFileFromBlacklist($file);
  24144. }
  24145. }
  24146. /**
  24147. * Removes a file from the blacklist.
  24148. *
  24149. * @param string $filename
  24150. */
  24151. public function removeFileFromBlacklist($filename)
  24152. {
  24153. $filename = realpath($filename);
  24154. if (isset($this->blacklistedFiles[$filename])) {
  24155. unset($this->blacklistedFiles[$filename]);
  24156. }
  24157. }
  24158. /**
  24159. * Adds a directory to the whitelist (recursively).
  24160. *
  24161. * @param string $directory
  24162. * @param string $suffix
  24163. * @param string $prefix
  24164. */
  24165. public function addDirectoryToWhitelist($directory, $suffix = '.php', $prefix = '')
  24166. {
  24167. $facade = new File_Iterator_Facade;
  24168. $files = $facade->getFilesAsArray($directory, $suffix, $prefix);
  24169. foreach ($files as $file) {
  24170. $this->addFileToWhitelist($file);
  24171. }
  24172. }
  24173. /**
  24174. * Adds a file to the whitelist.
  24175. *
  24176. * @param string $filename
  24177. */
  24178. public function addFileToWhitelist($filename)
  24179. {
  24180. $this->whitelistedFiles[realpath($filename)] = true;
  24181. }
  24182. /**
  24183. * Adds files to the whitelist.
  24184. *
  24185. * @param array $files
  24186. */
  24187. public function addFilesToWhitelist(array $files)
  24188. {
  24189. foreach ($files as $file) {
  24190. $this->addFileToWhitelist($file);
  24191. }
  24192. }
  24193. /**
  24194. * Removes a directory from the whitelist (recursively).
  24195. *
  24196. * @param string $directory
  24197. * @param string $suffix
  24198. * @param string $prefix
  24199. */
  24200. public function removeDirectoryFromWhitelist($directory, $suffix = '.php', $prefix = '')
  24201. {
  24202. $facade = new File_Iterator_Facade;
  24203. $files = $facade->getFilesAsArray($directory, $suffix, $prefix);
  24204. foreach ($files as $file) {
  24205. $this->removeFileFromWhitelist($file);
  24206. }
  24207. }
  24208. /**
  24209. * Removes a file from the whitelist.
  24210. *
  24211. * @param string $filename
  24212. */
  24213. public function removeFileFromWhitelist($filename)
  24214. {
  24215. $filename = realpath($filename);
  24216. if (isset($this->whitelistedFiles[$filename])) {
  24217. unset($this->whitelistedFiles[$filename]);
  24218. }
  24219. }
  24220. /**
  24221. * Checks whether a filename is a real filename.
  24222. *
  24223. * @param string $filename
  24224. */
  24225. public function isFile($filename)
  24226. {
  24227. if ($filename == '-' ||
  24228. strpos($filename, 'vfs://') === 0 ||
  24229. strpos($filename, 'xdebug://debug-eval') !== false ||
  24230. strpos($filename, 'eval()\'d code') !== false ||
  24231. strpos($filename, 'runtime-created function') !== false ||
  24232. strpos($filename, 'runkit created function') !== false ||
  24233. strpos($filename, 'assert code') !== false ||
  24234. strpos($filename, 'regexp code') !== false) {
  24235. return false;
  24236. }
  24237. return file_exists($filename);
  24238. }
  24239. /**
  24240. * Checks whether or not a file is filtered.
  24241. *
  24242. * When the whitelist is empty (default), blacklisting is used.
  24243. * When the whitelist is not empty, whitelisting is used.
  24244. *
  24245. * @param string $filename
  24246. * @return bool
  24247. * @throws PHP_CodeCoverage_Exception
  24248. */
  24249. public function isFiltered($filename)
  24250. {
  24251. if (!$this->isFile($filename)) {
  24252. return true;
  24253. }
  24254. $filename = realpath($filename);
  24255. if (!empty($this->whitelistedFiles)) {
  24256. return !isset($this->whitelistedFiles[$filename]);
  24257. }
  24258. return isset($this->blacklistedFiles[$filename]);
  24259. }
  24260. /**
  24261. * Returns the list of blacklisted files.
  24262. *
  24263. * @return array
  24264. */
  24265. public function getBlacklist()
  24266. {
  24267. return array_keys($this->blacklistedFiles);
  24268. }
  24269. /**
  24270. * Returns the list of whitelisted files.
  24271. *
  24272. * @return array
  24273. */
  24274. public function getWhitelist()
  24275. {
  24276. return array_keys($this->whitelistedFiles);
  24277. }
  24278. /**
  24279. * Returns whether this filter has a whitelist.
  24280. *
  24281. * @return bool
  24282. * @since Method available since Release 1.1.0
  24283. */
  24284. public function hasWhitelist()
  24285. {
  24286. return !empty($this->whitelistedFiles);
  24287. }
  24288. /**
  24289. * Returns the blacklisted files.
  24290. *
  24291. * @return array
  24292. * @since Method available since Release 2.0.0
  24293. */
  24294. public function getBlacklistedFiles()
  24295. {
  24296. return $this->blacklistedFiles;
  24297. }
  24298. /**
  24299. * Sets the blacklisted files.
  24300. *
  24301. * @param array $blacklistedFiles
  24302. * @since Method available since Release 2.0.0
  24303. */
  24304. public function setBlacklistedFiles($blacklistedFiles)
  24305. {
  24306. $this->blacklistedFiles = $blacklistedFiles;
  24307. }
  24308. /**
  24309. * Returns the whitelisted files.
  24310. *
  24311. * @return array
  24312. * @since Method available since Release 2.0.0
  24313. */
  24314. public function getWhitelistedFiles()
  24315. {
  24316. return $this->whitelistedFiles;
  24317. }
  24318. /**
  24319. * Sets the whitelisted files.
  24320. *
  24321. * @param array $whitelistedFiles
  24322. * @since Method available since Release 2.0.0
  24323. */
  24324. public function setWhitelistedFiles($whitelistedFiles)
  24325. {
  24326. $this->whitelistedFiles = $whitelistedFiles;
  24327. }
  24328. }
  24329. <?php
  24330. /*
  24331. * This file is part of the PHP_CodeCoverage package.
  24332. *
  24333. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  24334. *
  24335. * For the full copyright and license information, please view the LICENSE
  24336. * file that was distributed with this source code.
  24337. */
  24338. /**
  24339. * Factory for PHP_CodeCoverage_Exception objects that are used to describe
  24340. * invalid arguments passed to a function or method.
  24341. *
  24342. * @since Class available since Release 1.2.0
  24343. */
  24344. class PHP_CodeCoverage_Util_InvalidArgumentHelper
  24345. {
  24346. /**
  24347. * @param int $argument
  24348. * @param string $type
  24349. * @param mixed $value
  24350. */
  24351. public static function factory($argument, $type, $value = null)
  24352. {
  24353. $stack = debug_backtrace(false);
  24354. return new PHP_CodeCoverage_Exception(
  24355. sprintf(
  24356. 'Argument #%d%sof %s::%s() must be a %s',
  24357. $argument,
  24358. $value !== null ? ' (' . gettype($value) . '#' . $value . ')' : ' (No Value) ',
  24359. $stack[1]['class'],
  24360. $stack[1]['function'],
  24361. $type
  24362. )
  24363. );
  24364. }
  24365. }
  24366. <?php
  24367. /*
  24368. * This file is part of the PHP_CodeCoverage package.
  24369. *
  24370. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  24371. *
  24372. * For the full copyright and license information, please view the LICENSE
  24373. * file that was distributed with this source code.
  24374. */
  24375. /**
  24376. * Driver for HHVM's code coverage functionality.
  24377. *
  24378. * @since Class available since Release 1.3.0
  24379. * @codeCoverageIgnore
  24380. */
  24381. class PHP_CodeCoverage_Driver_HHVM implements PHP_CodeCoverage_Driver
  24382. {
  24383. /**
  24384. * Constructor.
  24385. */
  24386. public function __construct()
  24387. {
  24388. if (!defined('HHVM_VERSION')) {
  24389. throw new PHP_CodeCoverage_Exception('This driver requires HHVM');
  24390. }
  24391. }
  24392. /**
  24393. * Start collection of code coverage information.
  24394. */
  24395. public function start()
  24396. {
  24397. fb_enable_code_coverage();
  24398. }
  24399. /**
  24400. * Stop collection of code coverage information.
  24401. *
  24402. * @return array
  24403. */
  24404. public function stop()
  24405. {
  24406. $codeCoverage = fb_get_code_coverage(true);
  24407. fb_disable_code_coverage();
  24408. return $codeCoverage;
  24409. }
  24410. }
  24411. <?php
  24412. /*
  24413. * This file is part of the PHP_CodeCoverage package.
  24414. *
  24415. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  24416. *
  24417. * For the full copyright and license information, please view the LICENSE
  24418. * file that was distributed with this source code.
  24419. */
  24420. /**
  24421. * Driver for Xdebug's code coverage functionality.
  24422. *
  24423. * @since Class available since Release 1.0.0
  24424. * @codeCoverageIgnore
  24425. */
  24426. class PHP_CodeCoverage_Driver_Xdebug implements PHP_CodeCoverage_Driver
  24427. {
  24428. /**
  24429. * Constructor.
  24430. */
  24431. public function __construct()
  24432. {
  24433. if (!extension_loaded('xdebug')) {
  24434. throw new PHP_CodeCoverage_Exception('This driver requires Xdebug');
  24435. }
  24436. if (version_compare(phpversion('xdebug'), '2.2.0-dev', '>=') &&
  24437. !ini_get('xdebug.coverage_enable')) {
  24438. throw new PHP_CodeCoverage_Exception(
  24439. 'xdebug.coverage_enable=On has to be set in php.ini'
  24440. );
  24441. }
  24442. }
  24443. /**
  24444. * Start collection of code coverage information.
  24445. */
  24446. public function start()
  24447. {
  24448. xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
  24449. }
  24450. /**
  24451. * Stop collection of code coverage information.
  24452. *
  24453. * @return array
  24454. */
  24455. public function stop()
  24456. {
  24457. $data = xdebug_get_code_coverage();
  24458. xdebug_stop_code_coverage();
  24459. return $this->cleanup($data);
  24460. }
  24461. /**
  24462. * @param array $data
  24463. * @return array
  24464. * @since Method available since Release 2.0.0
  24465. */
  24466. private function cleanup(array $data)
  24467. {
  24468. foreach (array_keys($data) as $file) {
  24469. if (isset($data[$file][0])) {
  24470. unset($data[$file][0]);
  24471. }
  24472. if ($file != 'xdebug://debug-eval' && file_exists($file)) {
  24473. $numLines = $this->getNumberOfLinesInFile($file);
  24474. foreach (array_keys($data[$file]) as $line) {
  24475. if (isset($data[$file][$line]) && $line > $numLines) {
  24476. unset($data[$file][$line]);
  24477. }
  24478. }
  24479. }
  24480. }
  24481. return $data;
  24482. }
  24483. /**
  24484. * @param string $file
  24485. * @return int
  24486. * @since Method available since Release 2.0.0
  24487. */
  24488. private function getNumberOfLinesInFile($file)
  24489. {
  24490. $buffer = file_get_contents($file);
  24491. $lines = substr_count($buffer, "\n");
  24492. if (substr($buffer, -1) !== "\n") {
  24493. $lines++;
  24494. }
  24495. return $lines;
  24496. }
  24497. }
  24498. PHP_CodeCoverage
  24499. Copyright (c) 2009-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  24500. All rights reserved.
  24501. Redistribution and use in source and binary forms, with or without
  24502. modification, are permitted provided that the following conditions
  24503. are met:
  24504. * Redistributions of source code must retain the above copyright
  24505. notice, this list of conditions and the following disclaimer.
  24506. * Redistributions in binary form must reproduce the above copyright
  24507. notice, this list of conditions and the following disclaimer in
  24508. the documentation and/or other materials provided with the
  24509. distribution.
  24510. * Neither the name of Sebastian Bergmann nor the names of his
  24511. contributors may be used to endorse or promote products derived
  24512. from this software without specific prior written permission.
  24513. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  24514. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24515. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24516. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  24517. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24518. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  24519. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24520. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  24521. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24522. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  24523. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  24524. POSSIBILITY OF SUCH DAMAGE.
  24525. <?php
  24526. /*
  24527. * This file is part of the PHP_CodeCoverage package.
  24528. *
  24529. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  24530. *
  24531. * For the full copyright and license information, please view the LICENSE
  24532. * file that was distributed with this source code.
  24533. */
  24534. use SebastianBergmann\Environment\Runtime;
  24535. /**
  24536. * Provides collection functionality for PHP code coverage information.
  24537. *
  24538. * @since Class available since Release 1.0.0
  24539. */
  24540. class PHP_CodeCoverage
  24541. {
  24542. /**
  24543. * @var PHP_CodeCoverage_Driver
  24544. */
  24545. private $driver;
  24546. /**
  24547. * @var PHP_CodeCoverage_Filter
  24548. */
  24549. private $filter;
  24550. /**
  24551. * @var bool
  24552. */
  24553. private $cacheTokens = false;
  24554. /**
  24555. * @var bool
  24556. */
  24557. private $checkForUnintentionallyCoveredCode = false;
  24558. /**
  24559. * @var bool
  24560. */
  24561. private $forceCoversAnnotation = false;
  24562. /**
  24563. * @var bool
  24564. */
  24565. private $mapTestClassNameToCoveredClassName = false;
  24566. /**
  24567. * @var bool
  24568. */
  24569. private $addUncoveredFilesFromWhitelist = true;
  24570. /**
  24571. * @var bool
  24572. */
  24573. private $processUncoveredFilesFromWhitelist = false;
  24574. /**
  24575. * @var mixed
  24576. */
  24577. private $currentId;
  24578. /**
  24579. * Code coverage data.
  24580. *
  24581. * @var array
  24582. */
  24583. private $data = array();
  24584. /**
  24585. * @var array
  24586. */
  24587. private $ignoredLines = array();
  24588. /**
  24589. * Test data.
  24590. *
  24591. * @var array
  24592. */
  24593. private $tests = array();
  24594. /**
  24595. * Constructor.
  24596. *
  24597. * @param PHP_CodeCoverage_Driver $driver
  24598. * @param PHP_CodeCoverage_Filter $filter
  24599. * @throws PHP_CodeCoverage_Exception
  24600. */
  24601. public function __construct(PHP_CodeCoverage_Driver $driver = null, PHP_CodeCoverage_Filter $filter = null)
  24602. {
  24603. if ($driver === null) {
  24604. $runtime = new Runtime;
  24605. if ($runtime->isHHVM()) {
  24606. $driver = new PHP_CodeCoverage_Driver_HHVM;
  24607. } elseif ($runtime->hasXdebug()) {
  24608. $driver = new PHP_CodeCoverage_Driver_Xdebug;
  24609. } else {
  24610. throw new PHP_CodeCoverage_Exception('No code coverage driver available');
  24611. }
  24612. }
  24613. if ($filter === null) {
  24614. $filter = new PHP_CodeCoverage_Filter;
  24615. }
  24616. $this->driver = $driver;
  24617. $this->filter = $filter;
  24618. }
  24619. /**
  24620. * Returns the PHP_CodeCoverage_Report_Node_* object graph
  24621. * for this PHP_CodeCoverage object.
  24622. *
  24623. * @return PHP_CodeCoverage_Report_Node_Directory
  24624. * @since Method available since Release 1.1.0
  24625. */
  24626. public function getReport()
  24627. {
  24628. $factory = new PHP_CodeCoverage_Report_Factory;
  24629. return $factory->create($this);
  24630. }
  24631. /**
  24632. * Clears collected code coverage data.
  24633. */
  24634. public function clear()
  24635. {
  24636. $this->currentId = null;
  24637. $this->data = array();
  24638. $this->tests = array();
  24639. }
  24640. /**
  24641. * Returns the PHP_CodeCoverage_Filter used.
  24642. *
  24643. * @return PHP_CodeCoverage_Filter
  24644. */
  24645. public function filter()
  24646. {
  24647. return $this->filter;
  24648. }
  24649. /**
  24650. * Returns the collected code coverage data.
  24651. * Set $raw = true to bypass all filters.
  24652. *
  24653. * @param bool $raw
  24654. * @return array
  24655. * @since Method available since Release 1.1.0
  24656. */
  24657. public function getData($raw = false)
  24658. {
  24659. if (!$raw && $this->addUncoveredFilesFromWhitelist) {
  24660. $this->addUncoveredFilesFromWhitelist();
  24661. }
  24662. // We need to apply the blacklist filter a second time
  24663. // when no whitelist is used.
  24664. if (!$raw && !$this->filter->hasWhitelist()) {
  24665. $this->applyListsFilter($this->data);
  24666. }
  24667. return $this->data;
  24668. }
  24669. /**
  24670. * Sets the coverage data.
  24671. *
  24672. * @param array $data
  24673. * @since Method available since Release 2.0.0
  24674. */
  24675. public function setData(array $data)
  24676. {
  24677. $this->data = $data;
  24678. }
  24679. /**
  24680. * Returns the test data.
  24681. *
  24682. * @return array
  24683. * @since Method available since Release 1.1.0
  24684. */
  24685. public function getTests()
  24686. {
  24687. return $this->tests;
  24688. }
  24689. /**
  24690. * Sets the test data.
  24691. *
  24692. * @param array $tests
  24693. * @since Method available since Release 2.0.0
  24694. */
  24695. public function setTests(array $tests)
  24696. {
  24697. $this->tests = $tests;
  24698. }
  24699. /**
  24700. * Start collection of code coverage information.
  24701. *
  24702. * @param mixed $id
  24703. * @param bool $clear
  24704. * @throws PHP_CodeCoverage_Exception
  24705. */
  24706. public function start($id, $clear = false)
  24707. {
  24708. if (!is_bool($clear)) {
  24709. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  24710. 1,
  24711. 'boolean'
  24712. );
  24713. }
  24714. if ($clear) {
  24715. $this->clear();
  24716. }
  24717. $this->currentId = $id;
  24718. $this->driver->start();
  24719. }
  24720. /**
  24721. * Stop collection of code coverage information.
  24722. *
  24723. * @param bool $append
  24724. * @param mixed $linesToBeCovered
  24725. * @param array $linesToBeUsed
  24726. * @return array
  24727. * @throws PHP_CodeCoverage_Exception
  24728. */
  24729. public function stop($append = true, $linesToBeCovered = array(), array $linesToBeUsed = array())
  24730. {
  24731. if (!is_bool($append)) {
  24732. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  24733. 1,
  24734. 'boolean'
  24735. );
  24736. }
  24737. if (!is_array($linesToBeCovered) && $linesToBeCovered !== false) {
  24738. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  24739. 2,
  24740. 'array or false'
  24741. );
  24742. }
  24743. $data = $this->driver->stop();
  24744. $this->append($data, null, $append, $linesToBeCovered, $linesToBeUsed);
  24745. $this->currentId = null;
  24746. return $data;
  24747. }
  24748. /**
  24749. * Appends code coverage data.
  24750. *
  24751. * @param array $data
  24752. * @param mixed $id
  24753. * @param bool $append
  24754. * @param mixed $linesToBeCovered
  24755. * @param array $linesToBeUsed
  24756. * @throws PHP_CodeCoverage_Exception
  24757. */
  24758. public function append(array $data, $id = null, $append = true, $linesToBeCovered = array(), array $linesToBeUsed = array())
  24759. {
  24760. if ($id === null) {
  24761. $id = $this->currentId;
  24762. }
  24763. if ($id === null) {
  24764. throw new PHP_CodeCoverage_Exception;
  24765. }
  24766. $this->applyListsFilter($data);
  24767. $this->applyIgnoredLinesFilter($data);
  24768. $this->initializeFilesThatAreSeenTheFirstTime($data);
  24769. if (!$append) {
  24770. return;
  24771. }
  24772. if ($id != 'UNCOVERED_FILES_FROM_WHITELIST') {
  24773. $this->applyCoversAnnotationFilter(
  24774. $data,
  24775. $linesToBeCovered,
  24776. $linesToBeUsed
  24777. );
  24778. }
  24779. if (empty($data)) {
  24780. return;
  24781. }
  24782. $size = 'unknown';
  24783. $status = null;
  24784. if ($id instanceof PHPUnit_Framework_TestCase) {
  24785. $_size = $id->getSize();
  24786. if ($_size == PHPUnit_Util_Test::SMALL) {
  24787. $size = 'small';
  24788. } elseif ($_size == PHPUnit_Util_Test::MEDIUM) {
  24789. $size = 'medium';
  24790. } elseif ($_size == PHPUnit_Util_Test::LARGE) {
  24791. $size = 'large';
  24792. }
  24793. $status = $id->getStatus();
  24794. $id = get_class($id) . '::' . $id->getName();
  24795. } elseif ($id instanceof PHPUnit_Extensions_PhptTestCase) {
  24796. $size = 'large';
  24797. $id = $id->getName();
  24798. }
  24799. $this->tests[$id] = array('size' => $size, 'status' => $status);
  24800. foreach ($data as $file => $lines) {
  24801. if (!$this->filter->isFile($file)) {
  24802. continue;
  24803. }
  24804. foreach ($lines as $k => $v) {
  24805. if ($v == 1) {
  24806. if (empty($this->data[$file][$k]) || !in_array($id, $this->data[$file][$k])) {
  24807. $this->data[$file][$k][] = $id;
  24808. }
  24809. }
  24810. }
  24811. }
  24812. }
  24813. /**
  24814. * Merges the data from another instance of PHP_CodeCoverage.
  24815. *
  24816. * @param PHP_CodeCoverage $that
  24817. */
  24818. public function merge(PHP_CodeCoverage $that)
  24819. {
  24820. foreach ($that->data as $file => $lines) {
  24821. if (!isset($this->data[$file])) {
  24822. if (!$this->filter->isFiltered($file)) {
  24823. $this->data[$file] = $lines;
  24824. }
  24825. continue;
  24826. }
  24827. foreach ($lines as $line => $data) {
  24828. if ($data !== null) {
  24829. if (!isset($this->data[$file][$line])) {
  24830. $this->data[$file][$line] = $data;
  24831. } else {
  24832. $this->data[$file][$line] = array_unique(
  24833. array_merge($this->data[$file][$line], $data)
  24834. );
  24835. }
  24836. }
  24837. }
  24838. }
  24839. $this->tests = array_merge($this->tests, $that->getTests());
  24840. $this->filter->setBlacklistedFiles(
  24841. array_merge($this->filter->getBlacklistedFiles(), $that->filter()->getBlacklistedFiles())
  24842. );
  24843. $this->filter->setWhitelistedFiles(
  24844. array_merge($this->filter->getWhitelistedFiles(), $that->filter()->getWhitelistedFiles())
  24845. );
  24846. }
  24847. /**
  24848. * @param bool $flag
  24849. * @throws PHP_CodeCoverage_Exception
  24850. * @since Method available since Release 1.1.0
  24851. */
  24852. public function setCacheTokens($flag)
  24853. {
  24854. if (!is_bool($flag)) {
  24855. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  24856. 1,
  24857. 'boolean'
  24858. );
  24859. }
  24860. $this->cacheTokens = $flag;
  24861. }
  24862. /**
  24863. * @since Method available since Release 1.1.0
  24864. */
  24865. public function getCacheTokens()
  24866. {
  24867. return $this->cacheTokens;
  24868. }
  24869. /**
  24870. * @param bool $flag
  24871. * @throws PHP_CodeCoverage_Exception
  24872. * @since Method available since Release 2.0.0
  24873. */
  24874. public function setCheckForUnintentionallyCoveredCode($flag)
  24875. {
  24876. if (!is_bool($flag)) {
  24877. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  24878. 1,
  24879. 'boolean'
  24880. );
  24881. }
  24882. $this->checkForUnintentionallyCoveredCode = $flag;
  24883. }
  24884. /**
  24885. * @param bool $flag
  24886. * @throws PHP_CodeCoverage_Exception
  24887. */
  24888. public function setForceCoversAnnotation($flag)
  24889. {
  24890. if (!is_bool($flag)) {
  24891. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  24892. 1,
  24893. 'boolean'
  24894. );
  24895. }
  24896. $this->forceCoversAnnotation = $flag;
  24897. }
  24898. /**
  24899. * @param bool $flag
  24900. * @throws PHP_CodeCoverage_Exception
  24901. */
  24902. public function setMapTestClassNameToCoveredClassName($flag)
  24903. {
  24904. if (!is_bool($flag)) {
  24905. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  24906. 1,
  24907. 'boolean'
  24908. );
  24909. }
  24910. $this->mapTestClassNameToCoveredClassName = $flag;
  24911. }
  24912. /**
  24913. * @param bool $flag
  24914. * @throws PHP_CodeCoverage_Exception
  24915. */
  24916. public function setAddUncoveredFilesFromWhitelist($flag)
  24917. {
  24918. if (!is_bool($flag)) {
  24919. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  24920. 1,
  24921. 'boolean'
  24922. );
  24923. }
  24924. $this->addUncoveredFilesFromWhitelist = $flag;
  24925. }
  24926. /**
  24927. * @param bool $flag
  24928. * @throws PHP_CodeCoverage_Exception
  24929. */
  24930. public function setProcessUncoveredFilesFromWhitelist($flag)
  24931. {
  24932. if (!is_bool($flag)) {
  24933. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  24934. 1,
  24935. 'boolean'
  24936. );
  24937. }
  24938. $this->processUncoveredFilesFromWhitelist = $flag;
  24939. }
  24940. /**
  24941. * Applies the @covers annotation filtering.
  24942. *
  24943. * @param array $data
  24944. * @param mixed $linesToBeCovered
  24945. * @param array $linesToBeUsed
  24946. * @throws PHP_CodeCoverage_Exception_UnintentionallyCoveredCode
  24947. */
  24948. private function applyCoversAnnotationFilter(array &$data, $linesToBeCovered, array $linesToBeUsed)
  24949. {
  24950. if ($linesToBeCovered === false ||
  24951. ($this->forceCoversAnnotation && empty($linesToBeCovered))) {
  24952. $data = array();
  24953. return;
  24954. }
  24955. if (empty($linesToBeCovered)) {
  24956. return;
  24957. }
  24958. if ($this->checkForUnintentionallyCoveredCode) {
  24959. $this->performUnintentionallyCoveredCodeCheck(
  24960. $data,
  24961. $linesToBeCovered,
  24962. $linesToBeUsed
  24963. );
  24964. }
  24965. $data = array_intersect_key($data, $linesToBeCovered);
  24966. foreach (array_keys($data) as $filename) {
  24967. $_linesToBeCovered = array_flip($linesToBeCovered[$filename]);
  24968. $data[$filename] = array_intersect_key(
  24969. $data[$filename],
  24970. $_linesToBeCovered
  24971. );
  24972. }
  24973. }
  24974. /**
  24975. * Applies the blacklist/whitelist filtering.
  24976. *
  24977. * @param array $data
  24978. */
  24979. private function applyListsFilter(array &$data)
  24980. {
  24981. foreach (array_keys($data) as $filename) {
  24982. if ($this->filter->isFiltered($filename)) {
  24983. unset($data[$filename]);
  24984. }
  24985. }
  24986. }
  24987. /**
  24988. * Applies the "ignored lines" filtering.
  24989. *
  24990. * @param array $data
  24991. */
  24992. private function applyIgnoredLinesFilter(array &$data)
  24993. {
  24994. foreach (array_keys($data) as $filename) {
  24995. if (!$this->filter->isFile($filename)) {
  24996. continue;
  24997. }
  24998. foreach ($this->getLinesToBeIgnored($filename) as $line) {
  24999. unset($data[$filename][$line]);
  25000. }
  25001. }
  25002. }
  25003. /**
  25004. * @param array $data
  25005. * @since Method available since Release 1.1.0
  25006. */
  25007. private function initializeFilesThatAreSeenTheFirstTime(array $data)
  25008. {
  25009. foreach ($data as $file => $lines) {
  25010. if ($this->filter->isFile($file) && !isset($this->data[$file])) {
  25011. $this->data[$file] = array();
  25012. foreach ($lines as $k => $v) {
  25013. $this->data[$file][$k] = $v == -2 ? null : array();
  25014. }
  25015. }
  25016. }
  25017. }
  25018. /**
  25019. * Processes whitelisted files that are not covered.
  25020. */
  25021. private function addUncoveredFilesFromWhitelist()
  25022. {
  25023. $data = array();
  25024. $uncoveredFiles = array_diff(
  25025. $this->filter->getWhitelist(),
  25026. array_keys($this->data)
  25027. );
  25028. foreach ($uncoveredFiles as $uncoveredFile) {
  25029. if (!file_exists($uncoveredFile)) {
  25030. continue;
  25031. }
  25032. if ($this->processUncoveredFilesFromWhitelist) {
  25033. $this->processUncoveredFileFromWhitelist(
  25034. $uncoveredFile,
  25035. $data,
  25036. $uncoveredFiles
  25037. );
  25038. } else {
  25039. $data[$uncoveredFile] = array();
  25040. $lines = count(file($uncoveredFile));
  25041. for ($i = 1; $i <= $lines; $i++) {
  25042. $data[$uncoveredFile][$i] = -1;
  25043. }
  25044. }
  25045. }
  25046. $this->append($data, 'UNCOVERED_FILES_FROM_WHITELIST');
  25047. }
  25048. /**
  25049. * @param string $uncoveredFile
  25050. * @param array $data
  25051. * @param array $uncoveredFiles
  25052. */
  25053. private function processUncoveredFileFromWhitelist($uncoveredFile, array &$data, array $uncoveredFiles)
  25054. {
  25055. $this->driver->start();
  25056. include_once $uncoveredFile;
  25057. $coverage = $this->driver->stop();
  25058. foreach ($coverage as $file => $fileCoverage) {
  25059. if (!isset($data[$file]) &&
  25060. in_array($file, $uncoveredFiles)) {
  25061. foreach (array_keys($fileCoverage) as $key) {
  25062. if ($fileCoverage[$key] == 1) {
  25063. $fileCoverage[$key] = -1;
  25064. }
  25065. }
  25066. $data[$file] = $fileCoverage;
  25067. }
  25068. }
  25069. }
  25070. /**
  25071. * Returns the lines of a source file that should be ignored.
  25072. *
  25073. * @param string $filename
  25074. * @return array
  25075. * @throws PHP_CodeCoverage_Exception
  25076. * @since Method available since Release 2.0.0
  25077. */
  25078. private function getLinesToBeIgnored($filename)
  25079. {
  25080. if (!is_string($filename)) {
  25081. throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(
  25082. 1,
  25083. 'string'
  25084. );
  25085. }
  25086. if (!isset($this->ignoredLines[$filename])) {
  25087. $this->ignoredLines[$filename] = array();
  25088. $ignore = false;
  25089. $stop = false;
  25090. $lines = file($filename);
  25091. $numLines = count($lines);
  25092. foreach ($lines as $index => $line) {
  25093. if (!trim($line)) {
  25094. $this->ignoredLines[$filename][] = $index + 1;
  25095. }
  25096. }
  25097. if ($this->cacheTokens) {
  25098. $tokens = PHP_Token_Stream_CachingFactory::get($filename);
  25099. } else {
  25100. $tokens = new PHP_Token_Stream($filename);
  25101. }
  25102. $classes = array_merge($tokens->getClasses(), $tokens->getTraits());
  25103. $tokens = $tokens->tokens();
  25104. foreach ($tokens as $token) {
  25105. switch (get_class($token)) {
  25106. case 'PHP_Token_COMMENT':
  25107. case 'PHP_Token_DOC_COMMENT':
  25108. $_token = trim($token);
  25109. $_line = trim($lines[$token->getLine() - 1]);
  25110. if ($_token == '// @codeCoverageIgnore' ||
  25111. $_token == '//@codeCoverageIgnore') {
  25112. $ignore = true;
  25113. $stop = true;
  25114. } elseif ($_token == '// @codeCoverageIgnoreStart' ||
  25115. $_token == '//@codeCoverageIgnoreStart') {
  25116. $ignore = true;
  25117. } elseif ($_token == '// @codeCoverageIgnoreEnd' ||
  25118. $_token == '//@codeCoverageIgnoreEnd') {
  25119. $stop = true;
  25120. }
  25121. if (!$ignore) {
  25122. $start = $token->getLine();
  25123. $end = $start + substr_count($token, "\n");
  25124. // Do not ignore the first line when there is a token
  25125. // before the comment
  25126. if (0 !== strpos($_token, $_line)) {
  25127. $start++;
  25128. }
  25129. for ($i = $start; $i < $end; $i++) {
  25130. $this->ignoredLines[$filename][] = $i;
  25131. }
  25132. // A DOC_COMMENT token or a COMMENT token starting with "/*"
  25133. // does not contain the final \n character in its text
  25134. if (isset($lines[$i-1]) && 0 === strpos($_token, '/*') && '*/' === substr(trim($lines[$i-1]), -2)) {
  25135. $this->ignoredLines[$filename][] = $i;
  25136. }
  25137. }
  25138. break;
  25139. case 'PHP_Token_INTERFACE':
  25140. case 'PHP_Token_TRAIT':
  25141. case 'PHP_Token_CLASS':
  25142. case 'PHP_Token_FUNCTION':
  25143. $docblock = $token->getDocblock();
  25144. $this->ignoredLines[$filename][] = $token->getLine();
  25145. if (strpos($docblock, '@codeCoverageIgnore')) {
  25146. $endLine = $token->getEndLine();
  25147. for ($i = $token->getLine(); $i <= $endLine; $i++) {
  25148. $this->ignoredLines[$filename][] = $i;
  25149. }
  25150. } elseif ($token instanceof PHP_Token_INTERFACE ||
  25151. $token instanceof PHP_Token_TRAIT ||
  25152. $token instanceof PHP_Token_CLASS) {
  25153. if (empty($classes[$token->getName()]['methods'])) {
  25154. for ($i = $token->getLine();
  25155. $i <= $token->getEndLine();
  25156. $i++) {
  25157. $this->ignoredLines[$filename][] = $i;
  25158. }
  25159. } else {
  25160. $firstMethod = array_shift(
  25161. $classes[$token->getName()]['methods']
  25162. );
  25163. do {
  25164. $lastMethod = array_pop(
  25165. $classes[$token->getName()]['methods']
  25166. );
  25167. } while ($lastMethod !== null &&
  25168. substr($lastMethod['signature'], 0, 18) == 'anonymous function');
  25169. if ($lastMethod === null) {
  25170. $lastMethod = $firstMethod;
  25171. }
  25172. for ($i = $token->getLine();
  25173. $i < $firstMethod['startLine'];
  25174. $i++) {
  25175. $this->ignoredLines[$filename][] = $i;
  25176. }
  25177. for ($i = $token->getEndLine();
  25178. $i > $lastMethod['endLine'];
  25179. $i--) {
  25180. $this->ignoredLines[$filename][] = $i;
  25181. }
  25182. }
  25183. }
  25184. break;
  25185. case 'PHP_Token_NAMESPACE':
  25186. $this->ignoredLines[$filename][] = $token->getEndLine();
  25187. // Intentional fallthrough
  25188. case 'PHP_Token_OPEN_TAG':
  25189. case 'PHP_Token_CLOSE_TAG':
  25190. case 'PHP_Token_USE':
  25191. $this->ignoredLines[$filename][] = $token->getLine();
  25192. break;
  25193. }
  25194. if ($ignore) {
  25195. $this->ignoredLines[$filename][] = $token->getLine();
  25196. if ($stop) {
  25197. $ignore = false;
  25198. $stop = false;
  25199. }
  25200. }
  25201. }
  25202. $this->ignoredLines[$filename][] = $numLines + 1;
  25203. $this->ignoredLines[$filename] = array_unique(
  25204. $this->ignoredLines[$filename]
  25205. );
  25206. sort($this->ignoredLines[$filename]);
  25207. }
  25208. return $this->ignoredLines[$filename];
  25209. }
  25210. /**
  25211. * @param array $data
  25212. * @param array $linesToBeCovered
  25213. * @param array $linesToBeUsed
  25214. * @throws PHP_CodeCoverage_Exception_UnintentionallyCoveredCode
  25215. * @since Method available since Release 2.0.0
  25216. */
  25217. private function performUnintentionallyCoveredCodeCheck(array &$data, array $linesToBeCovered, array $linesToBeUsed)
  25218. {
  25219. $allowedLines = $this->getAllowedLines(
  25220. $linesToBeCovered,
  25221. $linesToBeUsed
  25222. );
  25223. $message = '';
  25224. foreach ($data as $file => $_data) {
  25225. foreach ($_data as $line => $flag) {
  25226. if ($flag == 1 &&
  25227. (!isset($allowedLines[$file]) ||
  25228. !isset($allowedLines[$file][$line]))) {
  25229. $message .= sprintf(
  25230. '- %s:%d' . PHP_EOL,
  25231. $file,
  25232. $line
  25233. );
  25234. }
  25235. }
  25236. }
  25237. if (!empty($message)) {
  25238. throw new PHP_CodeCoverage_Exception_UnintentionallyCoveredCode(
  25239. $message
  25240. );
  25241. }
  25242. }
  25243. /**
  25244. * @param array $linesToBeCovered
  25245. * @param array $linesToBeUsed
  25246. * @return array
  25247. * @since Method available since Release 2.0.0
  25248. */
  25249. private function getAllowedLines(array $linesToBeCovered, array $linesToBeUsed)
  25250. {
  25251. $allowedLines = array();
  25252. foreach (array_keys($linesToBeCovered) as $file) {
  25253. if (!isset($allowedLines[$file])) {
  25254. $allowedLines[$file] = array();
  25255. }
  25256. $allowedLines[$file] = array_merge(
  25257. $allowedLines[$file],
  25258. $linesToBeCovered[$file]
  25259. );
  25260. }
  25261. foreach (array_keys($linesToBeUsed) as $file) {
  25262. if (!isset($allowedLines[$file])) {
  25263. $allowedLines[$file] = array();
  25264. }
  25265. $allowedLines[$file] = array_merge(
  25266. $allowedLines[$file],
  25267. $linesToBeUsed[$file]
  25268. );
  25269. }
  25270. foreach (array_keys($allowedLines) as $file) {
  25271. $allowedLines[$file] = array_flip(
  25272. array_unique($allowedLines[$file])
  25273. );
  25274. }
  25275. return $allowedLines;
  25276. }
  25277. }
  25278. Copyright (c) 2004-2015 Fabien Potencier
  25279. Permission is hereby granted, free of charge, to any person obtaining a copy
  25280. of this software and associated documentation files (the "Software"), to deal
  25281. in the Software without restriction, including without limitation the rights
  25282. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  25283. copies of the Software, and to permit persons to whom the Software is furnished
  25284. to do so, subject to the following conditions:
  25285. The above copyright notice and this permission notice shall be included in all
  25286. copies or substantial portions of the Software.
  25287. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  25288. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  25289. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  25290. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  25291. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25292. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25293. THE SOFTWARE.
  25294. <?php
  25295. /*
  25296. * This file is part of the Symfony package.
  25297. *
  25298. * (c) Fabien Potencier <fabien@symfony.com>
  25299. *
  25300. * For the full copyright and license information, please view the LICENSE
  25301. * file that was distributed with this source code.
  25302. */
  25303. namespace Symfony\Component\Yaml;
  25304. use Symfony\Component\Yaml\Exception\ParseException;
  25305. use Symfony\Component\Yaml\Exception\DumpException;
  25306. /**
  25307. * Inline implements a YAML parser/dumper for the YAML inline syntax.
  25308. *
  25309. * @author Fabien Potencier <fabien@symfony.com>
  25310. */
  25311. class Inline
  25312. {
  25313. const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')';
  25314. private static $exceptionOnInvalidType = false;
  25315. private static $objectSupport = false;
  25316. private static $objectForMap = false;
  25317. /**
  25318. * Converts a YAML string to a PHP array.
  25319. *
  25320. * @param string $value A YAML string
  25321. * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
  25322. * @param bool $objectSupport true if object support is enabled, false otherwise
  25323. * @param bool $objectForMap true if maps should return a stdClass instead of array()
  25324. * @param array $references Mapping of variable names to values
  25325. *
  25326. * @return array A PHP array representing the YAML string
  25327. *
  25328. * @throws ParseException
  25329. */
  25330. public static function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false, $references = array())
  25331. {
  25332. self::$exceptionOnInvalidType = $exceptionOnInvalidType;
  25333. self::$objectSupport = $objectSupport;
  25334. self::$objectForMap = $objectForMap;
  25335. $value = trim($value);
  25336. if (0 == strlen($value)) {
  25337. return '';
  25338. }
  25339. if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
  25340. $mbEncoding = mb_internal_encoding();
  25341. mb_internal_encoding('ASCII');
  25342. }
  25343. $i = 0;
  25344. switch ($value[0]) {
  25345. case '[':
  25346. $result = self::parseSequence($value, $i, $references);
  25347. ++$i;
  25348. break;
  25349. case '{':
  25350. $result = self::parseMapping($value, $i, $references);
  25351. ++$i;
  25352. break;
  25353. default:
  25354. $result = self::parseScalar($value, null, array('"', "'"), $i, true, $references);
  25355. }
  25356. // some comments are allowed at the end
  25357. if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) {
  25358. throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)));
  25359. }
  25360. if (isset($mbEncoding)) {
  25361. mb_internal_encoding($mbEncoding);
  25362. }
  25363. return $result;
  25364. }
  25365. /**
  25366. * Dumps a given PHP variable to a YAML string.
  25367. *
  25368. * @param mixed $value The PHP variable to convert
  25369. * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
  25370. * @param bool $objectSupport true if object support is enabled, false otherwise
  25371. *
  25372. * @return string The YAML string representing the PHP array
  25373. *
  25374. * @throws DumpException When trying to dump PHP resource
  25375. */
  25376. public static function dump($value, $exceptionOnInvalidType = false, $objectSupport = false)
  25377. {
  25378. switch (true) {
  25379. case is_resource($value):
  25380. if ($exceptionOnInvalidType) {
  25381. throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value)));
  25382. }
  25383. return 'null';
  25384. case is_object($value):
  25385. if ($objectSupport) {
  25386. return '!!php/object:'.serialize($value);
  25387. }
  25388. if ($exceptionOnInvalidType) {
  25389. throw new DumpException('Object support when dumping a YAML file has been disabled.');
  25390. }
  25391. return 'null';
  25392. case is_array($value):
  25393. return self::dumpArray($value, $exceptionOnInvalidType, $objectSupport);
  25394. case null === $value:
  25395. return 'null';
  25396. case true === $value:
  25397. return 'true';
  25398. case false === $value:
  25399. return 'false';
  25400. case ctype_digit($value):
  25401. return is_string($value) ? "'$value'" : (int) $value;
  25402. case is_numeric($value):
  25403. $locale = setlocale(LC_NUMERIC, 0);
  25404. if (false !== $locale) {
  25405. setlocale(LC_NUMERIC, 'C');
  25406. }
  25407. if (is_float($value)) {
  25408. $repr = (string) $value;
  25409. if (is_infinite($value)) {
  25410. $repr = str_ireplace('INF', '.Inf', $repr);
  25411. } elseif (floor($value) == $value && $repr == $value) {
  25412. // Preserve float data type since storing a whole number will result in integer value.
  25413. $repr = '!!float '.$repr;
  25414. }
  25415. } else {
  25416. $repr = is_string($value) ? "'$value'" : (string) $value;
  25417. }
  25418. if (false !== $locale) {
  25419. setlocale(LC_NUMERIC, $locale);
  25420. }
  25421. return $repr;
  25422. case '' == $value:
  25423. return "''";
  25424. case Escaper::requiresDoubleQuoting($value):
  25425. return Escaper::escapeWithDoubleQuotes($value);
  25426. case Escaper::requiresSingleQuoting($value):
  25427. case preg_match(self::getHexRegex(), $value):
  25428. case preg_match(self::getTimestampRegex(), $value):
  25429. return Escaper::escapeWithSingleQuotes($value);
  25430. default:
  25431. return $value;
  25432. }
  25433. }
  25434. /**
  25435. * Dumps a PHP array to a YAML string.
  25436. *
  25437. * @param array $value The PHP array to dump
  25438. * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
  25439. * @param bool $objectSupport true if object support is enabled, false otherwise
  25440. *
  25441. * @return string The YAML string representing the PHP array
  25442. */
  25443. private static function dumpArray($value, $exceptionOnInvalidType, $objectSupport)
  25444. {
  25445. // array
  25446. $keys = array_keys($value);
  25447. $keysCount = count($keys);
  25448. if ((1 === $keysCount && '0' == $keys[0])
  25449. || ($keysCount > 1 && array_reduce($keys, function ($v, $w) { return (int) $v + $w; }, 0) === $keysCount * ($keysCount - 1) / 2)
  25450. ) {
  25451. $output = array();
  25452. foreach ($value as $val) {
  25453. $output[] = self::dump($val, $exceptionOnInvalidType, $objectSupport);
  25454. }
  25455. return sprintf('[%s]', implode(', ', $output));
  25456. }
  25457. // mapping
  25458. $output = array();
  25459. foreach ($value as $key => $val) {
  25460. $output[] = sprintf('%s: %s', self::dump($key, $exceptionOnInvalidType, $objectSupport), self::dump($val, $exceptionOnInvalidType, $objectSupport));
  25461. }
  25462. return sprintf('{ %s }', implode(', ', $output));
  25463. }
  25464. /**
  25465. * Parses a scalar to a YAML string.
  25466. *
  25467. * @param string $scalar
  25468. * @param string $delimiters
  25469. * @param array $stringDelimiters
  25470. * @param int &$i
  25471. * @param bool $evaluate
  25472. * @param array $references
  25473. *
  25474. * @return string A YAML string
  25475. *
  25476. * @throws ParseException When malformed inline YAML string is parsed
  25477. */
  25478. public static function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true, $references = array())
  25479. {
  25480. if (in_array($scalar[$i], $stringDelimiters)) {
  25481. // quoted scalar
  25482. $output = self::parseQuotedScalar($scalar, $i);
  25483. if (null !== $delimiters) {
  25484. $tmp = ltrim(substr($scalar, $i), ' ');
  25485. if (!in_array($tmp[0], $delimiters)) {
  25486. throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i)));
  25487. }
  25488. }
  25489. } else {
  25490. // "normal" string
  25491. if (!$delimiters) {
  25492. $output = substr($scalar, $i);
  25493. $i += strlen($output);
  25494. // remove comments
  25495. if (false !== $strpos = strpos($output, ' #')) {
  25496. $output = rtrim(substr($output, 0, $strpos));
  25497. }
  25498. } elseif (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) {
  25499. $output = $match[1];
  25500. $i += strlen($output);
  25501. } else {
  25502. throw new ParseException(sprintf('Malformed inline YAML string (%s).', $scalar));
  25503. }
  25504. if ($evaluate) {
  25505. $output = self::evaluateScalar($output, $references);
  25506. }
  25507. }
  25508. return $output;
  25509. }
  25510. /**
  25511. * Parses a quoted scalar to YAML.
  25512. *
  25513. * @param string $scalar
  25514. * @param int &$i
  25515. *
  25516. * @return string A YAML string
  25517. *
  25518. * @throws ParseException When malformed inline YAML string is parsed
  25519. */
  25520. private static function parseQuotedScalar($scalar, &$i)
  25521. {
  25522. if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) {
  25523. throw new ParseException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i)));
  25524. }
  25525. $output = substr($match[0], 1, strlen($match[0]) - 2);
  25526. $unescaper = new Unescaper();
  25527. if ('"' == $scalar[$i]) {
  25528. $output = $unescaper->unescapeDoubleQuotedString($output);
  25529. } else {
  25530. $output = $unescaper->unescapeSingleQuotedString($output);
  25531. }
  25532. $i += strlen($match[0]);
  25533. return $output;
  25534. }
  25535. /**
  25536. * Parses a sequence to a YAML string.
  25537. *
  25538. * @param string $sequence
  25539. * @param int &$i
  25540. * @param array $references
  25541. *
  25542. * @return string A YAML string
  25543. *
  25544. * @throws ParseException When malformed inline YAML string is parsed
  25545. */
  25546. private static function parseSequence($sequence, &$i = 0, $references = array())
  25547. {
  25548. $output = array();
  25549. $len = strlen($sequence);
  25550. ++$i;
  25551. // [foo, bar, ...]
  25552. while ($i < $len) {
  25553. switch ($sequence[$i]) {
  25554. case '[':
  25555. // nested sequence
  25556. $output[] = self::parseSequence($sequence, $i, $references);
  25557. break;
  25558. case '{':
  25559. // nested mapping
  25560. $output[] = self::parseMapping($sequence, $i, $references);
  25561. break;
  25562. case ']':
  25563. return $output;
  25564. case ',':
  25565. case ' ':
  25566. break;
  25567. default:
  25568. $isQuoted = in_array($sequence[$i], array('"', "'"));
  25569. $value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i, true, $references);
  25570. // the value can be an array if a reference has been resolved to an array var
  25571. if (!is_array($value) && !$isQuoted && false !== strpos($value, ': ')) {
  25572. // embedded mapping?
  25573. try {
  25574. $pos = 0;
  25575. $value = self::parseMapping('{'.$value.'}', $pos, $references);
  25576. } catch (\InvalidArgumentException $e) {
  25577. // no, it's not
  25578. }
  25579. }
  25580. $output[] = $value;
  25581. --$i;
  25582. }
  25583. ++$i;
  25584. }
  25585. throw new ParseException(sprintf('Malformed inline YAML string %s', $sequence));
  25586. }
  25587. /**
  25588. * Parses a mapping to a YAML string.
  25589. *
  25590. * @param string $mapping
  25591. * @param int &$i
  25592. * @param array $references
  25593. *
  25594. * @return string A YAML string
  25595. *
  25596. * @throws ParseException When malformed inline YAML string is parsed
  25597. */
  25598. private static function parseMapping($mapping, &$i = 0, $references = array())
  25599. {
  25600. $output = array();
  25601. $len = strlen($mapping);
  25602. ++$i;
  25603. // {foo: bar, bar:foo, ...}
  25604. while ($i < $len) {
  25605. switch ($mapping[$i]) {
  25606. case ' ':
  25607. case ',':
  25608. ++$i;
  25609. continue 2;
  25610. case '}':
  25611. if (self::$objectForMap) {
  25612. return (object) $output;
  25613. }
  25614. return $output;
  25615. }
  25616. // key
  25617. $key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false);
  25618. // value
  25619. $done = false;
  25620. while ($i < $len) {
  25621. switch ($mapping[$i]) {
  25622. case '[':
  25623. // nested sequence
  25624. $value = self::parseSequence($mapping, $i, $references);
  25625. // Spec: Keys MUST be unique; first one wins.
  25626. // Parser cannot abort this mapping earlier, since lines
  25627. // are processed sequentially.
  25628. if (!isset($output[$key])) {
  25629. $output[$key] = $value;
  25630. }
  25631. $done = true;
  25632. break;
  25633. case '{':
  25634. // nested mapping
  25635. $value = self::parseMapping($mapping, $i, $references);
  25636. // Spec: Keys MUST be unique; first one wins.
  25637. // Parser cannot abort this mapping earlier, since lines
  25638. // are processed sequentially.
  25639. if (!isset($output[$key])) {
  25640. $output[$key] = $value;
  25641. }
  25642. $done = true;
  25643. break;
  25644. case ':':
  25645. case ' ':
  25646. break;
  25647. default:
  25648. $value = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i, true, $references);
  25649. // Spec: Keys MUST be unique; first one wins.
  25650. // Parser cannot abort this mapping earlier, since lines
  25651. // are processed sequentially.
  25652. if (!isset($output[$key])) {
  25653. $output[$key] = $value;
  25654. }
  25655. $done = true;
  25656. --$i;
  25657. }
  25658. ++$i;
  25659. if ($done) {
  25660. continue 2;
  25661. }
  25662. }
  25663. }
  25664. throw new ParseException(sprintf('Malformed inline YAML string %s', $mapping));
  25665. }
  25666. /**
  25667. * Evaluates scalars and replaces magic values.
  25668. *
  25669. * @param string $scalar
  25670. * @param array $references
  25671. *
  25672. * @return string A YAML string
  25673. *
  25674. * @throws ParseException when object parsing support was disabled and the parser detected a PHP object or when a reference could not be resolved
  25675. */
  25676. private static function evaluateScalar($scalar, $references = array())
  25677. {
  25678. $scalar = trim($scalar);
  25679. $scalarLower = strtolower($scalar);
  25680. if (0 === strpos($scalar, '*')) {
  25681. if (false !== $pos = strpos($scalar, '#')) {
  25682. $value = substr($scalar, 1, $pos - 2);
  25683. } else {
  25684. $value = substr($scalar, 1);
  25685. }
  25686. // an unquoted *
  25687. if (false === $value || '' === $value) {
  25688. throw new ParseException('A reference must contain at least one character.');
  25689. }
  25690. if (!array_key_exists($value, $references)) {
  25691. throw new ParseException(sprintf('Reference "%s" does not exist.', $value));
  25692. }
  25693. return $references[$value];
  25694. }
  25695. switch (true) {
  25696. case 'null' === $scalarLower:
  25697. case '' === $scalar:
  25698. case '~' === $scalar:
  25699. return;
  25700. case 'true' === $scalarLower:
  25701. return true;
  25702. case 'false' === $scalarLower:
  25703. return false;
  25704. // Optimise for returning strings.
  25705. case $scalar[0] === '+' || $scalar[0] === '-' || $scalar[0] === '.' || $scalar[0] === '!' || is_numeric($scalar[0]):
  25706. switch (true) {
  25707. case 0 === strpos($scalar, '!str'):
  25708. return (string) substr($scalar, 5);
  25709. case 0 === strpos($scalar, '! '):
  25710. return (int) self::parseScalar(substr($scalar, 2));
  25711. case 0 === strpos($scalar, '!!php/object:'):
  25712. if (self::$objectSupport) {
  25713. return unserialize(substr($scalar, 13));
  25714. }
  25715. if (self::$exceptionOnInvalidType) {
  25716. throw new ParseException('Object support when parsing a YAML file has been disabled.');
  25717. }
  25718. return;
  25719. case 0 === strpos($scalar, '!!float '):
  25720. return (float) substr($scalar, 8);
  25721. case ctype_digit($scalar):
  25722. $raw = $scalar;
  25723. $cast = (int) $scalar;
  25724. return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
  25725. case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)):
  25726. $raw = $scalar;
  25727. $cast = (int) $scalar;
  25728. return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw === (string) $cast) ? $cast : $raw);
  25729. case is_numeric($scalar):
  25730. case preg_match(self::getHexRegex(), $scalar):
  25731. return '0x' === $scalar[0].$scalar[1] ? hexdec($scalar) : (float) $scalar;
  25732. case '.inf' === $scalarLower:
  25733. case '.nan' === $scalarLower:
  25734. return -log(0);
  25735. case '-.inf' === $scalarLower:
  25736. return log(0);
  25737. case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar):
  25738. return (float) str_replace(',', '', $scalar);
  25739. case preg_match(self::getTimestampRegex(), $scalar):
  25740. return strtotime($scalar);
  25741. }
  25742. default:
  25743. return (string) $scalar;
  25744. }
  25745. }
  25746. /**
  25747. * Gets a regex that matches a YAML date.
  25748. *
  25749. * @return string The regular expression
  25750. *
  25751. * @see http://www.yaml.org/spec/1.2/spec.html#id2761573
  25752. */
  25753. private static function getTimestampRegex()
  25754. {
  25755. return <<<EOF
  25756. ~^
  25757. (?P<year>[0-9][0-9][0-9][0-9])
  25758. -(?P<month>[0-9][0-9]?)
  25759. -(?P<day>[0-9][0-9]?)
  25760. (?:(?:[Tt]|[ \t]+)
  25761. (?P<hour>[0-9][0-9]?)
  25762. :(?P<minute>[0-9][0-9])
  25763. :(?P<second>[0-9][0-9])
  25764. (?:\.(?P<fraction>[0-9]*))?
  25765. (?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
  25766. (?::(?P<tz_minute>[0-9][0-9]))?))?)?
  25767. $~x
  25768. EOF;
  25769. }
  25770. /**
  25771. * Gets a regex that matches a YAML number in hexadecimal notation.
  25772. *
  25773. * @return string
  25774. */
  25775. private static function getHexRegex()
  25776. {
  25777. return '~^0x[0-9a-f]++$~i';
  25778. }
  25779. }
  25780. <?php
  25781. /*
  25782. * This file is part of the Symfony package.
  25783. *
  25784. * (c) Fabien Potencier <fabien@symfony.com>
  25785. *
  25786. * For the full copyright and license information, please view the LICENSE
  25787. * file that was distributed with this source code.
  25788. */
  25789. namespace Symfony\Component\Yaml;
  25790. /**
  25791. * Unescaper encapsulates unescaping rules for single and double-quoted
  25792. * YAML strings.
  25793. *
  25794. * @author Matthew Lewinski <matthew@lewinski.org>
  25795. */
  25796. class Unescaper
  25797. {
  25798. /**
  25799. * Parser and Inline assume UTF-8 encoding, so escaped Unicode characters
  25800. * must be converted to that encoding.
  25801. *
  25802. * @deprecated since version 2.5, to be removed in 3.0
  25803. * @internal
  25804. */
  25805. const ENCODING = 'UTF-8';
  25806. /**
  25807. * Regex fragment that matches an escaped character in a double quoted string.
  25808. */
  25809. const REGEX_ESCAPED_CHARACTER = "\\\\([0abt\tnvfre \\\"\\/\\\\N_LP]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})";
  25810. /**
  25811. * Unescapes a single quoted string.
  25812. *
  25813. * @param string $value A single quoted string.
  25814. *
  25815. * @return string The unescaped string.
  25816. */
  25817. public function unescapeSingleQuotedString($value)
  25818. {
  25819. return str_replace('\'\'', '\'', $value);
  25820. }
  25821. /**
  25822. * Unescapes a double quoted string.
  25823. *
  25824. * @param string $value A double quoted string.
  25825. *
  25826. * @return string The unescaped string.
  25827. */
  25828. public function unescapeDoubleQuotedString($value)
  25829. {
  25830. $self = $this;
  25831. $callback = function ($match) use ($self) {
  25832. return $self->unescapeCharacter($match[0]);
  25833. };
  25834. // evaluate the string
  25835. return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value);
  25836. }
  25837. /**
  25838. * Unescapes a character that was found in a double-quoted string.
  25839. *
  25840. * @param string $value An escaped character
  25841. *
  25842. * @return string The unescaped character
  25843. */
  25844. public function unescapeCharacter($value)
  25845. {
  25846. switch ($value{1}) {
  25847. case '0':
  25848. return "\x0";
  25849. case 'a':
  25850. return "\x7";
  25851. case 'b':
  25852. return "\x8";
  25853. case 't':
  25854. return "\t";
  25855. case "\t":
  25856. return "\t";
  25857. case 'n':
  25858. return "\n";
  25859. case 'v':
  25860. return "\xB";
  25861. case 'f':
  25862. return "\xC";
  25863. case 'r':
  25864. return "\r";
  25865. case 'e':
  25866. return "\x1B";
  25867. case ' ':
  25868. return ' ';
  25869. case '"':
  25870. return '"';
  25871. case '/':
  25872. return '/';
  25873. case '\\':
  25874. return '\\';
  25875. case 'N':
  25876. // U+0085 NEXT LINE
  25877. return "\xC2\x85";
  25878. case '_':
  25879. // U+00A0 NO-BREAK SPACE
  25880. return "\xC2\xA0";
  25881. case 'L':
  25882. // U+2028 LINE SEPARATOR
  25883. return "\xE2\x80\xA8";
  25884. case 'P':
  25885. // U+2029 PARAGRAPH SEPARATOR
  25886. return "\xE2\x80\xA9";
  25887. case 'x':
  25888. return self::utf8chr(hexdec(substr($value, 2, 2)));
  25889. case 'u':
  25890. return self::utf8chr(hexdec(substr($value, 2, 4)));
  25891. case 'U':
  25892. return self::utf8chr(hexdec(substr($value, 2, 8)));
  25893. }
  25894. }
  25895. /**
  25896. * Get the UTF-8 character for the given code point.
  25897. *
  25898. * @param int $c The unicode code point
  25899. *
  25900. * @return string The corresponding UTF-8 character
  25901. */
  25902. private static function utf8chr($c)
  25903. {
  25904. if (0x80 > $c %= 0x200000) {
  25905. return chr($c);
  25906. }
  25907. if (0x800 > $c) {
  25908. return chr(0xC0 | $c >> 6).chr(0x80 | $c & 0x3F);
  25909. }
  25910. if (0x10000 > $c) {
  25911. return chr(0xE0 | $c >> 12).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
  25912. }
  25913. return chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
  25914. }
  25915. }
  25916. <?php
  25917. /*
  25918. * This file is part of the Symfony package.
  25919. *
  25920. * (c) Fabien Potencier <fabien@symfony.com>
  25921. *
  25922. * For the full copyright and license information, please view the LICENSE
  25923. * file that was distributed with this source code.
  25924. */
  25925. namespace Symfony\Component\Yaml;
  25926. use Symfony\Component\Yaml\Exception\ParseException;
  25927. /**
  25928. * Yaml offers convenience methods to load and dump YAML.
  25929. *
  25930. * @author Fabien Potencier <fabien@symfony.com>
  25931. *
  25932. * @api
  25933. */
  25934. class Yaml
  25935. {
  25936. /**
  25937. * Parses YAML into a PHP array.
  25938. *
  25939. * The parse method, when supplied with a YAML stream (string or file),
  25940. * will do its best to convert YAML in a file into a PHP array.
  25941. *
  25942. * Usage:
  25943. * <code>
  25944. * $array = Yaml::parse(file_get_contents('config.yml'));
  25945. * print_r($array);
  25946. * </code>
  25947. *
  25948. * As this method accepts both plain strings and file names as an input,
  25949. * you must validate the input before calling this method. Passing a file
  25950. * as an input is a deprecated feature and will be removed in 3.0.
  25951. *
  25952. * Note: the ability to pass file names to the Yaml::parse method is deprecated since version 2.2 and will be removed in 3.0. Pass the YAML contents of the file instead.
  25953. *
  25954. * @param string $input Path to a YAML file or a string containing YAML
  25955. * @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
  25956. * @param bool $objectSupport True if object support is enabled, false otherwise
  25957. * @param bool $objectForMap True if maps should return a stdClass instead of array()
  25958. *
  25959. * @return array The YAML converted to a PHP array
  25960. *
  25961. * @throws ParseException If the YAML is not valid
  25962. *
  25963. * @api
  25964. */
  25965. public static function parse($input, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false)
  25966. {
  25967. // if input is a file, process it
  25968. $file = '';
  25969. if (strpos($input, "\n") === false && is_file($input)) {
  25970. @trigger_error('The ability to pass file names to the '.__METHOD__.' method is deprecated since version 2.2 and will be removed in 3.0. Pass the YAML contents of the file instead.', E_USER_DEPRECATED);
  25971. if (false === is_readable($input)) {
  25972. throw new ParseException(sprintf('Unable to parse "%s" as the file is not readable.', $input));
  25973. }
  25974. $file = $input;
  25975. $input = file_get_contents($file);
  25976. }
  25977. $yaml = new Parser();
  25978. try {
  25979. return $yaml->parse($input, $exceptionOnInvalidType, $objectSupport, $objectForMap);
  25980. } catch (ParseException $e) {
  25981. if ($file) {
  25982. $e->setParsedFile($file);
  25983. }
  25984. throw $e;
  25985. }
  25986. }
  25987. /**
  25988. * Dumps a PHP array to a YAML string.
  25989. *
  25990. * The dump method, when supplied with an array, will do its best
  25991. * to convert the array into friendly YAML.
  25992. *
  25993. * @param array $array PHP array
  25994. * @param int $inline The level where you switch to inline YAML
  25995. * @param int $indent The amount of spaces to use for indentation of nested nodes.
  25996. * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
  25997. * @param bool $objectSupport true if object support is enabled, false otherwise
  25998. *
  25999. * @return string A YAML string representing the original PHP array
  26000. *
  26001. * @api
  26002. */
  26003. public static function dump($array, $inline = 2, $indent = 4, $exceptionOnInvalidType = false, $objectSupport = false)
  26004. {
  26005. $yaml = new Dumper();
  26006. $yaml->setIndentation($indent);
  26007. return $yaml->dump($array, $inline, 0, $exceptionOnInvalidType, $objectSupport);
  26008. }
  26009. }
  26010. <?php
  26011. /*
  26012. * This file is part of the Symfony package.
  26013. *
  26014. * (c) Fabien Potencier <fabien@symfony.com>
  26015. *
  26016. * For the full copyright and license information, please view the LICENSE
  26017. * file that was distributed with this source code.
  26018. */
  26019. namespace Symfony\Component\Yaml\Exception;
  26020. /**
  26021. * Exception class thrown when an error occurs during parsing.
  26022. *
  26023. * @author Fabien Potencier <fabien@symfony.com>
  26024. *
  26025. * @api
  26026. */
  26027. class ParseException extends RuntimeException
  26028. {
  26029. private $parsedFile;
  26030. private $parsedLine;
  26031. private $snippet;
  26032. private $rawMessage;
  26033. /**
  26034. * Constructor.
  26035. *
  26036. * @param string $message The error message
  26037. * @param int $parsedLine The line where the error occurred
  26038. * @param int $snippet The snippet of code near the problem
  26039. * @param string $parsedFile The file name where the error occurred
  26040. * @param \Exception $previous The previous exception
  26041. */
  26042. public function __construct($message, $parsedLine = -1, $snippet = null, $parsedFile = null, \Exception $previous = null)
  26043. {
  26044. $this->parsedFile = $parsedFile;
  26045. $this->parsedLine = $parsedLine;
  26046. $this->snippet = $snippet;
  26047. $this->rawMessage = $message;
  26048. $this->updateRepr();
  26049. parent::__construct($this->message, 0, $previous);
  26050. }
  26051. /**
  26052. * Gets the snippet of code near the error.
  26053. *
  26054. * @return string The snippet of code
  26055. */
  26056. public function getSnippet()
  26057. {
  26058. return $this->snippet;
  26059. }
  26060. /**
  26061. * Sets the snippet of code near the error.
  26062. *
  26063. * @param string $snippet The code snippet
  26064. */
  26065. public function setSnippet($snippet)
  26066. {
  26067. $this->snippet = $snippet;
  26068. $this->updateRepr();
  26069. }
  26070. /**
  26071. * Gets the filename where the error occurred.
  26072. *
  26073. * This method returns null if a string is parsed.
  26074. *
  26075. * @return string The filename
  26076. */
  26077. public function getParsedFile()
  26078. {
  26079. return $this->parsedFile;
  26080. }
  26081. /**
  26082. * Sets the filename where the error occurred.
  26083. *
  26084. * @param string $parsedFile The filename
  26085. */
  26086. public function setParsedFile($parsedFile)
  26087. {
  26088. $this->parsedFile = $parsedFile;
  26089. $this->updateRepr();
  26090. }
  26091. /**
  26092. * Gets the line where the error occurred.
  26093. *
  26094. * @return int The file line
  26095. */
  26096. public function getParsedLine()
  26097. {
  26098. return $this->parsedLine;
  26099. }
  26100. /**
  26101. * Sets the line where the error occurred.
  26102. *
  26103. * @param int $parsedLine The file line
  26104. */
  26105. public function setParsedLine($parsedLine)
  26106. {
  26107. $this->parsedLine = $parsedLine;
  26108. $this->updateRepr();
  26109. }
  26110. private function updateRepr()
  26111. {
  26112. $this->message = $this->rawMessage;
  26113. $dot = false;
  26114. if ('.' === substr($this->message, -1)) {
  26115. $this->message = substr($this->message, 0, -1);
  26116. $dot = true;
  26117. }
  26118. if (null !== $this->parsedFile) {
  26119. if (PHP_VERSION_ID >= 50400) {
  26120. $jsonOptions = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
  26121. } else {
  26122. $jsonOptions = 0;
  26123. }
  26124. $this->message .= sprintf(' in %s', json_encode($this->parsedFile, $jsonOptions));
  26125. }
  26126. if ($this->parsedLine >= 0) {
  26127. $this->message .= sprintf(' at line %d', $this->parsedLine);
  26128. }
  26129. if ($this->snippet) {
  26130. $this->message .= sprintf(' (near "%s")', $this->snippet);
  26131. }
  26132. if ($dot) {
  26133. $this->message .= '.';
  26134. }
  26135. }
  26136. }
  26137. <?php
  26138. /*
  26139. * This file is part of the Symfony package.
  26140. *
  26141. * (c) Fabien Potencier <fabien@symfony.com>
  26142. *
  26143. * For the full copyright and license information, please view the LICENSE
  26144. * file that was distributed with this source code.
  26145. */
  26146. namespace Symfony\Component\Yaml\Exception;
  26147. /**
  26148. * Exception class thrown when an error occurs during dumping.
  26149. *
  26150. * @author Fabien Potencier <fabien@symfony.com>
  26151. *
  26152. * @api
  26153. */
  26154. class DumpException extends RuntimeException
  26155. {
  26156. }
  26157. <?php
  26158. /*
  26159. * This file is part of the Symfony package.
  26160. *
  26161. * (c) Fabien Potencier <fabien@symfony.com>
  26162. *
  26163. * For the full copyright and license information, please view the LICENSE
  26164. * file that was distributed with this source code.
  26165. */
  26166. namespace Symfony\Component\Yaml\Exception;
  26167. /**
  26168. * Exception class thrown when an error occurs during parsing.
  26169. *
  26170. * @author Romain Neutron <imprec@gmail.com>
  26171. *
  26172. * @api
  26173. */
  26174. class RuntimeException extends \RuntimeException implements ExceptionInterface
  26175. {
  26176. }
  26177. <?php
  26178. /*
  26179. * This file is part of the Symfony package.
  26180. *
  26181. * (c) Fabien Potencier <fabien@symfony.com>
  26182. *
  26183. * For the full copyright and license information, please view the LICENSE
  26184. * file that was distributed with this source code.
  26185. */
  26186. namespace Symfony\Component\Yaml\Exception;
  26187. /**
  26188. * Exception interface for all exceptions thrown by the component.
  26189. *
  26190. * @author Fabien Potencier <fabien@symfony.com>
  26191. *
  26192. * @api
  26193. */
  26194. interface ExceptionInterface
  26195. {
  26196. }
  26197. <?php
  26198. /*
  26199. * This file is part of the Symfony package.
  26200. *
  26201. * (c) Fabien Potencier <fabien@symfony.com>
  26202. *
  26203. * For the full copyright and license information, please view the LICENSE
  26204. * file that was distributed with this source code.
  26205. */
  26206. namespace Symfony\Component\Yaml;
  26207. use Symfony\Component\Yaml\Exception\ParseException;
  26208. /**
  26209. * Parser parses YAML strings to convert them to PHP arrays.
  26210. *
  26211. * @author Fabien Potencier <fabien@symfony.com>
  26212. */
  26213. class Parser
  26214. {
  26215. const FOLDED_SCALAR_PATTERN = '(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?';
  26216. private $offset = 0;
  26217. private $lines = array();
  26218. private $currentLineNb = -1;
  26219. private $currentLine = '';
  26220. private $refs = array();
  26221. /**
  26222. * Constructor.
  26223. *
  26224. * @param int $offset The offset of YAML document (used for line numbers in error messages)
  26225. */
  26226. public function __construct($offset = 0)
  26227. {
  26228. $this->offset = $offset;
  26229. }
  26230. /**
  26231. * Parses a YAML string to a PHP value.
  26232. *
  26233. * @param string $value A YAML string
  26234. * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
  26235. * @param bool $objectSupport true if object support is enabled, false otherwise
  26236. * @param bool $objectForMap true if maps should return a stdClass instead of array()
  26237. *
  26238. * @return mixed A PHP value
  26239. *
  26240. * @throws ParseException If the YAML is not valid
  26241. */
  26242. public function parse($value, $exceptionOnInvalidType = false, $objectSupport = false, $objectForMap = false)
  26243. {
  26244. if (!preg_match('//u', $value)) {
  26245. throw new ParseException('The YAML value does not appear to be valid UTF-8.');
  26246. }
  26247. $this->currentLineNb = -1;
  26248. $this->currentLine = '';
  26249. $value = $this->cleanup($value);
  26250. $this->lines = explode("\n", $value);
  26251. if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
  26252. $mbEncoding = mb_internal_encoding();
  26253. mb_internal_encoding('UTF-8');
  26254. }
  26255. $data = array();
  26256. $context = null;
  26257. $allowOverwrite = false;
  26258. while ($this->moveToNextLine()) {
  26259. if ($this->isCurrentLineEmpty()) {
  26260. continue;
  26261. }
  26262. // tab?
  26263. if ("\t" === $this->currentLine[0]) {
  26264. throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
  26265. }
  26266. $isRef = $mergeNode = false;
  26267. if (preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) {
  26268. if ($context && 'mapping' == $context) {
  26269. throw new ParseException('You cannot define a sequence item when in a mapping');
  26270. }
  26271. $context = 'sequence';
  26272. if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
  26273. $isRef = $matches['ref'];
  26274. $values['value'] = $matches['value'];
  26275. }
  26276. // array
  26277. if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
  26278. $c = $this->getRealCurrentLineNb() + 1;
  26279. $parser = new self($c);
  26280. $parser->refs = &$this->refs;
  26281. $data[] = $parser->parse($this->getNextEmbedBlock(null, true), $exceptionOnInvalidType, $objectSupport, $objectForMap);
  26282. } else {
  26283. if (isset($values['leadspaces'])
  26284. && preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $values['value'], $matches)
  26285. ) {
  26286. // this is a compact notation element, add to next block and parse
  26287. $c = $this->getRealCurrentLineNb();
  26288. $parser = new self($c);
  26289. $parser->refs = &$this->refs;
  26290. $block = $values['value'];
  26291. if ($this->isNextLineIndented()) {
  26292. $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + strlen($values['leadspaces']) + 1);
  26293. }
  26294. $data[] = $parser->parse($block, $exceptionOnInvalidType, $objectSupport, $objectForMap);
  26295. } else {
  26296. $data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap);
  26297. }
  26298. }
  26299. } elseif (preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values) && (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'")))) {
  26300. if ($context && 'sequence' == $context) {
  26301. throw new ParseException('You cannot define a mapping item when in a sequence');
  26302. }
  26303. $context = 'mapping';
  26304. // force correct settings
  26305. Inline::parse(null, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
  26306. try {
  26307. $key = Inline::parseScalar($values['key']);
  26308. } catch (ParseException $e) {
  26309. $e->setParsedLine($this->getRealCurrentLineNb() + 1);
  26310. $e->setSnippet($this->currentLine);
  26311. throw $e;
  26312. }
  26313. if ('<<' === $key) {
  26314. $mergeNode = true;
  26315. $allowOverwrite = true;
  26316. if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
  26317. $refName = substr($values['value'], 1);
  26318. if (!array_key_exists($refName, $this->refs)) {
  26319. throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine);
  26320. }
  26321. $refValue = $this->refs[$refName];
  26322. if (!is_array($refValue)) {
  26323. throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
  26324. }
  26325. foreach ($refValue as $key => $value) {
  26326. if (!isset($data[$key])) {
  26327. $data[$key] = $value;
  26328. }
  26329. }
  26330. } else {
  26331. if (isset($values['value']) && $values['value'] !== '') {
  26332. $value = $values['value'];
  26333. } else {
  26334. $value = $this->getNextEmbedBlock();
  26335. }
  26336. $c = $this->getRealCurrentLineNb() + 1;
  26337. $parser = new self($c);
  26338. $parser->refs = &$this->refs;
  26339. $parsed = $parser->parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap);
  26340. if (!is_array($parsed)) {
  26341. throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
  26342. }
  26343. if (isset($parsed[0])) {
  26344. // If the value associated with the merge key is a sequence, then this sequence is expected to contain mapping nodes
  26345. // and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier
  26346. // in the sequence override keys specified in later mapping nodes.
  26347. foreach ($parsed as $parsedItem) {
  26348. if (!is_array($parsedItem)) {
  26349. throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem);
  26350. }
  26351. foreach ($parsedItem as $key => $value) {
  26352. if (!isset($data[$key])) {
  26353. $data[$key] = $value;
  26354. }
  26355. }
  26356. }
  26357. } else {
  26358. // If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the
  26359. // current mapping, unless the key already exists in it.
  26360. foreach ($parsed as $key => $value) {
  26361. if (!isset($data[$key])) {
  26362. $data[$key] = $value;
  26363. }
  26364. }
  26365. }
  26366. }
  26367. } elseif (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
  26368. $isRef = $matches['ref'];
  26369. $values['value'] = $matches['value'];
  26370. }
  26371. if ($mergeNode) {
  26372. // Merge keys
  26373. } elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
  26374. // hash
  26375. // if next line is less indented or equal, then it means that the current value is null
  26376. if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {
  26377. // Spec: Keys MUST be unique; first one wins.
  26378. // But overwriting is allowed when a merge node is used in current block.
  26379. if ($allowOverwrite || !isset($data[$key])) {
  26380. $data[$key] = null;
  26381. }
  26382. } else {
  26383. $c = $this->getRealCurrentLineNb() + 1;
  26384. $parser = new self($c);
  26385. $parser->refs = &$this->refs;
  26386. $value = $parser->parse($this->getNextEmbedBlock(), $exceptionOnInvalidType, $objectSupport, $objectForMap);
  26387. // Spec: Keys MUST be unique; first one wins.
  26388. // But overwriting is allowed when a merge node is used in current block.
  26389. if ($allowOverwrite || !isset($data[$key])) {
  26390. $data[$key] = $value;
  26391. }
  26392. }
  26393. } else {
  26394. $value = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap);
  26395. // Spec: Keys MUST be unique; first one wins.
  26396. // But overwriting is allowed when a merge node is used in current block.
  26397. if ($allowOverwrite || !isset($data[$key])) {
  26398. $data[$key] = $value;
  26399. }
  26400. }
  26401. } else {
  26402. // multiple documents are not supported
  26403. if ('---' === $this->currentLine) {
  26404. throw new ParseException('Multiple documents are not supported.');
  26405. }
  26406. // 1-liner optionally followed by newline(s)
  26407. if ($this->lines[0] === trim($value)) {
  26408. try {
  26409. $value = Inline::parse($this->lines[0], $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
  26410. } catch (ParseException $e) {
  26411. $e->setParsedLine($this->getRealCurrentLineNb() + 1);
  26412. $e->setSnippet($this->currentLine);
  26413. throw $e;
  26414. }
  26415. if (is_array($value)) {
  26416. $first = reset($value);
  26417. if (is_string($first) && 0 === strpos($first, '*')) {
  26418. $data = array();
  26419. foreach ($value as $alias) {
  26420. $data[] = $this->refs[substr($alias, 1)];
  26421. }
  26422. $value = $data;
  26423. }
  26424. }
  26425. if (isset($mbEncoding)) {
  26426. mb_internal_encoding($mbEncoding);
  26427. }
  26428. return $value;
  26429. }
  26430. switch (preg_last_error()) {
  26431. case PREG_INTERNAL_ERROR:
  26432. $error = 'Internal PCRE error.';
  26433. break;
  26434. case PREG_BACKTRACK_LIMIT_ERROR:
  26435. $error = 'pcre.backtrack_limit reached.';
  26436. break;
  26437. case PREG_RECURSION_LIMIT_ERROR:
  26438. $error = 'pcre.recursion_limit reached.';
  26439. break;
  26440. case PREG_BAD_UTF8_ERROR:
  26441. $error = 'Malformed UTF-8 data.';
  26442. break;
  26443. case PREG_BAD_UTF8_OFFSET_ERROR:
  26444. $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.';
  26445. break;
  26446. default:
  26447. $error = 'Unable to parse.';
  26448. }
  26449. throw new ParseException($error, $this->getRealCurrentLineNb() + 1, $this->currentLine);
  26450. }
  26451. if ($isRef) {
  26452. $this->refs[$isRef] = end($data);
  26453. }
  26454. }
  26455. if (isset($mbEncoding)) {
  26456. mb_internal_encoding($mbEncoding);
  26457. }
  26458. return empty($data) ? null : $data;
  26459. }
  26460. /**
  26461. * Returns the current line number (takes the offset into account).
  26462. *
  26463. * @return int The current line number
  26464. */
  26465. private function getRealCurrentLineNb()
  26466. {
  26467. return $this->currentLineNb + $this->offset;
  26468. }
  26469. /**
  26470. * Returns the current line indentation.
  26471. *
  26472. * @return int The current line indentation
  26473. */
  26474. private function getCurrentLineIndentation()
  26475. {
  26476. return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' '));
  26477. }
  26478. /**
  26479. * Returns the next embed block of YAML.
  26480. *
  26481. * @param int $indentation The indent level at which the block is to be read, or null for default
  26482. * @param bool $inSequence True if the enclosing data structure is a sequence
  26483. *
  26484. * @return string A YAML string
  26485. *
  26486. * @throws ParseException When indentation problem are detected
  26487. */
  26488. private function getNextEmbedBlock($indentation = null, $inSequence = false)
  26489. {
  26490. $oldLineIndentation = $this->getCurrentLineIndentation();
  26491. if (!$this->moveToNextLine()) {
  26492. return;
  26493. }
  26494. if (null === $indentation) {
  26495. $newIndent = $this->getCurrentLineIndentation();
  26496. $unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem($this->currentLine);
  26497. if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) {
  26498. throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
  26499. }
  26500. } else {
  26501. $newIndent = $indentation;
  26502. }
  26503. $data = array();
  26504. if ($this->getCurrentLineIndentation() >= $newIndent) {
  26505. $data[] = substr($this->currentLine, $newIndent);
  26506. } else {
  26507. $this->moveToPreviousLine();
  26508. return;
  26509. }
  26510. if ($inSequence && $oldLineIndentation === $newIndent && '-' === $data[0][0]) {
  26511. // the previous line contained a dash but no item content, this line is a sequence item with the same indentation
  26512. // and therefore no nested list or mapping
  26513. $this->moveToPreviousLine();
  26514. return;
  26515. }
  26516. $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem($this->currentLine);
  26517. // Comments must not be removed inside a string block (ie. after a line ending with "|")
  26518. $removeCommentsPattern = '~'.self::FOLDED_SCALAR_PATTERN.'$~';
  26519. $removeComments = !preg_match($removeCommentsPattern, $this->currentLine);
  26520. while ($this->moveToNextLine()) {
  26521. $indent = $this->getCurrentLineIndentation();
  26522. if ($indent === $newIndent) {
  26523. $removeComments = !preg_match($removeCommentsPattern, $this->currentLine);
  26524. }
  26525. if ($isItUnindentedCollection && !$this->isStringUnIndentedCollectionItem($this->currentLine) && $newIndent === $indent) {
  26526. $this->moveToPreviousLine();
  26527. break;
  26528. }
  26529. if ($this->isCurrentLineBlank()) {
  26530. $data[] = substr($this->currentLine, $newIndent);
  26531. continue;
  26532. }
  26533. if ($removeComments && $this->isCurrentLineComment()) {
  26534. continue;
  26535. }
  26536. if ($indent >= $newIndent) {
  26537. $data[] = substr($this->currentLine, $newIndent);
  26538. } elseif (0 == $indent) {
  26539. $this->moveToPreviousLine();
  26540. break;
  26541. } else {
  26542. throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
  26543. }
  26544. }
  26545. return implode("\n", $data);
  26546. }
  26547. /**
  26548. * Moves the parser to the next line.
  26549. *
  26550. * @return bool
  26551. */
  26552. private function moveToNextLine()
  26553. {
  26554. if ($this->currentLineNb >= count($this->lines) - 1) {
  26555. return false;
  26556. }
  26557. $this->currentLine = $this->lines[++$this->currentLineNb];
  26558. return true;
  26559. }
  26560. /**
  26561. * Moves the parser to the previous line.
  26562. */
  26563. private function moveToPreviousLine()
  26564. {
  26565. $this->currentLine = $this->lines[--$this->currentLineNb];
  26566. }
  26567. /**
  26568. * Parses a YAML value.
  26569. *
  26570. * @param string $value A YAML value
  26571. * @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
  26572. * @param bool $objectSupport True if object support is enabled, false otherwise
  26573. * @param bool $objectForMap true if maps should return a stdClass instead of array()
  26574. *
  26575. * @return mixed A PHP value
  26576. *
  26577. * @throws ParseException When reference does not exist
  26578. */
  26579. private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $objectForMap)
  26580. {
  26581. if (0 === strpos($value, '*')) {
  26582. if (false !== $pos = strpos($value, '#')) {
  26583. $value = substr($value, 1, $pos - 2);
  26584. } else {
  26585. $value = substr($value, 1);
  26586. }
  26587. if (!array_key_exists($value, $this->refs)) {
  26588. throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLine);
  26589. }
  26590. return $this->refs[$value];
  26591. }
  26592. if (preg_match('/^'.self::FOLDED_SCALAR_PATTERN.'$/', $value, $matches)) {
  26593. $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : '';
  26594. return $this->parseFoldedScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers));
  26595. }
  26596. try {
  26597. return Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
  26598. } catch (ParseException $e) {
  26599. $e->setParsedLine($this->getRealCurrentLineNb() + 1);
  26600. $e->setSnippet($this->currentLine);
  26601. throw $e;
  26602. }
  26603. }
  26604. /**
  26605. * Parses a folded scalar.
  26606. *
  26607. * @param string $separator The separator that was used to begin this folded scalar (| or >)
  26608. * @param string $indicator The indicator that was used to begin this folded scalar (+ or -)
  26609. * @param int $indentation The indentation that was used to begin this folded scalar
  26610. *
  26611. * @return string The text value
  26612. */
  26613. private function parseFoldedScalar($separator, $indicator = '', $indentation = 0)
  26614. {
  26615. $notEOF = $this->moveToNextLine();
  26616. if (!$notEOF) {
  26617. return '';
  26618. }
  26619. $isCurrentLineBlank = $this->isCurrentLineBlank();
  26620. $text = '';
  26621. // leading blank lines are consumed before determining indentation
  26622. while ($notEOF && $isCurrentLineBlank) {
  26623. // newline only if not EOF
  26624. if ($notEOF = $this->moveToNextLine()) {
  26625. $text .= "\n";
  26626. $isCurrentLineBlank = $this->isCurrentLineBlank();
  26627. }
  26628. }
  26629. // determine indentation if not specified
  26630. if (0 === $indentation) {
  26631. if (preg_match('/^ +/', $this->currentLine, $matches)) {
  26632. $indentation = strlen($matches[0]);
  26633. }
  26634. }
  26635. if ($indentation > 0) {
  26636. $pattern = sprintf('/^ {%d}(.*)$/', $indentation);
  26637. while (
  26638. $notEOF && (
  26639. $isCurrentLineBlank ||
  26640. preg_match($pattern, $this->currentLine, $matches)
  26641. )
  26642. ) {
  26643. if ($isCurrentLineBlank) {
  26644. $text .= substr($this->currentLine, $indentation);
  26645. } else {
  26646. $text .= $matches[1];
  26647. }
  26648. // newline only if not EOF
  26649. if ($notEOF = $this->moveToNextLine()) {
  26650. $text .= "\n";
  26651. $isCurrentLineBlank = $this->isCurrentLineBlank();
  26652. }
  26653. }
  26654. } elseif ($notEOF) {
  26655. $text .= "\n";
  26656. }
  26657. if ($notEOF) {
  26658. $this->moveToPreviousLine();
  26659. }
  26660. // replace all non-trailing single newlines with spaces in folded blocks
  26661. if ('>' === $separator) {
  26662. preg_match('/(\n*)$/', $text, $matches);
  26663. $text = preg_replace('/(?<!\n)\n(?!\n)/', ' ', rtrim($text, "\n"));
  26664. $text .= $matches[1];
  26665. }
  26666. // deal with trailing newlines as indicated
  26667. if ('' === $indicator) {
  26668. $text = preg_replace('/\n+$/s', "\n", $text);
  26669. } elseif ('-' === $indicator) {
  26670. $text = preg_replace('/\n+$/s', '', $text);
  26671. }
  26672. return $text;
  26673. }
  26674. /**
  26675. * Returns true if the next line is indented.
  26676. *
  26677. * @return bool Returns true if the next line is indented, false otherwise
  26678. */
  26679. private function isNextLineIndented()
  26680. {
  26681. $currentIndentation = $this->getCurrentLineIndentation();
  26682. $EOF = !$this->moveToNextLine();
  26683. while (!$EOF && $this->isCurrentLineEmpty()) {
  26684. $EOF = !$this->moveToNextLine();
  26685. }
  26686. if ($EOF) {
  26687. return false;
  26688. }
  26689. $ret = false;
  26690. if ($this->getCurrentLineIndentation() > $currentIndentation) {
  26691. $ret = true;
  26692. }
  26693. $this->moveToPreviousLine();
  26694. return $ret;
  26695. }
  26696. /**
  26697. * Returns true if the current line is blank or if it is a comment line.
  26698. *
  26699. * @return bool Returns true if the current line is empty or if it is a comment line, false otherwise
  26700. */
  26701. private function isCurrentLineEmpty()
  26702. {
  26703. return $this->isCurrentLineBlank() || $this->isCurrentLineComment();
  26704. }
  26705. /**
  26706. * Returns true if the current line is blank.
  26707. *
  26708. * @return bool Returns true if the current line is blank, false otherwise
  26709. */
  26710. private function isCurrentLineBlank()
  26711. {
  26712. return '' == trim($this->currentLine, ' ');
  26713. }
  26714. /**
  26715. * Returns true if the current line is a comment line.
  26716. *
  26717. * @return bool Returns true if the current line is a comment line, false otherwise
  26718. */
  26719. private function isCurrentLineComment()
  26720. {
  26721. //checking explicitly the first char of the trim is faster than loops or strpos
  26722. $ltrimmedLine = ltrim($this->currentLine, ' ');
  26723. return $ltrimmedLine[0] === '#';
  26724. }
  26725. /**
  26726. * Cleanups a YAML string to be parsed.
  26727. *
  26728. * @param string $value The input YAML string
  26729. *
  26730. * @return string A cleaned up YAML string
  26731. */
  26732. private function cleanup($value)
  26733. {
  26734. $value = str_replace(array("\r\n", "\r"), "\n", $value);
  26735. // strip YAML header
  26736. $count = 0;
  26737. $value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#u', '', $value, -1, $count);
  26738. $this->offset += $count;
  26739. // remove leading comments
  26740. $trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
  26741. if ($count == 1) {
  26742. // items have been removed, update the offset
  26743. $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
  26744. $value = $trimmedValue;
  26745. }
  26746. // remove start of the document marker (---)
  26747. $trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
  26748. if ($count == 1) {
  26749. // items have been removed, update the offset
  26750. $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
  26751. $value = $trimmedValue;
  26752. // remove end of the document marker (...)
  26753. $value = preg_replace('#\.\.\.\s*$#s', '', $value);
  26754. }
  26755. return $value;
  26756. }
  26757. /**
  26758. * Returns true if the next line starts unindented collection.
  26759. *
  26760. * @return bool Returns true if the next line starts unindented collection, false otherwise
  26761. */
  26762. private function isNextLineUnIndentedCollection()
  26763. {
  26764. $currentIndentation = $this->getCurrentLineIndentation();
  26765. $notEOF = $this->moveToNextLine();
  26766. while ($notEOF && $this->isCurrentLineEmpty()) {
  26767. $notEOF = $this->moveToNextLine();
  26768. }
  26769. if (false === $notEOF) {
  26770. return false;
  26771. }
  26772. $ret = false;
  26773. if (
  26774. $this->getCurrentLineIndentation() == $currentIndentation
  26775. &&
  26776. $this->isStringUnIndentedCollectionItem($this->currentLine)
  26777. ) {
  26778. $ret = true;
  26779. }
  26780. $this->moveToPreviousLine();
  26781. return $ret;
  26782. }
  26783. /**
  26784. * Returns true if the string is un-indented collection item.
  26785. *
  26786. * @return bool Returns true if the string is un-indented collection item, false otherwise
  26787. */
  26788. private function isStringUnIndentedCollectionItem()
  26789. {
  26790. return (0 === strpos($this->currentLine, '- '));
  26791. }
  26792. }
  26793. <?php
  26794. /*
  26795. * This file is part of the Symfony package.
  26796. *
  26797. * (c) Fabien Potencier <fabien@symfony.com>
  26798. *
  26799. * For the full copyright and license information, please view the LICENSE
  26800. * file that was distributed with this source code.
  26801. */
  26802. namespace Symfony\Component\Yaml;
  26803. /**
  26804. * Dumper dumps PHP variables to YAML strings.
  26805. *
  26806. * @author Fabien Potencier <fabien@symfony.com>
  26807. */
  26808. class Dumper
  26809. {
  26810. /**
  26811. * The amount of spaces to use for indentation of nested nodes.
  26812. *
  26813. * @var int
  26814. */
  26815. protected $indentation = 4;
  26816. /**
  26817. * Sets the indentation.
  26818. *
  26819. * @param int $num The amount of spaces to use for indentation of nested nodes.
  26820. */
  26821. public function setIndentation($num)
  26822. {
  26823. $this->indentation = (int) $num;
  26824. }
  26825. /**
  26826. * Dumps a PHP value to YAML.
  26827. *
  26828. * @param mixed $input The PHP value
  26829. * @param int $inline The level where you switch to inline YAML
  26830. * @param int $indent The level of indentation (used internally)
  26831. * @param bool $exceptionOnInvalidType true if an exception must be thrown on invalid types (a PHP resource or object), false otherwise
  26832. * @param bool $objectSupport true if object support is enabled, false otherwise
  26833. *
  26834. * @return string The YAML representation of the PHP value
  26835. */
  26836. public function dump($input, $inline = 0, $indent = 0, $exceptionOnInvalidType = false, $objectSupport = false)
  26837. {
  26838. $output = '';
  26839. $prefix = $indent ? str_repeat(' ', $indent) : '';
  26840. if ($inline <= 0 || !is_array($input) || empty($input)) {
  26841. $output .= $prefix.Inline::dump($input, $exceptionOnInvalidType, $objectSupport);
  26842. } else {
  26843. $isAHash = array_keys($input) !== range(0, count($input) - 1);
  26844. foreach ($input as $key => $value) {
  26845. $willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value);
  26846. $output .= sprintf('%s%s%s%s',
  26847. $prefix,
  26848. $isAHash ? Inline::dump($key, $exceptionOnInvalidType, $objectSupport).':' : '-',
  26849. $willBeInlined ? ' ' : "\n",
  26850. $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $exceptionOnInvalidType, $objectSupport)
  26851. ).($willBeInlined ? "\n" : '');
  26852. }
  26853. }
  26854. return $output;
  26855. }
  26856. }
  26857. <?php
  26858. /*
  26859. * This file is part of the Symfony package.
  26860. *
  26861. * (c) Fabien Potencier <fabien@symfony.com>
  26862. *
  26863. * For the full copyright and license information, please view the LICENSE
  26864. * file that was distributed with this source code.
  26865. */
  26866. namespace Symfony\Component\Yaml;
  26867. /**
  26868. * Escaper encapsulates escaping rules for single and double-quoted
  26869. * YAML strings.
  26870. *
  26871. * @author Matthew Lewinski <matthew@lewinski.org>
  26872. */
  26873. class Escaper
  26874. {
  26875. // Characters that would cause a dumped string to require double quoting.
  26876. const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9";
  26877. // Mapping arrays for escaping a double quoted string. The backslash is
  26878. // first to ensure proper escaping because str_replace operates iteratively
  26879. // on the input arrays. This ordering of the characters avoids the use of strtr,
  26880. // which performs more slowly.
  26881. private static $escapees = array('\\', '\\\\', '\\"', '"',
  26882. "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07",
  26883. "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f",
  26884. "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17",
  26885. "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f",
  26886. "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9",);
  26887. private static $escaped = array('\\\\', '\\"', '\\\\', '\\"',
  26888. '\\0', '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\a',
  26889. '\\b', '\\t', '\\n', '\\v', '\\f', '\\r', '\\x0e', '\\x0f',
  26890. '\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17',
  26891. '\\x18', '\\x19', '\\x1a', '\\e', '\\x1c', '\\x1d', '\\x1e', '\\x1f',
  26892. '\\N', '\\_', '\\L', '\\P',);
  26893. /**
  26894. * Determines if a PHP value would require double quoting in YAML.
  26895. *
  26896. * @param string $value A PHP value
  26897. *
  26898. * @return bool True if the value would require double quotes.
  26899. */
  26900. public static function requiresDoubleQuoting($value)
  26901. {
  26902. return preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value);
  26903. }
  26904. /**
  26905. * Escapes and surrounds a PHP value with double quotes.
  26906. *
  26907. * @param string $value A PHP value
  26908. *
  26909. * @return string The quoted, escaped string
  26910. */
  26911. public static function escapeWithDoubleQuotes($value)
  26912. {
  26913. return sprintf('"%s"', str_replace(self::$escapees, self::$escaped, $value));
  26914. }
  26915. /**
  26916. * Determines if a PHP value would require single quoting in YAML.
  26917. *
  26918. * @param string $value A PHP value
  26919. *
  26920. * @return bool True if the value would require single quotes.
  26921. */
  26922. public static function requiresSingleQuoting($value)
  26923. {
  26924. // Determines if a PHP value is entirely composed of a value that would
  26925. // require single quoting in YAML.
  26926. if (in_array(strtolower($value), array('null', '~', 'true', 'false', 'y', 'n', 'yes', 'no', 'on', 'off'))) {
  26927. return true;
  26928. }
  26929. // Determines if the PHP value contains any single characters that would
  26930. // cause it to require single quoting in YAML.
  26931. return preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value);
  26932. }
  26933. /**
  26934. * Escapes and surrounds a PHP value with single quotes.
  26935. *
  26936. * @param string $value A PHP value
  26937. *
  26938. * @return string The quoted, escaped string
  26939. */
  26940. public static function escapeWithSingleQuotes($value)
  26941. {
  26942. return sprintf("'%s'", str_replace('\'', '\'\'', $value));
  26943. }
  26944. }
  26945. -----BEGIN CERTIFICATE-----
  26946. MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
  26947. MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
  26948. IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
  26949. MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
  26950. FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
  26951. bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
  26952. dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
  26953. H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
  26954. uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
  26955. mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
  26956. a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
  26957. E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
  26958. WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
  26959. VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
  26960. Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
  26961. cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
  26962. IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
  26963. AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
  26964. YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
  26965. 6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
  26966. Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
  26967. c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
  26968. mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
  26969. -----END CERTIFICATE-----
  26970. Copyright (c) 2014 Doctrine Project
  26971. Permission is hereby granted, free of charge, to any person obtaining a copy of
  26972. this software and associated documentation files (the "Software"), to deal in
  26973. the Software without restriction, including without limitation the rights to
  26974. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  26975. of the Software, and to permit persons to whom the Software is furnished to do
  26976. so, subject to the following conditions:
  26977. The above copyright notice and this permission notice shall be included in all
  26978. copies or substantial portions of the Software.
  26979. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  26980. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  26981. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  26982. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  26983. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  26984. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  26985. SOFTWARE.
  26986. <?php
  26987. /*
  26988. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  26989. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  26990. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  26991. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  26992. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  26993. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26994. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26995. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26996. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26997. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  26998. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26999. *
  27000. * This software consists of voluntary contributions made by many individuals
  27001. * and is licensed under the MIT license. For more information, see
  27002. * <http://www.doctrine-project.org>.
  27003. */
  27004. namespace Doctrine\Instantiator;
  27005. /**
  27006. * Instantiator provides utility methods to build objects without invoking their constructors
  27007. *
  27008. * @author Marco Pivetta <ocramius@gmail.com>
  27009. */
  27010. interface InstantiatorInterface
  27011. {
  27012. /**
  27013. * @param string $className
  27014. *
  27015. * @return object
  27016. *
  27017. * @throws \Doctrine\Instantiator\Exception\ExceptionInterface
  27018. */
  27019. public function instantiate($className);
  27020. }
  27021. <?php
  27022. /*
  27023. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27024. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27025. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27026. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  27027. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  27028. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27029. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27030. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27031. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27032. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27033. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27034. *
  27035. * This software consists of voluntary contributions made by many individuals
  27036. * and is licensed under the MIT license. For more information, see
  27037. * <http://www.doctrine-project.org>.
  27038. */
  27039. namespace Doctrine\Instantiator\Exception;
  27040. /**
  27041. * Base exception marker interface for the instantiator component
  27042. *
  27043. * @author Marco Pivetta <ocramius@gmail.com>
  27044. */
  27045. interface ExceptionInterface
  27046. {
  27047. }
  27048. <?php
  27049. /*
  27050. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27051. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27052. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27053. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  27054. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  27055. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27056. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27057. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27058. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27059. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27060. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27061. *
  27062. * This software consists of voluntary contributions made by many individuals
  27063. * and is licensed under the MIT license. For more information, see
  27064. * <http://www.doctrine-project.org>.
  27065. */
  27066. namespace Doctrine\Instantiator\Exception;
  27067. use InvalidArgumentException as BaseInvalidArgumentException;
  27068. use ReflectionClass;
  27069. /**
  27070. * Exception for invalid arguments provided to the instantiator
  27071. *
  27072. * @author Marco Pivetta <ocramius@gmail.com>
  27073. */
  27074. class InvalidArgumentException extends BaseInvalidArgumentException implements ExceptionInterface
  27075. {
  27076. /**
  27077. * @param string $className
  27078. *
  27079. * @return self
  27080. */
  27081. public static function fromNonExistingClass($className)
  27082. {
  27083. if (interface_exists($className)) {
  27084. return new self(sprintf('The provided type "%s" is an interface, and can not be instantiated', $className));
  27085. }
  27086. if (PHP_VERSION_ID >= 50400 && trait_exists($className)) {
  27087. return new self(sprintf('The provided type "%s" is a trait, and can not be instantiated', $className));
  27088. }
  27089. return new self(sprintf('The provided class "%s" does not exist', $className));
  27090. }
  27091. /**
  27092. * @param ReflectionClass $reflectionClass
  27093. *
  27094. * @return self
  27095. */
  27096. public static function fromAbstractClass(ReflectionClass $reflectionClass)
  27097. {
  27098. return new self(sprintf(
  27099. 'The provided class "%s" is abstract, and can not be instantiated',
  27100. $reflectionClass->getName()
  27101. ));
  27102. }
  27103. }
  27104. <?php
  27105. /*
  27106. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27107. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27108. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27109. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  27110. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  27111. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27112. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27113. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27114. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27115. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27116. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27117. *
  27118. * This software consists of voluntary contributions made by many individuals
  27119. * and is licensed under the MIT license. For more information, see
  27120. * <http://www.doctrine-project.org>.
  27121. */
  27122. namespace Doctrine\Instantiator\Exception;
  27123. use Exception;
  27124. use ReflectionClass;
  27125. use UnexpectedValueException as BaseUnexpectedValueException;
  27126. /**
  27127. * Exception for given parameters causing invalid/unexpected state on instantiation
  27128. *
  27129. * @author Marco Pivetta <ocramius@gmail.com>
  27130. */
  27131. class UnexpectedValueException extends BaseUnexpectedValueException implements ExceptionInterface
  27132. {
  27133. /**
  27134. * @param ReflectionClass $reflectionClass
  27135. * @param Exception $exception
  27136. *
  27137. * @return self
  27138. */
  27139. public static function fromSerializationTriggeredException(ReflectionClass $reflectionClass, Exception $exception)
  27140. {
  27141. return new self(
  27142. sprintf(
  27143. 'An exception was raised while trying to instantiate an instance of "%s" via un-serialization',
  27144. $reflectionClass->getName()
  27145. ),
  27146. 0,
  27147. $exception
  27148. );
  27149. }
  27150. /**
  27151. * @param ReflectionClass $reflectionClass
  27152. * @param string $errorString
  27153. * @param int $errorCode
  27154. * @param string $errorFile
  27155. * @param int $errorLine
  27156. *
  27157. * @return UnexpectedValueException
  27158. */
  27159. public static function fromUncleanUnSerialization(
  27160. ReflectionClass $reflectionClass,
  27161. $errorString,
  27162. $errorCode,
  27163. $errorFile,
  27164. $errorLine
  27165. ) {
  27166. return new self(
  27167. sprintf(
  27168. 'Could not produce an instance of "%s" via un-serialization, since an error was triggered '
  27169. . 'in file "%s" at line "%d"',
  27170. $reflectionClass->getName(),
  27171. $errorFile,
  27172. $errorLine
  27173. ),
  27174. 0,
  27175. new Exception($errorString, $errorCode)
  27176. );
  27177. }
  27178. }
  27179. <?php
  27180. /*
  27181. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27182. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27183. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27184. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  27185. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  27186. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27187. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27188. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27189. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27190. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27191. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27192. *
  27193. * This software consists of voluntary contributions made by many individuals
  27194. * and is licensed under the MIT license. For more information, see
  27195. * <http://www.doctrine-project.org>.
  27196. */
  27197. namespace Doctrine\Instantiator;
  27198. use Closure;
  27199. use Doctrine\Instantiator\Exception\InvalidArgumentException;
  27200. use Doctrine\Instantiator\Exception\UnexpectedValueException;
  27201. use Exception;
  27202. use ReflectionClass;
  27203. /**
  27204. * {@inheritDoc}
  27205. *
  27206. * @author Marco Pivetta <ocramius@gmail.com>
  27207. */
  27208. final class Instantiator implements InstantiatorInterface
  27209. {
  27210. /**
  27211. * Markers used internally by PHP to define whether {@see \unserialize} should invoke
  27212. * the method {@see \Serializable::unserialize()} when dealing with classes implementing
  27213. * the {@see \Serializable} interface.
  27214. */
  27215. const SERIALIZATION_FORMAT_USE_UNSERIALIZER = 'C';
  27216. const SERIALIZATION_FORMAT_AVOID_UNSERIALIZER = 'O';
  27217. /**
  27218. * @var \Closure[] of {@see \Closure} instances used to instantiate specific classes
  27219. */
  27220. private static $cachedInstantiators = array();
  27221. /**
  27222. * @var object[] of objects that can directly be cloned
  27223. */
  27224. private static $cachedCloneables = array();
  27225. /**
  27226. * {@inheritDoc}
  27227. */
  27228. public function instantiate($className)
  27229. {
  27230. if (isset(self::$cachedCloneables[$className])) {
  27231. return clone self::$cachedCloneables[$className];
  27232. }
  27233. if (isset(self::$cachedInstantiators[$className])) {
  27234. $factory = self::$cachedInstantiators[$className];
  27235. return $factory();
  27236. }
  27237. return $this->buildAndCacheFromFactory($className);
  27238. }
  27239. /**
  27240. * Builds the requested object and caches it in static properties for performance
  27241. *
  27242. * @param string $className
  27243. *
  27244. * @return object
  27245. */
  27246. private function buildAndCacheFromFactory($className)
  27247. {
  27248. $factory = self::$cachedInstantiators[$className] = $this->buildFactory($className);
  27249. $instance = $factory();
  27250. if ($this->isSafeToClone(new ReflectionClass($instance))) {
  27251. self::$cachedCloneables[$className] = clone $instance;
  27252. }
  27253. return $instance;
  27254. }
  27255. /**
  27256. * Builds a {@see \Closure} capable of instantiating the given $className without
  27257. * invoking its constructor.
  27258. *
  27259. * @param string $className
  27260. *
  27261. * @return Closure
  27262. */
  27263. private function buildFactory($className)
  27264. {
  27265. $reflectionClass = $this->getReflectionClass($className);
  27266. if ($this->isInstantiableViaReflection($reflectionClass)) {
  27267. return function () use ($reflectionClass) {
  27268. return $reflectionClass->newInstanceWithoutConstructor();
  27269. };
  27270. }
  27271. $serializedString = sprintf(
  27272. '%s:%d:"%s":0:{}',
  27273. $this->getSerializationFormat($reflectionClass),
  27274. strlen($className),
  27275. $className
  27276. );
  27277. $this->checkIfUnSerializationIsSupported($reflectionClass, $serializedString);
  27278. return function () use ($serializedString) {
  27279. return unserialize($serializedString);
  27280. };
  27281. }
  27282. /**
  27283. * @param string $className
  27284. *
  27285. * @return ReflectionClass
  27286. *
  27287. * @throws InvalidArgumentException
  27288. */
  27289. private function getReflectionClass($className)
  27290. {
  27291. if (! class_exists($className)) {
  27292. throw InvalidArgumentException::fromNonExistingClass($className);
  27293. }
  27294. $reflection = new ReflectionClass($className);
  27295. if ($reflection->isAbstract()) {
  27296. throw InvalidArgumentException::fromAbstractClass($reflection);
  27297. }
  27298. return $reflection;
  27299. }
  27300. /**
  27301. * @param ReflectionClass $reflectionClass
  27302. * @param string $serializedString
  27303. *
  27304. * @throws UnexpectedValueException
  27305. *
  27306. * @return void
  27307. */
  27308. private function checkIfUnSerializationIsSupported(ReflectionClass $reflectionClass, $serializedString)
  27309. {
  27310. set_error_handler(function ($code, $message, $file, $line) use ($reflectionClass, & $error) {
  27311. $error = UnexpectedValueException::fromUncleanUnSerialization(
  27312. $reflectionClass,
  27313. $message,
  27314. $code,
  27315. $file,
  27316. $line
  27317. );
  27318. });
  27319. $this->attemptInstantiationViaUnSerialization($reflectionClass, $serializedString);
  27320. restore_error_handler();
  27321. if ($error) {
  27322. throw $error;
  27323. }
  27324. }
  27325. /**
  27326. * @param ReflectionClass $reflectionClass
  27327. * @param string $serializedString
  27328. *
  27329. * @throws UnexpectedValueException
  27330. *
  27331. * @return void
  27332. */
  27333. private function attemptInstantiationViaUnSerialization(ReflectionClass $reflectionClass, $serializedString)
  27334. {
  27335. try {
  27336. unserialize($serializedString);
  27337. } catch (Exception $exception) {
  27338. restore_error_handler();
  27339. throw UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $exception);
  27340. }
  27341. }
  27342. /**
  27343. * @param ReflectionClass $reflectionClass
  27344. *
  27345. * @return bool
  27346. */
  27347. private function isInstantiableViaReflection(ReflectionClass $reflectionClass)
  27348. {
  27349. if (\PHP_VERSION_ID >= 50600) {
  27350. return ! ($this->hasInternalAncestors($reflectionClass) && $reflectionClass->isFinal());
  27351. }
  27352. return \PHP_VERSION_ID >= 50400 && ! $this->hasInternalAncestors($reflectionClass);
  27353. }
  27354. /**
  27355. * Verifies whether the given class is to be considered internal
  27356. *
  27357. * @param ReflectionClass $reflectionClass
  27358. *
  27359. * @return bool
  27360. */
  27361. private function hasInternalAncestors(ReflectionClass $reflectionClass)
  27362. {
  27363. do {
  27364. if ($reflectionClass->isInternal()) {
  27365. return true;
  27366. }
  27367. } while ($reflectionClass = $reflectionClass->getParentClass());
  27368. return false;
  27369. }
  27370. /**
  27371. * Verifies if the given PHP version implements the `Serializable` interface serialization
  27372. * with an incompatible serialization format. If that's the case, use serialization marker
  27373. * "C" instead of "O".
  27374. *
  27375. * @link http://news.php.net/php.internals/74654
  27376. *
  27377. * @param ReflectionClass $reflectionClass
  27378. *
  27379. * @return string the serialization format marker, either self::SERIALIZATION_FORMAT_USE_UNSERIALIZER
  27380. * or self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER
  27381. */
  27382. private function getSerializationFormat(ReflectionClass $reflectionClass)
  27383. {
  27384. if ($this->isPhpVersionWithBrokenSerializationFormat()
  27385. && $reflectionClass->implementsInterface('Serializable')
  27386. ) {
  27387. return self::SERIALIZATION_FORMAT_USE_UNSERIALIZER;
  27388. }
  27389. return self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER;
  27390. }
  27391. /**
  27392. * Checks whether the current PHP runtime uses an incompatible serialization format
  27393. *
  27394. * @return bool
  27395. */
  27396. private function isPhpVersionWithBrokenSerializationFormat()
  27397. {
  27398. return PHP_VERSION_ID === 50429 || PHP_VERSION_ID === 50513;
  27399. }
  27400. /**
  27401. * Checks if a class is cloneable
  27402. *
  27403. * @param ReflectionClass $reflection
  27404. *
  27405. * @return bool
  27406. */
  27407. private function isSafeToClone(ReflectionClass $reflection)
  27408. {
  27409. if (method_exists($reflection, 'isCloneable') && ! $reflection->isCloneable()) {
  27410. return false;
  27411. }
  27412. // not cloneable if it implements `__clone`, as we want to avoid calling it
  27413. return ! $reflection->hasMethod('__clone');
  27414. }
  27415. }
  27416. PHP_TokenStream
  27417. Copyright (c) 2009-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  27418. All rights reserved.
  27419. Redistribution and use in source and binary forms, with or without
  27420. modification, are permitted provided that the following conditions
  27421. are met:
  27422. * Redistributions of source code must retain the above copyright
  27423. notice, this list of conditions and the following disclaimer.
  27424. * Redistributions in binary form must reproduce the above copyright
  27425. notice, this list of conditions and the following disclaimer in
  27426. the documentation and/or other materials provided with the
  27427. distribution.
  27428. * Neither the name of Sebastian Bergmann nor the names of his
  27429. contributors may be used to endorse or promote products derived
  27430. from this software without specific prior written permission.
  27431. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27432. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27433. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  27434. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  27435. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  27436. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27437. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27438. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  27439. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27440. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  27441. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  27442. POSSIBILITY OF SUCH DAMAGE.
  27443. <?php
  27444. /*
  27445. * This file is part of the PHP_TokenStream package.
  27446. *
  27447. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27448. *
  27449. * For the full copyright and license information, please view the LICENSE
  27450. * file that was distributed with this source code.
  27451. */
  27452. /**
  27453. * A caching factory for token stream objects.
  27454. *
  27455. * @author Sebastian Bergmann <sebastian@phpunit.de>
  27456. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  27457. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  27458. * @link http://github.com/sebastianbergmann/php-token-stream/tree
  27459. * @since Class available since Release 1.0.0
  27460. */
  27461. class PHP_Token_Stream_CachingFactory
  27462. {
  27463. /**
  27464. * @var array
  27465. */
  27466. protected static $cache = array();
  27467. /**
  27468. * @param string $filename
  27469. * @return PHP_Token_Stream
  27470. */
  27471. public static function get($filename)
  27472. {
  27473. if (!isset(self::$cache[$filename])) {
  27474. self::$cache[$filename] = new PHP_Token_Stream($filename);
  27475. }
  27476. return self::$cache[$filename];
  27477. }
  27478. /**
  27479. * @param string $filename
  27480. */
  27481. public static function clear($filename = null)
  27482. {
  27483. if (is_string($filename)) {
  27484. unset(self::$cache[$filename]);
  27485. } else {
  27486. self::$cache = array();
  27487. }
  27488. }
  27489. }
  27490. <?php
  27491. /*
  27492. * This file is part of the PHP_TokenStream package.
  27493. *
  27494. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  27495. *
  27496. * For the full copyright and license information, please view the LICENSE
  27497. * file that was distributed with this source code.
  27498. */
  27499. /**
  27500. * A stream of PHP tokens.
  27501. *
  27502. * @author Sebastian Bergmann <sebastian@phpunit.de>
  27503. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  27504. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  27505. * @link http://github.com/sebastianbergmann/php-token-stream/tree
  27506. * @since Class available since Release 1.0.0
  27507. */
  27508. class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator
  27509. {
  27510. /**
  27511. * @var array
  27512. */
  27513. protected static $customTokens = array(
  27514. '(' => 'PHP_Token_OPEN_BRACKET',
  27515. ')' => 'PHP_Token_CLOSE_BRACKET',
  27516. '[' => 'PHP_Token_OPEN_SQUARE',
  27517. ']' => 'PHP_Token_CLOSE_SQUARE',
  27518. '{' => 'PHP_Token_OPEN_CURLY',
  27519. '}' => 'PHP_Token_CLOSE_CURLY',
  27520. ';' => 'PHP_Token_SEMICOLON',
  27521. '.' => 'PHP_Token_DOT',
  27522. ',' => 'PHP_Token_COMMA',
  27523. '=' => 'PHP_Token_EQUAL',
  27524. '<' => 'PHP_Token_LT',
  27525. '>' => 'PHP_Token_GT',
  27526. '+' => 'PHP_Token_PLUS',
  27527. '-' => 'PHP_Token_MINUS',
  27528. '*' => 'PHP_Token_MULT',
  27529. '/' => 'PHP_Token_DIV',
  27530. '?' => 'PHP_Token_QUESTION_MARK',
  27531. '!' => 'PHP_Token_EXCLAMATION_MARK',
  27532. ':' => 'PHP_Token_COLON',
  27533. '"' => 'PHP_Token_DOUBLE_QUOTES',
  27534. '@' => 'PHP_Token_AT',
  27535. '&' => 'PHP_Token_AMPERSAND',
  27536. '%' => 'PHP_Token_PERCENT',
  27537. '|' => 'PHP_Token_PIPE',
  27538. '$' => 'PHP_Token_DOLLAR',
  27539. '^' => 'PHP_Token_CARET',
  27540. '~' => 'PHP_Token_TILDE',
  27541. '`' => 'PHP_Token_BACKTICK'
  27542. );
  27543. /**
  27544. * @var string
  27545. */
  27546. protected $filename;
  27547. /**
  27548. * @var array
  27549. */
  27550. protected $tokens = array();
  27551. /**
  27552. * @var integer
  27553. */
  27554. protected $position = 0;
  27555. /**
  27556. * @var array
  27557. */
  27558. protected $linesOfCode = array('loc' => 0, 'cloc' => 0, 'ncloc' => 0);
  27559. /**
  27560. * @var array
  27561. */
  27562. protected $classes;
  27563. /**
  27564. * @var array
  27565. */
  27566. protected $functions;
  27567. /**
  27568. * @var array
  27569. */
  27570. protected $includes;
  27571. /**
  27572. * @var array
  27573. */
  27574. protected $interfaces;
  27575. /**
  27576. * @var array
  27577. */
  27578. protected $traits;
  27579. /**
  27580. * @var array
  27581. */
  27582. protected $lineToFunctionMap = array();
  27583. /**
  27584. * Constructor.
  27585. *
  27586. * @param string $sourceCode
  27587. */
  27588. public function __construct($sourceCode)
  27589. {
  27590. if (is_file($sourceCode)) {
  27591. $this->filename = $sourceCode;
  27592. $sourceCode = file_get_contents($sourceCode);
  27593. }
  27594. $this->scan($sourceCode);
  27595. }
  27596. /**
  27597. * Destructor.
  27598. */
  27599. public function __destruct()
  27600. {
  27601. $this->tokens = array();
  27602. }
  27603. /**
  27604. * @return string
  27605. */
  27606. public function __toString()
  27607. {
  27608. $buffer = '';
  27609. foreach ($this as $token) {
  27610. $buffer .= $token;
  27611. }
  27612. return $buffer;
  27613. }
  27614. /**
  27615. * @return string
  27616. * @since Method available since Release 1.1.0
  27617. */
  27618. public function getFilename()
  27619. {
  27620. return $this->filename;
  27621. }
  27622. /**
  27623. * Scans the source for sequences of characters and converts them into a
  27624. * stream of tokens.
  27625. *
  27626. * @param string $sourceCode
  27627. */
  27628. protected function scan($sourceCode)
  27629. {
  27630. $line = 1;
  27631. $tokens = token_get_all($sourceCode);
  27632. $numTokens = count($tokens);
  27633. $lastNonWhitespaceTokenWasDoubleColon = false;
  27634. for ($i = 0; $i < $numTokens; ++$i) {
  27635. $token = $tokens[$i];
  27636. unset($tokens[$i]);
  27637. if (is_array($token)) {
  27638. $name = substr(token_name($token[0]), 2);
  27639. $text = $token[1];
  27640. if ($lastNonWhitespaceTokenWasDoubleColon && $name == 'CLASS') {
  27641. $name = 'CLASS_NAME_CONSTANT';
  27642. }
  27643. $tokenClass = 'PHP_Token_' . $name;
  27644. } else {
  27645. $text = $token;
  27646. $tokenClass = self::$customTokens[$token];
  27647. }
  27648. $this->tokens[] = new $tokenClass($text, $line, $this, $i);
  27649. $lines = substr_count($text, "\n");
  27650. $line += $lines;
  27651. if ($tokenClass == 'PHP_Token_HALT_COMPILER') {
  27652. break;
  27653. } elseif ($tokenClass == 'PHP_Token_COMMENT' ||
  27654. $tokenClass == 'PHP_Token_DOC_COMMENT') {
  27655. $this->linesOfCode['cloc'] += $lines + 1;
  27656. }
  27657. if ($name == 'DOUBLE_COLON') {
  27658. $lastNonWhitespaceTokenWasDoubleColon = true;
  27659. } elseif ($name != 'WHITESPACE') {
  27660. $lastNonWhitespaceTokenWasDoubleColon = false;
  27661. }
  27662. }
  27663. $this->linesOfCode['loc'] = substr_count($sourceCode, "\n");
  27664. $this->linesOfCode['ncloc'] = $this->linesOfCode['loc'] -
  27665. $this->linesOfCode['cloc'];
  27666. }
  27667. /**
  27668. * @return integer
  27669. */
  27670. public function count()
  27671. {
  27672. return count($this->tokens);
  27673. }
  27674. /**
  27675. * @return PHP_Token[]
  27676. */
  27677. public function tokens()
  27678. {
  27679. return $this->tokens;
  27680. }
  27681. /**
  27682. * @return array
  27683. */
  27684. public function getClasses()
  27685. {
  27686. if ($this->classes !== null) {
  27687. return $this->classes;
  27688. }
  27689. $this->parse();
  27690. return $this->classes;
  27691. }
  27692. /**
  27693. * @return array
  27694. */
  27695. public function getFunctions()
  27696. {
  27697. if ($this->functions !== null) {
  27698. return $this->functions;
  27699. }
  27700. $this->parse();
  27701. return $this->functions;
  27702. }
  27703. /**
  27704. * @return array
  27705. */
  27706. public function getInterfaces()
  27707. {
  27708. if ($this->interfaces !== null) {
  27709. return $this->interfaces;
  27710. }
  27711. $this->parse();
  27712. return $this->interfaces;
  27713. }
  27714. /**
  27715. * @return array
  27716. * @since Method available since Release 1.1.0
  27717. */
  27718. public function getTraits()
  27719. {
  27720. if ($this->traits !== null) {
  27721. return $this->traits;
  27722. }
  27723. $this->parse();
  27724. return $this->traits;
  27725. }
  27726. /**
  27727. * Gets the names of all files that have been included
  27728. * using include(), include_once(), require() or require_once().
  27729. *
  27730. * Parameter $categorize set to TRUE causing this function to return a
  27731. * multi-dimensional array with categories in the keys of the first dimension
  27732. * and constants and their values in the second dimension.
  27733. *
  27734. * Parameter $category allow to filter following specific inclusion type
  27735. *
  27736. * @param bool $categorize OPTIONAL
  27737. * @param string $category OPTIONAL Either 'require_once', 'require',
  27738. * 'include_once', 'include'.
  27739. * @return array
  27740. * @since Method available since Release 1.1.0
  27741. */
  27742. public function getIncludes($categorize = false, $category = null)
  27743. {
  27744. if ($this->includes === null) {
  27745. $this->includes = array(
  27746. 'require_once' => array(),
  27747. 'require' => array(),
  27748. 'include_once' => array(),
  27749. 'include' => array()
  27750. );
  27751. foreach ($this->tokens as $token) {
  27752. switch (get_class($token)) {
  27753. case 'PHP_Token_REQUIRE_ONCE':
  27754. case 'PHP_Token_REQUIRE':
  27755. case 'PHP_Token_INCLUDE_ONCE':
  27756. case 'PHP_Token_INCLUDE':
  27757. $this->includes[$token->getType()][] = $token->getName();
  27758. break;
  27759. }
  27760. }
  27761. }
  27762. if (isset($this->includes[$category])) {
  27763. $includes = $this->includes[$category];
  27764. } elseif ($categorize === false) {
  27765. $includes = array_merge(
  27766. $this->includes['require_once'],
  27767. $this->includes['require'],
  27768. $this->includes['include_once'],
  27769. $this->includes['include']
  27770. );
  27771. } else {
  27772. $includes = $this->includes;
  27773. }
  27774. return $includes;
  27775. }
  27776. /**
  27777. * Returns the name of the function or method a line belongs to.
  27778. *
  27779. * @return string or null if the line is not in a function or method
  27780. * @since Method available since Release 1.2.0
  27781. */
  27782. public function getFunctionForLine($line)
  27783. {
  27784. $this->parse();
  27785. if (isset($this->lineToFunctionMap[$line])) {
  27786. return $this->lineToFunctionMap[$line];
  27787. }
  27788. }
  27789. protected function parse()
  27790. {
  27791. $this->interfaces = array();
  27792. $this->classes = array();
  27793. $this->traits = array();
  27794. $this->functions = array();
  27795. $class = false;
  27796. $classEndLine = false;
  27797. $trait = false;
  27798. $traitEndLine = false;
  27799. $interface = false;
  27800. $interfaceEndLine = false;
  27801. foreach ($this->tokens as $token) {
  27802. switch (get_class($token)) {
  27803. case 'PHP_Token_HALT_COMPILER':
  27804. return;
  27805. case 'PHP_Token_INTERFACE':
  27806. $interface = $token->getName();
  27807. $interfaceEndLine = $token->getEndLine();
  27808. $this->interfaces[$interface] = array(
  27809. 'methods' => array(),
  27810. 'parent' => $token->getParent(),
  27811. 'keywords' => $token->getKeywords(),
  27812. 'docblock' => $token->getDocblock(),
  27813. 'startLine' => $token->getLine(),
  27814. 'endLine' => $interfaceEndLine,
  27815. 'package' => $token->getPackage(),
  27816. 'file' => $this->filename
  27817. );
  27818. break;
  27819. case 'PHP_Token_CLASS':
  27820. case 'PHP_Token_TRAIT':
  27821. $tmp = array(
  27822. 'methods' => array(),
  27823. 'parent' => $token->getParent(),
  27824. 'interfaces'=> $token->getInterfaces(),
  27825. 'keywords' => $token->getKeywords(),
  27826. 'docblock' => $token->getDocblock(),
  27827. 'startLine' => $token->getLine(),
  27828. 'endLine' => $token->getEndLine(),
  27829. 'package' => $token->getPackage(),
  27830. 'file' => $this->filename
  27831. );
  27832. if ($token instanceof PHP_Token_CLASS) {
  27833. $class = $token->getName();
  27834. $classEndLine = $token->getEndLine();
  27835. $this->classes[$class] = $tmp;
  27836. } else {
  27837. $trait = $token->getName();
  27838. $traitEndLine = $token->getEndLine();
  27839. $this->traits[$trait] = $tmp;
  27840. }
  27841. break;
  27842. case 'PHP_Token_FUNCTION':
  27843. $name = $token->getName();
  27844. $tmp = array(
  27845. 'docblock' => $token->getDocblock(),
  27846. 'keywords' => $token->getKeywords(),
  27847. 'visibility'=> $token->getVisibility(),
  27848. 'signature' => $token->getSignature(),
  27849. 'startLine' => $token->getLine(),
  27850. 'endLine' => $token->getEndLine(),
  27851. 'ccn' => $token->getCCN(),
  27852. 'file' => $this->filename
  27853. );
  27854. if ($class === false &&
  27855. $trait === false &&
  27856. $interface === false) {
  27857. $this->functions[$name] = $tmp;
  27858. $this->addFunctionToMap(
  27859. $name,
  27860. $tmp['startLine'],
  27861. $tmp['endLine']
  27862. );
  27863. } elseif ($class !== false) {
  27864. $this->classes[$class]['methods'][$name] = $tmp;
  27865. $this->addFunctionToMap(
  27866. $class . '::' . $name,
  27867. $tmp['startLine'],
  27868. $tmp['endLine']
  27869. );
  27870. } elseif ($trait !== false) {
  27871. $this->traits[$trait]['methods'][$name] = $tmp;
  27872. $this->addFunctionToMap(
  27873. $trait . '::' . $name,
  27874. $tmp['startLine'],
  27875. $tmp['endLine']
  27876. );
  27877. } else {
  27878. $this->interfaces[$interface]['methods'][$name] = $tmp;
  27879. }
  27880. break;
  27881. case 'PHP_Token_CLOSE_CURLY':
  27882. if ($classEndLine !== false &&
  27883. $classEndLine == $token->getLine()) {
  27884. $class = false;
  27885. $classEndLine = false;
  27886. } elseif ($traitEndLine !== false &&
  27887. $traitEndLine == $token->getLine()) {
  27888. $trait = false;
  27889. $traitEndLine = false;
  27890. } elseif ($interfaceEndLine !== false &&
  27891. $interfaceEndLine == $token->getLine()) {
  27892. $interface = false;
  27893. $interfaceEndLine = false;
  27894. }
  27895. break;
  27896. }
  27897. }
  27898. }
  27899. /**
  27900. * @return array
  27901. */
  27902. public function getLinesOfCode()
  27903. {
  27904. return $this->linesOfCode;
  27905. }
  27906. /**
  27907. */
  27908. public function rewind()
  27909. {
  27910. $this->position = 0;
  27911. }
  27912. /**
  27913. * @return boolean
  27914. */
  27915. public function valid()
  27916. {
  27917. return isset($this->tokens[$this->position]);
  27918. }
  27919. /**
  27920. * @return integer
  27921. */
  27922. public function key()
  27923. {
  27924. return $this->position;
  27925. }
  27926. /**
  27927. * @return PHP_Token
  27928. */
  27929. public function current()
  27930. {
  27931. return $this->tokens[$this->position];
  27932. }
  27933. /**
  27934. */
  27935. public function next()
  27936. {
  27937. $this->position++;
  27938. }
  27939. /**
  27940. * @param integer $offset
  27941. * @return boolean
  27942. */
  27943. public function offsetExists($offset)
  27944. {
  27945. return isset($this->tokens[$offset]);
  27946. }
  27947. /**
  27948. * @param integer $offset
  27949. * @return mixed
  27950. * @throws OutOfBoundsException
  27951. */
  27952. public function offsetGet($offset)
  27953. {
  27954. if (!$this->offsetExists($offset)) {
  27955. throw new OutOfBoundsException(
  27956. sprintf(
  27957. 'No token at position "%s"',
  27958. $offset
  27959. )
  27960. );
  27961. }
  27962. return $this->tokens[$offset];
  27963. }
  27964. /**
  27965. * @param integer $offset
  27966. * @param mixed $value
  27967. */
  27968. public function offsetSet($offset, $value)
  27969. {
  27970. $this->tokens[$offset] = $value;
  27971. }
  27972. /**
  27973. * @param integer $offset
  27974. * @throws OutOfBoundsException
  27975. */
  27976. public function offsetUnset($offset)
  27977. {
  27978. if (!$this->offsetExists($offset)) {
  27979. throw new OutOfBoundsException(
  27980. sprintf(
  27981. 'No token at position "%s"',
  27982. $offset
  27983. )
  27984. );
  27985. }
  27986. unset($this->tokens[$offset]);
  27987. }
  27988. /**
  27989. * Seek to an absolute position.
  27990. *
  27991. * @param integer $position
  27992. * @throws OutOfBoundsException
  27993. */
  27994. public function seek($position)
  27995. {
  27996. $this->position = $position;
  27997. if (!$this->valid()) {
  27998. throw new OutOfBoundsException(
  27999. sprintf(
  28000. 'No token at position "%s"',
  28001. $this->position
  28002. )
  28003. );
  28004. }
  28005. }
  28006. /**
  28007. * @param string $name
  28008. * @param integer $startLine
  28009. * @param integer $endLine
  28010. */
  28011. private function addFunctionToMap($name, $startLine, $endLine)
  28012. {
  28013. for ($line = $startLine; $line <= $endLine; $line++) {
  28014. $this->lineToFunctionMap[$line] = $name;
  28015. }
  28016. }
  28017. }
  28018. <?php
  28019. /*
  28020. * This file is part of the PHP_TokenStream package.
  28021. *
  28022. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28023. *
  28024. * For the full copyright and license information, please view the LICENSE
  28025. * file that was distributed with this source code.
  28026. */
  28027. /**
  28028. * A PHP token.
  28029. *
  28030. * @author Sebastian Bergmann <sebastian@phpunit.de>
  28031. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  28032. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  28033. * @link http://github.com/sebastianbergmann/php-token-stream/tree
  28034. * @since Class available since Release 1.0.0
  28035. */
  28036. abstract class PHP_Token
  28037. {
  28038. /**
  28039. * @var string
  28040. */
  28041. protected $text;
  28042. /**
  28043. * @var integer
  28044. */
  28045. protected $line;
  28046. /**
  28047. * @var PHP_Token_Stream
  28048. */
  28049. protected $tokenStream;
  28050. /**
  28051. * @var integer
  28052. */
  28053. protected $id;
  28054. /**
  28055. * Constructor.
  28056. *
  28057. * @param string $text
  28058. * @param integer $line
  28059. * @param PHP_Token_Stream $tokenStream
  28060. * @param integer $id
  28061. */
  28062. public function __construct($text, $line, PHP_Token_Stream $tokenStream, $id)
  28063. {
  28064. $this->text = $text;
  28065. $this->line = $line;
  28066. $this->tokenStream = $tokenStream;
  28067. $this->id = $id;
  28068. }
  28069. /**
  28070. * @return string
  28071. */
  28072. public function __toString()
  28073. {
  28074. return $this->text;
  28075. }
  28076. /**
  28077. * @return integer
  28078. */
  28079. public function getLine()
  28080. {
  28081. return $this->line;
  28082. }
  28083. }
  28084. abstract class PHP_TokenWithScope extends PHP_Token
  28085. {
  28086. /**
  28087. * @var integer
  28088. */
  28089. protected $endTokenId;
  28090. /**
  28091. * Get the docblock for this token
  28092. *
  28093. * This method will fetch the docblock belonging to the current token. The
  28094. * docblock must be placed on the line directly above the token to be
  28095. * recognized.
  28096. *
  28097. * @return string|null Returns the docblock as a string if found
  28098. */
  28099. public function getDocblock()
  28100. {
  28101. $tokens = $this->tokenStream->tokens();
  28102. $currentLineNumber = $tokens[$this->id]->getLine();
  28103. $prevLineNumber = $currentLineNumber - 1;
  28104. for ($i = $this->id - 1; $i; $i--) {
  28105. if (!isset($tokens[$i])) {
  28106. return;
  28107. }
  28108. if ($tokens[$i] instanceof PHP_Token_FUNCTION ||
  28109. $tokens[$i] instanceof PHP_Token_CLASS ||
  28110. $tokens[$i] instanceof PHP_Token_TRAIT) {
  28111. // Some other trait, class or function, no docblock can be
  28112. // used for the current token
  28113. break;
  28114. }
  28115. $line = $tokens[$i]->getLine();
  28116. if ($line == $currentLineNumber ||
  28117. ($line == $prevLineNumber &&
  28118. $tokens[$i] instanceof PHP_Token_WHITESPACE)) {
  28119. continue;
  28120. }
  28121. if ($line < $currentLineNumber &&
  28122. !$tokens[$i] instanceof PHP_Token_DOC_COMMENT) {
  28123. break;
  28124. }
  28125. return (string)$tokens[$i];
  28126. }
  28127. }
  28128. /**
  28129. * @return integer
  28130. */
  28131. public function getEndTokenId()
  28132. {
  28133. $block = 0;
  28134. $i = $this->id;
  28135. $tokens = $this->tokenStream->tokens();
  28136. while ($this->endTokenId === null && isset($tokens[$i])) {
  28137. if ($tokens[$i] instanceof PHP_Token_OPEN_CURLY ||
  28138. $tokens[$i] instanceof PHP_Token_CURLY_OPEN) {
  28139. $block++;
  28140. } elseif ($tokens[$i] instanceof PHP_Token_CLOSE_CURLY) {
  28141. $block--;
  28142. if ($block === 0) {
  28143. $this->endTokenId = $i;
  28144. }
  28145. } elseif (($this instanceof PHP_Token_FUNCTION ||
  28146. $this instanceof PHP_Token_NAMESPACE) &&
  28147. $tokens[$i] instanceof PHP_Token_SEMICOLON) {
  28148. if ($block === 0) {
  28149. $this->endTokenId = $i;
  28150. }
  28151. }
  28152. $i++;
  28153. }
  28154. if ($this->endTokenId === null) {
  28155. $this->endTokenId = $this->id;
  28156. }
  28157. return $this->endTokenId;
  28158. }
  28159. /**
  28160. * @return integer
  28161. */
  28162. public function getEndLine()
  28163. {
  28164. return $this->tokenStream[$this->getEndTokenId()]->getLine();
  28165. }
  28166. }
  28167. abstract class PHP_TokenWithScopeAndVisibility extends PHP_TokenWithScope
  28168. {
  28169. /**
  28170. * @return string
  28171. */
  28172. public function getVisibility()
  28173. {
  28174. $tokens = $this->tokenStream->tokens();
  28175. for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) {
  28176. if (isset($tokens[$i]) &&
  28177. ($tokens[$i] instanceof PHP_Token_PRIVATE ||
  28178. $tokens[$i] instanceof PHP_Token_PROTECTED ||
  28179. $tokens[$i] instanceof PHP_Token_PUBLIC)) {
  28180. return strtolower(
  28181. str_replace('PHP_Token_', '', get_class($tokens[$i]))
  28182. );
  28183. }
  28184. if (isset($tokens[$i]) &&
  28185. !($tokens[$i] instanceof PHP_Token_STATIC ||
  28186. $tokens[$i] instanceof PHP_Token_FINAL ||
  28187. $tokens[$i] instanceof PHP_Token_ABSTRACT)) {
  28188. // no keywords; stop visibility search
  28189. break;
  28190. }
  28191. }
  28192. }
  28193. /**
  28194. * @return string
  28195. */
  28196. public function getKeywords()
  28197. {
  28198. $keywords = array();
  28199. $tokens = $this->tokenStream->tokens();
  28200. for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) {
  28201. if (isset($tokens[$i]) &&
  28202. ($tokens[$i] instanceof PHP_Token_PRIVATE ||
  28203. $tokens[$i] instanceof PHP_Token_PROTECTED ||
  28204. $tokens[$i] instanceof PHP_Token_PUBLIC)) {
  28205. continue;
  28206. }
  28207. if (isset($tokens[$i]) &&
  28208. ($tokens[$i] instanceof PHP_Token_STATIC ||
  28209. $tokens[$i] instanceof PHP_Token_FINAL ||
  28210. $tokens[$i] instanceof PHP_Token_ABSTRACT)) {
  28211. $keywords[] = strtolower(
  28212. str_replace('PHP_Token_', '', get_class($tokens[$i]))
  28213. );
  28214. }
  28215. }
  28216. return implode(',', $keywords);
  28217. }
  28218. }
  28219. abstract class PHP_Token_Includes extends PHP_Token
  28220. {
  28221. /**
  28222. * @var string
  28223. */
  28224. protected $name;
  28225. /**
  28226. * @var string
  28227. */
  28228. protected $type;
  28229. /**
  28230. * @return string
  28231. */
  28232. public function getName()
  28233. {
  28234. if ($this->name === null) {
  28235. $this->process();
  28236. }
  28237. return $this->name;
  28238. }
  28239. /**
  28240. * @return string
  28241. */
  28242. public function getType()
  28243. {
  28244. if ($this->type === null) {
  28245. $this->process();
  28246. }
  28247. return $this->type;
  28248. }
  28249. private function process()
  28250. {
  28251. $tokens = $this->tokenStream->tokens();
  28252. if ($tokens[$this->id+2] instanceof PHP_Token_CONSTANT_ENCAPSED_STRING) {
  28253. $this->name = trim($tokens[$this->id+2], "'\"");
  28254. $this->type = strtolower(
  28255. str_replace('PHP_Token_', '', get_class($tokens[$this->id]))
  28256. );
  28257. }
  28258. }
  28259. }
  28260. class PHP_Token_FUNCTION extends PHP_TokenWithScopeAndVisibility
  28261. {
  28262. /**
  28263. * @var array
  28264. */
  28265. protected $arguments;
  28266. /**
  28267. * @var integer
  28268. */
  28269. protected $ccn;
  28270. /**
  28271. * @var string
  28272. */
  28273. protected $name;
  28274. /**
  28275. * @var string
  28276. */
  28277. protected $signature;
  28278. /**
  28279. * @return array
  28280. */
  28281. public function getArguments()
  28282. {
  28283. if ($this->arguments !== null) {
  28284. return $this->arguments;
  28285. }
  28286. $this->arguments = array();
  28287. $tokens = $this->tokenStream->tokens();
  28288. $typeDeclaration = null;
  28289. // Search for first token inside brackets
  28290. $i = $this->id + 2;
  28291. while (!$tokens[$i-1] instanceof PHP_Token_OPEN_BRACKET) {
  28292. $i++;
  28293. }
  28294. while (!$tokens[$i] instanceof PHP_Token_CLOSE_BRACKET) {
  28295. if ($tokens[$i] instanceof PHP_Token_STRING) {
  28296. $typeDeclaration = (string)$tokens[$i];
  28297. } elseif ($tokens[$i] instanceof PHP_Token_VARIABLE) {
  28298. $this->arguments[(string)$tokens[$i]] = $typeDeclaration;
  28299. $typeDeclaration = null;
  28300. }
  28301. $i++;
  28302. }
  28303. return $this->arguments;
  28304. }
  28305. /**
  28306. * @return string
  28307. */
  28308. public function getName()
  28309. {
  28310. if ($this->name !== null) {
  28311. return $this->name;
  28312. }
  28313. $tokens = $this->tokenStream->tokens();
  28314. for ($i = $this->id + 1; $i < count($tokens); $i++) {
  28315. if ($tokens[$i] instanceof PHP_Token_STRING) {
  28316. $this->name = (string)$tokens[$i];
  28317. break;
  28318. } elseif ($tokens[$i] instanceof PHP_Token_AMPERSAND &&
  28319. $tokens[$i+1] instanceof PHP_Token_STRING) {
  28320. $this->name = (string)$tokens[$i+1];
  28321. break;
  28322. } elseif ($tokens[$i] instanceof PHP_Token_OPEN_BRACKET) {
  28323. $this->name = 'anonymous function';
  28324. break;
  28325. }
  28326. }
  28327. if ($this->name != 'anonymous function') {
  28328. for ($i = $this->id; $i; --$i) {
  28329. if ($tokens[$i] instanceof PHP_Token_NAMESPACE) {
  28330. $this->name = $tokens[$i]->getName() . '\\' . $this->name;
  28331. break;
  28332. }
  28333. if ($tokens[$i] instanceof PHP_Token_INTERFACE) {
  28334. break;
  28335. }
  28336. }
  28337. }
  28338. return $this->name;
  28339. }
  28340. /**
  28341. * @return integer
  28342. */
  28343. public function getCCN()
  28344. {
  28345. if ($this->ccn !== null) {
  28346. return $this->ccn;
  28347. }
  28348. $this->ccn = 1;
  28349. $end = $this->getEndTokenId();
  28350. $tokens = $this->tokenStream->tokens();
  28351. for ($i = $this->id; $i <= $end; $i++) {
  28352. switch (get_class($tokens[$i])) {
  28353. case 'PHP_Token_IF':
  28354. case 'PHP_Token_ELSEIF':
  28355. case 'PHP_Token_FOR':
  28356. case 'PHP_Token_FOREACH':
  28357. case 'PHP_Token_WHILE':
  28358. case 'PHP_Token_CASE':
  28359. case 'PHP_Token_CATCH':
  28360. case 'PHP_Token_BOOLEAN_AND':
  28361. case 'PHP_Token_LOGICAL_AND':
  28362. case 'PHP_Token_BOOLEAN_OR':
  28363. case 'PHP_Token_LOGICAL_OR':
  28364. case 'PHP_Token_QUESTION_MARK':
  28365. $this->ccn++;
  28366. break;
  28367. }
  28368. }
  28369. return $this->ccn;
  28370. }
  28371. /**
  28372. * @return string
  28373. */
  28374. public function getSignature()
  28375. {
  28376. if ($this->signature !== null) {
  28377. return $this->signature;
  28378. }
  28379. if ($this->getName() == 'anonymous function') {
  28380. $this->signature = 'anonymous function';
  28381. $i = $this->id + 1;
  28382. } else {
  28383. $this->signature = '';
  28384. $i = $this->id + 2;
  28385. }
  28386. $tokens = $this->tokenStream->tokens();
  28387. while (isset($tokens[$i]) &&
  28388. !$tokens[$i] instanceof PHP_Token_OPEN_CURLY &&
  28389. !$tokens[$i] instanceof PHP_Token_SEMICOLON) {
  28390. $this->signature .= $tokens[$i++];
  28391. }
  28392. $this->signature = trim($this->signature);
  28393. return $this->signature;
  28394. }
  28395. }
  28396. class PHP_Token_INTERFACE extends PHP_TokenWithScopeAndVisibility
  28397. {
  28398. /**
  28399. * @var array
  28400. */
  28401. protected $interfaces;
  28402. /**
  28403. * @return string
  28404. */
  28405. public function getName()
  28406. {
  28407. return (string)$this->tokenStream[$this->id + 2];
  28408. }
  28409. /**
  28410. * @return boolean
  28411. */
  28412. public function hasParent()
  28413. {
  28414. return $this->tokenStream[$this->id + 4] instanceof PHP_Token_EXTENDS;
  28415. }
  28416. /**
  28417. * @return array
  28418. */
  28419. public function getPackage()
  28420. {
  28421. $className = $this->getName();
  28422. $docComment = $this->getDocblock();
  28423. $result = array(
  28424. 'namespace' => '',
  28425. 'fullPackage' => '',
  28426. 'category' => '',
  28427. 'package' => '',
  28428. 'subpackage' => ''
  28429. );
  28430. for ($i = $this->id; $i; --$i) {
  28431. if ($this->tokenStream[$i] instanceof PHP_Token_NAMESPACE) {
  28432. $result['namespace'] = $this->tokenStream[$i]->getName();
  28433. break;
  28434. }
  28435. }
  28436. if (preg_match('/@category[\s]+([\.\w]+)/', $docComment, $matches)) {
  28437. $result['category'] = $matches[1];
  28438. }
  28439. if (preg_match('/@package[\s]+([\.\w]+)/', $docComment, $matches)) {
  28440. $result['package'] = $matches[1];
  28441. $result['fullPackage'] = $matches[1];
  28442. }
  28443. if (preg_match('/@subpackage[\s]+([\.\w]+)/', $docComment, $matches)) {
  28444. $result['subpackage'] = $matches[1];
  28445. $result['fullPackage'] .= '.' . $matches[1];
  28446. }
  28447. if (empty($result['fullPackage'])) {
  28448. $result['fullPackage'] = $this->arrayToName(
  28449. explode('_', str_replace('\\', '_', $className)),
  28450. '.'
  28451. );
  28452. }
  28453. return $result;
  28454. }
  28455. /**
  28456. * @param array $parts
  28457. * @param string $join
  28458. * @return string
  28459. */
  28460. protected function arrayToName(array $parts, $join = '\\')
  28461. {
  28462. $result = '';
  28463. if (count($parts) > 1) {
  28464. array_pop($parts);
  28465. $result = join($join, $parts);
  28466. }
  28467. return $result;
  28468. }
  28469. /**
  28470. * @return boolean|string
  28471. */
  28472. public function getParent()
  28473. {
  28474. if (!$this->hasParent()) {
  28475. return false;
  28476. }
  28477. $i = $this->id + 6;
  28478. $tokens = $this->tokenStream->tokens();
  28479. $className = (string)$tokens[$i];
  28480. while (isset($tokens[$i+1]) &&
  28481. !$tokens[$i+1] instanceof PHP_Token_WHITESPACE) {
  28482. $className .= (string)$tokens[++$i];
  28483. }
  28484. return $className;
  28485. }
  28486. /**
  28487. * @return boolean
  28488. */
  28489. public function hasInterfaces()
  28490. {
  28491. return (isset($this->tokenStream[$this->id + 4]) &&
  28492. $this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) ||
  28493. (isset($this->tokenStream[$this->id + 8]) &&
  28494. $this->tokenStream[$this->id + 8] instanceof PHP_Token_IMPLEMENTS);
  28495. }
  28496. /**
  28497. * @return array|boolean
  28498. */
  28499. public function getInterfaces()
  28500. {
  28501. if ($this->interfaces !== null) {
  28502. return $this->interfaces;
  28503. }
  28504. if (!$this->hasInterfaces()) {
  28505. return ($this->interfaces = false);
  28506. }
  28507. if ($this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) {
  28508. $i = $this->id + 3;
  28509. } else {
  28510. $i = $this->id + 7;
  28511. }
  28512. $tokens = $this->tokenStream->tokens();
  28513. while (!$tokens[$i+1] instanceof PHP_Token_OPEN_CURLY) {
  28514. $i++;
  28515. if ($tokens[$i] instanceof PHP_Token_STRING) {
  28516. $this->interfaces[] = (string)$tokens[$i];
  28517. }
  28518. }
  28519. return $this->interfaces;
  28520. }
  28521. }
  28522. class PHP_Token_ABSTRACT extends PHP_Token {}
  28523. class PHP_Token_AMPERSAND extends PHP_Token {}
  28524. class PHP_Token_AND_EQUAL extends PHP_Token {}
  28525. class PHP_Token_ARRAY extends PHP_Token {}
  28526. class PHP_Token_ARRAY_CAST extends PHP_Token {}
  28527. class PHP_Token_AS extends PHP_Token {}
  28528. class PHP_Token_AT extends PHP_Token {}
  28529. class PHP_Token_BACKTICK extends PHP_Token {}
  28530. class PHP_Token_BAD_CHARACTER extends PHP_Token {}
  28531. class PHP_Token_BOOLEAN_AND extends PHP_Token {}
  28532. class PHP_Token_BOOLEAN_OR extends PHP_Token {}
  28533. class PHP_Token_BOOL_CAST extends PHP_Token {}
  28534. class PHP_Token_BREAK extends PHP_Token {}
  28535. class PHP_Token_CARET extends PHP_Token {}
  28536. class PHP_Token_CASE extends PHP_Token {}
  28537. class PHP_Token_CATCH extends PHP_Token {}
  28538. class PHP_Token_CHARACTER extends PHP_Token {}
  28539. class PHP_Token_CLASS extends PHP_Token_INTERFACE {}
  28540. class PHP_Token_CLASS_C extends PHP_Token {}
  28541. class PHP_Token_CLASS_NAME_CONSTANT extends PHP_Token {}
  28542. class PHP_Token_CLONE extends PHP_Token {}
  28543. class PHP_Token_CLOSE_BRACKET extends PHP_Token {}
  28544. class PHP_Token_CLOSE_CURLY extends PHP_Token {}
  28545. class PHP_Token_CLOSE_SQUARE extends PHP_Token {}
  28546. class PHP_Token_CLOSE_TAG extends PHP_Token {}
  28547. class PHP_Token_COLON extends PHP_Token {}
  28548. class PHP_Token_COMMA extends PHP_Token {}
  28549. class PHP_Token_COMMENT extends PHP_Token {}
  28550. class PHP_Token_CONCAT_EQUAL extends PHP_Token {}
  28551. class PHP_Token_CONST extends PHP_Token {}
  28552. class PHP_Token_CONSTANT_ENCAPSED_STRING extends PHP_Token {}
  28553. class PHP_Token_CONTINUE extends PHP_Token {}
  28554. class PHP_Token_CURLY_OPEN extends PHP_Token {}
  28555. class PHP_Token_DEC extends PHP_Token {}
  28556. class PHP_Token_DECLARE extends PHP_Token {}
  28557. class PHP_Token_DEFAULT extends PHP_Token {}
  28558. class PHP_Token_DIV extends PHP_Token {}
  28559. class PHP_Token_DIV_EQUAL extends PHP_Token {}
  28560. class PHP_Token_DNUMBER extends PHP_Token {}
  28561. class PHP_Token_DO extends PHP_Token {}
  28562. class PHP_Token_DOC_COMMENT extends PHP_Token {}
  28563. class PHP_Token_DOLLAR extends PHP_Token {}
  28564. class PHP_Token_DOLLAR_OPEN_CURLY_BRACES extends PHP_Token {}
  28565. class PHP_Token_DOT extends PHP_Token {}
  28566. class PHP_Token_DOUBLE_ARROW extends PHP_Token {}
  28567. class PHP_Token_DOUBLE_CAST extends PHP_Token {}
  28568. class PHP_Token_DOUBLE_COLON extends PHP_Token {}
  28569. class PHP_Token_DOUBLE_QUOTES extends PHP_Token {}
  28570. class PHP_Token_ECHO extends PHP_Token {}
  28571. class PHP_Token_ELSE extends PHP_Token {}
  28572. class PHP_Token_ELSEIF extends PHP_Token {}
  28573. class PHP_Token_EMPTY extends PHP_Token {}
  28574. class PHP_Token_ENCAPSED_AND_WHITESPACE extends PHP_Token {}
  28575. class PHP_Token_ENDDECLARE extends PHP_Token {}
  28576. class PHP_Token_ENDFOR extends PHP_Token {}
  28577. class PHP_Token_ENDFOREACH extends PHP_Token {}
  28578. class PHP_Token_ENDIF extends PHP_Token {}
  28579. class PHP_Token_ENDSWITCH extends PHP_Token {}
  28580. class PHP_Token_ENDWHILE extends PHP_Token {}
  28581. class PHP_Token_END_HEREDOC extends PHP_Token {}
  28582. class PHP_Token_EQUAL extends PHP_Token {}
  28583. class PHP_Token_EVAL extends PHP_Token {}
  28584. class PHP_Token_EXCLAMATION_MARK extends PHP_Token {}
  28585. class PHP_Token_EXIT extends PHP_Token {}
  28586. class PHP_Token_EXTENDS extends PHP_Token {}
  28587. class PHP_Token_FILE extends PHP_Token {}
  28588. class PHP_Token_FINAL extends PHP_Token {}
  28589. class PHP_Token_FOR extends PHP_Token {}
  28590. class PHP_Token_FOREACH extends PHP_Token {}
  28591. class PHP_Token_FUNC_C extends PHP_Token {}
  28592. class PHP_Token_GLOBAL extends PHP_Token {}
  28593. class PHP_Token_GT extends PHP_Token {}
  28594. class PHP_Token_IF extends PHP_Token {}
  28595. class PHP_Token_IMPLEMENTS extends PHP_Token {}
  28596. class PHP_Token_INC extends PHP_Token {}
  28597. class PHP_Token_INCLUDE extends PHP_Token_Includes {}
  28598. class PHP_Token_INCLUDE_ONCE extends PHP_Token_Includes {}
  28599. class PHP_Token_INLINE_HTML extends PHP_Token {}
  28600. class PHP_Token_INSTANCEOF extends PHP_Token {}
  28601. class PHP_Token_INT_CAST extends PHP_Token {}
  28602. class PHP_Token_ISSET extends PHP_Token {}
  28603. class PHP_Token_IS_EQUAL extends PHP_Token {}
  28604. class PHP_Token_IS_GREATER_OR_EQUAL extends PHP_Token {}
  28605. class PHP_Token_IS_IDENTICAL extends PHP_Token {}
  28606. class PHP_Token_IS_NOT_EQUAL extends PHP_Token {}
  28607. class PHP_Token_IS_NOT_IDENTICAL extends PHP_Token {}
  28608. class PHP_Token_IS_SMALLER_OR_EQUAL extends PHP_Token {}
  28609. class PHP_Token_LINE extends PHP_Token {}
  28610. class PHP_Token_LIST extends PHP_Token {}
  28611. class PHP_Token_LNUMBER extends PHP_Token {}
  28612. class PHP_Token_LOGICAL_AND extends PHP_Token {}
  28613. class PHP_Token_LOGICAL_OR extends PHP_Token {}
  28614. class PHP_Token_LOGICAL_XOR extends PHP_Token {}
  28615. class PHP_Token_LT extends PHP_Token {}
  28616. class PHP_Token_METHOD_C extends PHP_Token {}
  28617. class PHP_Token_MINUS extends PHP_Token {}
  28618. class PHP_Token_MINUS_EQUAL extends PHP_Token {}
  28619. class PHP_Token_MOD_EQUAL extends PHP_Token {}
  28620. class PHP_Token_MULT extends PHP_Token {}
  28621. class PHP_Token_MUL_EQUAL extends PHP_Token {}
  28622. class PHP_Token_NEW extends PHP_Token {}
  28623. class PHP_Token_NUM_STRING extends PHP_Token {}
  28624. class PHP_Token_OBJECT_CAST extends PHP_Token {}
  28625. class PHP_Token_OBJECT_OPERATOR extends PHP_Token {}
  28626. class PHP_Token_OPEN_BRACKET extends PHP_Token {}
  28627. class PHP_Token_OPEN_CURLY extends PHP_Token {}
  28628. class PHP_Token_OPEN_SQUARE extends PHP_Token {}
  28629. class PHP_Token_OPEN_TAG extends PHP_Token {}
  28630. class PHP_Token_OPEN_TAG_WITH_ECHO extends PHP_Token {}
  28631. class PHP_Token_OR_EQUAL extends PHP_Token {}
  28632. class PHP_Token_PAAMAYIM_NEKUDOTAYIM extends PHP_Token {}
  28633. class PHP_Token_PERCENT extends PHP_Token {}
  28634. class PHP_Token_PIPE extends PHP_Token {}
  28635. class PHP_Token_PLUS extends PHP_Token {}
  28636. class PHP_Token_PLUS_EQUAL extends PHP_Token {}
  28637. class PHP_Token_PRINT extends PHP_Token {}
  28638. class PHP_Token_PRIVATE extends PHP_Token {}
  28639. class PHP_Token_PROTECTED extends PHP_Token {}
  28640. class PHP_Token_PUBLIC extends PHP_Token {}
  28641. class PHP_Token_QUESTION_MARK extends PHP_Token {}
  28642. class PHP_Token_REQUIRE extends PHP_Token_Includes {}
  28643. class PHP_Token_REQUIRE_ONCE extends PHP_Token_Includes {}
  28644. class PHP_Token_RETURN extends PHP_Token {}
  28645. class PHP_Token_SEMICOLON extends PHP_Token {}
  28646. class PHP_Token_SL extends PHP_Token {}
  28647. class PHP_Token_SL_EQUAL extends PHP_Token {}
  28648. class PHP_Token_SR extends PHP_Token {}
  28649. class PHP_Token_SR_EQUAL extends PHP_Token {}
  28650. class PHP_Token_START_HEREDOC extends PHP_Token {}
  28651. class PHP_Token_STATIC extends PHP_Token {}
  28652. class PHP_Token_STRING extends PHP_Token {}
  28653. class PHP_Token_STRING_CAST extends PHP_Token {}
  28654. class PHP_Token_STRING_VARNAME extends PHP_Token {}
  28655. class PHP_Token_SWITCH extends PHP_Token {}
  28656. class PHP_Token_THROW extends PHP_Token {}
  28657. class PHP_Token_TILDE extends PHP_Token {}
  28658. class PHP_Token_TRY extends PHP_Token {}
  28659. class PHP_Token_UNSET extends PHP_Token {}
  28660. class PHP_Token_UNSET_CAST extends PHP_Token {}
  28661. class PHP_Token_USE extends PHP_Token {}
  28662. class PHP_Token_VAR extends PHP_Token {}
  28663. class PHP_Token_VARIABLE extends PHP_Token {}
  28664. class PHP_Token_WHILE extends PHP_Token {}
  28665. class PHP_Token_WHITESPACE extends PHP_Token {}
  28666. class PHP_Token_XOR_EQUAL extends PHP_Token {}
  28667. // Tokens introduced in PHP 5.1
  28668. class PHP_Token_HALT_COMPILER extends PHP_Token {}
  28669. // Tokens introduced in PHP 5.3
  28670. class PHP_Token_DIR extends PHP_Token {}
  28671. class PHP_Token_GOTO extends PHP_Token {}
  28672. class PHP_Token_NAMESPACE extends PHP_TokenWithScope
  28673. {
  28674. /**
  28675. * @return string
  28676. */
  28677. public function getName()
  28678. {
  28679. $tokens = $this->tokenStream->tokens();
  28680. $namespace = (string)$tokens[$this->id+2];
  28681. for ($i = $this->id + 3;; $i += 2) {
  28682. if (isset($tokens[$i]) &&
  28683. $tokens[$i] instanceof PHP_Token_NS_SEPARATOR) {
  28684. $namespace .= '\\' . $tokens[$i+1];
  28685. } else {
  28686. break;
  28687. }
  28688. }
  28689. return $namespace;
  28690. }
  28691. }
  28692. class PHP_Token_NS_C extends PHP_Token {}
  28693. class PHP_Token_NS_SEPARATOR extends PHP_Token {}
  28694. // Tokens introduced in PHP 5.4
  28695. class PHP_Token_CALLABLE extends PHP_Token {}
  28696. class PHP_Token_INSTEADOF extends PHP_Token {}
  28697. class PHP_Token_TRAIT extends PHP_Token_INTERFACE {}
  28698. class PHP_Token_TRAIT_C extends PHP_Token {}
  28699. // Tokens introduced in PHP 5.5
  28700. class PHP_Token_FINALLY extends PHP_Token {}
  28701. class PHP_Token_YIELD extends PHP_Token {}
  28702. // Tokens introduced in PHP 5.6
  28703. class PHP_Token_ELLIPSIS extends PHP_Token {}
  28704. class PHP_Token_POW extends PHP_Token {}
  28705. class PHP_Token_POW_EQUAL extends PHP_Token {}
  28706. // Tokens introduced in PHP 7.0
  28707. class PHP_Token_COALESCE extends PHP_Token {}
  28708. class PHP_Token_SPACESHIP extends PHP_Token {}
  28709. class PHP_Token_YIELD_FROM extends PHP_Token {}
  28710. // Tokens introduced in HackLang / HHVM
  28711. class PHP_Token_COMPILER_HALT_OFFSET extends PHP_Token {}
  28712. class PHP_Token_ENUM extends PHP_Token {}
  28713. class PHP_Token_IN extends PHP_Token {}
  28714. class PHP_Token_JOIN extends PHP_Token {}
  28715. class PHP_Token_LAMBDA_ARROW extends PHP_Token {}
  28716. class PHP_Token_LAMBDA_CP extends PHP_Token {}
  28717. class PHP_Token_LAMBDA_OP extends PHP_Token {}
  28718. class PHP_Token_ONUMBER extends PHP_Token {}
  28719. class PHP_Token_SHAPE extends PHP_Token {}
  28720. class PHP_Token_TYPE extends PHP_Token {}
  28721. class PHP_Token_TYPELIST_GT extends PHP_Token {}
  28722. class PHP_Token_TYPELIST_LT extends PHP_Token {}
  28723. class PHP_Token_XHP_ATTRIBUTE extends PHP_Token {}
  28724. class PHP_Token_XHP_CATEGORY extends PHP_Token {}
  28725. class PHP_Token_XHP_CATEGORY_LABEL extends PHP_Token {}
  28726. class PHP_Token_XHP_CHILDREN extends PHP_Token {}
  28727. class PHP_Token_XHP_LABEL extends PHP_Token {}
  28728. class PHP_Token_XHP_REQUIRED extends PHP_Token {}
  28729. class PHP_Token_XHP_TAG_GT extends PHP_Token {}
  28730. class PHP_Token_XHP_TAG_LT extends PHP_Token {}
  28731. class PHP_Token_XHP_TEXT extends PHP_Token {}
  28732. <?php
  28733. /*
  28734. * This file is part of DBUnit.
  28735. *
  28736. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28737. *
  28738. * For the full copyright and license information, please view the LICENSE
  28739. * file that was distributed with this source code.
  28740. */
  28741. /**
  28742. * Thrown for exceptions encountered with database operations. Provides
  28743. * information regarding which operations failed and the query (if any) it
  28744. * failed on.
  28745. *
  28746. * @package DbUnit
  28747. * @author Mike Lively <m@digitalsandwich.com>
  28748. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  28749. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  28750. * @version Release: @package_version@
  28751. * @link http://www.phpunit.de/
  28752. * @since Class available since Release 1.0.0
  28753. */
  28754. class PHPUnit_Extensions_Database_Exception extends Exception
  28755. {
  28756. }
  28757. <?php
  28758. /*
  28759. * This file is part of DBUnit.
  28760. *
  28761. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28762. *
  28763. * For the full copyright and license information, please view the LICENSE
  28764. * file that was distributed with this source code.
  28765. */
  28766. /**
  28767. * Defines the interface necessary to create new medium printers.
  28768. *
  28769. * @package DbUnit
  28770. * @author Mike Lively <m@digitalsandwich.com>
  28771. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  28772. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  28773. * @version Release: @package_version@
  28774. * @link http://www.phpunit.de//**
  28775. * @since Class available since Release 1.0.0
  28776. */
  28777. interface PHPUnit_Extensions_Database_UI_IMediumPrinter
  28778. {
  28779. /**
  28780. * Prints standard output messages.
  28781. *
  28782. * @param string $message
  28783. */
  28784. public function output($message);
  28785. /**
  28786. * Prints standard error messages.
  28787. *
  28788. * @param string $message
  28789. */
  28790. public function error($message);
  28791. }
  28792. <?php
  28793. /*
  28794. * This file is part of DBUnit.
  28795. *
  28796. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28797. *
  28798. * For the full copyright and license information, please view the LICENSE
  28799. * file that was distributed with this source code.
  28800. */
  28801. /**
  28802. * Delegates database extension commands to the appropriate mode classes.
  28803. *
  28804. * @package DbUnit
  28805. * @author Mike Lively <m@digitalsandwich.com>
  28806. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  28807. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  28808. * @version Release: @package_version@
  28809. * @link http://www.phpunit.de//**
  28810. * @since Class available since Release 1.0.0
  28811. */
  28812. class PHPUnit_Extensions_Database_UI_Command
  28813. {
  28814. /**
  28815. * @var PHPUnit_Extensions_Database_UI_IModeFactory
  28816. */
  28817. protected $modeFactory;
  28818. /**
  28819. * @param PHPUnit_Extensions_Database_UI_IModeFactory $modeFactory
  28820. */
  28821. public function __construct(PHPUnit_Extensions_Database_UI_IModeFactory $modeFactory)
  28822. {
  28823. $this->modeFactory = $modeFactory;
  28824. }
  28825. /**
  28826. * Executes the database extension ui.
  28827. *
  28828. * @param PHPUnit_Extensions_Database_UI_IMedium $medium
  28829. * @param PHPUnit_Extensions_Database_UI_Context $context
  28830. */
  28831. public function main(PHPUnit_Extensions_Database_UI_IMedium $medium, PHPUnit_Extensions_Database_UI_Context $context)
  28832. {
  28833. try {
  28834. $medium->buildContext($context);
  28835. $mode = $this->modeFactory->getMode($context->getMode());
  28836. $mode->execute($context->getModeArguments(), $medium);
  28837. } catch (Exception $e) {
  28838. $medium->handleException($e);
  28839. }
  28840. }
  28841. }
  28842. <?php
  28843. /*
  28844. * This file is part of DBUnit.
  28845. *
  28846. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28847. *
  28848. * For the full copyright and license information, please view the LICENSE
  28849. * file that was distributed with this source code.
  28850. */
  28851. /**
  28852. * A text medium for the database extension tool.
  28853. *
  28854. * This class builds the call context based on command line parameters and
  28855. * prints output to stdout and stderr as appropriate.
  28856. *
  28857. * @package DbUnit
  28858. * @author Mike Lively <m@digitalsandwich.com>
  28859. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  28860. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  28861. * @version Release: @package_version@
  28862. * @link http://www.phpunit.de/
  28863. * @since Class available since Release 1.0.0
  28864. */
  28865. class PHPUnit_Extensions_Database_UI_Mediums_Text implements PHPUnit_Extensions_Database_UI_IMedium
  28866. {
  28867. /**
  28868. * @var array
  28869. */
  28870. protected $arguments;
  28871. /**
  28872. * @var string
  28873. */
  28874. protected $command;
  28875. /**
  28876. * @param array $arguments
  28877. */
  28878. public function __construct(Array $arguments)
  28879. {
  28880. $this->arguments = $arguments;
  28881. }
  28882. /**
  28883. * Builds the context for the application.
  28884. *
  28885. * @param PHPUnit_Extensions_Database_UI_Context $context
  28886. */
  28887. public function buildContext(PHPUnit_Extensions_Database_UI_Context $context)
  28888. {
  28889. $arguments = $this->arguments;
  28890. $this->command = array_shift($arguments);
  28891. $context->setMode(array_shift($arguments));
  28892. $context->setModeArguments($arguments);
  28893. }
  28894. /**
  28895. * Handles the displaying of exceptions received from the application.
  28896. *
  28897. * @param Exception $e
  28898. */
  28899. public function handleException(Exception $e)
  28900. {
  28901. try {
  28902. throw $e;
  28903. } catch (PHPUnit_Extensions_Database_UI_InvalidModeException $invalidMode) {
  28904. if ($invalidMode->getMode() == '') {
  28905. $this->error('Please Specify a Command!' . PHP_EOL);
  28906. } else {
  28907. $this->error('Command Does Not Exist: ' . $invalidMode->getMode() . PHP_EOL);
  28908. }
  28909. $this->error('Valid Commands:' . PHP_EOL);
  28910. foreach ($invalidMode->getValidModes() as $mode) {
  28911. $this->error(' ' . $mode . PHP_EOL);
  28912. }
  28913. } catch (Exception $e) {
  28914. $this->error('Unknown Error: ' . $e->getMessage() . PHP_EOL);
  28915. }
  28916. }
  28917. /**
  28918. * Prints the message to stdout.
  28919. *
  28920. * @param string $message
  28921. */
  28922. public function output($message)
  28923. {
  28924. echo $message;
  28925. }
  28926. /**
  28927. * Prints the message to stderr
  28928. *
  28929. * @param string $message
  28930. */
  28931. public function error($message)
  28932. {
  28933. fputs(STDERR, $message);
  28934. }
  28935. }
  28936. <?php
  28937. /*
  28938. * This file is part of DBUnit.
  28939. *
  28940. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28941. *
  28942. * For the full copyright and license information, please view the LICENSE
  28943. * file that was distributed with this source code.
  28944. */
  28945. /**
  28946. * An exception thrown when an invalid mode is requested from a mode factory.
  28947. *
  28948. * @package DbUnit
  28949. * @author Mike Lively <m@digitalsandwich.com>
  28950. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  28951. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  28952. * @version Release: @package_version@
  28953. * @link http://www.phpunit.de//**
  28954. * @since Class available since Release 1.0.0
  28955. */
  28956. class PHPUnit_Extensions_Database_UI_InvalidModeException extends LogicException
  28957. {
  28958. /**
  28959. * @var string
  28960. */
  28961. protected $mode;
  28962. /**
  28963. * @var PHPUnit_Extensions_Database_UI_IModeFactory
  28964. */
  28965. protected $modeFactory;
  28966. /**
  28967. * @param string $mode
  28968. * @param string $msg
  28969. * @param PHPUnit_Extensions_Database_UI_IModeFactory $modeFactory
  28970. */
  28971. public function __construct($mode, $msg, PHPUnit_Extensions_Database_UI_IModeFactory $modeFactory)
  28972. {
  28973. $this->mode = $mode;
  28974. $this->modeFactory = $modeFactory;
  28975. parent::__construct($msg);
  28976. }
  28977. /**
  28978. * @return string
  28979. */
  28980. public function getMode()
  28981. {
  28982. return $this->mode;
  28983. }
  28984. /**
  28985. * @return array
  28986. */
  28987. public function getValidModes()
  28988. {
  28989. return $this->modeFactory->getModeList();
  28990. }
  28991. }
  28992. <?php
  28993. /*
  28994. * This file is part of DBUnit.
  28995. *
  28996. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  28997. *
  28998. * For the full copyright and license information, please view the LICENSE
  28999. * file that was distributed with this source code.
  29000. */
  29001. /**
  29002. * Defines the interface necessary to create new modes
  29003. *
  29004. * @package DbUnit
  29005. * @author Mike Lively <m@digitalsandwich.com>
  29006. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29007. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29008. * @version Release: @package_version@
  29009. * @link http://www.phpunit.de//**
  29010. * @since Class available since Release 1.0.0
  29011. */
  29012. interface PHPUnit_Extensions_Database_UI_IMode
  29013. {
  29014. /**
  29015. * Executes the mode using the given arguments and medium.
  29016. *
  29017. * @param array $modeArguments
  29018. * @param PHPUnit_Extensions_Database_UI_IMediumPrinter $medium
  29019. */
  29020. public function execute(array $modeArguments, PHPUnit_Extensions_Database_UI_IMediumPrinter $medium);
  29021. }
  29022. <?php
  29023. /*
  29024. * This file is part of DBUnit.
  29025. *
  29026. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29027. *
  29028. * For the full copyright and license information, please view the LICENSE
  29029. * file that was distributed with this source code.
  29030. */
  29031. /**
  29032. * Holds the context of a particular database extension ui call.
  29033. *
  29034. * @package DbUnit
  29035. * @author Mike Lively <m@digitalsandwich.com>
  29036. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29037. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29038. * @version Release: @package_version@
  29039. * @link http://www.phpunit.de//**
  29040. * @since Class available since Release 1.0.0
  29041. */
  29042. class PHPUnit_Extensions_Database_UI_Context
  29043. {
  29044. /**
  29045. * @var string
  29046. */
  29047. protected $mode;
  29048. /**
  29049. * @var array
  29050. */
  29051. protected $modeArguments;
  29052. /**
  29053. * @param string $mode
  29054. */
  29055. public function setMode($mode)
  29056. {
  29057. $this->mode = $mode;
  29058. }
  29059. /**
  29060. * @return string
  29061. */
  29062. public function getMode()
  29063. {
  29064. return $this->mode;
  29065. }
  29066. /**
  29067. * @param array $arguments
  29068. */
  29069. public function setModeArguments(array $arguments)
  29070. {
  29071. $this->mode_arguments = $arguments;
  29072. }
  29073. /**
  29074. * @return array
  29075. */
  29076. public function getModeArguments()
  29077. {
  29078. return $this->mode_arguments;
  29079. }
  29080. }
  29081. <?php
  29082. /*
  29083. * This file is part of DBUnit.
  29084. *
  29085. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29086. *
  29087. * For the full copyright and license information, please view the LICENSE
  29088. * file that was distributed with this source code.
  29089. */
  29090. /**
  29091. * Represents arguments received from a medium.
  29092. *
  29093. * @package DbUnit
  29094. * @author Mike Lively <m@digitalsandwich.com>
  29095. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29096. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29097. * @version Release: @package_version@
  29098. * @link http://www.phpunit.de/
  29099. * @since Class available since Release 1.0.0
  29100. */
  29101. class PHPUnit_Extensions_Database_UI_Modes_ExportDataSet_Arguments
  29102. {
  29103. /**
  29104. * @var array
  29105. */
  29106. protected $arguments = array();
  29107. /**
  29108. * @param array $arguments
  29109. */
  29110. public function __construct(array $arguments)
  29111. {
  29112. foreach ($arguments as $argument) {
  29113. list($argName, $argValue) = explode('=', $argument, 2);
  29114. $argName = trim($argName, '-');
  29115. if (!isset($this->arguments[$argName])) {
  29116. $this->arguments[$argName] = array();
  29117. }
  29118. $this->arguments[$argName][] = $argValue;
  29119. }
  29120. }
  29121. /**
  29122. * Returns an array of arguments matching the given $argName
  29123. *
  29124. * @param string $argName
  29125. * @return array
  29126. */
  29127. public function getArgumentArray($argName)
  29128. {
  29129. if ($this->argumentIsSet($argName)) {
  29130. return $this->arguments[$argName];
  29131. } else {
  29132. return NULL;
  29133. }
  29134. }
  29135. /**
  29136. * Returns a single argument value.
  29137. *
  29138. * If $argName points to an array the first argument will be returned.
  29139. *
  29140. * @param string $argName
  29141. * @return mixed
  29142. */
  29143. public function getSingleArgument($argName)
  29144. {
  29145. if ($this->argumentIsSet($argName)) {
  29146. return reset($this->arguments[$argName]);
  29147. } else {
  29148. return NULL;
  29149. }
  29150. }
  29151. /**
  29152. * Returns whether an argument is set.
  29153. *
  29154. * @param string $argName
  29155. * @return bool
  29156. */
  29157. public function argumentIsSet($argName)
  29158. {
  29159. return array_key_exists($argName, $this->arguments);
  29160. }
  29161. /**
  29162. * Returns an array containing the names of all arguments provided.
  29163. *
  29164. * @return array
  29165. */
  29166. public function getArgumentNames()
  29167. {
  29168. return array_keys($this->arguments);
  29169. }
  29170. /**
  29171. * Returns an array of database arguments keyed by name.
  29172. *
  29173. * @todo this should be moved.
  29174. * @return array
  29175. */
  29176. public function getDatabases()
  29177. {
  29178. $databases = $this->getArgumentArray('database');
  29179. $retDb = array();
  29180. foreach ($databases as $db) {
  29181. list($name, $arg) = explode(':', $db, 2);
  29182. $retDb[$name] = $arg;
  29183. }
  29184. return $retDb;
  29185. }
  29186. }
  29187. <?php
  29188. /*
  29189. * This file is part of DBUnit.
  29190. *
  29191. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29192. *
  29193. * For the full copyright and license information, please view the LICENSE
  29194. * file that was distributed with this source code.
  29195. */
  29196. /**
  29197. * The class for the export-dataset command.
  29198. *
  29199. * This command is used to convert existing data sets or data in the database
  29200. * into a valid data set format.
  29201. *
  29202. * @package DbUnit
  29203. * @author Mike Lively <m@digitalsandwich.com>
  29204. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29205. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29206. * @version Release: @package_version@
  29207. * @link http://www.phpunit.de/
  29208. * @since Class available since Release 1.0.0
  29209. */
  29210. class PHPUnit_Extensions_Database_UI_Modes_ExportDataSet implements PHPUnit_Extensions_Database_UI_IMode
  29211. {
  29212. /**
  29213. * Executes the export dataset command.
  29214. *
  29215. * @param array $modeArguments
  29216. * @param PHPUnit_Extensions_Database_UI_IMediumPrinter $medium
  29217. */
  29218. public function execute(array $modeArguments, PHPUnit_Extensions_Database_UI_IMediumPrinter $medium)
  29219. {
  29220. $arguments = new PHPUnit_Extensions_Database_UI_Modes_ExportDataSet_Arguments($modeArguments);
  29221. if (FALSE && !$arguments->areValid()) {
  29222. throw new InvalidArgumentException("The arguments for this command are incorrect.");
  29223. }
  29224. $datasets = array();
  29225. foreach ($arguments->getArgumentArray('dataset') as $argString) {
  29226. $datasets[] = $this->getDataSetFromArgument($argString, $arguments->getDatabases());
  29227. }
  29228. $finalDataset = new PHPUnit_Extensions_Database_DataSet_CompositeDataSet($datasets);
  29229. $outputDataset = $this->getPersistorFromArgument($arguments->getSingleArgument('output'));
  29230. $outputDataset->write($finalDataset);
  29231. }
  29232. /**
  29233. * Returns the correct dataset given an argument containing a dataset spec.
  29234. *
  29235. * @param string $argString
  29236. * @param array $databaseList
  29237. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  29238. */
  29239. protected function getDataSetFromArgument($argString, $databaseList)
  29240. {
  29241. $dataSetSpecFactory = new PHPUnit_Extensions_Database_DataSet_Specs_Factory();
  29242. list($type, $dataSetSpecStr) = explode(':', $argString, 2);
  29243. $dataSetSpec = $dataSetSpecFactory->getDataSetSpecByType($type);
  29244. if ($dataSetSpec instanceof PHPUnit_Extensions_Database_IDatabaseListConsumer) {
  29245. $dataSetSpec->setDatabases($databaseList);
  29246. }
  29247. return $dataSetSpec->getDataSet($dataSetSpecStr);
  29248. }
  29249. /**
  29250. * Returns the correct persistor given an argument containing a persistor spec.
  29251. *
  29252. * @param string $argString
  29253. * @return PHPUnit_Extensions_Database_DataSet_IPersistable
  29254. */
  29255. protected function getPersistorFromArgument($argString)
  29256. {
  29257. $persistorFactory = new PHPUnit_Extensions_Database_DataSet_Persistors_Factory();
  29258. list($type, $spec) = explode(':', $argString, 2);
  29259. return $persistorFactory->getPersistorBySpec($type, $spec);
  29260. }
  29261. }
  29262. <?php
  29263. /*
  29264. * This file is part of DBUnit.
  29265. *
  29266. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29267. *
  29268. * For the full copyright and license information, please view the LICENSE
  29269. * file that was distributed with this source code.
  29270. */
  29271. /**
  29272. * Defines the interface necessary to create new mediums.
  29273. *
  29274. * @package DbUnit
  29275. * @author Mike Lively <m@digitalsandwich.com>
  29276. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29277. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29278. * @version Release: @package_version@
  29279. * @link http://www.phpunit.de//**
  29280. * @since Class available since Release 1.0.0
  29281. */
  29282. interface PHPUnit_Extensions_Database_UI_IMedium extends PHPUnit_Extensions_Database_UI_IMediumPrinter
  29283. {
  29284. /**
  29285. * Builds the context for the application.
  29286. *
  29287. * @param PHPUnit_Extensions_Database_UI_Context $context
  29288. */
  29289. public function buildContext(PHPUnit_Extensions_Database_UI_Context $context);
  29290. /**
  29291. * Handles the displaying of exceptions received from the application.
  29292. *
  29293. * @param Exception $e
  29294. */
  29295. public function handleException(Exception $e);
  29296. }
  29297. <?php
  29298. /*
  29299. * This file is part of DBUnit.
  29300. *
  29301. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29302. *
  29303. * For the full copyright and license information, please view the LICENSE
  29304. * file that was distributed with this source code.
  29305. */
  29306. /**
  29307. * The default factory for db extension modes.
  29308. *
  29309. * @package DbUnit
  29310. * @author Mike Lively <m@digitalsandwich.com>
  29311. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29312. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29313. * @version Release: @package_version@
  29314. * @link http://www.phpunit.de//**
  29315. * @since Class available since Release 1.0.0
  29316. */
  29317. class PHPUnit_Extensions_Database_UI_ModeFactory implements PHPUnit_Extensions_Database_UI_IModeFactory
  29318. {
  29319. /**
  29320. * Generates a new mode based on a given name.
  29321. *
  29322. * @param string $mode
  29323. * @return PHPUnit_Extensions_Database_UI_IMode
  29324. */
  29325. public function getMode($mode)
  29326. {
  29327. if ($mode == '') {
  29328. throw new PHPUnit_Extensions_Database_UI_InvalidModeException($mode, 'A mode was not provided.', $this);
  29329. }
  29330. $modeMap = $this->getModeMap();
  29331. if (isset($modeMap[$mode])) {
  29332. $modeClass = $this->getModeClass($mode, $modeMap[$mode]);
  29333. return new $modeClass();
  29334. } else {
  29335. throw new PHPUnit_Extensions_Database_UI_InvalidModeException($mode, 'The mode does not exist. Attempting to load mode ' . $mode, $this);
  29336. }
  29337. }
  29338. /**
  29339. * Returns the names of valid modes this factory can create.
  29340. *
  29341. * @return array
  29342. */
  29343. public function getModeList()
  29344. {
  29345. return array_keys($this->getModeMap());
  29346. }
  29347. /**
  29348. * Returns a map of modes to class name parts
  29349. *
  29350. * @return array
  29351. */
  29352. protected function getModeMap()
  29353. {
  29354. return array('export-dataset' => 'ExportDataSet');
  29355. }
  29356. /**
  29357. * Given a $mode label and a $mode_name class part attempts to return the
  29358. * class name necessary to instantiate the mode.
  29359. *
  29360. * @param string $mode
  29361. * @param string $mode_name
  29362. * @return string
  29363. */
  29364. protected function getModeClass($mode, $mode_name)
  29365. {
  29366. $modeClass = 'PHPUnit_Extensions_Database_UI_Modes_' . $mode_name;
  29367. $modeFile = dirname(__FILE__) . '/Modes/' . $mode_name . '.php';
  29368. if (class_exists($modeClass)) {
  29369. return $modeClass;
  29370. }
  29371. if (!is_readable($modeFile)) {
  29372. throw new PHPUnit_Extensions_Database_UI_InvalidModeException($mode, 'The mode\'s file could not be loaded. Trying file ' . $modeFile, $this);
  29373. }
  29374. require_once ($modeFile);
  29375. if (!class_exists($modeClass)) {
  29376. throw new PHPUnit_Extensions_Database_UI_InvalidModeException($mode, 'The mode class was not found in the file. Expecting class name ' . $modeClass, $this);
  29377. }
  29378. return $modeClass;
  29379. }
  29380. }
  29381. <?php
  29382. /*
  29383. * This file is part of DBUnit.
  29384. *
  29385. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29386. *
  29387. * For the full copyright and license information, please view the LICENSE
  29388. * file that was distributed with this source code.
  29389. */
  29390. /**
  29391. * Defines the interface necessary to create new mode factories
  29392. *
  29393. * @package DbUnit
  29394. * @author Mike Lively <m@digitalsandwich.com>
  29395. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29396. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29397. * @version Release: @package_version@
  29398. * @link http://www.phpunit.de//**
  29399. * @since Class available since Release 1.0.0
  29400. */
  29401. interface PHPUnit_Extensions_Database_UI_IModeFactory
  29402. {
  29403. /**
  29404. * Generates a new mode based on a given name.
  29405. *
  29406. * @param string $mode
  29407. * @return PHPUnit_Extensions_Database_UI_IMode
  29408. */
  29409. public function getMode($mode);
  29410. /**
  29411. * Returns the names of valid modes this factory can create.
  29412. *
  29413. * @return array
  29414. */
  29415. public function getModeList();
  29416. }
  29417. <?php
  29418. /*
  29419. * This file is part of DBUnit.
  29420. *
  29421. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29422. *
  29423. * For the full copyright and license information, please view the LICENSE
  29424. * file that was distributed with this source code.
  29425. */
  29426. /**
  29427. * An interface for classes that require a list of databases to operate.
  29428. *
  29429. * @package DbUnit
  29430. * @author Mike Lively <m@digitalsandwich.com>
  29431. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29432. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29433. * @version Release: @package_version@
  29434. * @link http://www.phpunit.de/
  29435. * @since Class available since Release 1.0.0
  29436. */
  29437. interface PHPUnit_Extensions_Database_IDatabaseListConsumer
  29438. {
  29439. /**
  29440. * Sets the database for the spec
  29441. *
  29442. * @param array $databases
  29443. */
  29444. public function setDatabases(array $databases);
  29445. }
  29446. <?php
  29447. /*
  29448. * This file is part of DBUnit.
  29449. *
  29450. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29451. *
  29452. * For the full copyright and license information, please view the LICENSE
  29453. * file that was distributed with this source code.
  29454. */
  29455. /**
  29456. * Thrown for exceptions encountered with database operations. Provides
  29457. * information regarding which operations failed and the query (if any) it
  29458. * failed on.
  29459. *
  29460. * @package DbUnit
  29461. * @author Mike Lively <m@digitalsandwich.com>
  29462. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29463. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29464. * @version Release: @package_version@
  29465. * @link http://www.phpunit.de/
  29466. * @since Class available since Release 1.0.0
  29467. */
  29468. class PHPUnit_Extensions_Database_Operation_Exception extends RuntimeException
  29469. {
  29470. /**
  29471. * @var string
  29472. */
  29473. protected $operation;
  29474. /**
  29475. * @var string
  29476. */
  29477. protected $preparedQuery;
  29478. /**
  29479. * @var array
  29480. */
  29481. protected $preparedArgs;
  29482. /**
  29483. * @var PHPUnit_Extensions_Database_DataSet_ITable
  29484. */
  29485. protected $table;
  29486. /**
  29487. * @var string
  29488. */
  29489. protected $error;
  29490. /**
  29491. * Creates a new dbunit operation exception
  29492. *
  29493. * @param string $operation
  29494. * @param string $current_query
  29495. * @param PHPUnit_Extensions_Database_DataSet_ITable $current_table
  29496. * @param string $error
  29497. */
  29498. public function __construct($operation, $current_query, $current_args, $current_table, $error)
  29499. {
  29500. parent::__construct("{$operation} operation failed on query: {$current_query} using args: " . print_r($current_args, TRUE) . " [{$error}]");
  29501. $this->operation = $operation;
  29502. $this->preparedQuery = $current_query;
  29503. $this->preparedArgs = $current_args;
  29504. $this->table = $current_table;
  29505. $this->error = $error;
  29506. }
  29507. public function getOperation()
  29508. {
  29509. return $this->operation;
  29510. }
  29511. public function getQuery()
  29512. {
  29513. return $this->preparedQuery;
  29514. }
  29515. public function getTable()
  29516. {
  29517. return $this->table;
  29518. }
  29519. public function getArgs()
  29520. {
  29521. return $this->preparedArgs;
  29522. }
  29523. public function getError()
  29524. {
  29525. return $this->error;
  29526. }
  29527. }
  29528. <?php
  29529. /*
  29530. * This file is part of DBUnit.
  29531. *
  29532. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29533. *
  29534. * For the full copyright and license information, please view the LICENSE
  29535. * file that was distributed with this source code.
  29536. */
  29537. /**
  29538. * Updates the rows in a given dataset using primary key columns.
  29539. *
  29540. * @package DbUnit
  29541. * @author Mike Lively <m@digitalsandwich.com>
  29542. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29543. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29544. * @version Release: @package_version@
  29545. * @link http://www.phpunit.de/
  29546. * @since Class available since Release 1.0.0
  29547. */
  29548. class PHPUnit_Extensions_Database_Operation_Replace extends PHPUnit_Extensions_Database_Operation_RowBased
  29549. {
  29550. protected $operationName = 'REPLACE';
  29551. protected function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  29552. {
  29553. $keys = $databaseTableMetaData->getPrimaryKeys();
  29554. $whereStatement = 'WHERE ' . implode(' AND ', $this->buildPreparedColumnArray($keys, $connection));
  29555. $query = "
  29556. SELECT COUNT(*)
  29557. FROM {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())}
  29558. {$whereStatement}
  29559. ";
  29560. return $query;
  29561. }
  29562. protected function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row)
  29563. {
  29564. $args = array();
  29565. foreach ($databaseTableMetaData->getPrimaryKeys() as $columnName) {
  29566. $args[] = $table->getValue($row, $columnName);
  29567. }
  29568. return $args;
  29569. }
  29570. /**
  29571. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
  29572. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet
  29573. */
  29574. public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet)
  29575. {
  29576. $insertOperation = new PHPUnit_Extensions_Database_Operation_Insert;
  29577. $updateOperation = new PHPUnit_Extensions_Database_Operation_Update;
  29578. $databaseDataSet = $connection->createDataSet();
  29579. foreach ($dataSet as $table) {
  29580. /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */
  29581. $databaseTableMetaData = $databaseDataSet->getTableMetaData($table->getTableMetaData()->getTableName());
  29582. $insertQuery = $insertOperation->buildOperationQuery($databaseTableMetaData, $table, $connection);
  29583. $updateQuery = $updateOperation->buildOperationQuery($databaseTableMetaData, $table, $connection);
  29584. $selectQuery = $this->buildOperationQuery($databaseTableMetaData, $table, $connection);
  29585. $insertStatement = $connection->getConnection()->prepare($insertQuery);
  29586. $updateStatement = $connection->getConnection()->prepare($updateQuery);
  29587. $selectStatement = $connection->getConnection()->prepare($selectQuery);
  29588. $rowCount = $table->getRowCount();
  29589. for ($i = 0; $i < $rowCount; $i++) {
  29590. $selectArgs = $this->buildOperationArguments($databaseTableMetaData, $table, $i);
  29591. $query = $selectQuery;
  29592. $args = $selectArgs;
  29593. try {
  29594. $selectStatement->execute($selectArgs);
  29595. if ($selectStatement->fetchColumn(0) > 0) {
  29596. $updateArgs = $updateOperation->buildOperationArguments($databaseTableMetaData, $table, $i);
  29597. $query = $updateQuery;
  29598. $args = $updateArgs;
  29599. $updateStatement->execute($updateArgs);
  29600. } else {
  29601. $insertArgs = $insertOperation->buildOperationArguments($databaseTableMetaData, $table, $i);
  29602. $query = $insertQuery;
  29603. $args = $insertArgs;
  29604. $insertStatement->execute($insertArgs);
  29605. }
  29606. }
  29607. catch (Exception $e) {
  29608. throw new PHPUnit_Extensions_Database_Operation_Exception(
  29609. $this->operationName, $query, $args, $table, $e->getMessage()
  29610. );
  29611. }
  29612. }
  29613. }
  29614. }
  29615. }
  29616. <?php
  29617. /*
  29618. * This file is part of DBUnit.
  29619. *
  29620. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29621. *
  29622. * For the full copyright and license information, please view the LICENSE
  29623. * file that was distributed with this source code.
  29624. */
  29625. /**
  29626. * This class provides functionality for inserting rows from a dataset into a database.
  29627. *
  29628. * @package DbUnit
  29629. * @author Mike Lively <m@digitalsandwich.com>
  29630. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29631. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29632. * @version Release: @package_version@
  29633. * @link http://www.phpunit.de/
  29634. * @since Class available since Release 1.0.0
  29635. */
  29636. class PHPUnit_Extensions_Database_Operation_Insert extends PHPUnit_Extensions_Database_Operation_RowBased
  29637. {
  29638. protected $operationName = 'INSERT';
  29639. protected function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  29640. {
  29641. $columnCount = count($table->getTableMetaData()->getColumns());
  29642. if ($columnCount > 0) {
  29643. $placeHolders = implode(', ', array_fill(0, $columnCount, '?'));
  29644. $columns = '';
  29645. foreach ($table->getTableMetaData()->getColumns() as $column) {
  29646. $columns .= $connection->quoteSchemaObject($column).', ';
  29647. }
  29648. $columns = substr($columns, 0, -2);
  29649. $query = "
  29650. INSERT INTO {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())}
  29651. ({$columns})
  29652. VALUES
  29653. ({$placeHolders})
  29654. ";
  29655. return $query;
  29656. } else {
  29657. return FALSE;
  29658. }
  29659. }
  29660. protected function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row)
  29661. {
  29662. $args = array();
  29663. foreach ($table->getTableMetaData()->getColumns() as $columnName) {
  29664. $args[] = $table->getValue($row, $columnName);
  29665. }
  29666. return $args;
  29667. }
  29668. protected function disablePrimaryKeys(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  29669. {
  29670. if (count($databaseTableMetaData->getPrimaryKeys())) {
  29671. return TRUE;
  29672. }
  29673. return FALSE;
  29674. }
  29675. }
  29676. <?php
  29677. /*
  29678. * This file is part of DBUnit.
  29679. *
  29680. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29681. *
  29682. * For the full copyright and license information, please view the LICENSE
  29683. * file that was distributed with this source code.
  29684. */
  29685. /**
  29686. * Deletes the rows in a given dataset using primary key columns.
  29687. *
  29688. * @package DbUnit
  29689. * @author Mike Lively <m@digitalsandwich.com>
  29690. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29691. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29692. * @version Release: @package_version@
  29693. * @link http://www.phpunit.de/
  29694. * @since Class available since Release 1.0.0
  29695. */
  29696. class PHPUnit_Extensions_Database_Operation_Delete extends PHPUnit_Extensions_Database_Operation_RowBased
  29697. {
  29698. protected $operationName = 'DELETE';
  29699. protected $iteratorDirection = self::ITERATOR_TYPE_REVERSE;
  29700. protected function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  29701. {
  29702. $keys = $databaseTableMetaData->getPrimaryKeys();
  29703. $whereStatement = 'WHERE ' . implode(' AND ', $this->buildPreparedColumnArray($keys, $connection));
  29704. $query = "
  29705. DELETE FROM {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())}
  29706. {$whereStatement}
  29707. ";
  29708. return $query;
  29709. }
  29710. protected function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row)
  29711. {
  29712. $args = array();
  29713. foreach ($databaseTableMetaData->getPrimaryKeys() as $columnName) {
  29714. $args[] = $table->getValue($row, $columnName);
  29715. }
  29716. return $args;
  29717. }
  29718. }
  29719. <?php
  29720. /*
  29721. * This file is part of DBUnit.
  29722. *
  29723. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29724. *
  29725. * For the full copyright and license information, please view the LICENSE
  29726. * file that was distributed with this source code.
  29727. */
  29728. /**
  29729. * Provides a basic interface and functionality for executing database
  29730. * operations against a connection using a specific dataSet.
  29731. *
  29732. * @package DbUnit
  29733. * @author Mike Lively <m@digitalsandwich.com>
  29734. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29735. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29736. * @version Release: @package_version@
  29737. * @link http://www.phpunit.de/
  29738. * @since Class available since Release 1.0.0
  29739. */
  29740. interface PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  29741. {
  29742. /**
  29743. * Executes the database operation against the given $connection for the
  29744. * given $dataSet.
  29745. *
  29746. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
  29747. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet
  29748. * @throws PHPUnit_Extensions_Database_Operation_Exception
  29749. */
  29750. public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet);
  29751. }
  29752. <?php
  29753. /*
  29754. * This file is part of DBUnit.
  29755. *
  29756. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29757. *
  29758. * For the full copyright and license information, please view the LICENSE
  29759. * file that was distributed with this source code.
  29760. */
  29761. /**
  29762. * This class represents a null database operation.
  29763. *
  29764. * @package DbUnit
  29765. * @author Mike Lively <m@digitalsandwich.com>
  29766. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  29767. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29768. * @version Release: @package_version@
  29769. * @link http://www.phpunit.de/
  29770. * @since Class available since Release 1.0.0
  29771. */
  29772. class PHPUnit_Extensions_Database_Operation_Null implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  29773. {
  29774. public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet)
  29775. {
  29776. /* do nothing */
  29777. }
  29778. }
  29779. <?php
  29780. /*
  29781. * This file is part of DBUnit.
  29782. *
  29783. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29784. *
  29785. * For the full copyright and license information, please view the LICENSE
  29786. * file that was distributed with this source code.
  29787. */
  29788. /**
  29789. * Deletes all rows from all tables in a dataset.
  29790. *
  29791. * @package DbUnit
  29792. * @author Mike Lively <m@digitalsandwich.com>
  29793. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29794. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29795. * @version Release: @package_version@
  29796. * @link http://www.phpunit.de/
  29797. * @since Class available since Release 1.0.0
  29798. */
  29799. class PHPUnit_Extensions_Database_Operation_DeleteAll implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  29800. {
  29801. public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet)
  29802. {
  29803. foreach ($dataSet->getReverseIterator() as $table) {
  29804. /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */
  29805. $query = "
  29806. DELETE FROM {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())}
  29807. ";
  29808. try {
  29809. $connection->getConnection()->query($query);
  29810. } catch (PDOException $e) {
  29811. throw new PHPUnit_Extensions_Database_Operation_Exception('DELETE_ALL', $query, array(), $table, $e->getMessage());
  29812. }
  29813. }
  29814. }
  29815. }
  29816. <?php
  29817. /*
  29818. * This file is part of DBUnit.
  29819. *
  29820. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29821. *
  29822. * For the full copyright and license information, please view the LICENSE
  29823. * file that was distributed with this source code.
  29824. */
  29825. /**
  29826. * Updates the rows in a given dataset using primary key columns.
  29827. *
  29828. * @package DbUnit
  29829. * @author Mike Lively <m@digitalsandwich.com>
  29830. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29831. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29832. * @version Release: @package_version@
  29833. * @link http://www.phpunit.de/
  29834. * @since Class available since Release 1.0.0
  29835. */
  29836. class PHPUnit_Extensions_Database_Operation_Update extends PHPUnit_Extensions_Database_Operation_RowBased
  29837. {
  29838. protected $operationName = 'UPDATE';
  29839. protected function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  29840. {
  29841. $keys = $databaseTableMetaData->getPrimaryKeys();
  29842. $columns = $table->getTableMetaData()->getColumns();
  29843. $whereStatement = 'WHERE ' . implode(' AND ', $this->buildPreparedColumnArray($keys, $connection));
  29844. $setStatement = 'SET ' . implode(', ', $this->buildPreparedColumnArray($columns, $connection));
  29845. $query = "
  29846. UPDATE {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())}
  29847. {$setStatement}
  29848. {$whereStatement}
  29849. ";
  29850. return $query;
  29851. }
  29852. protected function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row)
  29853. {
  29854. $args = array();
  29855. foreach ($table->getTableMetaData()->getColumns() as $columnName) {
  29856. $args[] = $table->getValue($row, $columnName);
  29857. }
  29858. foreach ($databaseTableMetaData->getPrimaryKeys() as $columnName) {
  29859. $args[] = $table->getValue($row, $columnName);
  29860. }
  29861. return $args;
  29862. }
  29863. protected function disablePrimaryKeys(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  29864. {
  29865. if (count($databaseTableMetaData->getPrimaryKeys())) {
  29866. return TRUE;
  29867. }
  29868. return FALSE;
  29869. }
  29870. }
  29871. <?php
  29872. /*
  29873. * This file is part of DBUnit.
  29874. *
  29875. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29876. *
  29877. * For the full copyright and license information, please view the LICENSE
  29878. * file that was distributed with this source code.
  29879. */
  29880. /**
  29881. * Provides basic functionality for row based operations.
  29882. *
  29883. * To create a row based operation you must create two functions. The first
  29884. * one, buildOperationQuery(), must return a query that will be used to create
  29885. * a prepared statement. The second one, buildOperationArguments(), should
  29886. * return an array containing arguments for each row.
  29887. *
  29888. * @package DbUnit
  29889. * @author Mike Lively <m@digitalsandwich.com>
  29890. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29891. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29892. * @version Release: @package_version@
  29893. * @link http://www.phpunit.de/
  29894. * @since Class available since Release 1.0.0
  29895. */
  29896. abstract class PHPUnit_Extensions_Database_Operation_RowBased implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  29897. {
  29898. const ITERATOR_TYPE_FORWARD = 0;
  29899. const ITERATOR_TYPE_REVERSE = 1;
  29900. protected $operationName;
  29901. protected $iteratorDirection = self::ITERATOR_TYPE_FORWARD;
  29902. /**
  29903. * @return string|boolean String containing the query or FALSE if a valid query cannot be constructed
  29904. */
  29905. protected abstract function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection);
  29906. protected abstract function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row);
  29907. /**
  29908. * Allows an operation to disable primary keys if necessary.
  29909. *
  29910. * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData
  29911. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  29912. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
  29913. */
  29914. protected function disablePrimaryKeys(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  29915. {
  29916. return FALSE;
  29917. }
  29918. /**
  29919. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
  29920. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet
  29921. */
  29922. public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet)
  29923. {
  29924. $databaseDataSet = $connection->createDataSet();
  29925. $dsIterator = $this->iteratorDirection == self::ITERATOR_TYPE_REVERSE ? $dataSet->getReverseIterator() : $dataSet->getIterator();
  29926. foreach ($dsIterator as $table) {
  29927. $rowCount = $table->getRowCount();
  29928. if($rowCount == 0) continue;
  29929. /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */
  29930. $databaseTableMetaData = $databaseDataSet->getTableMetaData($table->getTableMetaData()->getTableName());
  29931. $query = $this->buildOperationQuery($databaseTableMetaData, $table, $connection);
  29932. $disablePrimaryKeys = $this->disablePrimaryKeys($databaseTableMetaData, $table, $connection);
  29933. if ($query === FALSE) {
  29934. if ($table->getRowCount() > 0) {
  29935. throw new PHPUnit_Extensions_Database_Operation_Exception($this->operationName, '', array(), $table, "Rows requested for insert, but no columns provided!");
  29936. }
  29937. continue;
  29938. }
  29939. if ($disablePrimaryKeys) {
  29940. $connection->disablePrimaryKeys($databaseTableMetaData->getTableName());
  29941. }
  29942. $statement = $connection->getConnection()->prepare($query);
  29943. for ($i = 0; $i < $rowCount; $i++) {
  29944. $args = $this->buildOperationArguments($databaseTableMetaData, $table, $i);
  29945. try {
  29946. $statement->execute($args);
  29947. }
  29948. catch (Exception $e) {
  29949. throw new PHPUnit_Extensions_Database_Operation_Exception(
  29950. $this->operationName, $query, $args, $table, $e->getMessage()
  29951. );
  29952. }
  29953. }
  29954. if ($disablePrimaryKeys) {
  29955. $connection->enablePrimaryKeys($databaseTableMetaData->getTableName());
  29956. }
  29957. }
  29958. }
  29959. protected function buildPreparedColumnArray($columns, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  29960. {
  29961. $columnArray = array();
  29962. foreach ($columns as $columnName) {
  29963. $columnArray[] = "{$connection->quoteSchemaObject($columnName)} = ?";
  29964. }
  29965. return $columnArray;
  29966. }
  29967. }
  29968. <?php
  29969. /*
  29970. * This file is part of DBUnit.
  29971. *
  29972. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  29973. *
  29974. * For the full copyright and license information, please view the LICENSE
  29975. * file that was distributed with this source code.
  29976. */
  29977. /**
  29978. * A class factory to easily return database operations.
  29979. *
  29980. * @package DbUnit
  29981. * @author Mike Lively <m@digitalsandwich.com>
  29982. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  29983. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  29984. * @version Release: @package_version@
  29985. * @link http://www.phpunit.de/
  29986. * @since Class available since Release 1.0.0
  29987. */
  29988. class PHPUnit_Extensions_Database_Operation_Factory
  29989. {
  29990. /**
  29991. * Returns a null database operation
  29992. *
  29993. * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  29994. */
  29995. public static function NONE()
  29996. {
  29997. return new PHPUnit_Extensions_Database_Operation_Null();
  29998. }
  29999. /**
  30000. * Returns a clean insert database operation. It will remove all contents
  30001. * from the table prior to re-inserting rows.
  30002. *
  30003. * @param bool $cascadeTruncates Set to true to force truncates to cascade on databases that support this.
  30004. * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30005. */
  30006. public static function CLEAN_INSERT($cascadeTruncates = FALSE)
  30007. {
  30008. return new PHPUnit_Extensions_Database_Operation_Composite(array(
  30009. self::TRUNCATE($cascadeTruncates),
  30010. self::INSERT()
  30011. ));
  30012. }
  30013. /**
  30014. * Returns an insert database operation.
  30015. *
  30016. * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30017. */
  30018. public static function INSERT()
  30019. {
  30020. return new PHPUnit_Extensions_Database_Operation_Insert();
  30021. }
  30022. /**
  30023. * Returns a truncate database operation.
  30024. *
  30025. * @param bool $cascadeTruncates Set to true to force truncates to cascade on databases that support this.
  30026. * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30027. */
  30028. public static function TRUNCATE($cascadeTruncates = FALSE)
  30029. {
  30030. $truncate = new PHPUnit_Extensions_Database_Operation_Truncate();
  30031. $truncate->setCascade($cascadeTruncates);
  30032. return $truncate;
  30033. }
  30034. /**
  30035. * Returns a delete database operation.
  30036. *
  30037. * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30038. */
  30039. public static function DELETE()
  30040. {
  30041. return new PHPUnit_Extensions_Database_Operation_Delete();
  30042. }
  30043. /**
  30044. * Returns a delete_all database operation.
  30045. *
  30046. * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30047. */
  30048. public static function DELETE_ALL()
  30049. {
  30050. return new PHPUnit_Extensions_Database_Operation_DeleteAll();
  30051. }
  30052. /**
  30053. * Returns an update database operation.
  30054. *
  30055. * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30056. */
  30057. public static function UPDATE()
  30058. {
  30059. return new PHPUnit_Extensions_Database_Operation_Update();
  30060. }
  30061. }
  30062. <?php
  30063. /*
  30064. * This file is part of DBUnit.
  30065. *
  30066. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30067. *
  30068. * For the full copyright and license information, please view the LICENSE
  30069. * file that was distributed with this source code.
  30070. */
  30071. /**
  30072. * This class facilitates combining database operations. To create a composite
  30073. * operation pass an array of classes that implement
  30074. * PHPUnit_Extensions_Database_Operation_IDatabaseOperation and they will be
  30075. * executed in that order against all data sets.
  30076. *
  30077. * @package DbUnit
  30078. * @author Mike Lively <m@digitalsandwich.com>
  30079. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  30080. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  30081. * @version Release: @package_version@
  30082. * @link http://www.phpunit.de/
  30083. * @since Class available since Release 1.0.0
  30084. */
  30085. class PHPUnit_Extensions_Database_Operation_Composite implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30086. {
  30087. /**
  30088. * @var array
  30089. */
  30090. protected $operations = array();
  30091. /**
  30092. * Creates a composite operation.
  30093. *
  30094. * @param array $operations
  30095. */
  30096. public function __construct(Array $operations)
  30097. {
  30098. foreach ($operations as $operation) {
  30099. if ($operation instanceof PHPUnit_Extensions_Database_Operation_IDatabaseOperation) {
  30100. $this->operations[] = $operation;
  30101. } else {
  30102. throw new InvalidArgumentException("Only database operation instances can be passed to a composite database operation.");
  30103. }
  30104. }
  30105. }
  30106. public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet)
  30107. {
  30108. try {
  30109. foreach ($this->operations as $operation) {
  30110. /* @var $operation PHPUnit_Extensions_Database_Operation_IDatabaseOperation */
  30111. $operation->execute($connection, $dataSet);
  30112. }
  30113. } catch (PHPUnit_Extensions_Database_Operation_Exception $e) {
  30114. throw new PHPUnit_Extensions_Database_Operation_Exception("COMPOSITE[{$e->getOperation()}]", $e->getQuery(), $e->getArgs(), $e->getTable(), $e->getError());
  30115. }
  30116. }
  30117. }
  30118. <?php
  30119. /*
  30120. * This file is part of DBUnit.
  30121. *
  30122. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30123. *
  30124. * For the full copyright and license information, please view the LICENSE
  30125. * file that was distributed with this source code.
  30126. */
  30127. /**
  30128. * Executes a truncate against all tables in a dataset.
  30129. *
  30130. * @package DbUnit
  30131. * @author Mike Lively <m@digitalsandwich.com>
  30132. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  30133. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  30134. * @version Release: @package_version@
  30135. * @link http://www.phpunit.de/
  30136. * @since Class available since Release 1.0.0
  30137. */
  30138. class PHPUnit_Extensions_Database_Operation_Truncate implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30139. {
  30140. protected $useCascade = FALSE;
  30141. public function setCascade($cascade = TRUE)
  30142. {
  30143. $this->useCascade = $cascade;
  30144. }
  30145. public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet)
  30146. {
  30147. foreach ($dataSet->getReverseIterator() as $table) {
  30148. /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */
  30149. $query = "
  30150. {$connection->getTruncateCommand()} {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())}
  30151. ";
  30152. if ($this->useCascade && $connection->allowsCascading()) {
  30153. $query .= " CASCADE";
  30154. }
  30155. try {
  30156. $this->disableForeignKeyChecksForMysql($connection);
  30157. $connection->getConnection()->query($query);
  30158. $this->enableForeignKeyChecksForMysql($connection);
  30159. } catch (\Exception $e) {
  30160. $this->enableForeignKeyChecksForMysql($connection);
  30161. if ($e instanceof PDOException) {
  30162. throw new PHPUnit_Extensions_Database_Operation_Exception('TRUNCATE', $query, array(), $table, $e->getMessage());
  30163. }
  30164. throw $e;
  30165. }
  30166. }
  30167. }
  30168. private function disableForeignKeyChecksForMysql(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  30169. {
  30170. if ($this->isMysql($connection)) {
  30171. $connection->getConnection()->query('SET FOREIGN_KEY_CHECKS = 0');
  30172. }
  30173. }
  30174. private function enableForeignKeyChecksForMysql(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  30175. {
  30176. if ($this->isMysql($connection)) {
  30177. $connection->getConnection()->query('SET FOREIGN_KEY_CHECKS = 1');
  30178. }
  30179. }
  30180. private function isMysql(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  30181. {
  30182. return $connection->getConnection()->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql';
  30183. }
  30184. }
  30185. <?php
  30186. /*
  30187. * This file is part of DBUnit.
  30188. *
  30189. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30190. *
  30191. * For the full copyright and license information, please view the LICENSE
  30192. * file that was distributed with this source code.
  30193. */
  30194. /**
  30195. * A TestCase extension that provides functionality for testing and asserting
  30196. * against a real database.
  30197. *
  30198. * @package DbUnit
  30199. * @author Mike Lively <m@digitalsandwich.com>
  30200. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  30201. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  30202. * @version Release: @package_version@
  30203. * @link http://www.phpunit.de/
  30204. * @since Class available since Release 1.0.0
  30205. */
  30206. abstract class PHPUnit_Extensions_Database_TestCase extends PHPUnit_Framework_TestCase
  30207. {
  30208. /**
  30209. * @var PHPUnit_Extensions_Database_ITester
  30210. */
  30211. protected $databaseTester;
  30212. /**
  30213. * Closes the specified connection.
  30214. *
  30215. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
  30216. */
  30217. protected function closeConnection(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  30218. {
  30219. $this->getDatabaseTester()->closeConnection($connection);
  30220. }
  30221. /**
  30222. * Returns the test database connection.
  30223. *
  30224. * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
  30225. */
  30226. protected abstract function getConnection();
  30227. /**
  30228. * Gets the IDatabaseTester for this testCase. If the IDatabaseTester is
  30229. * not set yet, this method calls newDatabaseTester() to obtain a new
  30230. * instance.
  30231. *
  30232. * @return PHPUnit_Extensions_Database_ITester
  30233. */
  30234. protected function getDatabaseTester()
  30235. {
  30236. if (empty($this->databaseTester)) {
  30237. $this->databaseTester = $this->newDatabaseTester();
  30238. }
  30239. return $this->databaseTester;
  30240. }
  30241. /**
  30242. * Returns the test dataset.
  30243. *
  30244. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  30245. */
  30246. protected abstract function getDataSet();
  30247. /**
  30248. * Returns the database operation executed in test setup.
  30249. *
  30250. * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation
  30251. */
  30252. protected function getSetUpOperation()
  30253. {
  30254. return PHPUnit_Extensions_Database_Operation_Factory::CLEAN_INSERT();
  30255. }
  30256. /**
  30257. * Returns the database operation executed in test cleanup.
  30258. *
  30259. * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation
  30260. */
  30261. protected function getTearDownOperation()
  30262. {
  30263. return PHPUnit_Extensions_Database_Operation_Factory::NONE();
  30264. }
  30265. /**
  30266. * Creates a IDatabaseTester for this testCase.
  30267. *
  30268. * @return PHPUnit_Extensions_Database_ITester
  30269. */
  30270. protected function newDatabaseTester()
  30271. {
  30272. return new PHPUnit_Extensions_Database_DefaultTester($this->getConnection());
  30273. }
  30274. /**
  30275. * Creates a new DefaultDatabaseConnection using the given PDO connection
  30276. * and database schema name.
  30277. *
  30278. * @param PDO $connection
  30279. * @param string $schema
  30280. * @return PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection
  30281. */
  30282. protected function createDefaultDBConnection(PDO $connection, $schema = '')
  30283. {
  30284. return new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($connection, $schema);
  30285. }
  30286. /**
  30287. * Creates a new ArrayDataSet with the given array.
  30288. * The array parameter is an associative array of tables where the key is
  30289. * the table name and the value an array of rows. Each row is an associative
  30290. * array by itself with keys representing the field names and the values the
  30291. * actual data.
  30292. * For example:
  30293. * array(
  30294. * "addressbook" => array(
  30295. * array("id" => 1, "name" => "...", "address" => "..."),
  30296. * array("id" => 2, "name" => "...", "address" => "...")
  30297. * )
  30298. * )
  30299. *
  30300. * @param array $data
  30301. * @return PHPUnit_Extensions_Database_DataSet_ArrayDataSet
  30302. */
  30303. protected function createArrayDataSet(array $data)
  30304. {
  30305. return new PHPUnit_Extensions_Database_DataSet_ArrayDataSet($data);
  30306. }
  30307. /**
  30308. * Creates a new FlatXmlDataSet with the given $xmlFile. (absolute path.)
  30309. *
  30310. * @param string $xmlFile
  30311. * @return PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet
  30312. */
  30313. protected function createFlatXMLDataSet($xmlFile)
  30314. {
  30315. return new PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet($xmlFile);
  30316. }
  30317. /**
  30318. * Creates a new XMLDataSet with the given $xmlFile. (absolute path.)
  30319. *
  30320. * @param string $xmlFile
  30321. * @return PHPUnit_Extensions_Database_DataSet_XmlDataSet
  30322. */
  30323. protected function createXMLDataSet($xmlFile)
  30324. {
  30325. return new PHPUnit_Extensions_Database_DataSet_XmlDataSet($xmlFile);
  30326. }
  30327. /**
  30328. * Create a a new MysqlXmlDataSet with the given $xmlFile. (absolute path.)
  30329. *
  30330. * @param string $xmlFile
  30331. * @return PHPUnit_Extensions_Database_DataSet_MysqlXmlDataSet
  30332. * @since Method available since Release 1.0.0
  30333. */
  30334. protected function createMySQLXMLDataSet($xmlFile)
  30335. {
  30336. return new PHPUnit_Extensions_Database_DataSet_MysqlXmlDataSet($xmlFile);
  30337. }
  30338. /**
  30339. * Returns an operation factory instance that can be used to instantiate
  30340. * new operations.
  30341. *
  30342. * @return PHPUnit_Extensions_Database_Operation_Factory
  30343. */
  30344. protected function getOperations()
  30345. {
  30346. return new PHPUnit_Extensions_Database_Operation_Factory();
  30347. }
  30348. /**
  30349. * Performs operation returned by getSetUpOperation().
  30350. */
  30351. protected function setUp()
  30352. {
  30353. parent::setUp();
  30354. $this->databaseTester = NULL;
  30355. $this->getDatabaseTester()->setSetUpOperation($this->getSetUpOperation());
  30356. $this->getDatabaseTester()->setDataSet($this->getDataSet());
  30357. $this->getDatabaseTester()->onSetUp();
  30358. }
  30359. /**
  30360. * Performs operation returned by getTearDownOperation().
  30361. */
  30362. protected function tearDown()
  30363. {
  30364. $this->getDatabaseTester()->setTearDownOperation($this->getTearDownOperation());
  30365. $this->getDatabaseTester()->setDataSet($this->getDataSet());
  30366. $this->getDatabaseTester()->onTearDown();
  30367. /**
  30368. * Destroy the tester after the test is run to keep DB connections
  30369. * from piling up.
  30370. */
  30371. $this->databaseTester = NULL;
  30372. }
  30373. /**
  30374. * Asserts that two given tables are equal.
  30375. *
  30376. * @param PHPUnit_Extensions_Database_DataSet_ITable $expected
  30377. * @param PHPUnit_Extensions_Database_DataSet_ITable $actual
  30378. * @param string $message
  30379. */
  30380. public static function assertTablesEqual(PHPUnit_Extensions_Database_DataSet_ITable $expected, PHPUnit_Extensions_Database_DataSet_ITable $actual, $message = '')
  30381. {
  30382. $constraint = new PHPUnit_Extensions_Database_Constraint_TableIsEqual($expected);
  30383. self::assertThat($actual, $constraint, $message);
  30384. }
  30385. /**
  30386. * Asserts that two given datasets are equal.
  30387. *
  30388. * @param PHPUnit_Extensions_Database_DataSet_ITable $expected
  30389. * @param PHPUnit_Extensions_Database_DataSet_ITable $actual
  30390. * @param string $message
  30391. */
  30392. public static function assertDataSetsEqual(PHPUnit_Extensions_Database_DataSet_IDataSet $expected, PHPUnit_Extensions_Database_DataSet_IDataSet $actual, $message = '')
  30393. {
  30394. $constraint = new PHPUnit_Extensions_Database_Constraint_DataSetIsEqual($expected);
  30395. self::assertThat($actual, $constraint, $message);
  30396. }
  30397. /**
  30398. * Assert that a given table has a given amount of rows
  30399. *
  30400. * @param string $tableName Name of the table
  30401. * @param int $expected Expected amount of rows in the table
  30402. * @param string $message Optional message
  30403. */
  30404. public function assertTableRowCount($tableName, $expected, $message = '')
  30405. {
  30406. $constraint = new PHPUnit_Extensions_Database_Constraint_TableRowCount($tableName, $expected);
  30407. $actual = $this->getConnection()->getRowCount($tableName);
  30408. self::assertThat($actual, $constraint, $message);
  30409. }
  30410. /**
  30411. * Asserts that a given table contains a given row
  30412. *
  30413. * @param array $expectedRow Row expected to find
  30414. * @param PHPUnit_Extensions_Database_DataSet_ITable $table Table to look into
  30415. * @param string $message Optional message
  30416. */
  30417. public function assertTableContains(array $expectedRow, PHPUnit_Extensions_Database_DataSet_ITable $table, $message = '')
  30418. {
  30419. self::assertThat($table->assertContainsRow($expectedRow), self::isTrue(), $message);
  30420. }
  30421. }
  30422. <?php
  30423. /*
  30424. * This file is part of DBUnit.
  30425. *
  30426. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30427. *
  30428. * For the full copyright and license information, please view the LICENSE
  30429. * file that was distributed with this source code.
  30430. */
  30431. /**
  30432. * Can be used as a foundation for new DatabaseTesters.
  30433. *
  30434. * @package DbUnit
  30435. * @author Mike Lively <m@digitalsandwich.com>
  30436. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  30437. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  30438. * @version Release: @package_version@
  30439. * @link http://www.phpunit.de/
  30440. * @since Class available since Release 1.0.0
  30441. */
  30442. abstract class PHPUnit_Extensions_Database_AbstractTester implements PHPUnit_Extensions_Database_ITester
  30443. {
  30444. /**
  30445. * @var PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30446. */
  30447. protected $setUpOperation;
  30448. /**
  30449. * @var PHPUnit_Extensions_Database_Operation_IDatabaseOperation
  30450. */
  30451. protected $tearDownOperation;
  30452. /**
  30453. * @var PHPUnit_Extensions_Database_DataSet_IDataSet
  30454. */
  30455. protected $dataSet;
  30456. /**
  30457. * @var string
  30458. */
  30459. protected $schema;
  30460. /**
  30461. * Creates a new database tester.
  30462. */
  30463. public function __construct()
  30464. {
  30465. $this->setUpOperation = PHPUnit_Extensions_Database_Operation_Factory::CLEAN_INSERT();
  30466. $this->tearDownOperation = PHPUnit_Extensions_Database_Operation_Factory::NONE();
  30467. }
  30468. /**
  30469. * Closes the specified connection.
  30470. *
  30471. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
  30472. */
  30473. public function closeConnection(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  30474. {
  30475. $connection->close();
  30476. }
  30477. /**
  30478. * Returns the test dataset.
  30479. *
  30480. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  30481. */
  30482. public function getDataSet()
  30483. {
  30484. return $this->dataSet;
  30485. }
  30486. /**
  30487. * TestCases must call this method inside setUp().
  30488. */
  30489. public function onSetUp()
  30490. {
  30491. $this->getSetUpOperation()->execute($this->getConnection(), $this->getDataSet());
  30492. }
  30493. /**
  30494. * TestCases must call this method inside tearDown().
  30495. */
  30496. public function onTearDown()
  30497. {
  30498. $this->getTearDownOperation()->execute($this->getConnection(), $this->getDataSet());
  30499. }
  30500. /**
  30501. * Sets the test dataset to use.
  30502. *
  30503. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet
  30504. */
  30505. public function setDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet)
  30506. {
  30507. $this->dataSet = $dataSet;
  30508. }
  30509. /**
  30510. * Sets the schema value.
  30511. *
  30512. * @param string $schema
  30513. */
  30514. public function setSchema($schema)
  30515. {
  30516. $this->schema = $schema;
  30517. }
  30518. /**
  30519. * Sets the DatabaseOperation to call when starting the test.
  30520. *
  30521. * @param PHPUnit_Extensions_Database_Operation_DatabaseOperation $setUpOperation
  30522. */
  30523. public function setSetUpOperation(PHPUnit_Extensions_Database_Operation_IDatabaseOperation $setUpOperation)
  30524. {
  30525. $this->setUpOperation = $setUpOperation;
  30526. }
  30527. /**
  30528. * Sets the DatabaseOperation to call when ending the test.
  30529. *
  30530. * @param PHPUnit_Extensions_Database_Operation_DatabaseOperation $tearDownOperation
  30531. */
  30532. public function setTearDownOperation(PHPUnit_Extensions_Database_Operation_IDatabaseOperation $tearDownOperation)
  30533. {
  30534. $this->tearDownOperation = $tearDownOperation;
  30535. }
  30536. /**
  30537. * Returns the schema value
  30538. *
  30539. * @return string
  30540. */
  30541. protected function getSchema()
  30542. {
  30543. return $this->schema;
  30544. }
  30545. /**
  30546. * Returns the database operation that will be called when starting the test.
  30547. *
  30548. * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation
  30549. */
  30550. protected function getSetUpOperation()
  30551. {
  30552. return $this->setUpOperation;
  30553. }
  30554. /**
  30555. * Returns the database operation that will be called when ending the test.
  30556. *
  30557. * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation
  30558. */
  30559. protected function getTearDownOperation()
  30560. {
  30561. return $this->tearDownOperation;
  30562. }
  30563. }
  30564. <?php
  30565. /*
  30566. * This file is part of DBUnit.
  30567. *
  30568. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30569. *
  30570. * For the full copyright and license information, please view the LICENSE
  30571. * file that was distributed with this source code.
  30572. */
  30573. /**
  30574. * Provides functionality to retrieve meta data from an Sqlite database.
  30575. *
  30576. * @package DbUnit
  30577. * @author Mike Lively <m@digitalsandwich.com>
  30578. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  30579. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  30580. * @version Release: @package_version@
  30581. * @link http://www.phpunit.de/
  30582. * @since Class available since Release 1.0.0
  30583. */
  30584. class PHPUnit_Extensions_Database_DB_MetaData_Sqlite extends PHPUnit_Extensions_Database_DB_MetaData
  30585. {
  30586. protected $columns = array();
  30587. protected $keys = array();
  30588. protected $truncateCommand = 'DELETE FROM';
  30589. /**
  30590. * Returns an array containing the names of all the tables in the database.
  30591. *
  30592. * @return array
  30593. */
  30594. public function getTableNames()
  30595. {
  30596. $query = "
  30597. SELECT name
  30598. FROM sqlite_master
  30599. WHERE
  30600. type='table' AND
  30601. name <> 'sqlite_sequence'
  30602. ORDER BY name
  30603. ";
  30604. $result = $this->pdo->query($query);
  30605. $tableNames = array();
  30606. while ($tableName = $result->fetchColumn(0)) {
  30607. $tableNames[] = $tableName;
  30608. }
  30609. return $tableNames;
  30610. }
  30611. /**
  30612. * Returns an array containing the names of all the columns in the
  30613. * $tableName table,
  30614. *
  30615. * @param string $tableName
  30616. * @return array
  30617. */
  30618. public function getTableColumns($tableName)
  30619. {
  30620. if (!isset($this->columns[$tableName])) {
  30621. $this->loadColumnInfo($tableName);
  30622. }
  30623. return $this->columns[$tableName];
  30624. }
  30625. /**
  30626. * Returns an array containing the names of all the primary key columns in
  30627. * the $tableName table.
  30628. *
  30629. * @param string $tableName
  30630. * @return array
  30631. */
  30632. public function getTablePrimaryKeys($tableName)
  30633. {
  30634. if (!isset($this->keys[$tableName])) {
  30635. $this->loadColumnInfo($tableName);
  30636. }
  30637. return $this->keys[$tableName];
  30638. }
  30639. /**
  30640. * Loads column info from a sqlite database.
  30641. *
  30642. * @param string $tableName
  30643. */
  30644. protected function loadColumnInfo($tableName)
  30645. {
  30646. $query = "PRAGMA table_info('{$tableName}')";
  30647. $statement = $this->pdo->query($query);
  30648. /* @var $statement PDOStatement */
  30649. $this->columns[$tableName] = array();
  30650. $this->keys[$tableName] = array();
  30651. while ($columnData = $statement->fetch(PDO::FETCH_NUM)) {
  30652. $this->columns[$tableName][] = $columnData[1];
  30653. if ($columnData[5] == 1) {
  30654. $this->keys[$tableName][] = $columnData[1];
  30655. }
  30656. }
  30657. }
  30658. }
  30659. <?php
  30660. /**
  30661. * Provides functionality to retrieve meta data from an Dblib (SQL Server) database.
  30662. *
  30663. * @package DbUnit
  30664. * @author Tom Ford <tom@switchsystems.co.uk>
  30665. * @copyright Sebastian Bergmann <sb@sebastian-bergmann.de>
  30666. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  30667. * @link http://www.phpunit.de/
  30668. */
  30669. class PHPUnit_Extensions_Database_DB_MetaData_Dblib extends PHPUnit_Extensions_Database_DB_MetaData
  30670. {
  30671. /**
  30672. * No character used to quote schema objects.
  30673. * @var string
  30674. */
  30675. protected $schemaObjectQuoteChar = '';
  30676. /**
  30677. * The command used to perform a TRUNCATE operation.
  30678. * @var string
  30679. */
  30680. protected $truncateCommand = 'TRUNCATE TABLE';
  30681. /**
  30682. * @var array
  30683. */
  30684. protected $columns = array();
  30685. /**
  30686. * @var array
  30687. */
  30688. protected $keys = array();
  30689. /**
  30690. * Returns an array containing the names of all the tables in the database.
  30691. *
  30692. * @return array
  30693. */
  30694. public function getTableNames()
  30695. {
  30696. $tableNames = array();
  30697. $query = "SELECT name
  30698. FROM sys.tables
  30699. ORDER BY name";
  30700. $result = $this->pdo->query($query);
  30701. while ($tableName = $result->fetchColumn(0)) {
  30702. $tableNames[] = $tableName;
  30703. }
  30704. return $tableNames;
  30705. }
  30706. /**
  30707. * Returns an array containing the names of all the columns in the
  30708. * $tableName table,
  30709. *
  30710. * @param string $tableName
  30711. * @return array
  30712. */
  30713. public function getTableColumns($tableName)
  30714. {
  30715. if (!isset($this->columns[$tableName])) {
  30716. $this->loadColumnInfo($tableName);
  30717. }
  30718. return $this->columns[$tableName];
  30719. }
  30720. /**
  30721. * Returns an array containing the names of all the primary key columns in
  30722. * the $tableName table.
  30723. *
  30724. * @param string $tableName
  30725. * @return array
  30726. */
  30727. public function getTablePrimaryKeys($tableName)
  30728. {
  30729. if (!isset($this->keys[$tableName])) {
  30730. $this->loadColumnInfo($tableName);
  30731. }
  30732. return $this->keys[$tableName];
  30733. }
  30734. /**
  30735. * Loads column info from a sql server database.
  30736. *
  30737. * @param string $tableName
  30738. */
  30739. protected function loadColumnInfo($tableName)
  30740. {
  30741. $query = "SELECT name
  30742. FROM sys.columns
  30743. WHERE object_id = OBJECT_ID('".$tableName."')
  30744. ORDER BY column_id";
  30745. $result = $this->pdo->query($query);
  30746. while ($columnName = $result->fetchColumn(0)) {
  30747. $this->columns[$tableName][] = $columnName;
  30748. }
  30749. $keyQuery = "SELECT COL_NAME(ic.OBJECT_ID,ic.column_id) AS ColumnName
  30750. FROM sys.indexes AS i INNER JOIN
  30751. sys.index_columns AS ic ON i.OBJECT_ID = ic.OBJECT_ID
  30752. AND i.index_id = ic.index_id
  30753. WHERE i.is_primary_key = 1 AND OBJECT_NAME(ic.OBJECT_ID) = '".$tableName."'";
  30754. $result = $this->pdo->query($keyQuery);
  30755. while ($columnName = $result->fetchColumn(0)) {
  30756. $this->keys[$tableName][] = $columnName;
  30757. }
  30758. }
  30759. }
  30760. <?php
  30761. /*
  30762. * This file is part of DBUnit.
  30763. *
  30764. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30765. *
  30766. * For the full copyright and license information, please view the LICENSE
  30767. * file that was distributed with this source code.
  30768. */
  30769. /**
  30770. * Provides functionality to retrieve meta data from a MySQL database.
  30771. *
  30772. * @package DbUnit
  30773. * @author Mike Lively <m@digitalsandwich.com>
  30774. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  30775. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  30776. * @version Release: @package_version@
  30777. * @link http://www.phpunit.de/
  30778. * @since Class available since Release 1.0.0
  30779. */
  30780. class PHPUnit_Extensions_Database_DB_MetaData_MySQL extends PHPUnit_Extensions_Database_DB_MetaData
  30781. {
  30782. protected $schemaObjectQuoteChar = '`';
  30783. /**
  30784. * Returns an array containing the names of all the tables in the database.
  30785. *
  30786. * @return array
  30787. */
  30788. public function getTableNames()
  30789. {
  30790. $query = 'SHOW TABLES';
  30791. $statement = $this->pdo->prepare($query);
  30792. $statement->execute();
  30793. $tableNames = array();
  30794. while (($tableName = $statement->fetchColumn(0))) {
  30795. $tableNames[] = $tableName;
  30796. }
  30797. return $tableNames;
  30798. }
  30799. /**
  30800. * Returns an array containing the names of all the columns in the
  30801. * $tableName table,
  30802. *
  30803. * @param string $tableName
  30804. * @return array
  30805. */
  30806. public function getTableColumns($tableName)
  30807. {
  30808. $query = 'SHOW COLUMNS FROM ' . $this->quoteSchemaObject($tableName);
  30809. $statement = $this->pdo->prepare($query);
  30810. $statement->execute();
  30811. $columnNames = array();
  30812. while (($columnName = $statement->fetchColumn(0))) {
  30813. $columnNames[] = $columnName;
  30814. }
  30815. return $columnNames;
  30816. }
  30817. /**
  30818. * Returns an array containing the names of all the primary key columns in
  30819. * the $tableName table.
  30820. *
  30821. * @param string $tableName
  30822. * @return array
  30823. */
  30824. public function getTablePrimaryKeys($tableName)
  30825. {
  30826. $query = 'SHOW INDEX FROM ' . $this->quoteSchemaObject($tableName);
  30827. $statement = $this->pdo->prepare($query);
  30828. $statement->execute();
  30829. $statement->setFetchMode(PDO::FETCH_ASSOC);
  30830. $columnNames = array();
  30831. while (($column = $statement->fetch())) {
  30832. if ($column['Key_name'] == 'PRIMARY') {
  30833. $columnNames[] = $column['Column_name'];
  30834. }
  30835. }
  30836. return $columnNames;
  30837. }
  30838. }
  30839. <?php
  30840. /*
  30841. * This file is part of DBUnit.
  30842. *
  30843. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30844. *
  30845. * For the full copyright and license information, please view the LICENSE
  30846. * file that was distributed with this source code.
  30847. */
  30848. /**
  30849. * Provides functionality to retrieve meta data from a database with information_schema support.
  30850. *
  30851. * @package DbUnit
  30852. * @author Mike Lively <m@digitalsandwich.com>
  30853. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  30854. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  30855. * @version Release: @package_version@
  30856. * @link http://www.phpunit.de/
  30857. * @since Class available since Release 1.0.0
  30858. */
  30859. class PHPUnit_Extensions_Database_DB_MetaData_InformationSchema extends PHPUnit_Extensions_Database_DB_MetaData
  30860. {
  30861. protected $columns = array();
  30862. protected $keys = array();
  30863. /**
  30864. * Returns an array containing the names of all the tables in the database.
  30865. *
  30866. * @return array
  30867. */
  30868. public function getTableNames()
  30869. {
  30870. $query = "
  30871. SELECT DISTINCT
  30872. TABLE_NAME
  30873. FROM INFORMATION_SCHEMA.TABLES
  30874. WHERE
  30875. TABLE_TYPE='BASE TABLE' AND
  30876. TABLE_SCHEMA = ?
  30877. ORDER BY TABLE_NAME
  30878. ";
  30879. $statement = $this->pdo->prepare($query);
  30880. $statement->execute(array($this->getSchema()));
  30881. $tableNames = array();
  30882. while ($tableName = $statement->fetchColumn(0)) {
  30883. $tableNames[] = $tableName;
  30884. }
  30885. return $tableNames;
  30886. }
  30887. /**
  30888. * Returns an array containing the names of all the columns in the
  30889. * $tableName table,
  30890. *
  30891. * @param string $tableName
  30892. * @return array
  30893. */
  30894. public function getTableColumns($tableName)
  30895. {
  30896. if (!isset($this->columns[$tableName])) {
  30897. $this->loadColumnInfo($tableName);
  30898. }
  30899. return $this->columns[$tableName];
  30900. }
  30901. /**
  30902. * Returns an array containing the names of all the primary key columns in
  30903. * the $tableName table.
  30904. *
  30905. * @param string $tableName
  30906. * @return array
  30907. */
  30908. public function getTablePrimaryKeys($tableName)
  30909. {
  30910. if (!isset($this->keys[$tableName])) {
  30911. $this->loadColumnInfo($tableName);
  30912. }
  30913. return $this->keys[$tableName];
  30914. }
  30915. /**
  30916. * Loads column info from a sqlite database.
  30917. *
  30918. * @param string $tableName
  30919. */
  30920. protected function loadColumnInfo($tableName)
  30921. {
  30922. $this->columns[$tableName] = array();
  30923. $this->keys[$tableName] = array();
  30924. $columnQuery = "
  30925. SELECT DISTINCT
  30926. COLUMN_NAME
  30927. FROM INFORMATION_SCHEMA.COLUMNS
  30928. WHERE
  30929. TABLE_NAME = ? AND
  30930. TABLE_SCHEMA = ?
  30931. ORDER BY ORDINAL_POSITION
  30932. ";
  30933. $columnStatement = $this->pdo->prepare($columnQuery);
  30934. $columnStatement->execute(array($tableName, $this->getSchema()));
  30935. while ($columName = $columnStatement->fetchColumn(0)) {
  30936. $this->columns[$tableName][] = $columName;
  30937. }
  30938. $keyQuery = "
  30939. SELECT
  30940. KCU.COLUMN_NAME
  30941. FROM
  30942. INFORMATION_SCHEMA.TABLE_CONSTRAINTS as TC,
  30943. INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU
  30944. WHERE
  30945. TC.CONSTRAINT_NAME = KCU.CONSTRAINT_NAME AND
  30946. TC.TABLE_NAME = KCU.TABLE_NAME AND
  30947. TC.TABLE_SCHEMA = KCU.TABLE_SCHEMA AND
  30948. TC.CONSTRAINT_TYPE = 'PRIMARY KEY' AND
  30949. TC.TABLE_NAME = ? AND
  30950. TC.TABLE_SCHEMA = ?
  30951. ORDER BY
  30952. KCU.ORDINAL_POSITION ASC
  30953. ";
  30954. $keyStatement = $this->pdo->prepare($keyQuery);
  30955. $keyStatement->execute(array($tableName, $this->getSchema()));
  30956. while ($columName = $keyStatement->fetchColumn(0)) {
  30957. $this->keys[$tableName][] = $columName;
  30958. }
  30959. }
  30960. }
  30961. <?php
  30962. /*
  30963. * This file is part of DBUnit.
  30964. *
  30965. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  30966. *
  30967. * For the full copyright and license information, please view the LICENSE
  30968. * file that was distributed with this source code.
  30969. */
  30970. /**
  30971. * Provides functionality to retrieve meta data from a Firebird database.
  30972. *
  30973. * @package DbUnit
  30974. * @author Matheus Degiovani (matheus@gigatron.com.br)
  30975. * @copyright 2002-2014 Matheus Degiovani (matheus@gigatron.com.br)
  30976. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  30977. * @version Release: 1.1.2
  30978. * @link http://www.phpunit.de/
  30979. * @since
  30980. */
  30981. class PHPUnit_Extensions_Database_DB_MetaData_Firebird extends PHPUnit_Extensions_Database_DB_MetaData
  30982. {
  30983. /**
  30984. * The command used to perform a TRUNCATE operation.
  30985. * @var string
  30986. */
  30987. protected $truncateCommand = 'DELETE FROM';
  30988. /**
  30989. * Returns an array containing the names of all the tables in the database.
  30990. *
  30991. * @return array
  30992. */
  30993. public function getTableNames()
  30994. {
  30995. $query = "
  30996. SELECT DISTINCT
  30997. TABLE_NAME
  30998. FROM INFORMATION_SCHEMA.TABLES
  30999. WHERE
  31000. TABLE_TYPE='BASE TABLE' AND
  31001. TABLE_SCHEMA = ?
  31002. ORDER BY TABLE_NAME
  31003. ";
  31004. $query = "
  31005. select
  31006. RDB$RELATION_NAME as TABLE_NAME
  31007. from RDB$RELATIONS
  31008. where
  31009. ((RDB$RELATION_TYPE = 0) or
  31010. (RDB$RELATION_TYPE is null)) and
  31011. (RDB$SYSTEM_FLAG = 0)
  31012. order by (RDB$RELATION_NAME)
  31013. ";
  31014. $statement = $this->pdo->prepare($query);
  31015. $statement->execute(array($this->getSchema()));
  31016. $tableNames = array();
  31017. while ($tableName = $statement->fetchColumn(0)) {
  31018. $tableNames[] = $tableName;
  31019. }
  31020. return $tableNames;
  31021. }
  31022. /**
  31023. * Returns an array containing the names of all the columns in the
  31024. * $tableName table,
  31025. *
  31026. * @param string $tableName
  31027. * @return array
  31028. */
  31029. public function getTableColumns($tableName)
  31030. {
  31031. if (!isset($this->columns[$tableName])) {
  31032. $this->loadColumnInfo($tableName);
  31033. }
  31034. return $this->columns[$tableName];
  31035. }
  31036. /**
  31037. * Returns an array containing the names of all the primary key columns in
  31038. * the $tableName table.
  31039. *
  31040. * @param string $tableName
  31041. * @return array
  31042. */
  31043. public function getTablePrimaryKeys($tableName)
  31044. {
  31045. if (!isset($this->keys[$tableName])) {
  31046. $this->loadColumnInfo($tableName);
  31047. }
  31048. return $this->keys[$tableName];
  31049. }
  31050. /**
  31051. * Loads column info from a database table.
  31052. *
  31053. * @param string $tableName
  31054. */
  31055. protected function loadColumnInfo($tableName)
  31056. {
  31057. $this->columns[$tableName] = array();
  31058. $this->keys[$tableName] = array();
  31059. $columnQuery = "
  31060. SELECT DISTINCT
  31061. COLUMN_NAME, ORDINAL_POSITION
  31062. FROM INFORMATION_SCHEMA.COLUMNS
  31063. WHERE
  31064. TABLE_NAME = ? AND
  31065. TABLE_SCHEMA = ?
  31066. ORDER BY ORDINAL_POSITION
  31067. ";
  31068. $columnQuery = "
  31069. select
  31070. rf.RDB\$FIELD_NAME as COLUMN_NAME,
  31071. rf.RDB\$FIELD_POSITION as ORDINAL_POSITION
  31072. from RDB\$RELATION_FIELDS as rf
  31073. where
  31074. upper(RDB\$RELATION_NAME) = upper(?)
  31075. order by
  31076. ORDINAL_POSITION
  31077. ";
  31078. $columnStatement = $this->pdo->prepare($columnQuery);
  31079. $columnStatement->execute(array($tableName));
  31080. while ($columName = $columnStatement->fetchColumn(0)) {
  31081. $this->columns[$tableName][] = $columName;
  31082. }
  31083. $keyQuery = "
  31084. SELECT
  31085. KCU.COLUMN_NAME,
  31086. KCU.ORDINAL_POSITION
  31087. FROM
  31088. INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU
  31089. LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as TC
  31090. ON TC.TABLE_NAME = KCU.TABLE_NAME
  31091. WHERE
  31092. TC.CONSTRAINT_TYPE = 'PRIMARY KEY' AND
  31093. TC.TABLE_NAME = ? AND
  31094. TC.TABLE_SCHEMA = ?
  31095. ORDER BY
  31096. KCU.ORDINAL_POSITION ASC
  31097. ";
  31098. $keyQuery = "
  31099. select
  31100. idseg.rdb\$field_name as COLUMN_NAME,
  31101. idseg.rdb\$field_position as ORDINAL_POSITION,
  31102. rc.rdb\$relation_name as tablename,
  31103. rc.rdb\$constraint_name as pk_name
  31104. from
  31105. RDB\$RELATION_CONSTRAINTS AS rc
  31106. left join
  31107. rdb\$index_segments as idseg on
  31108. (rc.rdb\$index_name = idseg.rdb\$index_name)
  31109. where
  31110. rc.RDB\$CONSTRAINT_TYPE = 'PRIMARY KEY'
  31111. and upper(rc.RDB\$RELATION_NAME) = upper(?)
  31112. order by
  31113. rc.rdb\$constraint_name, idseg.rdb\$field_position
  31114. ";
  31115. $keyStatement = $this->pdo->prepare($keyQuery);
  31116. $keyStatement->execute(array($tableName));
  31117. while ($columName = $keyStatement->fetchColumn(0)) {
  31118. $this->keys[$tableName][] = $columName;
  31119. }
  31120. }
  31121. /**
  31122. * Returns the schema for the connection.
  31123. *
  31124. * @return string
  31125. */
  31126. public function getSchema()
  31127. {
  31128. if (empty($this->schema)) {
  31129. return 'public';
  31130. } else {
  31131. return $this->schema;
  31132. }
  31133. }
  31134. /**
  31135. * Returns true if the rdbms allows cascading
  31136. *
  31137. * @return bool
  31138. */
  31139. public function allowsCascading()
  31140. {
  31141. return false;
  31142. }
  31143. /**
  31144. * Returns a quoted schema object. (table name, column name, etc)
  31145. *
  31146. * @param string $object
  31147. * @return string
  31148. */
  31149. public function quoteSchemaObject($object) {
  31150. return $object; //firebird does not allow object quoting
  31151. }
  31152. }
  31153. <?php
  31154. /*
  31155. * This file is part of DBUnit.
  31156. *
  31157. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31158. *
  31159. * For the full copyright and license information, please view the LICENSE
  31160. * file that was distributed with this source code.
  31161. */
  31162. /**
  31163. * Provides functionality to retrieve meta data from an Oracle database.
  31164. *
  31165. * @package DbUnit
  31166. * @author Trond Hansen <trond@xait.no>
  31167. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  31168. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31169. * @version Release: @package_version@
  31170. * @link http://www.phpunit.de/
  31171. * @since Class available since Release 3.2.3
  31172. */
  31173. class PHPUnit_Extensions_Database_DB_MetaData_Oci extends PHPUnit_Extensions_Database_DB_MetaData
  31174. {
  31175. /**
  31176. * No character used to quote schema objects.
  31177. * @var string
  31178. */
  31179. protected $schemaObjectQuoteChar = '';
  31180. /**
  31181. * The command used to perform a TRUNCATE operation.
  31182. * @var string
  31183. */
  31184. protected $truncateCommand = 'TRUNCATE TABLE';
  31185. /**
  31186. * @var array
  31187. */
  31188. protected $columns = array();
  31189. /**
  31190. * @var array
  31191. */
  31192. protected $keys = array();
  31193. /**
  31194. * Returns an array containing the names of all the tables in the database.
  31195. *
  31196. * @return array
  31197. */
  31198. public function getTableNames()
  31199. {
  31200. $tableNames = array();
  31201. $query = "SELECT table_name
  31202. FROM cat
  31203. WHERE table_type='TABLE'
  31204. ORDER BY table_name";
  31205. $result = $this->pdo->query($query);
  31206. while ($tableName = $result->fetchColumn(0)) {
  31207. $tableNames[] = $tableName;
  31208. }
  31209. return $tableNames;
  31210. }
  31211. /**
  31212. * Returns an array containing the names of all the columns in the
  31213. * $tableName table,
  31214. *
  31215. * @param string $tableName
  31216. * @return array
  31217. */
  31218. public function getTableColumns($tableName)
  31219. {
  31220. if (!isset($this->columns[$tableName])) {
  31221. $this->loadColumnInfo($tableName);
  31222. }
  31223. return $this->columns[$tableName];
  31224. }
  31225. /**
  31226. * Returns an array containing the names of all the primary key columns in
  31227. * the $tableName table.
  31228. *
  31229. * @param string $tableName
  31230. * @return array
  31231. */
  31232. public function getTablePrimaryKeys($tableName)
  31233. {
  31234. if (!isset($this->keys[$tableName])) {
  31235. $this->loadColumnInfo($tableName);
  31236. }
  31237. return $this->keys[$tableName];
  31238. }
  31239. /**
  31240. * Loads column info from a oracle database.
  31241. *
  31242. * @param string $tableName
  31243. */
  31244. protected function loadColumnInfo($tableName)
  31245. {
  31246. $ownerQuery = '';
  31247. $conOwnerQuery = '';
  31248. $tableParts = $this->splitTableName($tableName);
  31249. $this->columns[$tableName] = array();
  31250. $this->keys[$tableName] = array();
  31251. if (!empty($tableParts['schema']))
  31252. {
  31253. $ownerQuery = " AND OWNER = '{$tableParts['schema']}'";
  31254. $conOwnerQuery = " AND a.owner = '{$tableParts['schema']}'";
  31255. }
  31256. $query = "SELECT DISTINCT COLUMN_NAME
  31257. FROM USER_TAB_COLUMNS
  31258. WHERE TABLE_NAME='".$tableParts['table']."'
  31259. $ownerQuery
  31260. ORDER BY COLUMN_NAME";
  31261. $result = $this->pdo->query($query);
  31262. while ($columnName = $result->fetchColumn(0)) {
  31263. $this->columns[$tableName][] = $columnName;
  31264. }
  31265. $keyQuery = "SELECT b.column_name
  31266. FROM user_constraints a, user_cons_columns b
  31267. WHERE a.constraint_type='P'
  31268. AND a.constraint_name=b.constraint_name
  31269. $conOwnerQuery
  31270. AND a.table_name = '".$tableParts['table']."' ";
  31271. $result = $this->pdo->query($keyQuery);
  31272. while ($columnName = $result->fetchColumn(0)) {
  31273. $this->keys[$tableName][] = $columnName;
  31274. }
  31275. }
  31276. }
  31277. <?php
  31278. /*
  31279. * This file is part of DBUnit.
  31280. *
  31281. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31282. *
  31283. * For the full copyright and license information, please view the LICENSE
  31284. * file that was distributed with this source code.
  31285. */
  31286. /**
  31287. * Provides functionality to retrieve meta data from a PostgreSQL database.
  31288. *
  31289. * @package DbUnit
  31290. * @author Mike Lively <m@digitalsandwich.com>
  31291. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  31292. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31293. * @version Release: @package_version@
  31294. * @link http://www.phpunit.de/
  31295. * @since Class available since Release 1.0.0
  31296. */
  31297. class PHPUnit_Extensions_Database_DB_MetaData_PgSQL extends PHPUnit_Extensions_Database_DB_MetaData
  31298. {
  31299. /**
  31300. * Returns an array containing the names of all the tables in the database.
  31301. *
  31302. * @return array
  31303. */
  31304. public function getTableNames()
  31305. {
  31306. $query = "
  31307. SELECT DISTINCT
  31308. TABLE_NAME
  31309. FROM INFORMATION_SCHEMA.TABLES
  31310. WHERE
  31311. TABLE_TYPE='BASE TABLE' AND
  31312. TABLE_SCHEMA = ?
  31313. ORDER BY TABLE_NAME
  31314. ";
  31315. $statement = $this->pdo->prepare($query);
  31316. $statement->execute(array($this->getSchema()));
  31317. $tableNames = array();
  31318. while ($tableName = $statement->fetchColumn(0)) {
  31319. $tableNames[] = $tableName;
  31320. }
  31321. return $tableNames;
  31322. }
  31323. /**
  31324. * Returns an array containing the names of all the columns in the
  31325. * $tableName table,
  31326. *
  31327. * @param string $tableName
  31328. * @return array
  31329. */
  31330. public function getTableColumns($tableName)
  31331. {
  31332. if (!isset($this->columns[$tableName])) {
  31333. $this->loadColumnInfo($tableName);
  31334. }
  31335. return $this->columns[$tableName];
  31336. }
  31337. /**
  31338. * Returns an array containing the names of all the primary key columns in
  31339. * the $tableName table.
  31340. *
  31341. * @param string $tableName
  31342. * @return array
  31343. */
  31344. public function getTablePrimaryKeys($tableName)
  31345. {
  31346. if (!isset($this->keys[$tableName])) {
  31347. $this->loadColumnInfo($tableName);
  31348. }
  31349. return $this->keys[$tableName];
  31350. }
  31351. /**
  31352. * Loads column info from a database table.
  31353. *
  31354. * @param string $tableName
  31355. */
  31356. protected function loadColumnInfo($tableName)
  31357. {
  31358. $this->columns[$tableName] = array();
  31359. $this->keys[$tableName] = array();
  31360. $columnQuery = "
  31361. SELECT DISTINCT
  31362. COLUMN_NAME, ORDINAL_POSITION
  31363. FROM INFORMATION_SCHEMA.COLUMNS
  31364. WHERE
  31365. TABLE_NAME = ? AND
  31366. TABLE_SCHEMA = ?
  31367. ORDER BY ORDINAL_POSITION
  31368. ";
  31369. $columnStatement = $this->pdo->prepare($columnQuery);
  31370. $columnStatement->execute(array($tableName, $this->getSchema()));
  31371. while ($columName = $columnStatement->fetchColumn(0)) {
  31372. $this->columns[$tableName][] = $columName;
  31373. }
  31374. $keyQuery = "
  31375. SELECT
  31376. KCU.COLUMN_NAME,
  31377. KCU.ORDINAL_POSITION
  31378. FROM
  31379. INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU
  31380. LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as TC
  31381. ON TC.TABLE_NAME = KCU.TABLE_NAME AND
  31382. TC.CONSTRAINT_NAME = KCU.CONSTRAINT_NAME
  31383. WHERE
  31384. TC.CONSTRAINT_TYPE = 'PRIMARY KEY' AND
  31385. TC.TABLE_NAME = ? AND
  31386. TC.TABLE_SCHEMA = ?
  31387. ORDER BY
  31388. KCU.ORDINAL_POSITION ASC
  31389. ";
  31390. $keyStatement = $this->pdo->prepare($keyQuery);
  31391. $keyStatement->execute(array($tableName, $this->getSchema()));
  31392. while ($columName = $keyStatement->fetchColumn(0)) {
  31393. $this->keys[$tableName][] = $columName;
  31394. }
  31395. }
  31396. /**
  31397. * Returns the schema for the connection.
  31398. *
  31399. * @return string
  31400. */
  31401. public function getSchema()
  31402. {
  31403. if (empty($this->schema)) {
  31404. return 'public';
  31405. } else {
  31406. return $this->schema;
  31407. }
  31408. }
  31409. /**
  31410. * Returns true if the rdbms allows cascading
  31411. *
  31412. * @return bool
  31413. */
  31414. public function allowsCascading()
  31415. {
  31416. return TRUE;
  31417. }
  31418. }
  31419. <?php
  31420. /*
  31421. * This file is part of DBUnit.
  31422. *
  31423. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31424. *
  31425. * For the full copyright and license information, please view the LICENSE
  31426. * file that was distributed with this source code.
  31427. */
  31428. /**
  31429. * Provides functionality to retrieve meta data from a Microsoft SQL Server database.
  31430. *
  31431. * @package DbUnit
  31432. * @author Nils Adermann <naderman@naderman.de>
  31433. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  31434. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31435. * @version Release: @package_version@
  31436. * @link http://www.phpunit.de/
  31437. * @since Class available since Release 1.1.0
  31438. */
  31439. class PHPUnit_Extensions_Database_DB_MetaData_SqlSrv extends PHPUnit_Extensions_Database_DB_MetaData
  31440. {
  31441. /**
  31442. * No character used to quote schema objects.
  31443. * @var string
  31444. */
  31445. protected $schemaObjectQuoteChar = '';
  31446. /**
  31447. * The command used to perform a TRUNCATE operation.
  31448. * @var string
  31449. */
  31450. protected $truncateCommand = 'TRUNCATE TABLE';
  31451. /**
  31452. * Returns an array containing the names of all the tables in the database.
  31453. *
  31454. * @return array
  31455. */
  31456. public function getTableNames()
  31457. {
  31458. $query = "SELECT name
  31459. FROM sysobjects
  31460. WHERE type='U'";
  31461. $statement = $this->pdo->prepare($query);
  31462. $statement->execute();
  31463. $tableNames = array();
  31464. while (($tableName = $statement->fetchColumn(0))) {
  31465. $tableNames[] = $tableName;
  31466. }
  31467. return $tableNames;
  31468. }
  31469. /**
  31470. * Returns an array containing the names of all the columns in the
  31471. * $tableName table.
  31472. *
  31473. * @param string $tableName
  31474. * @return array
  31475. */
  31476. public function getTableColumns($tableName)
  31477. {
  31478. $query = "SELECT c.name
  31479. FROM syscolumns c
  31480. LEFT JOIN sysobjects o ON c.id = o.id
  31481. WHERE o.name = '$tableName'";
  31482. $statement = $this->pdo->prepare($query);
  31483. $statement->execute();
  31484. $columnNames = array();
  31485. while (($columnName = $statement->fetchColumn(0))) {
  31486. $columnNames[] = $columnName;
  31487. }
  31488. return $columnNames;
  31489. }
  31490. /**
  31491. * Returns an array containing the names of all the primary key columns in
  31492. * the $tableName table.
  31493. *
  31494. * @param string $tableName
  31495. * @return array
  31496. */
  31497. public function getTablePrimaryKeys($tableName)
  31498. {
  31499. $query = "EXEC sp_statistics '$tableName'";
  31500. $statement = $this->pdo->prepare($query);
  31501. $statement->execute();
  31502. $statement->setFetchMode(PDO::FETCH_ASSOC);
  31503. $columnNames = array();
  31504. while (($column = $statement->fetch())) {
  31505. if ($column['TYPE'] == 1) {
  31506. $columnNames[] = $column['COLUMN_NAME'];
  31507. }
  31508. }
  31509. return $columnNames;
  31510. }
  31511. /**
  31512. * Allow overwriting identities for the given table.
  31513. *
  31514. * @param string $tableName
  31515. */
  31516. public function disablePrimaryKeys($tableName)
  31517. {
  31518. try {
  31519. $query = "SET IDENTITY_INSERT $tableName ON";
  31520. $this->pdo->exec($query);
  31521. }
  31522. catch (PDOException $e) {
  31523. // ignore the error here - can happen if primary key is not an identity
  31524. }
  31525. }
  31526. /**
  31527. * Reenable auto creation of identities for the given table.
  31528. *
  31529. * @param string $tableName
  31530. */
  31531. public function enablePrimaryKeys($tableName)
  31532. {
  31533. try {
  31534. $query = "SET IDENTITY_INSERT $tableName OFF";
  31535. $this->pdo->exec($query);
  31536. }
  31537. catch (PDOException $e) {
  31538. // ignore the error here - can happen if primary key is not an identity
  31539. }
  31540. }
  31541. }
  31542. <?php
  31543. /*
  31544. * This file is part of DBUnit.
  31545. *
  31546. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31547. *
  31548. * For the full copyright and license information, please view the LICENSE
  31549. * file that was distributed with this source code.
  31550. */
  31551. /**
  31552. * Provides the functionality to represent a database table.
  31553. *
  31554. * @package DbUnit
  31555. * @author Mike Lively <m@digitalsandwich.com>
  31556. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  31557. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31558. * @version Release: @package_version@
  31559. * @link http://www.phpunit.de/
  31560. * @since Class available since Release 1.0.0
  31561. */
  31562. class PHPUnit_Extensions_Database_DB_Table extends PHPUnit_Extensions_Database_DataSet_AbstractTable
  31563. {
  31564. /**
  31565. * Creates a new database table object.
  31566. *
  31567. * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData
  31568. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection
  31569. */
  31570. public function __construct(PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData, PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection)
  31571. {
  31572. $this->setTableMetaData($tableMetaData);
  31573. $pdoStatement = $databaseConnection->getConnection()->prepare(PHPUnit_Extensions_Database_DB_DataSet::buildTableSelect($tableMetaData, $databaseConnection));
  31574. $pdoStatement->execute();
  31575. $this->data = $pdoStatement->fetchAll(PDO::FETCH_ASSOC);
  31576. }
  31577. }
  31578. <?php
  31579. /*
  31580. * This file is part of DBUnit.
  31581. *
  31582. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31583. *
  31584. * For the full copyright and license information, please view the LICENSE
  31585. * file that was distributed with this source code.
  31586. */
  31587. /**
  31588. * Provides access to a database instance as a data set.
  31589. *
  31590. * @package DbUnit
  31591. * @author Mike Lively <m@digitalsandwich.com>
  31592. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  31593. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31594. * @version Release: @package_version@
  31595. * @link http://www.phpunit.de/
  31596. * @since Class available since Release 1.0.0
  31597. */
  31598. class PHPUnit_Extensions_Database_DB_FilteredDataSet extends PHPUnit_Extensions_Database_DB_DataSet
  31599. {
  31600. /**
  31601. * @var Array
  31602. */
  31603. protected $tableNames;
  31604. /**
  31605. * Creates a new dataset using the given database connection.
  31606. *
  31607. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection
  31608. */
  31609. public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection, Array $tableNames)
  31610. {
  31611. parent::__construct($databaseConnection);
  31612. $this->tableNames = $tableNames;
  31613. }
  31614. /**
  31615. * Returns a list of table names for the database
  31616. *
  31617. * @return Array
  31618. */
  31619. public function getTableNames()
  31620. {
  31621. return $this->tableNames;
  31622. }
  31623. }
  31624. <?php
  31625. /*
  31626. * This file is part of DBUnit.
  31627. *
  31628. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31629. *
  31630. * For the full copyright and license information, please view the LICENSE
  31631. * file that was distributed with this source code.
  31632. */
  31633. /**
  31634. * Provides a basic interface for communicating with a database.
  31635. *
  31636. * @package DbUnit
  31637. * @author Mike Lively <m@digitalsandwich.com>
  31638. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  31639. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31640. * @version Release: @package_version@
  31641. * @link http://www.phpunit.de/
  31642. * @since Class available since Release 1.0.0
  31643. */
  31644. interface PHPUnit_Extensions_Database_DB_IDatabaseConnection
  31645. {
  31646. /**
  31647. * Close this connection.
  31648. */
  31649. public function close();
  31650. /**
  31651. * Creates a dataset containing the specified table names. If no table
  31652. * names are specified then it will created a dataset over the entire
  31653. * database.
  31654. *
  31655. * @param array $tableNames
  31656. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  31657. */
  31658. public function createDataSet(Array $tableNames = NULL);
  31659. /**
  31660. * Creates a table with the result of the specified SQL statement.
  31661. *
  31662. * @param string $resultName
  31663. * @param string $sql
  31664. * @return PHPUnit_Extensions_Database_DataSet_ITable
  31665. */
  31666. public function createQueryTable($resultName, $sql);
  31667. /**
  31668. * Returns a PDO Connection
  31669. *
  31670. * @return PDO
  31671. */
  31672. public function getConnection();
  31673. /**
  31674. * Returns a database metadata object that can be used to retrieve table
  31675. * meta data from the database.
  31676. *
  31677. * @return PHPUnit_Extensions_Database_DB_IMetaData
  31678. */
  31679. public function getMetaData();
  31680. /**
  31681. * Returns the number of rows in the given table. You can specify an
  31682. * optional where clause to return a subset of the table.
  31683. *
  31684. * @param string $tableName
  31685. * @param string $whereClause
  31686. * @param int
  31687. */
  31688. public function getRowCount($tableName, $whereClause = NULL);
  31689. /**
  31690. * Returns the schema for the connection.
  31691. *
  31692. * @return string
  31693. */
  31694. public function getSchema();
  31695. /**
  31696. * Returns a quoted schema object. (table name, column name, etc)
  31697. *
  31698. * @param string $object
  31699. * @return string
  31700. */
  31701. public function quoteSchemaObject($object);
  31702. /**
  31703. * Returns the command used to truncate a table.
  31704. *
  31705. * @return string
  31706. */
  31707. public function getTruncateCommand();
  31708. /**
  31709. * Returns true if the connection allows cascading
  31710. *
  31711. * @return bool
  31712. */
  31713. public function allowsCascading();
  31714. /**
  31715. * Disables primary keys if connection does not allow setting them otherwise
  31716. *
  31717. * @param string $tableName
  31718. */
  31719. public function disablePrimaryKeys($tableName);
  31720. /**
  31721. * Reenables primary keys after they have been disabled
  31722. *
  31723. * @param string $tableName
  31724. */
  31725. public function enablePrimaryKeys($tableName);
  31726. }
  31727. <?php
  31728. /*
  31729. * This file is part of DBUnit.
  31730. *
  31731. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31732. *
  31733. * For the full copyright and license information, please view the LICENSE
  31734. * file that was distributed with this source code.
  31735. */
  31736. /**
  31737. * This class loads a table metadata object with database metadata.
  31738. *
  31739. * @package DbUnit
  31740. * @author Mike Lively <m@digitalsandwich.com>
  31741. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  31742. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31743. * @version Release: @package_version@
  31744. * @link http://www.phpunit.de/
  31745. * @since Class available since Release 1.0.0
  31746. */
  31747. class PHPUnit_Extensions_Database_DB_TableMetaData extends PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData
  31748. {
  31749. public function __construct($tableName, PHPUnit_Extensions_Database_DB_IMetaData $databaseMetaData)
  31750. {
  31751. $this->tableName = $tableName;
  31752. $this->columns = $databaseMetaData->getTableColumns($tableName);
  31753. $this->primaryKeys = $databaseMetaData->getTablePrimaryKeys($tableName);
  31754. }
  31755. }
  31756. <?php
  31757. /*
  31758. * This file is part of DBUnit.
  31759. *
  31760. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31761. *
  31762. * For the full copyright and license information, please view the LICENSE
  31763. * file that was distributed with this source code.
  31764. */
  31765. /**
  31766. * Provides a basic constructor for all meta data classes and a factory for
  31767. * generating the appropriate meta data class.
  31768. *
  31769. * @package DbUnit
  31770. * @author Mike Lively <m@digitalsandwich.com>
  31771. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  31772. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31773. * @version Release: @package_version@
  31774. * @link http://www.phpunit.de/
  31775. * @since Class available since Release 1.0.0
  31776. */
  31777. abstract class PHPUnit_Extensions_Database_DB_MetaData implements PHPUnit_Extensions_Database_DB_IMetaData
  31778. {
  31779. protected static $metaDataClassMap = array(
  31780. 'pgsql' => 'PHPUnit_Extensions_Database_DB_MetaData_PgSQL',
  31781. 'mysql' => 'PHPUnit_Extensions_Database_DB_MetaData_MySQL',
  31782. 'oci' => 'PHPUnit_Extensions_Database_DB_MetaData_Oci',
  31783. 'sqlite' => 'PHPUnit_Extensions_Database_DB_MetaData_Sqlite',
  31784. 'sqlite2'=> 'PHPUnit_Extensions_Database_DB_MetaData_Sqlite',
  31785. 'sqlsrv' => 'PHPUnit_Extensions_Database_DB_MetaData_SqlSrv',
  31786. 'firebird' => 'PHPUnit_Extensions_Database_DB_MetaData_Firebird',
  31787. 'dblib' => 'PHPUnit_Extensions_Database_DB_MetaData_Dblib'
  31788. );
  31789. /**
  31790. * The PDO connection used to retreive database meta data
  31791. *
  31792. * @var PDO
  31793. */
  31794. protected $pdo;
  31795. /**
  31796. * The default schema name for the meta data object.
  31797. *
  31798. * @var string
  31799. */
  31800. protected $schema;
  31801. /**
  31802. * The character used to quote schema objects.
  31803. */
  31804. protected $schemaObjectQuoteChar = '"';
  31805. /**
  31806. * The command used to perform a TRUNCATE operation.
  31807. */
  31808. protected $truncateCommand = 'TRUNCATE';
  31809. /**
  31810. * Creates a new database meta data object using the given pdo connection
  31811. * and schema name.
  31812. *
  31813. * @param PDO $pdo
  31814. * @param string $schema
  31815. */
  31816. public final function __construct(PDO $pdo, $schema = '')
  31817. {
  31818. $this->pdo = $pdo;
  31819. $this->schema = $schema;
  31820. }
  31821. /**
  31822. * Creates a meta data object based on the driver of given $pdo object and
  31823. * $schema name.
  31824. *
  31825. * @param PDO $pdo
  31826. * @param string $schema
  31827. * @return PHPUnit_Extensions_Database_DB_MetaData
  31828. */
  31829. public static function createMetaData(PDO $pdo, $schema = '')
  31830. {
  31831. $driverName = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
  31832. if (isset(self::$metaDataClassMap[$driverName])) {
  31833. $className = self::$metaDataClassMap[$driverName];
  31834. if ($className instanceof ReflectionClass) {
  31835. return $className->newInstance($pdo, $schema);
  31836. } else {
  31837. return self::registerClassWithDriver($className, $driverName)->newInstance($pdo, $schema);
  31838. }
  31839. } else {
  31840. throw new PHPUnit_Extensions_Database_Exception("Could not find a meta data driver for {$driverName} pdo driver.");
  31841. }
  31842. }
  31843. /**
  31844. * Validates and registers the given $className with the given $pdoDriver.
  31845. * It should be noted that this function will not attempt to include /
  31846. * require the file. The $pdoDriver can be determined by the value of the
  31847. * PDO::ATTR_DRIVER_NAME attribute for a pdo object.
  31848. *
  31849. * A reflection of the $className is returned.
  31850. *
  31851. * @param string $className
  31852. * @param string $pdoDriver
  31853. * @return ReflectionClass
  31854. */
  31855. public static function registerClassWithDriver($className, $pdoDriver)
  31856. {
  31857. if (!class_exists($className)) {
  31858. throw new PHPUnit_Extensions_Database_Exception("Specified class for {$pdoDriver} driver ({$className}) does not exist.");
  31859. }
  31860. $reflection = new ReflectionClass($className);
  31861. if ($reflection->isSubclassOf('PHPUnit_Extensions_Database_DB_MetaData')) {
  31862. return self::$metaDataClassMap[$pdoDriver] = $reflection;
  31863. } else {
  31864. throw new PHPUnit_Extensions_Database_Exception("Specified class for {$pdoDriver} driver ({$className}) does not extend PHPUnit_Extensions_Database_DB_MetaData.");
  31865. }
  31866. }
  31867. /**
  31868. * Returns the schema for the connection.
  31869. *
  31870. * @return string
  31871. */
  31872. public function getSchema()
  31873. {
  31874. return $this->schema;
  31875. }
  31876. /**
  31877. * Returns a quoted schema object. (table name, column name, etc)
  31878. *
  31879. * @param string $object
  31880. * @return string
  31881. */
  31882. public function quoteSchemaObject($object)
  31883. {
  31884. $parts = explode('.', $object);
  31885. $quotedParts = array();
  31886. foreach ($parts as $part) {
  31887. $quotedParts[] = $this->schemaObjectQuoteChar .
  31888. str_replace($this->schemaObjectQuoteChar, $this->schemaObjectQuoteChar.$this->schemaObjectQuoteChar, $part).
  31889. $this->schemaObjectQuoteChar;
  31890. }
  31891. return implode('.', $quotedParts);
  31892. }
  31893. /**
  31894. * Seperates the schema and the table from a fully qualified table name.
  31895. *
  31896. * Returns an associative array containing the 'schema' and the 'table'.
  31897. *
  31898. * @param string $fullTableName
  31899. * @return array
  31900. */
  31901. public function splitTableName($fullTableName)
  31902. {
  31903. if (($dot = strpos($fullTableName, '.')) !== FALSE) {
  31904. return array(
  31905. 'schema' => substr($fullTableName, 0, $dot),
  31906. 'table' => substr($fullTableName, $dot + 1)
  31907. );
  31908. } else {
  31909. return array(
  31910. 'schema' => NULL,
  31911. 'table' => $fullTableName
  31912. );
  31913. }
  31914. }
  31915. /**
  31916. * Returns the command for the database to truncate a table.
  31917. *
  31918. * @return string
  31919. */
  31920. public function getTruncateCommand()
  31921. {
  31922. return $this->truncateCommand;
  31923. }
  31924. /**
  31925. * Returns true if the rdbms allows cascading
  31926. *
  31927. * @return bool
  31928. */
  31929. public function allowsCascading()
  31930. {
  31931. return FALSE;
  31932. }
  31933. /**
  31934. * Disables primary keys if the rdbms does not allow setting them otherwise
  31935. *
  31936. * @param string $tableName
  31937. */
  31938. public function disablePrimaryKeys($tableName)
  31939. {
  31940. return;
  31941. }
  31942. /**
  31943. * Reenables primary keys after they have been disabled
  31944. *
  31945. * @param string $tableName
  31946. */
  31947. public function enablePrimaryKeys($tableName)
  31948. {
  31949. return;
  31950. }
  31951. }
  31952. <?php
  31953. /*
  31954. * This file is part of DBUnit.
  31955. *
  31956. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  31957. *
  31958. * For the full copyright and license information, please view the LICENSE
  31959. * file that was distributed with this source code.
  31960. */
  31961. /**
  31962. * Provides a basic interface for communicating with a database.
  31963. *
  31964. * @package DbUnit
  31965. * @author Mike Lively <m@digitalsandwich.com>
  31966. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  31967. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  31968. * @version Release: @package_version@
  31969. * @link http://www.phpunit.de/
  31970. * @since Class available since Release 1.0.0
  31971. */
  31972. class PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection implements PHPUnit_Extensions_Database_DB_IDatabaseConnection
  31973. {
  31974. /**
  31975. * @var PDO
  31976. */
  31977. protected $connection;
  31978. /**
  31979. * The metadata object used to retrieve table meta data from the database.
  31980. *
  31981. * @var PHPUnit_Extensions_Database_DB_IMetaData
  31982. */
  31983. protected $metaData;
  31984. /**
  31985. * Creates a new database connection
  31986. *
  31987. * @param PDO $connection
  31988. * @param string $schema - The name of the database schema you will be testing against.
  31989. */
  31990. public function __construct(PDO $connection, $schema = '')
  31991. {
  31992. $this->connection = $connection;
  31993. $this->metaData = PHPUnit_Extensions_Database_DB_MetaData::createMetaData($connection, $schema);
  31994. $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  31995. }
  31996. /**
  31997. * Close this connection.
  31998. */
  31999. public function close()
  32000. {
  32001. unset($this->connection);
  32002. }
  32003. /**
  32004. * Returns a database metadata object that can be used to retrieve table
  32005. * meta data from the database.
  32006. *
  32007. * @return PHPUnit_Extensions_Database_DB_IMetaData
  32008. */
  32009. public function getMetaData()
  32010. {
  32011. return $this->metaData;
  32012. }
  32013. /**
  32014. * Returns the schema for the connection.
  32015. *
  32016. * @return string
  32017. */
  32018. public function getSchema()
  32019. {
  32020. return $this->getMetaData()->getSchema();
  32021. }
  32022. /**
  32023. * Creates a dataset containing the specified table names. If no table
  32024. * names are specified then it will created a dataset over the entire
  32025. * database.
  32026. *
  32027. * @param array $tableNames
  32028. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  32029. * @todo Implement the filtered data set.
  32030. */
  32031. public function createDataSet(array $tableNames = NULL)
  32032. {
  32033. if (empty($tableNames)) {
  32034. return new PHPUnit_Extensions_Database_DB_DataSet($this);
  32035. } else {
  32036. return new PHPUnit_Extensions_Database_DB_FilteredDataSet($this, $tableNames);
  32037. }
  32038. }
  32039. /**
  32040. * Creates a table with the result of the specified SQL statement.
  32041. *
  32042. * @param string $resultName
  32043. * @param string $sql
  32044. * @return PHPUnit_Extensions_Database_DB_Table
  32045. */
  32046. public function createQueryTable($resultName, $sql)
  32047. {
  32048. return new PHPUnit_Extensions_Database_DataSet_QueryTable($resultName, $sql, $this);
  32049. }
  32050. /**
  32051. * Returns this connection database configuration
  32052. *
  32053. * @return PHPUnit_Extensions_Database_Database_DatabaseConfig
  32054. */
  32055. public function getConfig()
  32056. {
  32057. }
  32058. /**
  32059. * Returns a PDO Connection
  32060. *
  32061. * @return PDO
  32062. */
  32063. public function getConnection()
  32064. {
  32065. return $this->connection;
  32066. }
  32067. /**
  32068. * Returns the number of rows in the given table. You can specify an
  32069. * optional where clause to return a subset of the table.
  32070. *
  32071. * @param string $tableName
  32072. * @param string $whereClause
  32073. * @return int
  32074. */
  32075. public function getRowCount($tableName, $whereClause = NULL)
  32076. {
  32077. $query = "SELECT COUNT(*) FROM ".$this->quoteSchemaObject($tableName);
  32078. if (isset($whereClause)) {
  32079. $query .= " WHERE {$whereClause}";
  32080. }
  32081. return (int) $this->connection->query($query)->fetchColumn();
  32082. }
  32083. /**
  32084. * Returns a quoted schema object. (table name, column name, etc)
  32085. *
  32086. * @param string $object
  32087. * @return string
  32088. */
  32089. public function quoteSchemaObject($object)
  32090. {
  32091. return $this->getMetaData()->quoteSchemaObject($object);
  32092. }
  32093. /**
  32094. * Returns the command used to truncate a table.
  32095. *
  32096. * @return string
  32097. */
  32098. public function getTruncateCommand()
  32099. {
  32100. return $this->getMetaData()->getTruncateCommand();
  32101. }
  32102. /**
  32103. * Returns true if the connection allows cascading
  32104. *
  32105. * @return bool
  32106. */
  32107. public function allowsCascading()
  32108. {
  32109. return $this->getMetaData()->allowsCascading();
  32110. }
  32111. /**
  32112. * Disables primary keys if connection does not allow setting them otherwise
  32113. *
  32114. * @param string $tableName
  32115. */
  32116. public function disablePrimaryKeys($tableName)
  32117. {
  32118. $this->getMetaData()->disablePrimaryKeys($tableName);
  32119. }
  32120. /**
  32121. * Reenables primary keys after they have been disabled
  32122. *
  32123. * @param string $tableName
  32124. */
  32125. public function enablePrimaryKeys($tableName)
  32126. {
  32127. $this->getMetaData()->enablePrimaryKeys($tableName);
  32128. }
  32129. }
  32130. <?php
  32131. /*
  32132. * This file is part of DBUnit.
  32133. *
  32134. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32135. *
  32136. * For the full copyright and license information, please view the LICENSE
  32137. * file that was distributed with this source code.
  32138. */
  32139. /**
  32140. * Provides a basic interface for retreiving metadata from a database.
  32141. *
  32142. * @package DbUnit
  32143. * @author Mike Lively <m@digitalsandwich.com>
  32144. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32145. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32146. * @version Release: @package_version@
  32147. * @link http://www.phpunit.de/
  32148. * @since Class available since Release 1.0.0
  32149. */
  32150. interface PHPUnit_Extensions_Database_DB_IMetaData
  32151. {
  32152. /**
  32153. * Returns an array containing the names of all the tables in the database.
  32154. *
  32155. * @return array
  32156. */
  32157. public function getTableNames();
  32158. /**
  32159. * Returns an array containing the names of all the columns in the
  32160. * $tableName table,
  32161. *
  32162. * @param string $tableName
  32163. * @return array
  32164. */
  32165. public function getTableColumns($tableName);
  32166. /**
  32167. * Returns an array containing the names of all the primary key columns in
  32168. * the $tableName table.
  32169. *
  32170. * @param string $tableName
  32171. * @return array
  32172. */
  32173. public function getTablePrimaryKeys($tableName);
  32174. /**
  32175. * Returns the name of the default schema.
  32176. *
  32177. * @return string
  32178. */
  32179. public function getSchema();
  32180. /**
  32181. * Returns a quoted schema object. (table name, column name, etc)
  32182. *
  32183. * @param string $object
  32184. * @return string
  32185. */
  32186. public function quoteSchemaObject($object);
  32187. /**
  32188. * Returns true if the rdbms allows cascading
  32189. *
  32190. * @return bool
  32191. */
  32192. public function allowsCascading();
  32193. /**
  32194. * Disables primary keys if rdbms does not allow setting them otherwise
  32195. *
  32196. * @param string $tableName
  32197. */
  32198. public function disablePrimaryKeys($tableName);
  32199. /**
  32200. * Reenables primary keys after they have been disabled
  32201. *
  32202. * @param string $tableName
  32203. */
  32204. public function enablePrimaryKeys($tableName);
  32205. }
  32206. <?php
  32207. /*
  32208. * This file is part of DBUnit.
  32209. *
  32210. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32211. *
  32212. * For the full copyright and license information, please view the LICENSE
  32213. * file that was distributed with this source code.
  32214. */
  32215. /**
  32216. * Provides iterative access to tables from a database instance.
  32217. *
  32218. * @package DbUnit
  32219. * @author Mike Lively <m@digitalsandwich.com>
  32220. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32221. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32222. * @version Release: @package_version@
  32223. * @link http://www.phpunit.de/
  32224. * @since Class available since Release 1.0.0
  32225. */
  32226. class PHPUnit_Extensions_Database_DB_TableIterator implements PHPUnit_Extensions_Database_DataSet_ITableIterator
  32227. {
  32228. /**
  32229. * An array of tablenames.
  32230. *
  32231. * @var Array
  32232. */
  32233. protected $tableNames;
  32234. /**
  32235. * If this property is true then the tables will be iterated in reverse
  32236. * order.
  32237. *
  32238. * @var bool
  32239. */
  32240. protected $reverse;
  32241. /**
  32242. * The database dataset that this iterator iterates over.
  32243. *
  32244. * @var PHPUnit_Extensions_Database_DB_DataSet
  32245. */
  32246. protected $dataSet;
  32247. public function __construct($tableNames, PHPUnit_Extensions_Database_DB_DataSet $dataSet, $reverse = FALSE)
  32248. {
  32249. $this->tableNames = $tableNames;
  32250. $this->dataSet = $dataSet;
  32251. $this->reverse = $reverse;
  32252. $this->rewind();
  32253. }
  32254. /**
  32255. * Returns the current table.
  32256. *
  32257. * @return PHPUnit_Extensions_Database_DataSet_ITable
  32258. */
  32259. public function getTable()
  32260. {
  32261. return $this->current();
  32262. }
  32263. /**
  32264. * Returns the current table's meta data.
  32265. *
  32266. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  32267. */
  32268. public function getTableMetaData()
  32269. {
  32270. return $this->current()->getTableMetaData();
  32271. }
  32272. /**
  32273. * Returns the current table.
  32274. *
  32275. * @return PHPUnit_Extensions_Database_DataSet_ITable
  32276. */
  32277. public function current()
  32278. {
  32279. $tableName = current($this->tableNames);
  32280. return $this->dataSet->getTable($tableName);
  32281. }
  32282. /**
  32283. * Returns the name of the current table.
  32284. *
  32285. * @return string
  32286. */
  32287. public function key()
  32288. {
  32289. return $this->current()->getTableMetaData()->getTableName();
  32290. }
  32291. /**
  32292. * advances to the next element.
  32293. *
  32294. */
  32295. public function next()
  32296. {
  32297. if ($this->reverse) {
  32298. prev($this->tableNames);
  32299. } else {
  32300. next($this->tableNames);
  32301. }
  32302. }
  32303. /**
  32304. * Rewinds to the first element
  32305. */
  32306. public function rewind()
  32307. {
  32308. if ($this->reverse) {
  32309. end($this->tableNames);
  32310. } else {
  32311. reset($this->tableNames);
  32312. }
  32313. }
  32314. /**
  32315. * Returns true if the current index is valid
  32316. *
  32317. * @return bool
  32318. */
  32319. public function valid()
  32320. {
  32321. return (current($this->tableNames) !== FALSE);
  32322. }
  32323. }
  32324. <?php
  32325. /*
  32326. * This file is part of DBUnit.
  32327. *
  32328. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32329. *
  32330. * For the full copyright and license information, please view the LICENSE
  32331. * file that was distributed with this source code.
  32332. */
  32333. /**
  32334. * Provides access to a database instance as a data set.
  32335. *
  32336. * @package DbUnit
  32337. * @author Mike Lively <m@digitalsandwich.com>
  32338. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32339. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32340. * @version Release: @package_version@
  32341. * @link http://www.phpunit.de/
  32342. * @since Class available since Release 1.0.0
  32343. */
  32344. class PHPUnit_Extensions_Database_DB_DataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  32345. {
  32346. /**
  32347. * An array of ITable objects.
  32348. *
  32349. * @var array
  32350. */
  32351. protected $tables = array();
  32352. /**
  32353. * The database connection this dataset is using.
  32354. *
  32355. * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection
  32356. */
  32357. protected $databaseConnection;
  32358. /**
  32359. * Creates a new dataset using the given database connection.
  32360. *
  32361. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection
  32362. */
  32363. public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection)
  32364. {
  32365. $this->databaseConnection = $databaseConnection;
  32366. }
  32367. /**
  32368. * Creates the query necessary to pull all of the data from a table.
  32369. *
  32370. * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData
  32371. * @return unknown
  32372. */
  32373. public static function buildTableSelect(PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData, PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection = NULL)
  32374. {
  32375. if ($tableMetaData->getTableName() == '') {
  32376. $e = new Exception("Empty Table Name");
  32377. echo $e->getTraceAsString();
  32378. throw $e;
  32379. }
  32380. $columns = $tableMetaData->getColumns();
  32381. if ($databaseConnection) {
  32382. $columns = array_map(array($databaseConnection, 'quoteSchemaObject'), $columns);
  32383. }
  32384. $columnList = implode(', ', $columns);
  32385. if ($databaseConnection) {
  32386. $tableName = $databaseConnection->quoteSchemaObject($tableMetaData->getTableName());
  32387. } else {
  32388. $tableName = $tableMetaData->getTableName();
  32389. }
  32390. $primaryKeys = $tableMetaData->getPrimaryKeys();
  32391. if ($databaseConnection) {
  32392. $primaryKeys = array_map(array($databaseConnection, 'quoteSchemaObject'), $primaryKeys);
  32393. }
  32394. if (count($primaryKeys)) {
  32395. $orderBy = 'ORDER BY ' . implode(' ASC, ', $primaryKeys) . ' ASC';
  32396. } else {
  32397. $orderBy = '';
  32398. }
  32399. return "SELECT {$columnList} FROM {$tableName} {$orderBy}";
  32400. }
  32401. /**
  32402. * Creates an iterator over the tables in the data set. If $reverse is
  32403. * true a reverse iterator will be returned.
  32404. *
  32405. * @param bool $reverse
  32406. * @return PHPUnit_Extensions_Database_DB_TableIterator
  32407. */
  32408. protected function createIterator($reverse = FALSE)
  32409. {
  32410. return new PHPUnit_Extensions_Database_DB_TableIterator($this->getTableNames(), $this, $reverse);
  32411. }
  32412. /**
  32413. * Returns a table object for the given table.
  32414. *
  32415. * @param string $tableName
  32416. * @return PHPUnit_Extensions_Database_DB_Table
  32417. */
  32418. public function getTable($tableName)
  32419. {
  32420. if (!in_array($tableName, $this->getTableNames())) {
  32421. throw new InvalidArgumentException("$tableName is not a table in the current database.");
  32422. }
  32423. if (empty($this->tables[$tableName])) {
  32424. $this->tables[$tableName] = new PHPUnit_Extensions_Database_DB_Table($this->getTableMetaData($tableName), $this->databaseConnection);
  32425. }
  32426. return $this->tables[$tableName];
  32427. }
  32428. /**
  32429. * Returns a table meta data object for the given table.
  32430. *
  32431. * @param string $tableName
  32432. * @return PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData
  32433. */
  32434. public function getTableMetaData($tableName)
  32435. {
  32436. return new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $this->databaseConnection->getMetaData()->getTableColumns($tableName), $this->databaseConnection->getMetaData()->getTablePrimaryKeys($tableName));
  32437. }
  32438. /**
  32439. * Returns a list of table names for the database
  32440. *
  32441. * @return Array
  32442. */
  32443. public function getTableNames()
  32444. {
  32445. return $this->databaseConnection->getMetaData()->getTableNames();
  32446. }
  32447. }
  32448. <?php
  32449. /*
  32450. * This file is part of DBUnit.
  32451. *
  32452. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32453. *
  32454. * For the full copyright and license information, please view the LICENSE
  32455. * file that was distributed with this source code.
  32456. */
  32457. /**
  32458. * Provides the functionality to represent a database result set as a DBUnit
  32459. * table.
  32460. *
  32461. * @package DbUnit
  32462. * @author Mike Lively <m@digitalsandwich.com>
  32463. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32464. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32465. * @version Release: @package_version@
  32466. * @link http://www.phpunit.de/
  32467. * @deprecated The PHPUnit_Extension_Database_DataSet_QueryTable should be used instead
  32468. * @see PHPUnit_Extension_Database_DataSet_QueryTable
  32469. * @see PHPUnit_Extension_Database_DataSet_QueryDataSet
  32470. * @since Class available since Release 1.0.0
  32471. */
  32472. class PHPUnit_Extensions_Database_DB_ResultSetTable extends PHPUnit_Extensions_Database_DataSet_AbstractTable
  32473. {
  32474. /**
  32475. * Creates a new result set table.
  32476. *
  32477. * @param string $tableName
  32478. * @param PDOStatement $pdoStatement
  32479. */
  32480. public function __construct($tableName, PDOStatement $pdoStatement)
  32481. {
  32482. $this->data = $pdoStatement->fetchAll(PDO::FETCH_ASSOC);
  32483. if (count($this->data)) {
  32484. $columns = array_keys($this->data[0]);
  32485. } else {
  32486. $columns = array();
  32487. }
  32488. $this->setTableMetaData(new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $columns));
  32489. }
  32490. }
  32491. <?php
  32492. /*
  32493. * This file is part of DBUnit.
  32494. *
  32495. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32496. *
  32497. * For the full copyright and license information, please view the LICENSE
  32498. * file that was distributed with this source code.
  32499. */
  32500. /**
  32501. * This is the default implementation of the database tester. It receives its
  32502. * connection object from the constructor.
  32503. *
  32504. * @package DbUnit
  32505. * @author Mike Lively <m@digitalsandwich.com>
  32506. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32507. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32508. * @version Release: @package_version@
  32509. * @link http://www.phpunit.de/
  32510. * @since Class available since Release 1.0.0
  32511. */
  32512. class PHPUnit_Extensions_Database_DefaultTester extends PHPUnit_Extensions_Database_AbstractTester
  32513. {
  32514. /**
  32515. * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection
  32516. */
  32517. protected $connection;
  32518. /**
  32519. * Creates a new default database tester using the given connection.
  32520. *
  32521. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
  32522. */
  32523. public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection)
  32524. {
  32525. parent::__construct();
  32526. $this->connection = $connection;
  32527. }
  32528. /**
  32529. * Returns the test database connection.
  32530. *
  32531. * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
  32532. */
  32533. public function getConnection()
  32534. {
  32535. return $this->connection;
  32536. }
  32537. }
  32538. <?php
  32539. /*
  32540. * This file is part of DBUnit.
  32541. *
  32542. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32543. *
  32544. * For the full copyright and license information, please view the LICENSE
  32545. * file that was distributed with this source code.
  32546. */
  32547. /**
  32548. * Asserts whether or not two dbunit tables are equal.
  32549. *
  32550. * @package DbUnit
  32551. * @author Mike Lively <m@digitalsandwich.com>
  32552. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32553. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32554. * @version Release: @package_version@
  32555. * @link http://www.phpunit.de/
  32556. * @since Class available since Release 1.0.0
  32557. */
  32558. class PHPUnit_Extensions_Database_Constraint_TableIsEqual extends PHPUnit_Framework_Constraint
  32559. {
  32560. /**
  32561. * @var PHPUnit_Extensions_Database_DataSet_ITable
  32562. */
  32563. protected $value;
  32564. /**
  32565. * @var string
  32566. */
  32567. protected $failure_reason;
  32568. /**
  32569. * Creates a new constraint.
  32570. *
  32571. * @param PHPUnit_Extensions_Database_DataSet_ITable $value
  32572. */
  32573. public function __construct(PHPUnit_Extensions_Database_DataSet_ITable $value)
  32574. {
  32575. parent::__construct();
  32576. $this->value = $value;
  32577. }
  32578. /**
  32579. * Evaluates the constraint for parameter $other. Returns TRUE if the
  32580. * constraint is met, FALSE otherwise.
  32581. *
  32582. * This method can be overridden to implement the evaluation algorithm.
  32583. *
  32584. * @param mixed $other Value or object to evaluate.
  32585. * @return bool
  32586. */
  32587. protected function matches($other)
  32588. {
  32589. if (!$other instanceof PHPUnit_Extensions_Database_DataSet_ITable) {
  32590. throw new InvalidArgumentException(
  32591. 'PHPUnit_Extensions_Database_DataSet_ITable expected'
  32592. );
  32593. }
  32594. return $this->value->matches($other);
  32595. }
  32596. /**
  32597. * Returns the description of the failure
  32598. *
  32599. * The beginning of failure messages is "Failed asserting that" in most
  32600. * cases. This method should return the second part of that sentence.
  32601. *
  32602. * @param mixed $other Evaluated value or object.
  32603. * @return string
  32604. */
  32605. protected function failureDescription($other)
  32606. {
  32607. return $other->__toString() . ' ' . $this->toString();
  32608. }
  32609. /**
  32610. * Returns a string representation of the constraint.
  32611. *
  32612. * @return string
  32613. */
  32614. public function toString()
  32615. {
  32616. return sprintf(
  32617. 'is equal to expected %s', $this->value->__toString()
  32618. );
  32619. }
  32620. }
  32621. <?php
  32622. /*
  32623. * This file is part of DBUnit.
  32624. *
  32625. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32626. *
  32627. * For the full copyright and license information, please view the LICENSE
  32628. * file that was distributed with this source code.
  32629. */
  32630. /**
  32631. * Asserts whether or not two dbunit datasets are equal.
  32632. *
  32633. * @package DbUnit
  32634. * @author Mike Lively <m@digitalsandwich.com>
  32635. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32636. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32637. * @version Release: @package_version@
  32638. * @link http://www.phpunit.de/
  32639. * @since Class available since Release 1.0.0
  32640. */
  32641. class PHPUnit_Extensions_Database_Constraint_DataSetIsEqual extends PHPUnit_Framework_Constraint
  32642. {
  32643. /**
  32644. * @var PHPUnit_Extensions_Database_DataSet_IDataSet
  32645. */
  32646. protected $value;
  32647. /**
  32648. * @var string
  32649. */
  32650. protected $failure_reason;
  32651. /**
  32652. * Creates a new constraint.
  32653. *
  32654. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $value
  32655. */
  32656. public function __construct(PHPUnit_Extensions_Database_DataSet_IDataSet $value)
  32657. {
  32658. parent::__construct();
  32659. $this->value = $value;
  32660. }
  32661. /**
  32662. * Evaluates the constraint for parameter $other. Returns TRUE if the
  32663. * constraint is met, FALSE otherwise.
  32664. *
  32665. * This method can be overridden to implement the evaluation algorithm.
  32666. *
  32667. * @param mixed $other Value or object to evaluate.
  32668. * @return bool
  32669. */
  32670. protected function matches($other)
  32671. {
  32672. if (!$other instanceof PHPUnit_Extensions_Database_DataSet_IDataSet) {
  32673. throw new InvalidArgumentException(
  32674. 'PHPUnit_Extensions_Database_DataSet_IDataSet expected'
  32675. );
  32676. }
  32677. return $this->value->matches($other);
  32678. }
  32679. /**
  32680. * Returns the description of the failure
  32681. *
  32682. * The beginning of failure messages is "Failed asserting that" in most
  32683. * cases. This method should return the second part of that sentence.
  32684. *
  32685. * @param mixed $other Evaluated value or object.
  32686. * @return string
  32687. */
  32688. protected function failureDescription($other)
  32689. {
  32690. return $other->__toString() . ' ' . $this->toString();
  32691. }
  32692. /**
  32693. * Returns a string representation of the constraint.
  32694. *
  32695. * @return string
  32696. */
  32697. public function toString()
  32698. {
  32699. return sprintf(
  32700. 'is equal to expected %s', $this->value->__toString()
  32701. );
  32702. }
  32703. }
  32704. <?php
  32705. /*
  32706. * This file is part of DBUnit.
  32707. *
  32708. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32709. *
  32710. * For the full copyright and license information, please view the LICENSE
  32711. * file that was distributed with this source code.
  32712. */
  32713. /**
  32714. * Asserts the row count in a table
  32715. *
  32716. * @package DbUnit
  32717. * @author Mike Lively <m@digitalsandwich.com>
  32718. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32719. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32720. * @version Release: @package_version@
  32721. * @link http://www.phpunit.de/
  32722. * @since Class available since Release 1.0.0
  32723. */
  32724. class PHPUnit_Extensions_Database_Constraint_TableRowCount extends PHPUnit_Framework_Constraint
  32725. {
  32726. /**
  32727. * @var int
  32728. */
  32729. protected $value;
  32730. /**
  32731. * @var string
  32732. */
  32733. protected $tableName;
  32734. /**
  32735. * Creates a new constraint.
  32736. *
  32737. * @param $tableName
  32738. * @param $value
  32739. */
  32740. public function __construct($tableName, $value)
  32741. {
  32742. parent::__construct();
  32743. $this->tableName = $tableName;
  32744. $this->value = $value;
  32745. }
  32746. /**
  32747. * Evaluates the constraint for parameter $other. Returns TRUE if the
  32748. * constraint is met, FALSE otherwise.
  32749. *
  32750. * This method can be overridden to implement the evaluation algorithm.
  32751. *
  32752. * @param mixed $other Value or object to evaluate.
  32753. * @return bool
  32754. */
  32755. protected function matches($other)
  32756. {
  32757. return $other == $this->value;
  32758. }
  32759. /**
  32760. * Returns a string representation of the constraint.
  32761. *
  32762. * @return string
  32763. */
  32764. public function toString()
  32765. {
  32766. return sprintf('is equal to expected row count %d', $this->value);
  32767. }
  32768. }
  32769. <?php
  32770. /*
  32771. * This file is part of DBUnit.
  32772. *
  32773. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32774. *
  32775. * For the full copyright and license information, please view the LICENSE
  32776. * file that was distributed with this source code.
  32777. */
  32778. /**
  32779. * This is the interface for DatabaseTester objects. These objects are used to
  32780. * add database testing to existing test cases using composition instead of
  32781. * extension.
  32782. *
  32783. * @package DbUnit
  32784. * @author Mike Lively <m@digitalsandwich.com>
  32785. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32786. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32787. * @version Release: @package_version@
  32788. * @link http://www.phpunit.de/
  32789. * @since Class available since Release 1.0.0
  32790. */
  32791. interface PHPUnit_Extensions_Database_ITester
  32792. {
  32793. /**
  32794. * Closes the specified connection.
  32795. *
  32796. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection
  32797. */
  32798. public function closeConnection(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection);
  32799. /**
  32800. * Returns the test database connection.
  32801. *
  32802. * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
  32803. */
  32804. public function getConnection();
  32805. /**
  32806. * Returns the test dataset.
  32807. *
  32808. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  32809. */
  32810. public function getDataSet();
  32811. /**
  32812. * TestCases must call this method inside setUp().
  32813. */
  32814. public function onSetUp();
  32815. /**
  32816. * TestCases must call this method inside tearDown().
  32817. */
  32818. public function onTearDown();
  32819. /**
  32820. * Sets the test dataset to use.
  32821. *
  32822. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet
  32823. */
  32824. public function setDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet);
  32825. /**
  32826. * Sets the schema value.
  32827. *
  32828. * @param string $schema
  32829. */
  32830. public function setSchema($schema);
  32831. /**
  32832. * Sets the DatabaseOperation to call when starting the test.
  32833. *
  32834. * @param PHPUnit_Extensions_Database_Operation_DatabaseOperation $setUpOperation
  32835. */
  32836. public function setSetUpOperation(PHPUnit_Extensions_Database_Operation_IDatabaseOperation $setUpOperation);
  32837. /**
  32838. * Sets the DatabaseOperation to call when stopping the test.
  32839. *
  32840. * @param PHPUnit_Extensions_Database_Operation_DatabaseOperation $tearDownOperation
  32841. */
  32842. public function setTearDownOperation(PHPUnit_Extensions_Database_Operation_IDatabaseOperation $tearDownOperation);
  32843. }
  32844. <?php
  32845. /*
  32846. * This file is part of DBUnit.
  32847. *
  32848. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32849. *
  32850. * For the full copyright and license information, please view the LICENSE
  32851. * file that was distributed with this source code.
  32852. */
  32853. /**
  32854. * Data set implementation for the output of mysqldump --xml.
  32855. *
  32856. * @package DbUnit
  32857. * @author Matthew Turland <tobias382@gmail.com>
  32858. * @copyright 2010-2014 Matthew Turland <tobias382@gmail.com>
  32859. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32860. * @version Release: @package_version@
  32861. * @link http://www.phpunit.de/
  32862. * @since Class available since Release 1.0.0
  32863. */
  32864. class PHPUnit_Extensions_Database_DataSet_MysqlXmlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractXmlDataSet
  32865. {
  32866. protected function getTableInfo(array &$tableColumns, array &$tableValues)
  32867. {
  32868. if ($this->xmlFileContents->getName() != 'mysqldump') {
  32869. throw new PHPUnit_Extensions_Database_Exception('The root element of a MySQL XML data set file must be called <mysqldump>');
  32870. }
  32871. foreach ($this->xmlFileContents->xpath('./database/table_data') as $tableElement) {
  32872. if (empty($tableElement['name'])) {
  32873. throw new PHPUnit_Extensions_Database_Exception('<table_data> elements must include a name attribute');
  32874. }
  32875. $tableName = (string)$tableElement['name'];
  32876. if (!isset($tableColumns[$tableName])) {
  32877. $tableColumns[$tableName] = array();
  32878. }
  32879. if (!isset($tableValues[$tableName])) {
  32880. $tableValues[$tableName] = array();
  32881. }
  32882. foreach ($tableElement->xpath('./row') as $rowElement) {
  32883. $rowValues = array();
  32884. foreach ($rowElement->xpath('./field') as $columnElement) {
  32885. if (empty($columnElement['name'])) {
  32886. throw new PHPUnit_Extensions_Database_Exception('<field> element name attributes cannot be empty');
  32887. }
  32888. $columnName = (string)$columnElement['name'];
  32889. if (!in_array($columnName, $tableColumns[$tableName])) {
  32890. $tableColumns[$tableName][] = $columnName;
  32891. }
  32892. }
  32893. foreach ($tableColumns[$tableName] as $columnName) {
  32894. $fields = $rowElement->xpath('./field[@name="' . $columnName . '"]');
  32895. $column = $fields[0];
  32896. $attr = $column->attributes('http://www.w3.org/2001/XMLSchema-instance');
  32897. if (isset($attr['type']) && (string) $attr['type'] === 'xs:hexBinary') {
  32898. $columnValue = pack('H*',(string)$column);
  32899. } else {
  32900. $null = isset($column['nil']) || isset($attr[0]);
  32901. $columnValue = $null ? NULL : (string)$column;
  32902. }
  32903. $rowValues[$columnName] = $columnValue;
  32904. }
  32905. $tableValues[$tableName][] = $rowValues;
  32906. }
  32907. }
  32908. foreach ($this->xmlFileContents->xpath('./database/table_structure') as $tableElement) {
  32909. if (empty($tableElement['name'])) {
  32910. throw new PHPUnit_Extensions_Database_Exception('<table_structure> elements must include a name attribute');
  32911. }
  32912. $tableName = (string) $tableElement['name'];
  32913. foreach ($tableElement->xpath('./field') as $fieldElement) {
  32914. if (empty($fieldElement['Field'])) {
  32915. throw new PHPUnit_Extensions_Database_Exception('<field> elements must include a Field attribute');
  32916. }
  32917. $columnName = (string) $fieldElement['Field'];
  32918. if (!in_array($columnName, $tableColumns[$tableName])) {
  32919. $tableColumns[$tableName][] = $columnName;
  32920. }
  32921. }
  32922. }
  32923. }
  32924. public static function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset, $filename)
  32925. {
  32926. $pers = new PHPUnit_Extensions_Database_DataSet_Persistors_MysqlXml;
  32927. $pers->setFileName($filename);
  32928. try {
  32929. $pers->write($dataset);
  32930. }
  32931. catch (RuntimeException $e) {
  32932. throw new PHPUnit_Framework_Exception(__METHOD__ . ' called with an unwritable file.');
  32933. }
  32934. }
  32935. }
  32936. <?php
  32937. /*
  32938. * This file is part of DBUnit.
  32939. *
  32940. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  32941. *
  32942. * For the full copyright and license information, please view the LICENSE
  32943. * file that was distributed with this source code.
  32944. */
  32945. /**
  32946. * Provides access to a database instance as a data set.
  32947. *
  32948. * @package DbUnit
  32949. * @author Mike Lively <m@digitalsandwich.com>
  32950. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  32951. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  32952. * @version Release: @package_version@
  32953. * @link http://www.phpunit.de/
  32954. * @since Class available since Release 1.0.0
  32955. */
  32956. class PHPUnit_Extensions_Database_DataSet_QueryDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  32957. {
  32958. /**
  32959. * An array of ITable objects.
  32960. *
  32961. * @var array
  32962. */
  32963. protected $tables = array();
  32964. /**
  32965. * The database connection this dataset is using.
  32966. *
  32967. * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection
  32968. */
  32969. protected $databaseConnection;
  32970. /**
  32971. * Creates a new dataset using the given database connection.
  32972. *
  32973. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection
  32974. */
  32975. public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection)
  32976. {
  32977. $this->databaseConnection = $databaseConnection;
  32978. }
  32979. public function addTable($tableName, $query = NULL)
  32980. {
  32981. if ($query === NULL) {
  32982. $query = 'SELECT * FROM ' . $tableName;
  32983. }
  32984. $this->tables[$tableName] = new PHPUnit_Extensions_Database_DataSet_QueryTable($tableName, $query, $this->databaseConnection);
  32985. }
  32986. /**
  32987. * Creates an iterator over the tables in the data set. If $reverse is
  32988. * true a reverse iterator will be returned.
  32989. *
  32990. * @param bool $reverse
  32991. * @return PHPUnit_Extensions_Database_DB_TableIterator
  32992. */
  32993. protected function createIterator($reverse = FALSE)
  32994. {
  32995. return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse);
  32996. }
  32997. /**
  32998. * Returns a table object for the given table.
  32999. *
  33000. * @param string $tableName
  33001. * @return PHPUnit_Extensions_Database_DB_Table
  33002. */
  33003. public function getTable($tableName)
  33004. {
  33005. if (!isset($this->tables[$tableName])) {
  33006. throw new InvalidArgumentException("$tableName is not a table in the current database.");
  33007. }
  33008. return $this->tables[$tableName];
  33009. }
  33010. /**
  33011. * Returns a list of table names for the database
  33012. *
  33013. * @return Array
  33014. */
  33015. public function getTableNames()
  33016. {
  33017. return array_keys($this->tables);
  33018. }
  33019. }
  33020. <?php
  33021. /*
  33022. * This file is part of DBUnit.
  33023. *
  33024. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33025. *
  33026. * For the full copyright and license information, please view the LICENSE
  33027. * file that was distributed with this source code.
  33028. */
  33029. /**
  33030. * Creates YamlDataSets.
  33031. *
  33032. * You can incrementally add YAML files as tables to your datasets
  33033. *
  33034. * @package DbUnit
  33035. * @author Mike Lively <m@digitalsandwich.com>
  33036. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33037. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33038. * @version Release: @package_version@
  33039. * @link http://www.phpunit.de/
  33040. * @since Class available since Release 1.0.0
  33041. */
  33042. class PHPUnit_Extensions_Database_DataSet_YamlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  33043. {
  33044. /**
  33045. * @var array
  33046. */
  33047. protected $tables = array();
  33048. /**
  33049. * @var PHPUnit_Extensions_Database_DataSet_IYamlParser
  33050. */
  33051. protected $parser;
  33052. /**
  33053. * Creates a new YAML dataset
  33054. *
  33055. * @param string $yamlFile
  33056. * @param PHPUnit_Extensions_Database_DataSet_IYamlParser $parser
  33057. */
  33058. public function __construct($yamlFile, $parser = NULL)
  33059. {
  33060. if ($parser == NULL) {
  33061. $parser = new PHPUnit_Extensions_Database_DataSet_SymfonyYamlParser();
  33062. }
  33063. $this->parser = $parser;
  33064. $this->addYamlFile($yamlFile);
  33065. }
  33066. /**
  33067. * Adds a new yaml file to the dataset.
  33068. * @param string $yamlFile
  33069. */
  33070. public function addYamlFile($yamlFile)
  33071. {
  33072. $data = $this->parser->parseYaml($yamlFile);
  33073. foreach ($data as $tableName => $rows) {
  33074. if (!isset($rows)) {
  33075. $rows = array();
  33076. }
  33077. if (!is_array($rows)) {
  33078. continue;
  33079. }
  33080. if (!array_key_exists($tableName, $this->tables)) {
  33081. $columns = $this->getColumns($rows);
  33082. $tableMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData(
  33083. $tableName, $columns
  33084. );
  33085. $this->tables[$tableName] = new PHPUnit_Extensions_Database_DataSet_DefaultTable(
  33086. $tableMetaData
  33087. );
  33088. }
  33089. foreach ($rows as $row) {
  33090. $this->tables[$tableName]->addRow($row);
  33091. }
  33092. }
  33093. }
  33094. /**
  33095. * Creates a unique list of columns from all the rows in a table.
  33096. * If the table is defined another time in the Yaml, and if the Yaml
  33097. * parser could return the multiple occerrences, then this would be
  33098. * insufficient unless we grouped all the occurences of the table
  33099. * into onwe row set. sfYaml, however, does not provide multiple tables
  33100. * with the same name, it only supplies the last table.
  33101. *
  33102. * @params all the rows in a table.
  33103. */
  33104. private function getColumns($rows) {
  33105. $columns = array();
  33106. foreach ($rows as $row) {
  33107. $columns = array_merge($columns, array_keys($row));
  33108. }
  33109. return array_values(array_unique($columns));
  33110. }
  33111. /**
  33112. * Creates an iterator over the tables in the data set. If $reverse is
  33113. * true a reverse iterator will be returned.
  33114. *
  33115. * @param bool $reverse
  33116. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  33117. */
  33118. protected function createIterator($reverse = FALSE)
  33119. {
  33120. return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator(
  33121. $this->tables, $reverse
  33122. );
  33123. }
  33124. /**
  33125. * Saves a given $dataset to $filename in YAML format
  33126. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  33127. * @param string $filename
  33128. */
  33129. public static function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset, $filename)
  33130. {
  33131. $pers = new PHPUnit_Extensions_Database_DataSet_Persistors_Yaml();
  33132. $pers->setFileName($filename);
  33133. try {
  33134. $pers->write($dataset);
  33135. }
  33136. catch (RuntimeException $e) {
  33137. throw new PHPUnit_Framework_Exception(
  33138. __METHOD__ . ' called with an unwritable file.'
  33139. );
  33140. }
  33141. }
  33142. }
  33143. <?php
  33144. /*
  33145. * This file is part of DBUnit.
  33146. *
  33147. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33148. *
  33149. * For the full copyright and license information, please view the LICENSE
  33150. * file that was distributed with this source code.
  33151. */
  33152. /**
  33153. * Implements the basic functionality of data sets.
  33154. *
  33155. * @package DbUnit
  33156. * @author Mike Lively <m@digitalsandwich.com>
  33157. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33158. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33159. * @version Release: @package_version@
  33160. * @link http://www.phpunit.de/
  33161. * @since Class available since Release 1.0.0
  33162. */
  33163. abstract class PHPUnit_Extensions_Database_DataSet_AbstractDataSet implements PHPUnit_Extensions_Database_DataSet_IDataSet
  33164. {
  33165. /**
  33166. * Creates an iterator over the tables in the data set. If $reverse is
  33167. * true a reverse iterator will be returned.
  33168. *
  33169. * @param bool $reverse
  33170. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  33171. */
  33172. protected abstract function createIterator($reverse = FALSE);
  33173. /**
  33174. * Returns an array of table names contained in the dataset.
  33175. *
  33176. * @return array
  33177. */
  33178. public function getTableNames()
  33179. {
  33180. $tableNames = array();
  33181. foreach ($this->getIterator() as $table) {
  33182. /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */
  33183. $tableNames[] = $table->getTableMetaData()->getTableName();
  33184. }
  33185. return $tableNames;
  33186. }
  33187. /**
  33188. * Returns a table meta data object for the given table.
  33189. *
  33190. * @param string $tableName
  33191. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  33192. */
  33193. public function getTableMetaData($tableName)
  33194. {
  33195. return $this->getTable($tableName)->getTableMetaData();
  33196. }
  33197. /**
  33198. * Returns a table object for the given table.
  33199. *
  33200. * @param string $tableName
  33201. * @return PHPUnit_Extensions_Database_DataSet_ITable
  33202. */
  33203. public function getTable($tableName)
  33204. {
  33205. foreach ($this->getIterator() as $table) {
  33206. /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */
  33207. if ($table->getTableMetaData()->getTableName() == $tableName) {
  33208. return $table;
  33209. }
  33210. }
  33211. }
  33212. /**
  33213. * Returns an iterator for all table objects in the given dataset.
  33214. *
  33215. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  33216. */
  33217. public function getIterator()
  33218. {
  33219. return $this->createIterator();
  33220. }
  33221. /**
  33222. * Returns a reverse iterator for all table objects in the given dataset.
  33223. *
  33224. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  33225. */
  33226. public function getReverseIterator()
  33227. {
  33228. return $this->createIterator(TRUE);
  33229. }
  33230. /**
  33231. * Asserts that the given data set matches this data set.
  33232. *
  33233. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $other
  33234. */
  33235. public function matches(PHPUnit_Extensions_Database_DataSet_IDataSet $other)
  33236. {
  33237. $thisTableNames = $this->getTableNames();
  33238. $otherTableNames = $other->getTableNames();
  33239. sort($thisTableNames);
  33240. sort($otherTableNames);
  33241. if ($thisTableNames != $otherTableNames) {
  33242. return FALSE;
  33243. }
  33244. foreach ($thisTableNames as $tableName) {
  33245. $table = $this->getTable($tableName);
  33246. if (!$table->matches($other->getTable($tableName))) {
  33247. return FALSE;
  33248. }
  33249. }
  33250. return TRUE;
  33251. }
  33252. public function __toString()
  33253. {
  33254. $iterator = $this->getIterator();
  33255. $dataSetString = '';
  33256. foreach ($iterator as $table) {
  33257. $dataSetString .= $table->__toString();
  33258. }
  33259. return $dataSetString;
  33260. }
  33261. }
  33262. <?php
  33263. /*
  33264. * This file is part of DBUnit.
  33265. *
  33266. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33267. *
  33268. * For the full copyright and license information, please view the LICENSE
  33269. * file that was distributed with this source code.
  33270. */
  33271. /**
  33272. * Provides an interface for creating data sets from data set spec strings.
  33273. *
  33274. * @package DbUnit
  33275. * @author Mike Lively <m@digitalsandwich.com>
  33276. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33277. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33278. * @version Release: @package_version@
  33279. * @link http://www.phpunit.de//**
  33280. * @since Class available since Release 1.0.0
  33281. */
  33282. interface PHPUnit_Extensions_Database_DataSet_ISpec
  33283. {
  33284. /**
  33285. * Creates a data set from a data set spec string.
  33286. *
  33287. * @param string $dataSetSpec
  33288. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  33289. */
  33290. public function getDataSet($dataSetSpec);
  33291. }
  33292. <?php
  33293. /*
  33294. * This file is part of DBUnit.
  33295. *
  33296. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33297. *
  33298. * For the full copyright and license information, please view the LICENSE
  33299. * file that was distributed with this source code.
  33300. */
  33301. /**
  33302. * A table decorator that allows filtering out table columns from results.
  33303. *
  33304. * @package DbUnit
  33305. * @author Mike Lively <m@digitalsandwich.com>
  33306. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33307. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33308. * @version Release: @package_version@
  33309. * @link http://www.phpunit.de/
  33310. * @since Class available since Release 1.0.0
  33311. */
  33312. class PHPUnit_Extensions_Database_DataSet_TableFilter extends PHPUnit_Extensions_Database_DataSet_AbstractTable
  33313. {
  33314. /**
  33315. * The table meta data being decorated.
  33316. * @var PHPUnit_Extensions_Database_DataSet_ITable
  33317. */
  33318. protected $originalTable;
  33319. /**
  33320. * Creates a new table filter using the original table
  33321. *
  33322. * @param $originalTable PHPUnit_Extensions_Database_DataSet_ITable
  33323. * @param $excludeColumns Array @deprecated, use the set* methods instead.
  33324. */
  33325. public function __construct(PHPUnit_Extensions_Database_DataSet_ITable $originalTable, Array $excludeColumns = array())
  33326. {
  33327. $this->originalTable = $originalTable;
  33328. $this->setTableMetaData(new PHPUnit_Extensions_Database_DataSet_TableMetaDataFilter($originalTable->getTableMetaData()));
  33329. $this->addExcludeColumns($excludeColumns);
  33330. }
  33331. /**
  33332. * Returns the number of rows in this table.
  33333. *
  33334. * @return int
  33335. */
  33336. public function getRowCount()
  33337. {
  33338. return $this->originalTable->getRowCount();
  33339. }
  33340. /**
  33341. * Returns the value for the given column on the given row.
  33342. *
  33343. * @param int $row
  33344. * @param int $column
  33345. */
  33346. public function getValue($row, $column)
  33347. {
  33348. if (in_array($column, $this->getTableMetaData()->getColumns())) {
  33349. return $this->originalTable->getValue($row, $column);
  33350. } else {
  33351. throw new InvalidArgumentException("The given row ({$row}) and column ({$column}) do not exist in table {$this->getTableMetaData()->getTableName()}");
  33352. }
  33353. }
  33354. /**
  33355. * Sets the columns to include in the table.
  33356. * @param Array $includeColumns
  33357. */
  33358. public function addIncludeColumns(Array $includeColumns)
  33359. {
  33360. $this->tableMetaData->addIncludeColumns($includeColumns);
  33361. }
  33362. /**
  33363. * Clears the included columns.
  33364. */
  33365. public function clearIncludeColumns()
  33366. {
  33367. $this->tableMetaData->clearIncludeColumns();
  33368. }
  33369. /**
  33370. * Sets the columns to exclude from the table.
  33371. * @param Array $excludeColumns
  33372. */
  33373. public function addExcludeColumns(Array $excludeColumns)
  33374. {
  33375. $this->tableMetaData->addExcludeColumns($excludeColumns);
  33376. }
  33377. /**
  33378. * Clears the included columns.
  33379. */
  33380. public function clearExcludeColumns()
  33381. {
  33382. $this->tableMetaData->clearExcludeColumns();
  33383. }
  33384. /**
  33385. * Checks if a given row is in the table
  33386. *
  33387. * @param array $row
  33388. *
  33389. * @return bool
  33390. */
  33391. public function assertContainsRow(Array $row)
  33392. {
  33393. $this->loadData();
  33394. return parent::assertContainsRow($row);
  33395. }
  33396. /**
  33397. * Loads data into local data table if it's not already loaded
  33398. */
  33399. protected function loadData()
  33400. {
  33401. if ($this->data === NULL) {
  33402. $data = array();
  33403. for($row = 0;$row < $this->originalTable->getRowCount();$row++) {
  33404. $tRow = array();
  33405. foreach($this->getTableMetaData()->getColumns() as $col) {
  33406. $tRow[$col] = $this->getValue($row, $col);
  33407. }
  33408. $data[$row] = $tRow;
  33409. }
  33410. $this->data = $data;
  33411. }
  33412. }
  33413. }
  33414. <?php
  33415. /*
  33416. * This file is part of DBUnit.
  33417. *
  33418. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33419. *
  33420. * For the full copyright and license information, please view the LICENSE
  33421. * file that was distributed with this source code.
  33422. */
  33423. /**
  33424. * Provides basic functionality for table meta data.
  33425. *
  33426. * @package DbUnit
  33427. * @author Mike Lively <m@digitalsandwich.com>
  33428. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33429. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33430. * @version Release: @package_version@
  33431. * @link http://www.phpunit.de/
  33432. * @since Class available since Release 1.0.0
  33433. */
  33434. abstract class PHPUnit_Extensions_Database_DataSet_AbstractTableMetaData implements PHPUnit_Extensions_Database_DataSet_ITableMetaData
  33435. {
  33436. /**
  33437. * The names of all columns in the table.
  33438. *
  33439. * @var Array
  33440. */
  33441. protected $columns;
  33442. /**
  33443. * The names of all the primary keys in the table.
  33444. *
  33445. * @var Array
  33446. */
  33447. protected $primaryKeys;
  33448. /**
  33449. * @var string
  33450. */
  33451. protected $tableName;
  33452. /**
  33453. * Returns the names of the columns in the table.
  33454. *
  33455. * @return array
  33456. */
  33457. public function getColumns()
  33458. {
  33459. return $this->columns;
  33460. }
  33461. /**
  33462. * Returns the names of the primary key columns in the table.
  33463. *
  33464. * @return array
  33465. */
  33466. public function getPrimaryKeys()
  33467. {
  33468. return $this->primaryKeys;
  33469. }
  33470. /**
  33471. * Returns the name of the table.
  33472. *
  33473. * @return string
  33474. */
  33475. public function getTableName()
  33476. {
  33477. return $this->tableName;
  33478. }
  33479. /**
  33480. * Asserts that the given tableMetaData matches this tableMetaData.
  33481. *
  33482. * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $other
  33483. */
  33484. public function matches(PHPUnit_Extensions_Database_DataSet_ITableMetaData $other)
  33485. {
  33486. if ($this->getTableName() != $other->getTableName() ||
  33487. $this->getColumns() != $other->getColumns()) {
  33488. return FALSE;
  33489. }
  33490. return TRUE;
  33491. }
  33492. }
  33493. <?php
  33494. /*
  33495. * This file is part of DBUnit.
  33496. *
  33497. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33498. *
  33499. * For the full copyright and license information, please view the LICENSE
  33500. * file that was distributed with this source code.
  33501. */
  33502. /**
  33503. * Creates Composite Datasets
  33504. *
  33505. * Allows for creating datasets from multiple sources (csv, query, xml, etc.)
  33506. *
  33507. * @package DbUnit
  33508. * @author Mike Lively <m@digitalsandwich.com>
  33509. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33510. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33511. * @version Release: @package_version@
  33512. * @link http://www.phpunit.de/
  33513. * @since Class available since Release 1.0.0
  33514. */
  33515. class PHPUnit_Extensions_Database_DataSet_CompositeDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  33516. {
  33517. protected $motherDataSet;
  33518. /**
  33519. * Creates a new Composite dataset
  33520. *
  33521. * You can pass in any data set that implements PHPUnit_Extensions_Database_DataSet_IDataSet
  33522. *
  33523. * @param string $delimiter
  33524. * @param string $enclosure
  33525. * @param string $escape
  33526. */
  33527. public function __construct(Array $dataSets = array())
  33528. {
  33529. $this->motherDataset = new PHPUnit_Extensions_Database_DataSet_DefaultDataSet();
  33530. foreach ($dataSets as $dataSet)
  33531. {
  33532. $this->addDataSet($dataSet);
  33533. }
  33534. }
  33535. /**
  33536. * Adds a new data set to the composite.
  33537. *
  33538. * The dataset may not define tables that already exist in the composite.
  33539. *
  33540. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet
  33541. */
  33542. public function addDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet)
  33543. {
  33544. foreach ($dataSet->getTableNames() as $tableName)
  33545. {
  33546. if (!in_array($tableName, $this->getTableNames())) {
  33547. $this->motherDataset->addTable($dataSet->getTable($tableName));
  33548. } else {
  33549. $other = $dataSet->getTable($tableName);
  33550. $table = $this->getTable($tableName);
  33551. if (!$table->getTableMetaData()->matches($other->getTableMetaData()))
  33552. {
  33553. throw new InvalidArgumentException("There is already a table named $tableName with different table definition");
  33554. }
  33555. $table->addTableRows($dataSet->getTable($tableName));
  33556. }
  33557. }
  33558. }
  33559. /**
  33560. * Creates an iterator over the tables in the data set. If $reverse is
  33561. * true a reverse iterator will be returned.
  33562. *
  33563. * @param bool $reverse
  33564. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  33565. */
  33566. protected function createIterator($reverse = FALSE)
  33567. {
  33568. if ($reverse) {
  33569. return $this->motherDataset->getReverseIterator();
  33570. } else {
  33571. return $this->motherDataset->getIterator();
  33572. }
  33573. }
  33574. }
  33575. <?php
  33576. /*
  33577. * This file is part of DBUnit.
  33578. *
  33579. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33580. *
  33581. * For the full copyright and license information, please view the LICENSE
  33582. * file that was distributed with this source code.
  33583. */
  33584. /**
  33585. * The default table iterator
  33586. *
  33587. * @package DbUnit
  33588. * @author Mike Lively <m@digitalsandwich.com>
  33589. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33590. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33591. * @version Release: @package_version@
  33592. * @link http://www.phpunit.de/
  33593. * @since Class available since Release 1.0.0
  33594. */
  33595. class PHPUnit_Extensions_Database_DataSet_DefaultTableIterator implements PHPUnit_Extensions_Database_DataSet_ITableIterator
  33596. {
  33597. /**
  33598. * An array of tables in the iterator.
  33599. *
  33600. * @var Array
  33601. */
  33602. protected $tables;
  33603. /**
  33604. * If this property is true then the tables will be iterated in reverse
  33605. * order.
  33606. *
  33607. * @var bool
  33608. */
  33609. protected $reverse;
  33610. /**
  33611. * Creates a new default table iterator object.
  33612. *
  33613. * @param array $tables
  33614. * @param bool $reverse
  33615. */
  33616. public function __construct(Array $tables, $reverse = FALSE)
  33617. {
  33618. $this->tables = $tables;
  33619. $this->reverse = $reverse;
  33620. $this->rewind();
  33621. }
  33622. /**
  33623. * Returns the current table.
  33624. *
  33625. * @return PHPUnit_Extensions_Database_DataSet_ITable
  33626. */
  33627. public function getTable()
  33628. {
  33629. return $this->current();
  33630. }
  33631. /**
  33632. * Returns the current table's meta data.
  33633. *
  33634. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  33635. */
  33636. public function getTableMetaData()
  33637. {
  33638. return $this->current()->getTableMetaData();
  33639. }
  33640. /**
  33641. * Returns the current table.
  33642. *
  33643. * @return PHPUnit_Extensions_Database_DataSet_ITable
  33644. */
  33645. public function current()
  33646. {
  33647. return current($this->tables);
  33648. }
  33649. /**
  33650. * Returns the name of the current table.
  33651. *
  33652. * @return string
  33653. */
  33654. public function key()
  33655. {
  33656. return $this->current()->getTableMetaData()->getTableName();
  33657. }
  33658. /**
  33659. * advances to the next element.
  33660. *
  33661. */
  33662. public function next()
  33663. {
  33664. if ($this->reverse) {
  33665. prev($this->tables);
  33666. } else {
  33667. next($this->tables);
  33668. }
  33669. }
  33670. /**
  33671. * Rewinds to the first element
  33672. */
  33673. public function rewind()
  33674. {
  33675. if ($this->reverse) {
  33676. end($this->tables);
  33677. } else {
  33678. reset($this->tables);
  33679. }
  33680. }
  33681. /**
  33682. * Returns true if the current index is valid
  33683. *
  33684. * @return bool
  33685. */
  33686. public function valid()
  33687. {
  33688. return ($this->current() !== FALSE);
  33689. }
  33690. }
  33691. <?php
  33692. /*
  33693. * This file is part of DBUnit.
  33694. *
  33695. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33696. *
  33697. * For the full copyright and license information, please view the LICENSE
  33698. * file that was distributed with this source code.
  33699. */
  33700. /**
  33701. * A dataset decorator that allows filtering out tables and table columns from
  33702. * results.
  33703. *
  33704. * @package DbUnit
  33705. * @author Mike Lively <m@digitalsandwich.com>
  33706. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33707. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33708. * @version Release: @package_version@
  33709. * @link http://www.phpunit.de/
  33710. * @since Class available since Release 1.0.0
  33711. */
  33712. class PHPUnit_Extensions_Database_DataSet_DataSetFilter extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  33713. {
  33714. /**
  33715. * The dataset being decorated.
  33716. * @var PHPUnit_Extensions_Database_DataSet_IDataSet
  33717. */
  33718. protected $originalDataSet;
  33719. /**
  33720. * The tables to exclude from the data set.
  33721. * @var Array
  33722. */
  33723. protected $excludeTables = array();
  33724. /**
  33725. * The tables to exclude from the data set.
  33726. * @var Array
  33727. */
  33728. protected $includeTables = array();
  33729. /**
  33730. * The columns to exclude from the data set.
  33731. * @var Array
  33732. */
  33733. protected $excludeColumns = array();
  33734. /**
  33735. * The columns to exclude from the data set.
  33736. * @var Array
  33737. */
  33738. protected $includeColumns = array();
  33739. /**
  33740. * Creates a new filtered data set.
  33741. *
  33742. * The $exclude tables should be an associative array using table names as
  33743. * the key and an array of column names to exclude for the value. If you
  33744. * would like to exclude a full table set the value of the table's entry
  33745. * to the special string '*'.
  33746. *
  33747. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $originalDataSet
  33748. * @param Array $excludeTables @deprecated use set* methods instead.
  33749. */
  33750. public function __construct(PHPUnit_Extensions_Database_DataSet_IDataSet $originalDataSet, array $excludeTables = array())
  33751. {
  33752. $this->originalDataSet = $originalDataSet;
  33753. $tables = array();
  33754. foreach ($excludeTables as $tableName => $values) {
  33755. if (is_array($values)) {
  33756. $this->setExcludeColumnsForTable($tableName, $values);
  33757. } elseif ($values == '*') {
  33758. $tables[] = $tableName;
  33759. } else {
  33760. $this->setExcludeColumnsForTable($tableName, (array)$values);
  33761. }
  33762. }
  33763. $this->addExcludeTables($tables);
  33764. }
  33765. /**
  33766. * Creates an iterator over the tables in the data set. If $reverse is
  33767. * true a reverse iterator will be returned.
  33768. *
  33769. * @param bool $reverse
  33770. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  33771. */
  33772. protected function createIterator($reverse = FALSE)
  33773. {
  33774. $original_tables = $this->originalDataSet->getIterator($reverse);
  33775. $new_tables = array();
  33776. foreach ($original_tables as $table) {
  33777. /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */
  33778. $tableName = $table->getTableMetaData()->getTableName();
  33779. if ((!in_array($tableName, $this->includeTables) && !empty($this->includeTables)) ||
  33780. in_array($tableName, $this->excludeTables)
  33781. ) {
  33782. continue;
  33783. } elseif (!empty($this->excludeColumns[$tableName]) || !empty($this->includeColumns[$tableName])) {
  33784. $new_table = new PHPUnit_Extensions_Database_DataSet_TableFilter($table);
  33785. if (!empty($this->includeColumns[$tableName])) {
  33786. $new_table->addIncludeColumns($this->includeColumns[$tableName]);
  33787. }
  33788. if (!empty($this->excludeColumns[$tableName])) {
  33789. $new_table->addExcludeColumns($this->excludeColumns[$tableName]);
  33790. }
  33791. $new_tables[] = $new_table;
  33792. } else {
  33793. $new_tables[] = $table;
  33794. }
  33795. }
  33796. return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($new_tables);
  33797. }
  33798. /**
  33799. * Adds tables to be included in the data set.
  33800. * @param array $tables
  33801. */
  33802. public function addIncludeTables(Array $tables)
  33803. {
  33804. $this->includeTables = array_unique(array_merge($this->includeTables, $tables));
  33805. }
  33806. /**
  33807. * Adds tables to be included in the data set.
  33808. * @param array $tables
  33809. */
  33810. public function addExcludeTables(Array $tables)
  33811. {
  33812. $this->excludeTables = array_unique(array_merge($this->excludeTables, $tables));
  33813. }
  33814. /**
  33815. * Adds columns to include in the data set for the given table.
  33816. * @param string $table
  33817. * @param Array $columns
  33818. */
  33819. public function setIncludeColumnsForTable($table, Array $columns)
  33820. {
  33821. $this->includeColumns[$table] = $columns;
  33822. }
  33823. /**
  33824. * Adds columns to include in the data set for the given table.
  33825. * @param string $table
  33826. * @param Array $columns
  33827. */
  33828. public function setExcludeColumnsForTable($table, Array $columns)
  33829. {
  33830. $this->excludeColumns[$table] = $columns;
  33831. }
  33832. }
  33833. <?php
  33834. /*
  33835. * This file is part of DBUnit.
  33836. *
  33837. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33838. *
  33839. * For the full copyright and license information, please view the LICENSE
  33840. * file that was distributed with this source code.
  33841. */
  33842. /**
  33843. * An interface for parsing YAML files.
  33844. *
  33845. * @package DbUnit
  33846. * @author Yash Parghi <yash@yashparghi.com>
  33847. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  33848. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33849. * @link http://www.phpunit.de/
  33850. * @since Class available since Release 1.3.1
  33851. */
  33852. interface PHPUnit_Extensions_Database_DataSet_IYamlParser {
  33853. /**
  33854. * @param string $yamlFile
  33855. * @return array parsed YAML
  33856. */
  33857. public function parseYaml($yamlFile);
  33858. }
  33859. <?php
  33860. /*
  33861. * This file is part of DBUnit.
  33862. *
  33863. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33864. *
  33865. * For the full copyright and license information, please view the LICENSE
  33866. * file that was distributed with this source code.
  33867. */
  33868. /**
  33869. * The default implementation of a data set.
  33870. *
  33871. * @package DbUnit
  33872. * @author Mike Lively <m@digitalsandwich.com>
  33873. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33874. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33875. * @version Release: @package_version@
  33876. * @link http://www.phpunit.de/
  33877. * @since Class available since Release 1.0.0
  33878. */
  33879. class PHPUnit_Extensions_Database_DataSet_XmlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractXmlDataSet
  33880. {
  33881. protected function getTableInfo(Array &$tableColumns, Array &$tableValues)
  33882. {
  33883. if ($this->xmlFileContents->getName() != 'dataset') {
  33884. throw new PHPUnit_Extensions_Database_Exception("The root element of an xml data set file must be called <dataset>");
  33885. }
  33886. foreach ($this->xmlFileContents->xpath('/dataset/table') as $tableElement) {
  33887. if (empty($tableElement['name'])) {
  33888. throw new PHPUnit_Extensions_Database_Exception("Table elements must include a name attribute specifying the table name.");
  33889. }
  33890. $tableName = (string)$tableElement['name'];
  33891. if (!isset($tableColumns[$tableName])) {
  33892. $tableColumns[$tableName] = array();
  33893. }
  33894. if (!isset($tableValues[$tableName])) {
  33895. $tableValues[$tableName] = array();
  33896. }
  33897. $tableInstanceColumns = array();
  33898. foreach ($tableElement->xpath('./column') as $columnElement) {
  33899. $columnName = (string)$columnElement;
  33900. if (empty($columnName)) {
  33901. throw new PHPUnit_Extensions_Database_Exception("Missing <column> elements for table $tableName. Add one or more <column> elements to the <table> element.");
  33902. }
  33903. if (!in_array($columnName, $tableColumns[$tableName])) {
  33904. $tableColumns[$tableName][] = $columnName;
  33905. }
  33906. $tableInstanceColumns[] = $columnName;
  33907. }
  33908. foreach ($tableElement->xpath('./row') as $rowElement) {
  33909. $rowValues = array();
  33910. $index = 0;
  33911. $numOfTableInstanceColumns = count($tableInstanceColumns);
  33912. foreach ($rowElement->children() as $columnValue) {
  33913. if ($index >= $numOfTableInstanceColumns) {
  33914. throw new PHPUnit_Extensions_Database_Exception("Row contains more values than the number of columns defined for table $tableName.");
  33915. }
  33916. switch ($columnValue->getName()) {
  33917. case 'value':
  33918. $rowValues[$tableInstanceColumns[$index]] = (string)$columnValue;
  33919. $index++;
  33920. break;
  33921. case 'null':
  33922. $rowValues[$tableInstanceColumns[$index]] = NULL;
  33923. $index++;
  33924. break;
  33925. default:
  33926. throw new PHPUnit_Extensions_Database_Exception("Unknown element ".$columnValue->getName()." in a row element.");
  33927. }
  33928. }
  33929. $tableValues[$tableName][] = $rowValues;
  33930. }
  33931. }
  33932. }
  33933. public static function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset, $filename)
  33934. {
  33935. $pers = new PHPUnit_Extensions_Database_DataSet_Persistors_Xml();
  33936. $pers->setFileName($filename);
  33937. try {
  33938. $pers->write($dataset);
  33939. }
  33940. catch (RuntimeException $e) {
  33941. throw new PHPUnit_Framework_Exception(__METHOD__ . ' called with an unwritable file.');
  33942. }
  33943. }
  33944. }
  33945. <?php
  33946. /*
  33947. * This file is part of DBUnit.
  33948. *
  33949. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  33950. *
  33951. * For the full copyright and license information, please view the LICENSE
  33952. * file that was distributed with this source code.
  33953. */
  33954. /**
  33955. * The default implementation of a data set.
  33956. *
  33957. * @package DbUnit
  33958. * @author Mike Lively <m@digitalsandwich.com>
  33959. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  33960. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  33961. * @version Release: @package_version@
  33962. * @link http://www.phpunit.de/
  33963. * @since Class available since Release 1.0.0
  33964. */
  33965. class PHPUnit_Extensions_Database_DataSet_DefaultDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  33966. {
  33967. /**
  33968. * An array of ITable objects.
  33969. *
  33970. * @var array
  33971. */
  33972. protected $tables;
  33973. /**
  33974. * Creates a new dataset using the given tables.
  33975. *
  33976. * @param array $tables
  33977. */
  33978. public function __construct(Array $tables = array())
  33979. {
  33980. $this->tables = $tables;
  33981. }
  33982. /**
  33983. * Adds a table to the dataset.
  33984. *
  33985. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  33986. */
  33987. public function addTable(PHPUnit_Extensions_Database_DataSet_ITable $table)
  33988. {
  33989. $this->tables[] = $table;
  33990. }
  33991. /**
  33992. * Creates an iterator over the tables in the data set. If $reverse is
  33993. * true a reverse iterator will be returned.
  33994. *
  33995. * @param bool $reverse
  33996. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  33997. */
  33998. protected function createIterator($reverse = FALSE)
  33999. {
  34000. return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse);
  34001. }
  34002. }
  34003. <?php
  34004. /*
  34005. * This file is part of DBUnit.
  34006. *
  34007. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34008. *
  34009. * For the full copyright and license information, please view the LICENSE
  34010. * file that was distributed with this source code.
  34011. */
  34012. /**
  34013. * The default YAML parser, using Symfony/Yaml.
  34014. *
  34015. * @package DbUnit
  34016. * @author Yash Parghi <yash@yashparghi.com>
  34017. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  34018. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34019. * @link http://www.phpunit.de/
  34020. * @since Class available since Release 1.3.1
  34021. */
  34022. class PHPUnit_Extensions_Database_DataSet_SymfonyYamlParser implements PHPUnit_Extensions_Database_DataSet_IYamlParser {
  34023. public function parseYaml($yamlFile) {
  34024. return Symfony\Component\Yaml\Yaml::parse(file_get_contents($yamlFile));
  34025. }
  34026. }
  34027. <?php
  34028. /*
  34029. * This file is part of DBUnit.
  34030. *
  34031. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34032. *
  34033. * For the full copyright and license information, please view the LICENSE
  34034. * file that was distributed with this source code.
  34035. */
  34036. /**
  34037. * Provides a basic interface for creating and reading data from data sets.
  34038. *
  34039. * @package DbUnit
  34040. * @author Mike Lively <m@digitalsandwich.com>
  34041. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34042. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34043. * @version Release: @package_version@
  34044. * @link http://www.phpunit.de/
  34045. * @since Class available since Release 1.0.0
  34046. */
  34047. interface PHPUnit_Extensions_Database_DataSet_IDataSet extends IteratorAggregate
  34048. {
  34049. /**
  34050. * Returns an array of table names contained in the dataset.
  34051. *
  34052. * @return array
  34053. */
  34054. public function getTableNames();
  34055. /**
  34056. * Returns a table meta data object for the given table.
  34057. *
  34058. * @param string $tableName
  34059. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  34060. */
  34061. public function getTableMetaData($tableName);
  34062. /**
  34063. * Returns a table object for the given table.
  34064. *
  34065. * @param string $tableName
  34066. * @return PHPUnit_Extensions_Database_DataSet_ITable
  34067. */
  34068. public function getTable($tableName);
  34069. /**
  34070. * Returns a reverse iterator for all table objects in the given dataset.
  34071. *
  34072. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  34073. */
  34074. public function getReverseIterator();
  34075. /**
  34076. * Asserts that the given data set matches this data set.
  34077. *
  34078. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $other
  34079. */
  34080. public function matches(PHPUnit_Extensions_Database_DataSet_IDataSet $other);
  34081. }
  34082. <?php
  34083. /*
  34084. * This file is part of DBUnit.
  34085. *
  34086. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34087. *
  34088. * For the full copyright and license information, please view the LICENSE
  34089. * file that was distributed with this source code.
  34090. */
  34091. /**
  34092. * Provides a basic interface for returning table meta data.
  34093. *
  34094. * @package DbUnit
  34095. * @author Mike Lively <m@digitalsandwich.com>
  34096. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34097. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34098. * @version Release: @package_version@
  34099. * @link http://www.phpunit.de/
  34100. * @since Class available since Release 1.0.0
  34101. */
  34102. interface PHPUnit_Extensions_Database_DataSet_ITableMetaData
  34103. {
  34104. /**
  34105. * Returns the names of the columns in the table.
  34106. *
  34107. * @return array
  34108. */
  34109. public function getColumns();
  34110. /**
  34111. * Returns the names of the primary key columns in the table.
  34112. *
  34113. * @return array
  34114. */
  34115. public function getPrimaryKeys();
  34116. /**
  34117. * Returns the name of the table.
  34118. *
  34119. * @return string
  34120. */
  34121. public function getTableName();
  34122. /**
  34123. * Asserts that the given tableMetaData matches this tableMetaData.
  34124. *
  34125. * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $other
  34126. */
  34127. public function matches(PHPUnit_Extensions_Database_DataSet_ITableMetaData $other);
  34128. }
  34129. <?php
  34130. /*
  34131. * This file is part of DBUnit.
  34132. *
  34133. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34134. *
  34135. * For the full copyright and license information, please view the LICENSE
  34136. * file that was distributed with this source code.
  34137. */
  34138. /**
  34139. * An abstract implementation of a dataset persistor.
  34140. *
  34141. * @package DbUnit
  34142. * @author Mike Lively <m@digitalsandwich.com>
  34143. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34144. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34145. * @version Release: @package_version@
  34146. * @link http://www.phpunit.de/
  34147. * @since Class available since Release 1.0.0
  34148. */
  34149. abstract class PHPUnit_Extensions_Database_DataSet_Persistors_Abstract implements PHPUnit_Extensions_Database_DataSet_IPersistable
  34150. {
  34151. public function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34152. {
  34153. $this->saveDataSet($dataset);
  34154. }
  34155. /**
  34156. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34157. */
  34158. protected function saveDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34159. {
  34160. $this->startDataSet($dataset);
  34161. foreach ($dataset as $table) {
  34162. $this->saveTable($table);
  34163. }
  34164. $this->endDataSet($dataset);
  34165. }
  34166. /**
  34167. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34168. */
  34169. protected function saveTable(PHPUnit_Extensions_Database_DataSet_ITable $table)
  34170. {
  34171. $rowCount = $table->getRowCount();
  34172. $this->startTable($table);
  34173. for ($i = 0; $i < $rowCount; $i++) {
  34174. $this->row($table->getRow($i), $table);
  34175. }
  34176. $this->endTable($table);
  34177. }
  34178. /**
  34179. * Override to save the start of a dataset.
  34180. *
  34181. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34182. */
  34183. abstract protected function startDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset);
  34184. /**
  34185. * Override to save the end of a dataset.
  34186. *
  34187. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34188. */
  34189. abstract protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset);
  34190. /**
  34191. * Override to save the start of a table.
  34192. *
  34193. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34194. */
  34195. abstract protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table);
  34196. /**
  34197. * Override to save the end of a table.
  34198. *
  34199. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34200. */
  34201. abstract protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table);
  34202. /**
  34203. * Override to save a table row.
  34204. *
  34205. * @param array $row
  34206. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34207. */
  34208. abstract protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table);
  34209. }
  34210. <?php
  34211. /*
  34212. * This file is part of DBUnit.
  34213. *
  34214. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34215. *
  34216. * For the full copyright and license information, please view the LICENSE
  34217. * file that was distributed with this source code.
  34218. */
  34219. /**
  34220. * A XML dataset persistor.
  34221. *
  34222. * @package DbUnit
  34223. * @author Mike Lively <m@digitalsandwich.com>
  34224. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34225. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34226. * @version Release: @package_version@
  34227. * @link http://www.phpunit.de/
  34228. * @since Class available since Release 1.0.0
  34229. */
  34230. class PHPUnit_Extensions_Database_DataSet_Persistors_Xml extends PHPUnit_Extensions_Database_DataSet_Persistors_Abstract
  34231. {
  34232. /**
  34233. * @var string
  34234. */
  34235. protected $filename;
  34236. /**
  34237. * @var resource
  34238. */
  34239. protected $fh;
  34240. /**
  34241. * Sets the filename that this persistor will save to.
  34242. *
  34243. * @param string $filename
  34244. */
  34245. public function setFileName($filename)
  34246. {
  34247. $this->filename = $filename;
  34248. }
  34249. /**
  34250. * Override to save the start of a dataset.
  34251. *
  34252. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34253. */
  34254. protected function startDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34255. {
  34256. $this->fh = fopen($this->filename, 'w');
  34257. if ($this->fh === FALSE) {
  34258. throw new PHPUnit_Framework_Exception(
  34259. "Could not open {$this->filename} for writing see " . __CLASS__ . "::setFileName()"
  34260. );
  34261. }
  34262. fwrite($this->fh, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
  34263. fwrite($this->fh, "<dataset>\n");
  34264. }
  34265. /**
  34266. * Override to save the end of a dataset.
  34267. *
  34268. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34269. */
  34270. protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34271. {
  34272. fwrite($this->fh, "</dataset>\n");
  34273. }
  34274. /**
  34275. * Override to save the start of a table.
  34276. *
  34277. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34278. */
  34279. protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table)
  34280. {
  34281. fwrite($this->fh, "\t<table name=\"{$table->getTableMetaData()->getTableName()}\">\n");
  34282. foreach ($table->getTableMetaData()->getColumns() as $columnName) {
  34283. fwrite($this->fh, "\t\t<column>{$columnName}</column>\n");
  34284. }
  34285. }
  34286. /**
  34287. * Override to save the end of a table.
  34288. *
  34289. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34290. */
  34291. protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table)
  34292. {
  34293. fwrite($this->fh, "\t</table>\n");
  34294. }
  34295. /**
  34296. * Override to save a table row.
  34297. *
  34298. * @param array $row
  34299. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34300. */
  34301. protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table)
  34302. {
  34303. fwrite($this->fh, "\t\t<row>\n");
  34304. foreach ($table->getTableMetaData()->getColumns() as $columnName) {
  34305. if (isset($row[$columnName])) {
  34306. fwrite($this->fh, "\t\t\t<value>" . htmlspecialchars($row[$columnName]) . "</value>\n");
  34307. } else {
  34308. fwrite($this->fh, "\t\t\t<null />\n");
  34309. }
  34310. }
  34311. fwrite($this->fh, "\t\t</row>\n");
  34312. }
  34313. }
  34314. <?php
  34315. /*
  34316. * This file is part of DBUnit.
  34317. *
  34318. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34319. *
  34320. * For the full copyright and license information, please view the LICENSE
  34321. * file that was distributed with this source code.
  34322. */
  34323. /**
  34324. * A Flat XML dataset persistor.
  34325. *
  34326. * @package DbUnit
  34327. * @author Mike Lively <m@digitalsandwich.com>
  34328. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34329. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34330. * @version Release: @package_version@
  34331. * @link http://www.phpunit.de/
  34332. * @since Class available since Release 1.0.0
  34333. */
  34334. class PHPUnit_Extensions_Database_DataSet_Persistors_FlatXml extends PHPUnit_Extensions_Database_DataSet_Persistors_Abstract
  34335. {
  34336. /**
  34337. * @var string
  34338. */
  34339. protected $filename;
  34340. /**
  34341. * @var resource
  34342. */
  34343. protected $fh;
  34344. /**
  34345. * Sets the filename that this persistor will save to.
  34346. *
  34347. * @param string $filename
  34348. */
  34349. public function setFileName($filename)
  34350. {
  34351. $this->filename = $filename;
  34352. }
  34353. /**
  34354. * Override to save the start of a dataset.
  34355. *
  34356. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34357. */
  34358. protected function startDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34359. {
  34360. $this->fh = fopen($this->filename, 'w');
  34361. if ($this->fh === FALSE) {
  34362. throw new PHPUnit_Framework_Exception(
  34363. "Could not open {$this->filename} for writing see " . __CLASS__ . "::setFileName()"
  34364. );
  34365. }
  34366. fwrite($this->fh, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
  34367. fwrite($this->fh, "<dataset>\n");
  34368. }
  34369. /**
  34370. * Override to save the end of a dataset.
  34371. *
  34372. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34373. */
  34374. protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34375. {
  34376. fwrite($this->fh, "</dataset>\n");
  34377. }
  34378. /**
  34379. * Override to save the start of a table.
  34380. *
  34381. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34382. */
  34383. protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table)
  34384. {
  34385. if ($table->getRowCount() == 0) {
  34386. fwrite($this->fh, "\t<{$table->getTableMetaData()->getTableName()} />\n");
  34387. }
  34388. }
  34389. /**
  34390. * Override to save the end of a table.
  34391. *
  34392. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34393. */
  34394. protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table)
  34395. {
  34396. //do nothing
  34397. }
  34398. /**
  34399. * Override to save a table row.
  34400. *
  34401. * @param array $row
  34402. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34403. */
  34404. protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table)
  34405. {
  34406. fwrite($this->fh, "\t<{$table->getTableMetaData()->getTableName()}\n");
  34407. foreach ($table->getTableMetaData()->getColumns() as $columnName) {
  34408. if (isset($row[$columnName])) {
  34409. fwrite($this->fh, "\t\t{$columnName}=\"". htmlspecialchars($row[$columnName]) . "\"\n");
  34410. }
  34411. }
  34412. fwrite($this->fh, "\t/>\n");
  34413. }
  34414. }
  34415. <?php
  34416. /*
  34417. * This file is part of DBUnit.
  34418. *
  34419. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34420. *
  34421. * For the full copyright and license information, please view the LICENSE
  34422. * file that was distributed with this source code.
  34423. */
  34424. /**
  34425. * A yaml dataset persistor
  34426. *
  34427. * @package DbUnit
  34428. * @author Mike Lively <m@digitalsandwich.com>
  34429. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34430. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34431. * @version Release: @package_version@
  34432. * @link http://www.phpunit.de/
  34433. * @since Class available since Release 1.0.0
  34434. */
  34435. class PHPUnit_Extensions_Database_DataSet_Persistors_Yaml implements PHPUnit_Extensions_Database_DataSet_IPersistable
  34436. {
  34437. /**
  34438. * @var string
  34439. */
  34440. protected $filename;
  34441. /**
  34442. * Sets the filename that this persistor will save to.
  34443. *
  34444. * @param string $filename
  34445. */
  34446. public function setFileName($filename)
  34447. {
  34448. $this->filename = $filename;
  34449. }
  34450. /**
  34451. * Writes the dataset to a yaml file
  34452. *
  34453. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34454. */
  34455. public function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34456. {
  34457. $phpArr = array();
  34458. $emptyTables = array();
  34459. foreach ($dataset as $table) {
  34460. $tableName = $table->getTableMetaData()->getTableName();
  34461. $rowCount = $table->getRowCount();
  34462. if (!$rowCount) {
  34463. $emptyTables[] = $tableName;
  34464. continue;
  34465. }
  34466. $phpArr[$tableName] = array();
  34467. for ($i = 0; $i < $rowCount; $i++) {
  34468. $phpArr[$tableName][] = $table->getRow($i);
  34469. }
  34470. }
  34471. $emptyTablesAsString = '';
  34472. if (count($emptyTables)) {
  34473. $emptyTablesAsString = implode(":\n", $emptyTables) . ":\n\n";
  34474. }
  34475. file_put_contents(
  34476. $this->filename,
  34477. Symfony\Component\Yaml\Yaml::dump($phpArr, 3) . $emptyTablesAsString
  34478. );
  34479. }
  34480. }
  34481. <?php
  34482. /*
  34483. * This file is part of DBUnit.
  34484. *
  34485. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34486. *
  34487. * For the full copyright and license information, please view the LICENSE
  34488. * file that was distributed with this source code.
  34489. */
  34490. /**
  34491. * A MySQL XML dataset persistor.
  34492. *
  34493. * @package DbUnit
  34494. * @author Matthew Turland <tobias382@gmail.com>
  34495. * @copyright 2010-2014 Matthew Turland <tobias382@gmail.com>
  34496. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34497. * @version Release: @package_version@
  34498. * @link http://www.phpunit.de/
  34499. * @since Class available since Release 1.0.0
  34500. */
  34501. class PHPUnit_Extensions_Database_DataSet_Persistors_MysqlXml extends PHPUnit_Extensions_Database_DataSet_Persistors_Abstract
  34502. {
  34503. /**
  34504. * @var string
  34505. */
  34506. protected $filename;
  34507. /**
  34508. * @var string
  34509. */
  34510. protected $database;
  34511. /**
  34512. * @var resource
  34513. */
  34514. protected $fh;
  34515. /**
  34516. * Sets the filename that this persistor will save to.
  34517. *
  34518. * @param string $filename
  34519. */
  34520. public function setFileName($filename)
  34521. {
  34522. $this->filename = $filename;
  34523. }
  34524. /**
  34525. * Sets the name of the database.
  34526. *
  34527. * @param string $database
  34528. */
  34529. public function setDatabase($database)
  34530. {
  34531. $this->database = $database;
  34532. }
  34533. /**
  34534. * Override to save the start of a dataset.
  34535. *
  34536. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34537. */
  34538. protected function startDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34539. {
  34540. $this->fh = fopen($this->filename, 'w');
  34541. if ($this->fh === FALSE) {
  34542. throw new PHPUnit_Framework_Exception(
  34543. "Could not open {$this->filename} for writing see " . __CLASS__ . "::setFileName()"
  34544. );
  34545. }
  34546. fwrite($this->fh, '<?xml version="1.0" encoding="UTF-8"?>' . "\n");
  34547. fwrite($this->fh, '<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' . "\n");
  34548. fwrite($this->fh, '<database name="' . $this->database . '">' . "\n");
  34549. }
  34550. /**
  34551. * Override to save the end of a dataset.
  34552. *
  34553. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  34554. */
  34555. protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset)
  34556. {
  34557. fwrite($this->fh, '</database>' . "\n");
  34558. fwrite($this->fh, '</mysqldump>' . "\n");
  34559. }
  34560. /**
  34561. * Override to save the start of a table.
  34562. *
  34563. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34564. */
  34565. protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table)
  34566. {
  34567. fwrite($this->fh, "\t" . '<table_data name="' . $table->getTableMetaData()->getTableName() . '">' . "\n");
  34568. }
  34569. /**
  34570. * Override to save the end of a table.
  34571. *
  34572. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34573. */
  34574. protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table)
  34575. {
  34576. fwrite($this->fh, "\t" . '</table_data>' . "\n");
  34577. }
  34578. /**
  34579. * Override to save a table row.
  34580. *
  34581. * @param array $row
  34582. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  34583. */
  34584. protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table)
  34585. {
  34586. fwrite($this->fh, "\t" . '<row>' . "\n");
  34587. foreach ($table->getTableMetaData()->getColumns() as $columnName) {
  34588. fwrite($this->fh, "\t\t" . '<field name="' . $columnName . '"');
  34589. if (isset($row[$columnName])) {
  34590. fwrite($this->fh, '>' . htmlspecialchars($row[$columnName]) . '</field>' . "\n");
  34591. } else {
  34592. fwrite($this->fh, ' xsi:nil="true" />' . "\n");
  34593. }
  34594. }
  34595. fwrite($this->fh, "\t" . '</row>' . "\n");
  34596. }
  34597. }
  34598. <?php
  34599. /*
  34600. * This file is part of DBUnit.
  34601. *
  34602. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34603. *
  34604. * For the full copyright and license information, please view the LICENSE
  34605. * file that was distributed with this source code.
  34606. */
  34607. /**
  34608. * Creates the appropriate Persistor based on a given type and spec.
  34609. *
  34610. * @package DbUnit
  34611. * @author Mike Lively <m@digitalsandwich.com>
  34612. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34613. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34614. * @version Release: @package_version@
  34615. * @link http://www.phpunit.de//**
  34616. * @since Class available since Release 1.0.0
  34617. */
  34618. class PHPUnit_Extensions_Database_DataSet_Persistors_Factory
  34619. {
  34620. /**
  34621. * Returns the persistor.
  34622. *
  34623. * @param string $type
  34624. * @param string $spec
  34625. * @return PHPUnit_Extensions_Database_DataSet_IPersistable
  34626. */
  34627. public function getPersistorBySpec($type, $spec)
  34628. {
  34629. switch (strtolower($type)) {
  34630. case 'xml':
  34631. $xmlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_Xml();
  34632. $xmlPersistor->setFileName($spec);
  34633. return $xmlPersistor;
  34634. case 'flatxml':
  34635. $flatXmlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_FlatXml();
  34636. $flatXmlPersistor->setFileName($spec);
  34637. return $flatXmlPersistor;
  34638. case 'yaml':
  34639. $yamlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_Yaml();
  34640. $yamlPersistor->setFileName($spec);
  34641. return $yamlPersistor;
  34642. case 'mysqlxml':
  34643. $mysqlXmlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_MysqlXml();
  34644. $mysqlXmlPersistor->setFileName($spec);
  34645. return $mysqlXmlPersistor;
  34646. default:
  34647. throw new PHPUnit_Extensions_Database_Exception("I don't know what you want from me. PERSISTOR");
  34648. }
  34649. }
  34650. }
  34651. <?php
  34652. /*
  34653. * This file is part of DBUnit.
  34654. *
  34655. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34656. *
  34657. * For the full copyright and license information, please view the LICENSE
  34658. * file that was distributed with this source code.
  34659. */
  34660. /**
  34661. * Creates CsvDataSets.
  34662. *
  34663. * You can incrementally add CSV files as tables to your datasets
  34664. *
  34665. * @package DbUnit
  34666. * @author Mike Lively <m@digitalsandwich.com>
  34667. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34668. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34669. * @version Release: @package_version@
  34670. * @link http://www.phpunit.de/
  34671. * @since Class available since Release 1.0.0
  34672. */
  34673. class PHPUnit_Extensions_Database_DataSet_CsvDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  34674. {
  34675. /**
  34676. * @var array
  34677. */
  34678. protected $tables = array();
  34679. /**
  34680. * @var string
  34681. */
  34682. protected $delimiter = ',';
  34683. /**
  34684. * @var string
  34685. */
  34686. protected $enclosure = '"';
  34687. /**
  34688. * @var string
  34689. */
  34690. protected $escape = '"';
  34691. /**
  34692. * Creates a new CSV dataset
  34693. *
  34694. * You can pass in the parameters for how csv files will be read.
  34695. *
  34696. * @param string $delimiter
  34697. * @param string $enclosure
  34698. * @param string $escape
  34699. */
  34700. public function __construct($delimiter = ',', $enclosure = '"', $escape = '"')
  34701. {
  34702. $this->delimiter = $delimiter;
  34703. $this->enclosure = $enclosure;
  34704. $this->escape = $escape;
  34705. }
  34706. /**
  34707. * Adds a table to the dataset
  34708. *
  34709. * The table will be given the passed name. $csvFile should be a path to
  34710. * a valid csv file (based on the arguments passed to the constructor.)
  34711. *
  34712. * @param string $tableName
  34713. * @param string $csvFile
  34714. */
  34715. public function addTable($tableName, $csvFile)
  34716. {
  34717. if (!is_file($csvFile)) {
  34718. throw new InvalidArgumentException("Could not find csv file: {$csvFile}");
  34719. }
  34720. if (!is_readable($csvFile)) {
  34721. throw new InvalidArgumentException("Could not read csv file: {$csvFile}");
  34722. }
  34723. $fh = fopen($csvFile, 'r');
  34724. $columns = $this->getCsvRow($fh);
  34725. if ($columns === FALSE)
  34726. {
  34727. throw new InvalidArgumentException("Could not determine the headers from the given file {$csvFile}");
  34728. }
  34729. $metaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $columns);
  34730. $table = new PHPUnit_Extensions_Database_DataSet_DefaultTable($metaData);
  34731. while (($row = $this->getCsvRow($fh)) !== FALSE)
  34732. {
  34733. $table->addRow(array_combine($columns, $row));
  34734. }
  34735. $this->tables[$tableName] = $table;
  34736. }
  34737. /**
  34738. * Creates an iterator over the tables in the data set. If $reverse is
  34739. * true a reverse iterator will be returned.
  34740. *
  34741. * @param bool $reverse
  34742. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  34743. */
  34744. protected function createIterator($reverse = FALSE)
  34745. {
  34746. return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse);
  34747. }
  34748. /**
  34749. * Returns a row from the csv file in an indexed array.
  34750. *
  34751. * @param resource $fh
  34752. * @return array
  34753. */
  34754. protected function getCsvRow($fh)
  34755. {
  34756. if (version_compare(PHP_VERSION, '5.3.0', '>')) {
  34757. return fgetcsv($fh, NULL, $this->delimiter, $this->enclosure, $this->escape);
  34758. } else {
  34759. return fgetcsv($fh, NULL, $this->delimiter, $this->enclosure);
  34760. }
  34761. }
  34762. }
  34763. <?php
  34764. /*
  34765. * This file is part of DBUnit.
  34766. *
  34767. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34768. *
  34769. * For the full copyright and license information, please view the LICENSE
  34770. * file that was distributed with this source code.
  34771. */
  34772. /**
  34773. * The default table iterator
  34774. *
  34775. * @package DbUnit
  34776. * @author Mike Lively <m@digitalsandwich.com>
  34777. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34778. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34779. * @version Release: @package_version@
  34780. * @link http://www.phpunit.de/
  34781. * @since Class available since Release 1.0.0
  34782. */
  34783. class PHPUnit_Extensions_Database_DataSet_ReplacementTableIterator implements OuterIterator, PHPUnit_Extensions_Database_DataSet_ITableIterator
  34784. {
  34785. /**
  34786. * @var PHPUnit_Extensions_Database_DataSet_ITableIterator
  34787. */
  34788. protected $innerIterator;
  34789. /**
  34790. * @var array
  34791. */
  34792. protected $fullReplacements;
  34793. /**
  34794. * @var array
  34795. */
  34796. protected $subStrReplacements;
  34797. /**
  34798. * Creates a new replacement table iterator object.
  34799. *
  34800. * @param PHPUnit_Extensions_Database_DataSet_ITableIterator $innerIterator
  34801. * @param array $fullReplacements
  34802. * @param array $subStrReplacements
  34803. */
  34804. public function __construct(PHPUnit_Extensions_Database_DataSet_ITableIterator $innerIterator, Array $fullReplacements = array(), Array $subStrReplacements = array())
  34805. {
  34806. $this->innerIterator = $innerIterator;
  34807. $this->fullReplacements = $fullReplacements;
  34808. $this->subStrReplacements = $subStrReplacements;
  34809. }
  34810. /**
  34811. * Adds a new full replacement
  34812. *
  34813. * Full replacements will only replace values if the FULL value is a match
  34814. *
  34815. * @param string $value
  34816. * @param string $replacement
  34817. */
  34818. public function addFullReplacement($value, $replacement)
  34819. {
  34820. $this->fullReplacements[$value] = $replacement;
  34821. }
  34822. /**
  34823. * Adds a new substr replacement
  34824. *
  34825. * Substr replacements will replace all occurances of the substr in every column
  34826. *
  34827. * @param string $value
  34828. * @param string $replacement
  34829. */
  34830. public function addSubStrReplacement($value, $replacement)
  34831. {
  34832. $this->subStrReplacements[$value] = $replacement;
  34833. }
  34834. /**
  34835. * Returns the current table.
  34836. *
  34837. * @return PHPUnit_Extensions_Database_DataSet_ITable
  34838. */
  34839. public function getTable()
  34840. {
  34841. return $this->current();
  34842. }
  34843. /**
  34844. * Returns the current table's meta data.
  34845. *
  34846. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  34847. */
  34848. public function getTableMetaData()
  34849. {
  34850. $this->current()->getTableMetaData();
  34851. }
  34852. /**
  34853. * Returns the current table.
  34854. *
  34855. * @return PHPUnit_Extensions_Database_DataSet_ITable
  34856. */
  34857. public function current()
  34858. {
  34859. return new PHPUnit_Extensions_Database_DataSet_ReplacementTable($this->innerIterator->current(), $this->fullReplacements, $this->subStrReplacements);
  34860. }
  34861. /**
  34862. * Returns the name of the current table.
  34863. *
  34864. * @return string
  34865. */
  34866. public function key()
  34867. {
  34868. return $this->current()->getTableMetaData()->getTableName();
  34869. }
  34870. /**
  34871. * advances to the next element.
  34872. *
  34873. */
  34874. public function next()
  34875. {
  34876. $this->innerIterator->next();
  34877. }
  34878. /**
  34879. * Rewinds to the first element
  34880. */
  34881. public function rewind()
  34882. {
  34883. $this->innerIterator->rewind();
  34884. }
  34885. /**
  34886. * Returns true if the current index is valid
  34887. *
  34888. * @return bool
  34889. */
  34890. public function valid()
  34891. {
  34892. return $this->innerIterator->valid();
  34893. }
  34894. public function getInnerIterator()
  34895. {
  34896. return $this->innerIterator;
  34897. }
  34898. }
  34899. <?php
  34900. /*
  34901. * This file is part of DBUnit.
  34902. *
  34903. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34904. *
  34905. * For the full copyright and license information, please view the LICENSE
  34906. * file that was distributed with this source code.
  34907. */
  34908. /**
  34909. * Allows for replacing arbitrary values or portions of values with new data.
  34910. *
  34911. * A usage for this is replacing all values == '[NULL'] with a true NULL value
  34912. *
  34913. * @package DbUnit
  34914. * @author Mike Lively <m@digitalsandwich.com>
  34915. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  34916. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  34917. * @version Release: @package_version@
  34918. * @link http://www.phpunit.de/
  34919. * @since Class available since Release 1.0.0
  34920. */
  34921. class PHPUnit_Extensions_Database_DataSet_ReplacementDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  34922. {
  34923. /**
  34924. * @var PHPUnit_Extensions_Database_DataSet_IDataSet
  34925. */
  34926. protected $dataSet;
  34927. /**
  34928. * @var array
  34929. */
  34930. protected $fullReplacements;
  34931. /**
  34932. * @var array
  34933. */
  34934. protected $subStrReplacements;
  34935. /**
  34936. * Creates a new replacement dataset
  34937. *
  34938. * You can pass in any data set that implements PHPUnit_Extensions_Database_DataSet_IDataSet
  34939. *
  34940. * @param string $delimiter
  34941. * @param string $enclosure
  34942. * @param string $escape
  34943. */
  34944. public function __construct(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet, Array $fullReplacements = array(), Array $subStrReplacements = array())
  34945. {
  34946. $this->dataSet = $dataSet;
  34947. $this->fullReplacements = $fullReplacements;
  34948. $this->subStrReplacements = $subStrReplacements;
  34949. }
  34950. /**
  34951. * Adds a new full replacement
  34952. *
  34953. * Full replacements will only replace values if the FULL value is a match
  34954. *
  34955. * @param string $value
  34956. * @param string $replacement
  34957. */
  34958. public function addFullReplacement($value, $replacement)
  34959. {
  34960. $this->fullReplacements[$value] = $replacement;
  34961. }
  34962. /**
  34963. * Adds a new substr replacement
  34964. *
  34965. * Substr replacements will replace all occurances of the substr in every column
  34966. *
  34967. * @param string $value
  34968. * @param string $replacement
  34969. */
  34970. public function addSubStrReplacement($value, $replacement)
  34971. {
  34972. $this->subStrReplacements[$value] = $replacement;
  34973. }
  34974. /**
  34975. * Creates an iterator over the tables in the data set. If $reverse is
  34976. * true a reverse iterator will be returned.
  34977. *
  34978. * @param bool $reverse
  34979. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  34980. */
  34981. protected function createIterator($reverse = FALSE)
  34982. {
  34983. $innerIterator = $reverse ? $this->dataSet->getReverseIterator() : $this->dataSet->getIterator();
  34984. return new PHPUnit_Extensions_Database_DataSet_ReplacementTableIterator($innerIterator, $this->fullReplacements, $this->subStrReplacements);
  34985. }
  34986. }
  34987. <?php
  34988. /*
  34989. * This file is part of DBUnit.
  34990. *
  34991. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  34992. *
  34993. * For the full copyright and license information, please view the LICENSE
  34994. * file that was distributed with this source code.
  34995. */
  34996. /**
  34997. * Implements the basic functionality of data sets using a PHP array.
  34998. *
  34999. * @package DbUnit
  35000. * @author Richard Brinkman <richardbrinkman@hotmail.com>
  35001. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35002. * @version Release: @package_version@
  35003. * @link http://www.phpunit.de/
  35004. * @since Class available since Release 1.3.2
  35005. */
  35006. class PHPUnit_Extensions_Database_DataSet_ArrayDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  35007. {
  35008. /**
  35009. * @var array
  35010. */
  35011. protected $tables = array();
  35012. /**
  35013. * Constructor to build a new ArrayDataSet with the given array.
  35014. * The array parameter is an associative array of tables where the key is
  35015. * the table name and the value an array of rows. Each row is an associative
  35016. * array by itself with keys representing the field names and the values the
  35017. * actual data.
  35018. * For example:
  35019. * array(
  35020. * "addressbook" => array(
  35021. * array("id" => 1, "name" => "...", "address" => "..."),
  35022. * array("id" => 2, "name" => "...", "address" => "...")
  35023. * )
  35024. * )
  35025. *
  35026. * @param array $data
  35027. */
  35028. public function __construct(array $data)
  35029. {
  35030. foreach ($data AS $tableName => $rows) {
  35031. $columns = array();
  35032. if (isset($rows[0])) {
  35033. $columns = array_keys($rows[0]);
  35034. }
  35035. $metaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $columns);
  35036. $table = new PHPUnit_Extensions_Database_DataSet_DefaultTable($metaData);
  35037. foreach ($rows AS $row) {
  35038. $table->addRow($row);
  35039. }
  35040. $this->tables[$tableName] = $table;
  35041. }
  35042. }
  35043. protected function createIterator($reverse = FALSE)
  35044. {
  35045. return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse);
  35046. }
  35047. public function getTable($tableName)
  35048. {
  35049. if (!isset($this->tables[$tableName])) {
  35050. throw new InvalidArgumentException("$tableName is not a table in the current database.");
  35051. }
  35052. return $this->tables[$tableName];
  35053. }
  35054. }
  35055. ?><?php
  35056. /*
  35057. * This file is part of DBUnit.
  35058. *
  35059. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35060. *
  35061. * For the full copyright and license information, please view the LICENSE
  35062. * file that was distributed with this source code.
  35063. */
  35064. /**
  35065. * Provides default table functionality.
  35066. *
  35067. * @package DbUnit
  35068. * @author Mike Lively <m@digitalsandwich.com>
  35069. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35070. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35071. * @version Release: @package_version@
  35072. * @link http://www.phpunit.de/
  35073. * @since Class available since Release 1.0.0
  35074. */
  35075. class PHPUnit_Extensions_Database_DataSet_DefaultTable extends PHPUnit_Extensions_Database_DataSet_AbstractTable
  35076. {
  35077. /**
  35078. * Creates a new table object using the given $tableMetaData
  35079. *
  35080. * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData
  35081. */
  35082. public function __construct(PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData)
  35083. {
  35084. $this->setTableMetaData($tableMetaData);
  35085. $this->data = array();
  35086. }
  35087. /**
  35088. * Adds a row to the table with optional values.
  35089. *
  35090. * @param array $values
  35091. */
  35092. public function addRow($values = array())
  35093. {
  35094. $this->data[] = array_replace(
  35095. array_fill_keys($this->getTableMetaData()->getColumns(), NULL),
  35096. $values
  35097. );
  35098. }
  35099. /**
  35100. * Adds the rows in the passed table to the current table.
  35101. *
  35102. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  35103. */
  35104. public function addTableRows(PHPUnit_Extensions_Database_DataSet_ITable $table)
  35105. {
  35106. $tableColumns = $this->getTableMetaData()->getColumns();
  35107. $rowCount = $table->getRowCount();
  35108. for ($i = 0; $i < $rowCount; $i++) {
  35109. $newRow = array();
  35110. foreach ($tableColumns as $columnName) {
  35111. $newRow[$columnName] = $table->getValue($i, $columnName);
  35112. }
  35113. $this->addRow($newRow);
  35114. }
  35115. }
  35116. /**
  35117. * Sets the specified column of the specied row to the specified value.
  35118. *
  35119. * @param int $row
  35120. * @param string $column
  35121. * @param mixed $value
  35122. */
  35123. public function setValue($row, $column, $value)
  35124. {
  35125. if (isset($this->data[$row])) {
  35126. $this->data[$row][$column] = $value;
  35127. } else {
  35128. throw new InvalidArgumentException("The row given does not exist.");
  35129. }
  35130. }
  35131. }
  35132. <?php
  35133. /*
  35134. * This file is part of DBUnit.
  35135. *
  35136. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35137. *
  35138. * For the full copyright and license information, please view the LICENSE
  35139. * file that was distributed with this source code.
  35140. */
  35141. /**
  35142. * Provides a basic interface for creating and reading data from data sets.
  35143. *
  35144. * @package DbUnit
  35145. * @author Mike Lively <m@digitalsandwich.com>
  35146. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35147. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35148. * @version Release: @package_version@
  35149. * @link http://www.phpunit.de/
  35150. * @since Class available since Release 1.0.0
  35151. */
  35152. interface PHPUnit_Extensions_Database_DataSet_ITableIterator extends Iterator
  35153. {
  35154. /**
  35155. * Returns the current table.
  35156. *
  35157. * @return PHPUnit_Extensions_Database_DataSet_ITable
  35158. */
  35159. public function getTable();
  35160. /**
  35161. * Returns the current table's meta data.
  35162. *
  35163. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  35164. */
  35165. public function getTableMetaData();
  35166. }
  35167. <?php
  35168. /*
  35169. * This file is part of DBUnit.
  35170. *
  35171. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35172. *
  35173. * For the full copyright and license information, please view the LICENSE
  35174. * file that was distributed with this source code.
  35175. */
  35176. /**
  35177. * The default implementation of a data set.
  35178. *
  35179. * @package DbUnit
  35180. * @author Mike Lively <m@digitalsandwich.com>
  35181. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35182. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35183. * @version Release: @package_version@
  35184. * @link http://www.phpunit.de/
  35185. * @since Class available since Release 1.0.0
  35186. */
  35187. class PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractXmlDataSet
  35188. {
  35189. protected function getTableInfo(Array &$tableColumns, Array &$tableValues)
  35190. {
  35191. if ($this->xmlFileContents->getName() != 'dataset') {
  35192. throw new PHPUnit_Extensions_Database_Exception("The root element of a flat xml data set file must be called <dataset>");
  35193. }
  35194. foreach ($this->xmlFileContents->children() as $row) {
  35195. $tableName = $row->getName();
  35196. if (!isset($tableColumns[$tableName])) {
  35197. $tableColumns[$tableName] = array();
  35198. $tableValues[$tableName] = array();
  35199. }
  35200. $values = array();
  35201. foreach ($row->attributes() as $name => $value) {
  35202. if (!in_array($name, $tableColumns[$tableName])) {
  35203. $tableColumns[$tableName][] = $name;
  35204. }
  35205. $values[$name] = $value;
  35206. }
  35207. if (count($values)) {
  35208. $tableValues[$tableName][] = $values;
  35209. }
  35210. }
  35211. }
  35212. public static function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset, $filename)
  35213. {
  35214. $pers = new PHPUnit_Extensions_Database_DataSet_Persistors_FlatXml();
  35215. $pers->setFileName($filename);
  35216. try {
  35217. $pers->write($dataset);
  35218. } catch (RuntimeException $e) {
  35219. throw new PHPUnit_Framework_Exception(__METHOD__ . ' called with an unwritable file.');
  35220. }
  35221. }
  35222. }
  35223. <?php
  35224. /*
  35225. * This file is part of DBUnit.
  35226. *
  35227. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35228. *
  35229. * For the full copyright and license information, please view the LICENSE
  35230. * file that was distributed with this source code.
  35231. */
  35232. /**
  35233. * An interface for persisting datasets
  35234. *
  35235. * @package DbUnit
  35236. * @author Mike Lively <m@digitalsandwich.com>
  35237. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35238. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35239. * @version Release: @package_version@
  35240. * @link http://www.phpunit.de/
  35241. * @since Class available since Release 1.0.0
  35242. */
  35243. interface PHPUnit_Extensions_Database_DataSet_IPersistable
  35244. {
  35245. /**
  35246. * Writes the given dataset
  35247. *
  35248. * The previous dataset will be overwritten.
  35249. *
  35250. * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset
  35251. */
  35252. public function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset);
  35253. }
  35254. <?php
  35255. /*
  35256. * This file is part of DBUnit.
  35257. *
  35258. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35259. *
  35260. * For the full copyright and license information, please view the LICENSE
  35261. * file that was distributed with this source code.
  35262. */
  35263. /**
  35264. * The default implementation of a data set.
  35265. *
  35266. * @package DbUnit
  35267. * @author Mike Lively <m@digitalsandwich.com>
  35268. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35269. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35270. * @version Release: @package_version@
  35271. * @link http://www.phpunit.de/
  35272. * @since Class available since Release 1.0.0
  35273. */
  35274. abstract class PHPUnit_Extensions_Database_DataSet_AbstractXmlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet
  35275. {
  35276. /**
  35277. * @var array
  35278. */
  35279. protected $tables;
  35280. /**
  35281. * @var SimpleXmlElement
  35282. */
  35283. protected $xmlFileContents;
  35284. /**
  35285. * Creates a new dataset using the given tables.
  35286. *
  35287. * @param array $tables
  35288. */
  35289. public function __construct($xmlFile)
  35290. {
  35291. if (!is_file($xmlFile)) {
  35292. throw new InvalidArgumentException(
  35293. "Could not find xml file: {$xmlFile}"
  35294. );
  35295. }
  35296. $libxmlErrorReporting = libxml_use_internal_errors(TRUE);
  35297. $this->xmlFileContents = simplexml_load_file($xmlFile, 'SimpleXMLElement', LIBXML_COMPACT | LIBXML_PARSEHUGE);
  35298. if (!$this->xmlFileContents) {
  35299. $message = '';
  35300. foreach (libxml_get_errors() as $error) {
  35301. $message .= print_r($error, true);
  35302. }
  35303. throw new RuntimeException($message);
  35304. }
  35305. libxml_clear_errors();
  35306. libxml_use_internal_errors($libxmlErrorReporting);
  35307. $tableColumns = array();
  35308. $tableValues = array();
  35309. $this->getTableInfo($tableColumns, $tableValues);
  35310. $this->createTables($tableColumns, $tableValues);
  35311. }
  35312. /**
  35313. * Reads the simple xml object and creates the appropriate tables and meta
  35314. * data for this dataset.
  35315. */
  35316. protected abstract function getTableInfo(Array &$tableColumns, Array &$tableValues);
  35317. protected function createTables(Array &$tableColumns, Array &$tableValues)
  35318. {
  35319. foreach ($tableValues as $tableName => $values) {
  35320. $table = $this->getOrCreateTable($tableName, $tableColumns[$tableName]);
  35321. foreach ($values as $value) {
  35322. $table->addRow($value);
  35323. }
  35324. }
  35325. }
  35326. /**
  35327. * Returns the table with the matching name. If the table does not exist
  35328. * an empty one is created.
  35329. *
  35330. * @param string $tableName
  35331. * @return PHPUnit_Extensions_Database_DataSet_ITable
  35332. */
  35333. protected function getOrCreateTable($tableName, $tableColumns)
  35334. {
  35335. if (empty($this->tables[$tableName])) {
  35336. $tableMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $tableColumns);
  35337. $this->tables[$tableName] = new PHPUnit_Extensions_Database_DataSet_DefaultTable($tableMetaData);
  35338. }
  35339. return $this->tables[$tableName];
  35340. }
  35341. /**
  35342. * Creates an iterator over the tables in the data set. If $reverse is
  35343. * true a reverse iterator will be returned.
  35344. *
  35345. * @param bool $reverse
  35346. * @return PHPUnit_Extensions_Database_DataSet_ITableIterator
  35347. */
  35348. protected function createIterator($reverse = FALSE)
  35349. {
  35350. return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse);
  35351. }
  35352. }
  35353. <?php
  35354. /*
  35355. * This file is part of DBUnit.
  35356. *
  35357. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35358. *
  35359. * For the full copyright and license information, please view the LICENSE
  35360. * file that was distributed with this source code.
  35361. */
  35362. /**
  35363. * A TableMetaData decorator that allows filtering columns from another
  35364. * metaData object.
  35365. *
  35366. * The if a whitelist (include) filter is specified, then only those columns
  35367. * will be included.
  35368. *
  35369. * @package DbUnit
  35370. * @author Mike Lively <m@digitalsandwich.com>
  35371. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35372. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35373. * @version Release: @package_version@
  35374. * @link http://www.phpunit.de/
  35375. * @since Class available since Release 1.0.0
  35376. */
  35377. class PHPUnit_Extensions_Database_DataSet_TableMetaDataFilter extends PHPUnit_Extensions_Database_DataSet_AbstractTableMetaData
  35378. {
  35379. /**
  35380. * The table meta data being decorated.
  35381. * @var PHPUnit_Extensions_Database_DataSet_ITableMetaData
  35382. */
  35383. protected $originalMetaData;
  35384. /**
  35385. * The columns to exclude from the meta data.
  35386. * @var Array
  35387. */
  35388. protected $excludeColumns = array();
  35389. /**
  35390. * The columns to include from the meta data.
  35391. * @var Array
  35392. */
  35393. protected $includeColumns = array();
  35394. /**
  35395. * Creates a new filtered table meta data object filtering out
  35396. * $excludeColumns.
  35397. *
  35398. * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $originalMetaData
  35399. * @param array $excludeColumns - Deprecated. Use the set* methods instead.
  35400. */
  35401. public function __construct(PHPUnit_Extensions_Database_DataSet_ITableMetaData $originalMetaData, Array $excludeColumns = array())
  35402. {
  35403. $this->originalMetaData = $originalMetaData;
  35404. $this->addExcludeColumns($excludeColumns);
  35405. }
  35406. /**
  35407. * Returns the names of the columns in the table.
  35408. *
  35409. * @return array
  35410. */
  35411. public function getColumns()
  35412. {
  35413. if (!empty($this->includeColumns)) {
  35414. return array_values(array_intersect($this->originalMetaData->getColumns(), $this->includeColumns));
  35415. }
  35416. elseif (!empty($this->excludeColumns)) {
  35417. return array_values(array_diff($this->originalMetaData->getColumns(), $this->excludeColumns));
  35418. }
  35419. else {
  35420. return $this->originalMetaData->getColumns();
  35421. }
  35422. }
  35423. /**
  35424. * Returns the names of the primary key columns in the table.
  35425. *
  35426. * @return array
  35427. */
  35428. public function getPrimaryKeys()
  35429. {
  35430. return $this->originalMetaData->getPrimaryKeys();
  35431. }
  35432. /**
  35433. * Returns the name of the table.
  35434. *
  35435. * @return string
  35436. */
  35437. public function getTableName()
  35438. {
  35439. return $this->originalMetaData->getTableName();
  35440. }
  35441. /**
  35442. * Sets the columns to include in the table.
  35443. * @param Array $includeColumns
  35444. */
  35445. public function addIncludeColumns(Array $includeColumns)
  35446. {
  35447. $this->includeColumns = array_unique(array_merge($this->includeColumns, $includeColumns));
  35448. }
  35449. /**
  35450. * Clears the included columns.
  35451. */
  35452. public function clearIncludeColumns()
  35453. {
  35454. $this->includeColumns = array();
  35455. }
  35456. /**
  35457. * Sets the columns to exclude from the table.
  35458. * @param Array $excludeColumns
  35459. */
  35460. public function addExcludeColumns(Array $excludeColumns)
  35461. {
  35462. $this->excludeColumns = array_unique(array_merge($this->excludeColumns, $excludeColumns));
  35463. }
  35464. /**
  35465. * Clears the excluded columns.
  35466. */
  35467. public function clearExcludeColumns()
  35468. {
  35469. $this->excludeColumns = array();
  35470. }
  35471. }
  35472. <?php
  35473. /*
  35474. * This file is part of DBUnit.
  35475. *
  35476. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35477. *
  35478. * For the full copyright and license information, please view the LICENSE
  35479. * file that was distributed with this source code.
  35480. */
  35481. /**
  35482. * Allows for replacing arbitrary strings in your data sets with other values.
  35483. *
  35484. * @package DbUnit
  35485. * @author Mike Lively <m@digitalsandwich.com>
  35486. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35487. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35488. * @version Release: @package_version@
  35489. * @link http://www.phpunit.de/
  35490. * @since Class available since Release 1.0.0
  35491. * @todo When setTableMetaData() is taken out of the AbstractTable this class should extend AbstractTable.
  35492. */
  35493. class PHPUnit_Extensions_Database_DataSet_ReplacementTable implements PHPUnit_Extensions_Database_DataSet_ITable
  35494. {
  35495. /**
  35496. * @var PHPUnit_Extensions_Database_DataSet_ITable
  35497. */
  35498. protected $table;
  35499. /**
  35500. * @var array
  35501. */
  35502. protected $fullReplacements;
  35503. /**
  35504. * @var array
  35505. */
  35506. protected $subStrReplacements;
  35507. /**
  35508. * Creates a new replacement table
  35509. *
  35510. * @param PHPUnit_Extensions_Database_DataSet_ITable $table
  35511. * @param array $fullReplacements
  35512. * @param array $subStrReplacements
  35513. */
  35514. public function __construct(PHPUnit_Extensions_Database_DataSet_ITable $table, Array $fullReplacements = array(), Array $subStrReplacements = array())
  35515. {
  35516. $this->table = $table;
  35517. $this->fullReplacements = $fullReplacements;
  35518. $this->subStrReplacements = $subStrReplacements;
  35519. }
  35520. /**
  35521. * Adds a new full replacement
  35522. *
  35523. * Full replacements will only replace values if the FULL value is a match
  35524. *
  35525. * @param string $value
  35526. * @param string $replacement
  35527. */
  35528. public function addFullReplacement($value, $replacement)
  35529. {
  35530. $this->fullReplacements[$value] = $replacement;
  35531. }
  35532. /**
  35533. * Adds a new substr replacement
  35534. *
  35535. * Substr replacements will replace all occurances of the substr in every column
  35536. *
  35537. * @param string $value
  35538. * @param string $replacement
  35539. */
  35540. public function addSubStrReplacement($value, $replacement)
  35541. {
  35542. $this->subStrReplacements[$value] = $replacement;
  35543. }
  35544. /**
  35545. * Returns the table's meta data.
  35546. *
  35547. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  35548. */
  35549. public function getTableMetaData()
  35550. {
  35551. return $this->table->getTableMetaData();
  35552. }
  35553. /**
  35554. * Returns the number of rows in this table.
  35555. *
  35556. * @return int
  35557. */
  35558. public function getRowCount()
  35559. {
  35560. return $this->table->getRowCount();
  35561. }
  35562. /**
  35563. * Returns the value for the given column on the given row.
  35564. *
  35565. * @param int $row
  35566. * @param int $column
  35567. */
  35568. public function getValue($row, $column)
  35569. {
  35570. return $this->getReplacedValue($this->table->getValue($row, $column));
  35571. }
  35572. /**
  35573. * Returns the an associative array keyed by columns for the given row.
  35574. *
  35575. * @param int $row
  35576. * @return array
  35577. */
  35578. public function getRow($row)
  35579. {
  35580. $row = $this->table->getRow($row);
  35581. return array_map(array($this, 'getReplacedValue'), $row);
  35582. }
  35583. /**
  35584. * Asserts that the given table matches this table.
  35585. *
  35586. * @param PHPUnit_Extensions_Database_DataSet_ITable $other
  35587. */
  35588. public function matches(PHPUnit_Extensions_Database_DataSet_ITable $other)
  35589. {
  35590. $thisMetaData = $this->getTableMetaData();
  35591. $otherMetaData = $other->getTableMetaData();
  35592. if (!$thisMetaData->matches($otherMetaData) ||
  35593. $this->getRowCount() != $other->getRowCount()) {
  35594. return FALSE;
  35595. }
  35596. $columns = $thisMetaData->getColumns();
  35597. $rowCount = $this->getRowCount();
  35598. for ($i = 0; $i < $rowCount; $i++) {
  35599. foreach ($columns as $columnName) {
  35600. $thisValue = $this->getValue($i, $columnName);
  35601. $otherValue = $other->getValue($i, $columnName);
  35602. if (is_numeric($thisValue) && is_numeric($otherValue)) {
  35603. if ($thisValue != $otherValue) {
  35604. return FALSE;
  35605. }
  35606. } elseif ($thisValue !== $otherValue) {
  35607. return FALSE;
  35608. }
  35609. }
  35610. }
  35611. return TRUE;
  35612. }
  35613. public function __toString()
  35614. {
  35615. $columns = $this->getTableMetaData()->getColumns();
  35616. $lineSeperator = str_repeat('+----------------------', count($columns)) . "+\n";
  35617. $lineLength = strlen($lineSeperator) - 1;
  35618. $tableString = $lineSeperator;
  35619. $tableString .= '| ' . str_pad($this->getTableMetaData()->getTableName(), $lineLength - 4, ' ', STR_PAD_RIGHT) . " |\n";
  35620. $tableString .= $lineSeperator;
  35621. $tableString .= $this->rowToString($columns);
  35622. $tableString .= $lineSeperator;
  35623. $rowCount = $this->getRowCount();
  35624. for ($i = 0; $i < $rowCount; $i++) {
  35625. $values = array();
  35626. foreach ($columns as $columnName) {
  35627. $values[] = $this->getValue($i, $columnName);
  35628. }
  35629. $tableString .= $this->rowToString($values);
  35630. $tableString .= $lineSeperator;
  35631. }
  35632. return "\n" . $tableString . "\n";
  35633. }
  35634. protected function rowToString(Array $row)
  35635. {
  35636. $rowString = '';
  35637. foreach ($row as $value) {
  35638. if (is_null($value)) {
  35639. $value = 'NULL';
  35640. }
  35641. $rowString .= '| ' . str_pad(substr($value, 0, 20), 20, ' ', STR_PAD_BOTH) . ' ';
  35642. }
  35643. return $rowString . "|\n";
  35644. }
  35645. protected function getReplacedValue($value)
  35646. {
  35647. if (is_scalar($value) && array_key_exists((string)$value, $this->fullReplacements)) {
  35648. return $this->fullReplacements[$value];
  35649. }
  35650. else if (count($this->subStrReplacements) && isset($value)) {
  35651. return str_replace(array_keys($this->subStrReplacements), array_values($this->subStrReplacements), $value);
  35652. }
  35653. else {
  35654. return $value;
  35655. }
  35656. }
  35657. }
  35658. <?php
  35659. /*
  35660. * This file is part of DBUnit.
  35661. *
  35662. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35663. *
  35664. * For the full copyright and license information, please view the LICENSE
  35665. * file that was distributed with this source code.
  35666. */
  35667. /**
  35668. * Creates DefaultDataSets based off of a spec string.
  35669. *
  35670. * This spec class requires a list of databases to be set to the object before
  35671. * it can return a list of databases.
  35672. *
  35673. * The format of the spec string is as follows:
  35674. *
  35675. * <db label>:<schema>:<table name>:<sql>
  35676. *
  35677. * The db label should be equal to one of the keys in the array of databases
  35678. * passed to setDatabases().
  35679. *
  35680. * The schema should be the primary schema you will be running the sql query
  35681. * against.
  35682. *
  35683. * The table name should be set to what you would like the table name in the
  35684. * dataset to be.
  35685. *
  35686. * The sql is the query you want to use to generate the table columns and data.
  35687. * The column names in the table will be identical to the column aliases in the
  35688. * query.
  35689. *
  35690. * @package DbUnit
  35691. * @author Mike Lively <m@digitalsandwich.com>
  35692. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35693. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35694. * @version Release: @package_version@
  35695. * @link http://www.phpunit.de/
  35696. * @since Class available since Release 1.0.0
  35697. */
  35698. class PHPUnit_Extensions_Database_DataSet_Specs_DbQuery implements PHPUnit_Extensions_Database_DataSet_ISpec, PHPUnit_Extensions_Database_IDatabaseListConsumer
  35699. {
  35700. /**
  35701. * @var array
  35702. */
  35703. protected $databases = array();
  35704. /**
  35705. * Sets the database for the spec
  35706. *
  35707. * @param array $databases
  35708. */
  35709. public function setDatabases(array $databases)
  35710. {
  35711. $this->databases = $databases;
  35712. }
  35713. /**
  35714. * Creates a Default Data Set with a query table from a data set spec.
  35715. *
  35716. * @param string $dataSetSpec
  35717. * @return PHPUnit_Extensions_Database_DataSet_DefaultDataSet
  35718. */
  35719. public function getDataSet($dataSetSpec)
  35720. {
  35721. list($dbLabel, $schema, $table, $sql) = explode(':', $dataSetSpec, 4);
  35722. $databaseInfo = $this->databases[$dbLabel];
  35723. $pdoRflc = new ReflectionClass('PDO');
  35724. $pdo = $pdoRflc->newInstanceArgs(explode('|', $databaseInfo));
  35725. $dbConnection = new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($pdo, $schema);
  35726. $table = $dbConnection->createQueryTable($table, $sql);
  35727. return new PHPUnit_Extensions_Database_DataSet_DefaultDataSet(array($table));
  35728. }
  35729. }
  35730. <?php
  35731. /*
  35732. * This file is part of DBUnit.
  35733. *
  35734. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35735. *
  35736. * For the full copyright and license information, please view the LICENSE
  35737. * file that was distributed with this source code.
  35738. */
  35739. /**
  35740. * Creates a XML dataset based off of a spec string.
  35741. *
  35742. * The format of the spec string is as follows:
  35743. *
  35744. * <filename>
  35745. *
  35746. * The filename should be the location of a xml file relative to the
  35747. * current working directory.
  35748. *
  35749. * @package DbUnit
  35750. * @author Mike Lively <m@digitalsandwich.com>
  35751. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35752. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35753. * @version Release: @package_version@
  35754. * @link http://www.phpunit.de//**
  35755. * @since Class available since Release 1.0.0
  35756. */
  35757. class PHPUnit_Extensions_Database_DataSet_Specs_Xml implements PHPUnit_Extensions_Database_DataSet_ISpec
  35758. {
  35759. /**
  35760. * Creates XML Data Set from a data set spec.
  35761. *
  35762. * @param string $dataSetSpec
  35763. * @return PHPUnit_Extensions_Database_DataSet_XmlDataSet
  35764. */
  35765. public function getDataSet($dataSetSpec)
  35766. {
  35767. return new PHPUnit_Extensions_Database_DataSet_XmlDataSet($dataSetSpec);
  35768. }
  35769. }
  35770. <?php
  35771. /*
  35772. * This file is part of DBUnit.
  35773. *
  35774. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35775. *
  35776. * For the full copyright and license information, please view the LICENSE
  35777. * file that was distributed with this source code.
  35778. */
  35779. /**
  35780. * Creates a FlatXML dataset based off of a spec string.
  35781. *
  35782. * The format of the spec string is as follows:
  35783. *
  35784. * <filename>
  35785. *
  35786. * The filename should be the location of a flat xml file relative to the
  35787. * current working directory.
  35788. *
  35789. * @package DbUnit
  35790. * @author Mike Lively <m@digitalsandwich.com>
  35791. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35792. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35793. * @version Release: @package_version@
  35794. * @link http://www.phpunit.de//**
  35795. * @since Class available since Release 1.0.0
  35796. */
  35797. class PHPUnit_Extensions_Database_DataSet_Specs_FlatXml implements PHPUnit_Extensions_Database_DataSet_ISpec
  35798. {
  35799. /**
  35800. * Creates Flat XML Data Set from a data set spec.
  35801. *
  35802. * @param string $dataSetSpec
  35803. * @return PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet
  35804. */
  35805. public function getDataSet($dataSetSpec)
  35806. {
  35807. return new PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet($dataSetSpec);
  35808. }
  35809. }
  35810. <?php
  35811. /*
  35812. * This file is part of DBUnit.
  35813. *
  35814. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35815. *
  35816. * For the full copyright and license information, please view the LICENSE
  35817. * file that was distributed with this source code.
  35818. */
  35819. /**
  35820. * Creates a YAML dataset based off of a spec string.
  35821. *
  35822. * The format of the spec string is as follows:
  35823. *
  35824. * <filename>
  35825. *
  35826. * The filename should be the location of a yaml file relative to the
  35827. * current working directory.
  35828. *
  35829. * @package DbUnit
  35830. * @author Mike Lively <m@digitalsandwich.com>
  35831. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35832. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35833. * @version Release: @package_version@
  35834. * @link http://www.phpunit.de//**
  35835. * @since Class available since Release 1.0.0
  35836. */
  35837. class PHPUnit_Extensions_Database_DataSet_Specs_Yaml implements PHPUnit_Extensions_Database_DataSet_ISpec
  35838. {
  35839. /**
  35840. * Creates YAML Data Set from a data set spec.
  35841. *
  35842. * @param string $dataSetSpec
  35843. * @return PHPUnit_Extensions_Database_DataSet_YamlDataSet
  35844. */
  35845. public function getDataSet($dataSetSpec)
  35846. {
  35847. return new PHPUnit_Extensions_Database_DataSet_YamlDataSet($dataSetSpec);
  35848. }
  35849. }
  35850. <?php
  35851. /*
  35852. * This file is part of DBUnit.
  35853. *
  35854. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35855. *
  35856. * For the full copyright and license information, please view the LICENSE
  35857. * file that was distributed with this source code.
  35858. */
  35859. /**
  35860. * An interface for data set spec factories.
  35861. *
  35862. * @package DbUnit
  35863. * @author Mike Lively <m@digitalsandwich.com>
  35864. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35865. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35866. * @version Release: @package_version@
  35867. * @link http://www.phpunit.de//**
  35868. * @since Class available since Release 1.0.0
  35869. */
  35870. interface PHPUnit_Extensions_Database_DataSet_Specs_IFactory
  35871. {
  35872. /**
  35873. * Returns the data set
  35874. *
  35875. * @param string $type
  35876. * @return PHPUnit_Extensions_Database_DataSet_ISpec
  35877. */
  35878. public function getDataSetSpecByType($type);
  35879. }
  35880. <?php
  35881. /*
  35882. * This file is part of DBUnit.
  35883. *
  35884. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35885. *
  35886. * For the full copyright and license information, please view the LICENSE
  35887. * file that was distributed with this source code.
  35888. */
  35889. /**
  35890. * Creates CsvDataSets based off of a spec string.
  35891. *
  35892. * The format of the spec string is as follows:
  35893. *
  35894. * <csv options>|table1:filename.csv,table2:filename2.csv
  35895. *
  35896. * The first portion of the spec including the pipe symbol '|' is optional.
  35897. * If the pipe option is included than it may be preceded by up to four
  35898. * characters specifying values for the following arguments in order:
  35899. * delimiter (defaults to ',',) enclosure (defaults to '"',) escape (defaults to '"',).
  35900. *
  35901. * Any additional characters in the csv options will be discarded.
  35902. *
  35903. * @package DbUnit
  35904. * @author Mike Lively <m@digitalsandwich.com>
  35905. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35906. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35907. * @version Release: @package_version@
  35908. * @link http://www.phpunit.de/
  35909. * @since Class available since Release 1.0.0
  35910. */
  35911. class PHPUnit_Extensions_Database_DataSet_Specs_Csv implements PHPUnit_Extensions_Database_DataSet_ISpec
  35912. {
  35913. /**
  35914. * Creates CSV Data Set from a data set spec.
  35915. *
  35916. * @param string $dataSetSpec
  35917. * @return PHPUnit_Extensions_Database_DataSet_CsvDataSet
  35918. */
  35919. public function getDataSet($dataSetSpec)
  35920. {
  35921. $csvDataSetArgs = $this->getCsvOptions($dataSetSpec);
  35922. $csvDataSetRfl = new ReflectionClass('PHPUnit_Extensions_Database_DataSet_CsvDataSet');
  35923. $csvDataSet = $csvDataSetRfl->newInstanceArgs($csvDataSetArgs);
  35924. foreach ($this->getTableFileMap($dataSetSpec) as $tableName => $file) {
  35925. $csvDataSet->addTable($tableName, $file);
  35926. }
  35927. return $csvDataSet;
  35928. }
  35929. /**
  35930. * Returns CSV options.
  35931. *
  35932. * Returns an array containing the options that will be passed to the
  35933. * PHPUnit_Extensions_Database_DataSet_CsvDataSet constructor. The options
  35934. * are determined by the given $dataSetSpec.
  35935. *
  35936. * @param string $dataSetSpec
  35937. * @return array
  35938. */
  35939. protected function getCsvOptions($dataSetSpec)
  35940. {
  35941. list($csvOptStr, ) = explode('|', $dataSetSpec, 2);
  35942. return str_split($csvOptStr);
  35943. }
  35944. /**
  35945. * Returns map of tables to files.
  35946. *
  35947. * Returns an associative array containing a mapping of tables (the key)
  35948. * to files (the values.) The tables and files are determined by the given
  35949. * $dataSetSpec
  35950. *
  35951. * @param string $dataSetSpec
  35952. * @return array
  35953. */
  35954. protected function getTableFileMap($dataSetSpec)
  35955. {
  35956. $tables = array();
  35957. foreach (explode(',', $dataSetSpec) as $csvfile) {
  35958. list($tableName, $file) = explode(':', $csvfile, 2);
  35959. $tables[$tableName] = $file;
  35960. }
  35961. return $tables;
  35962. }
  35963. }
  35964. <?php
  35965. /*
  35966. * This file is part of DBUnit.
  35967. *
  35968. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  35969. *
  35970. * For the full copyright and license information, please view the LICENSE
  35971. * file that was distributed with this source code.
  35972. */
  35973. /**
  35974. * Creates a database dataset based off of a spec string.
  35975. *
  35976. * This spec class requires a list of databases to be set to the object before
  35977. * it can return a list of databases.
  35978. *
  35979. * The format of the spec string is as follows:
  35980. *
  35981. * <db label>:<schema>:<tables>
  35982. *
  35983. * The db label should be equal to one of the keys in the array of databases
  35984. * passed to setDatabases().
  35985. *
  35986. * The schema should be the primary schema you will be choosing tables from.
  35987. *
  35988. * The tables should be a comma delimited list of all tables you would like to
  35989. * pull data from.
  35990. *
  35991. * The sql is the query you want to use to generate the table columns and data.
  35992. * The column names in the table will be identical to the column aliases in the
  35993. * query.
  35994. *
  35995. * @package DbUnit
  35996. * @author Mike Lively <m@digitalsandwich.com>
  35997. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  35998. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  35999. * @version Release: @package_version@
  36000. * @link http://www.phpunit.de//**
  36001. * @since Class available since Release 1.0.0
  36002. */
  36003. class PHPUnit_Extensions_Database_DataSet_Specs_DbTable implements PHPUnit_Extensions_Database_DataSet_ISpec, PHPUnit_Extensions_Database_IDatabaseListConsumer
  36004. {
  36005. /**
  36006. * @var array
  36007. */
  36008. protected $databases = array();
  36009. /**
  36010. * Sets the database for the spec
  36011. *
  36012. * @param array $databases
  36013. */
  36014. public function setDatabases(array $databases)
  36015. {
  36016. $this->databases = $databases;
  36017. }
  36018. /**
  36019. * Creates a DB Data Set from a data set spec.
  36020. *
  36021. * @param string $dataSetSpec
  36022. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  36023. */
  36024. public function getDataSet($dataSetSpec)
  36025. {
  36026. list($dbLabel, $schema, $tables) = explode(':', $dataSetSpec, 3);
  36027. $databaseInfo = $this->databases[$dbLabel];
  36028. $pdoRflc = new ReflectionClass('PDO');
  36029. $pdo = $pdoRflc->newInstanceArgs(explode('|', $databaseInfo));
  36030. $dbConnection = new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($pdo, $schema);
  36031. return !empty($tables) ? $dbConnection->createDataSet(explode(',', $tables)) : $dbConnection->createDataSet();
  36032. }
  36033. }
  36034. <?php
  36035. /*
  36036. * This file is part of DBUnit.
  36037. *
  36038. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36039. *
  36040. * For the full copyright and license information, please view the LICENSE
  36041. * file that was distributed with this source code.
  36042. */
  36043. /**
  36044. * Creates the appropriate DataSet Spec based on a given type.
  36045. *
  36046. * @package DbUnit
  36047. * @author Mike Lively <m@digitalsandwich.com>
  36048. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  36049. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36050. * @version Release: @package_version@
  36051. * @link http://www.phpunit.de//**
  36052. * @since Class available since Release 1.0.0
  36053. */
  36054. class PHPUnit_Extensions_Database_DataSet_Specs_Factory implements PHPUnit_Extensions_Database_DataSet_Specs_IFactory
  36055. {
  36056. /**
  36057. * Returns the data set
  36058. *
  36059. * @param string $type
  36060. * @return PHPUnit_Extensions_Database_DataSet_ISpec
  36061. */
  36062. public function getDataSetSpecByType($type)
  36063. {
  36064. switch ($type) {
  36065. case 'xml':
  36066. return new PHPUnit_Extensions_Database_DataSet_Specs_Xml();
  36067. case 'flatxml':
  36068. return new PHPUnit_Extensions_Database_DataSet_Specs_FlatXml();
  36069. case 'csv':
  36070. return new PHPUnit_Extensions_Database_DataSet_Specs_Csv();
  36071. case 'yaml':
  36072. return new PHPUnit_Extensions_Database_DataSet_Specs_Yaml();
  36073. case 'dbtable':
  36074. return new PHPUnit_Extensions_Database_DataSet_Specs_DbTable();
  36075. case 'dbquery':
  36076. return new PHPUnit_Extensions_Database_DataSet_Specs_DbQuery();
  36077. default:
  36078. throw new PHPUnit_Extensions_Database_Exception("I don't know what you want from me.");
  36079. }
  36080. }
  36081. }
  36082. <?php
  36083. /*
  36084. * This file is part of DBUnit.
  36085. *
  36086. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36087. *
  36088. * For the full copyright and license information, please view the LICENSE
  36089. * file that was distributed with this source code.
  36090. */
  36091. /**
  36092. * Provides the functionality to represent a database table.
  36093. *
  36094. * @package DbUnit
  36095. * @author Mike Lively <m@digitalsandwich.com>
  36096. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  36097. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36098. * @version Release: @package_version@
  36099. * @link http://www.phpunit.de/
  36100. * @since Class available since Release 1.0.0
  36101. */
  36102. class PHPUnit_Extensions_Database_DataSet_QueryTable extends PHPUnit_Extensions_Database_DataSet_AbstractTable
  36103. {
  36104. /**
  36105. * @var string
  36106. */
  36107. protected $query;
  36108. /**
  36109. * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection
  36110. */
  36111. protected $databaseConnection;
  36112. /**
  36113. * @var string
  36114. */
  36115. protected $tableName;
  36116. /**
  36117. * Creates a new database query table object.
  36118. *
  36119. * @param string $table_name
  36120. * @param string $query
  36121. * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection
  36122. */
  36123. public function __construct($tableName, $query, PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection)
  36124. {
  36125. $this->query = $query;
  36126. $this->databaseConnection = $databaseConnection;
  36127. $this->tableName = $tableName;
  36128. }
  36129. /**
  36130. * Returns the table's meta data.
  36131. *
  36132. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  36133. */
  36134. public function getTableMetaData()
  36135. {
  36136. $this->createTableMetaData();
  36137. return parent::getTableMetaData();
  36138. }
  36139. /**
  36140. * Checks if a given row is in the table
  36141. *
  36142. * @param array $row
  36143. *
  36144. * @return bool
  36145. */
  36146. public function assertContainsRow(Array $row)
  36147. {
  36148. $this->loadData();
  36149. return parent::assertContainsRow($row);
  36150. }
  36151. /**
  36152. * Returns the number of rows in this table.
  36153. *
  36154. * @return int
  36155. */
  36156. public function getRowCount()
  36157. {
  36158. $this->loadData();
  36159. return parent::getRowCount();
  36160. }
  36161. /**
  36162. * Returns the value for the given column on the given row.
  36163. *
  36164. * @param int $row
  36165. * @param int $column
  36166. */
  36167. public function getValue($row, $column)
  36168. {
  36169. $this->loadData();
  36170. return parent::getValue($row, $column);
  36171. }
  36172. /**
  36173. * Returns the an associative array keyed by columns for the given row.
  36174. *
  36175. * @param int $row
  36176. * @return array
  36177. */
  36178. public function getRow($row)
  36179. {
  36180. $this->loadData();
  36181. return parent::getRow($row);
  36182. }
  36183. /**
  36184. * Asserts that the given table matches this table.
  36185. *
  36186. * @param PHPUnit_Extensions_Database_DataSet_ITable $other
  36187. */
  36188. public function matches(PHPUnit_Extensions_Database_DataSet_ITable $other)
  36189. {
  36190. $this->loadData();
  36191. return parent::matches($other);
  36192. }
  36193. protected function loadData()
  36194. {
  36195. if ($this->data === NULL) {
  36196. $pdoStatement = $this->databaseConnection->getConnection()->query($this->query);
  36197. $this->data = $pdoStatement->fetchAll(PDO::FETCH_ASSOC);
  36198. }
  36199. }
  36200. protected function createTableMetaData()
  36201. {
  36202. if ($this->tableMetaData === NULL)
  36203. {
  36204. $this->loadData();
  36205. // if some rows are in the table
  36206. $columns = array();
  36207. if (isset($this->data[0]))
  36208. // get column names from data
  36209. $columns = array_keys($this->data[0]);
  36210. else {
  36211. // if no rows found, get column names from database
  36212. $pdoStatement = $this->databaseConnection->getConnection()->prepare("SELECT column_name FROM information_schema.COLUMNS WHERE table_schema=:schema AND table_name=:table");
  36213. $pdoStatement->execute(array(
  36214. "table" => $this->tableName,
  36215. "schema" => $this->databaseConnection->getSchema()
  36216. ));
  36217. $columns = $pdoStatement->fetchAll(PDO::FETCH_COLUMN, 0);
  36218. }
  36219. // create metadata
  36220. $this->tableMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($this->tableName, $columns);
  36221. }
  36222. }
  36223. }
  36224. <?php
  36225. /*
  36226. * This file is part of DBUnit.
  36227. *
  36228. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36229. *
  36230. * For the full copyright and license information, please view the LICENSE
  36231. * file that was distributed with this source code.
  36232. */
  36233. /**
  36234. * Provides a basic functionality for dbunit tables
  36235. *
  36236. * @package DbUnit
  36237. * @author Mike Lively <m@digitalsandwich.com>
  36238. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  36239. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36240. * @version Release: @package_version@
  36241. * @link http://www.phpunit.de/
  36242. * @since Class available since Release 1.0.0
  36243. */
  36244. class PHPUnit_Extensions_Database_DataSet_AbstractTable implements PHPUnit_Extensions_Database_DataSet_ITable
  36245. {
  36246. /**
  36247. * @var PHPUnit_Extensions_Database_DataSet_ITableMetaData
  36248. */
  36249. protected $tableMetaData;
  36250. /**
  36251. * A 2-dimensional array containing the data for this table.
  36252. *
  36253. * @var array
  36254. */
  36255. protected $data;
  36256. /**
  36257. * @var PHPUnit_Extensions_Database_DataSet_ITable|null
  36258. */
  36259. private $other;
  36260. /**
  36261. * Sets the metadata for this table.
  36262. *
  36263. * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData
  36264. * @deprecated
  36265. */
  36266. protected function setTableMetaData(PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData)
  36267. {
  36268. $this->tableMetaData = $tableMetaData;
  36269. }
  36270. /**
  36271. * Returns the table's meta data.
  36272. *
  36273. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  36274. */
  36275. public function getTableMetaData()
  36276. {
  36277. return $this->tableMetaData;
  36278. }
  36279. /**
  36280. * Returns the number of rows in this table.
  36281. *
  36282. * @return int
  36283. */
  36284. public function getRowCount()
  36285. {
  36286. return count($this->data);
  36287. }
  36288. /**
  36289. * Returns the value for the given column on the given row.
  36290. *
  36291. * @param int $row
  36292. * @param int $column
  36293. * @todo reorganize this function to throw the exception first.
  36294. */
  36295. public function getValue($row, $column)
  36296. {
  36297. if (isset($this->data[$row][$column])) {
  36298. $value = $this->data[$row][$column];
  36299. return ($value instanceof SimpleXMLElement) ? (string) $value : $value;
  36300. } else {
  36301. if (!in_array($column, $this->getTableMetaData()->getColumns()) || $this->getRowCount() <= $row) {
  36302. throw new InvalidArgumentException("The given row ({$row}) and column ({$column}) do not exist in table {$this->getTableMetaData()->getTableName()}");
  36303. } else {
  36304. return NULL;
  36305. }
  36306. }
  36307. }
  36308. /**
  36309. * Returns the an associative array keyed by columns for the given row.
  36310. *
  36311. * @param int $row
  36312. * @return array
  36313. */
  36314. public function getRow($row)
  36315. {
  36316. if (isset($this->data[$row])) {
  36317. return $this->data[$row];
  36318. } else {
  36319. if ($this->getRowCount() <= $row) {
  36320. throw new InvalidArgumentException("The given row ({$row}) does not exist in table {$this->getTableMetaData()->getTableName()}");
  36321. } else {
  36322. return NULL;
  36323. }
  36324. }
  36325. }
  36326. /**
  36327. * Asserts that the given table matches this table.
  36328. *
  36329. * @param PHPUnit_Extensions_Database_DataSet_ITable $other
  36330. */
  36331. public function matches(PHPUnit_Extensions_Database_DataSet_ITable $other)
  36332. {
  36333. $thisMetaData = $this->getTableMetaData();
  36334. $otherMetaData = $other->getTableMetaData();
  36335. if (!$thisMetaData->matches($otherMetaData) ||
  36336. $this->getRowCount() != $other->getRowCount()) {
  36337. return FALSE;
  36338. }
  36339. $columns = $thisMetaData->getColumns();
  36340. $rowCount = $this->getRowCount();
  36341. for ($i = 0; $i < $rowCount; $i++) {
  36342. foreach ($columns as $columnName) {
  36343. $thisValue = $this->getValue($i, $columnName);
  36344. $otherValue = $other->getValue($i, $columnName);
  36345. if (is_numeric($thisValue) && is_numeric($otherValue)) {
  36346. if ($thisValue != $otherValue) {
  36347. $this->other = $other;
  36348. return FALSE;
  36349. }
  36350. } elseif ($thisValue !== $otherValue) {
  36351. $this->other = $other;
  36352. return FALSE;
  36353. }
  36354. }
  36355. }
  36356. return TRUE;
  36357. }
  36358. /**
  36359. * Checks if a given row is in the table
  36360. *
  36361. * @param array $row
  36362. *
  36363. * @return bool
  36364. */
  36365. public function assertContainsRow(array $row)
  36366. {
  36367. return in_array($row, $this->data);
  36368. }
  36369. public function __toString()
  36370. {
  36371. $columns = $this->getTableMetaData()->getColumns();
  36372. $lineSeperator = str_repeat('+----------------------', count($columns)) . "+\n";
  36373. $lineLength = strlen($lineSeperator) - 1;
  36374. $tableString = $lineSeperator;
  36375. $tableString .= '| ' . str_pad($this->getTableMetaData()->getTableName(), $lineLength - 4, ' ', STR_PAD_RIGHT) . " |\n";
  36376. $tableString .= $lineSeperator;
  36377. $tableString .= $this->rowToString($columns);
  36378. $tableString .= $lineSeperator;
  36379. $rowCount = $this->getRowCount();
  36380. for ($i = 0; $i < $rowCount; $i++) {
  36381. $values = array();
  36382. foreach ($columns as $columnName) {
  36383. if ($this->other) {
  36384. try {
  36385. if ($this->getValue($i, $columnName) != $this->other->getValue($i, $columnName)) {
  36386. $values[] = sprintf(
  36387. '%s != actual %s',
  36388. var_export($this->getValue($i, $columnName), TRUE),
  36389. var_export($this->other->getValue($i, $columnName), TRUE)
  36390. );
  36391. } else {
  36392. $values[] = $this->getValue($i, $columnName);
  36393. }
  36394. } catch (\InvalidArgumentException $ex) {
  36395. $values[] = $this->getValue($i, $columnName) . ': no row';
  36396. }
  36397. } else {
  36398. $values[] = $this->getValue($i, $columnName);
  36399. }
  36400. }
  36401. $tableString .= $this->rowToString($values) . $lineSeperator;
  36402. }
  36403. return ($this->other ? '(table diff enabled)' : '') . "\n" . $tableString . "\n";
  36404. }
  36405. protected function rowToString(Array $row)
  36406. {
  36407. $rowString = '';
  36408. foreach ($row as $value) {
  36409. if (is_null($value)) {
  36410. $value = 'NULL';
  36411. }
  36412. $rowString .= '| ' . str_pad(substr($value, 0, 20), 20, ' ', STR_PAD_BOTH) . ' ';
  36413. }
  36414. return $rowString . "|\n";
  36415. }
  36416. }
  36417. <?php
  36418. /*
  36419. * This file is part of DBUnit.
  36420. *
  36421. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36422. *
  36423. * For the full copyright and license information, please view the LICENSE
  36424. * file that was distributed with this source code.
  36425. */
  36426. /**
  36427. * Provides a basic interface for creating and reading data from data sets.
  36428. *
  36429. * @package DbUnit
  36430. * @author Mike Lively <m@digitalsandwich.com>
  36431. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  36432. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36433. * @version Release: @package_version@
  36434. * @link http://www.phpunit.de/
  36435. * @since Class available since Release 1.0.0
  36436. */
  36437. interface PHPUnit_Extensions_Database_DataSet_ITable
  36438. {
  36439. /**
  36440. * Returns the table's meta data.
  36441. *
  36442. * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData
  36443. */
  36444. public function getTableMetaData();
  36445. /**
  36446. * Returns the number of rows in this table.
  36447. *
  36448. * @return int
  36449. */
  36450. public function getRowCount();
  36451. /**
  36452. * Returns the value for the given column on the given row.
  36453. *
  36454. * @param int $row
  36455. * @param int $column
  36456. */
  36457. public function getValue($row, $column);
  36458. /**
  36459. * Returns the an associative array keyed by columns for the given row.
  36460. *
  36461. * @param int $row
  36462. * @return array
  36463. */
  36464. public function getRow($row);
  36465. /**
  36466. * Asserts that the given table matches this table.
  36467. *
  36468. * @param PHPUnit_Extensions_Database_DataSet_ITable $other
  36469. */
  36470. public function matches(PHPUnit_Extensions_Database_DataSet_ITable $other);
  36471. }
  36472. <?php
  36473. /*
  36474. * This file is part of DBUnit.
  36475. *
  36476. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36477. *
  36478. * For the full copyright and license information, please view the LICENSE
  36479. * file that was distributed with this source code.
  36480. */
  36481. /**
  36482. * The default implementation of table meta data
  36483. *
  36484. * @package DbUnit
  36485. * @author Mike Lively <m@digitalsandwich.com>
  36486. * @copyright 2010-2014 Mike Lively <m@digitalsandwich.com>
  36487. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  36488. * @version Release: @package_version@
  36489. * @link http://www.phpunit.de/
  36490. * @since Class available since Release 1.0.0
  36491. */
  36492. class PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData extends PHPUnit_Extensions_Database_DataSet_AbstractTableMetaData
  36493. {
  36494. /**
  36495. * Creates a new default table meta data object.
  36496. *
  36497. * @param string $tableName
  36498. * @param array $columns
  36499. * @param array $primaryKeys
  36500. */
  36501. public function __construct($tableName, Array $columns, Array $primaryKeys = array())
  36502. {
  36503. $this->tableName = $tableName;
  36504. $this->columns = $columns;
  36505. $this->primaryKeys = array();
  36506. foreach ($primaryKeys as $columnName) {
  36507. if (!in_array($columnName, $this->columns)) {
  36508. throw new InvalidArgumentException("Primary key column passed that is not in the column list.");
  36509. } else {
  36510. $this->primaryKeys[] = $columnName;
  36511. }
  36512. }
  36513. }
  36514. }
  36515. <?php
  36516. /*
  36517. * This file is part of the PHP_Invoker package.
  36518. *
  36519. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36520. *
  36521. * For the full copyright and license information, please view the LICENSE
  36522. * file that was distributed with this source code.
  36523. */
  36524. declare(ticks = 1);
  36525. /**
  36526. * Utility class for invoking callables with a timeout.
  36527. *
  36528. * @since Class available since Release 1.0.0
  36529. */
  36530. class PHP_Invoker
  36531. {
  36532. /**
  36533. * @var int
  36534. */
  36535. protected $timeout;
  36536. /**
  36537. * Invokes a callable and raises an exception when the execution does not
  36538. * finish before the specified timeout.
  36539. *
  36540. * @param callable $callable
  36541. * @param array $arguments
  36542. * @param int $timeout in seconds
  36543. * @return mixed
  36544. * @throws InvalidArgumentException
  36545. */
  36546. public function invoke($callable, array $arguments, $timeout)
  36547. {
  36548. if (!is_callable($callable)) {
  36549. throw new InvalidArgumentException;
  36550. }
  36551. if (!is_integer($timeout)) {
  36552. throw new InvalidArgumentException;
  36553. }
  36554. pcntl_signal(SIGALRM, array($this, 'callback'), TRUE);
  36555. pcntl_alarm($timeout);
  36556. $this->timeout = $timeout;
  36557. try {
  36558. $result = call_user_func_array($callable, $arguments);
  36559. }
  36560. catch (Exception $e) {
  36561. pcntl_alarm(0);
  36562. throw $e;
  36563. }
  36564. pcntl_alarm(0);
  36565. return $result;
  36566. }
  36567. /**
  36568. * Invoked by pcntl_signal() when a SIGALRM occurs.
  36569. */
  36570. public function callback()
  36571. {
  36572. throw new PHP_Invoker_TimeoutException(
  36573. sprintf(
  36574. 'Execution aborted after %s',
  36575. PHP_Timer::secondsToTimeString($this->timeout)
  36576. )
  36577. );
  36578. }
  36579. }
  36580. <?php
  36581. /*
  36582. * This file is part of the PHP_Invoker package.
  36583. *
  36584. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36585. *
  36586. * For the full copyright and license information, please view the LICENSE
  36587. * file that was distributed with this source code.
  36588. */
  36589. /**
  36590. * @since Class available since Release 1.0.0
  36591. */
  36592. class PHP_Invoker_TimeoutException extends RuntimeException
  36593. {
  36594. }
  36595. PHPUnit_MockObject
  36596. Copyright (c) 2002-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  36597. All rights reserved.
  36598. Redistribution and use in source and binary forms, with or without
  36599. modification, are permitted provided that the following conditions
  36600. are met:
  36601. * Redistributions of source code must retain the above copyright
  36602. notice, this list of conditions and the following disclaimer.
  36603. * Redistributions in binary form must reproduce the above copyright
  36604. notice, this list of conditions and the following disclaimer in
  36605. the documentation and/or other materials provided with the
  36606. distribution.
  36607. * Neither the name of Sebastian Bergmann nor the names of his
  36608. contributors may be used to endorse or promote products derived
  36609. from this software without specific prior written permission.
  36610. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  36611. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  36612. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  36613. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  36614. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  36615. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  36616. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36617. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  36618. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36619. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  36620. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36621. POSSIBILITY OF SUCH DAMAGE.
  36622. <?php
  36623. /*
  36624. * This file is part of the PHPUnit_MockObject package.
  36625. *
  36626. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36627. *
  36628. * For the full copyright and license information, please view the LICENSE
  36629. * file that was distributed with this source code.
  36630. */
  36631. /**
  36632. * Main matcher which defines a full expectation using method, parameter and
  36633. * invocation matchers.
  36634. * This matcher encapsulates all the other matchers and allows the builder to
  36635. * set the specific matchers when the appropriate methods are called (once(),
  36636. * where() etc.).
  36637. *
  36638. * All properties are public so that they can easily be accessed by the builder.
  36639. *
  36640. * @since Class available since Release 1.0.0
  36641. */
  36642. class PHPUnit_Framework_MockObject_Matcher implements PHPUnit_Framework_MockObject_Matcher_Invocation
  36643. {
  36644. /**
  36645. * @var PHPUnit_Framework_MockObject_Matcher_Invocation
  36646. */
  36647. public $invocationMatcher;
  36648. /**
  36649. * @var mixed
  36650. */
  36651. public $afterMatchBuilderId = null;
  36652. /**
  36653. * @var bool
  36654. */
  36655. public $afterMatchBuilderIsInvoked = false;
  36656. /**
  36657. * @var PHPUnit_Framework_MockObject_Matcher_MethodName
  36658. */
  36659. public $methodNameMatcher = null;
  36660. /**
  36661. * @var PHPUnit_Framework_MockObject_Matcher_Parameters
  36662. */
  36663. public $parametersMatcher = null;
  36664. /**
  36665. * @var PHPUnit_Framework_MockObject_Stub
  36666. */
  36667. public $stub = null;
  36668. /**
  36669. * @param PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher
  36670. */
  36671. public function __construct(PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher)
  36672. {
  36673. $this->invocationMatcher = $invocationMatcher;
  36674. }
  36675. /**
  36676. * @return string
  36677. */
  36678. public function toString()
  36679. {
  36680. $list = array();
  36681. if ($this->invocationMatcher !== null) {
  36682. $list[] = $this->invocationMatcher->toString();
  36683. }
  36684. if ($this->methodNameMatcher !== null) {
  36685. $list[] = 'where ' . $this->methodNameMatcher->toString();
  36686. }
  36687. if ($this->parametersMatcher !== null) {
  36688. $list[] = 'and ' . $this->parametersMatcher->toString();
  36689. }
  36690. if ($this->afterMatchBuilderId !== null) {
  36691. $list[] = 'after ' . $this->afterMatchBuilderId;
  36692. }
  36693. if ($this->stub !== null) {
  36694. $list[] = 'will ' . $this->stub->toString();
  36695. }
  36696. return implode(' ', $list);
  36697. }
  36698. /**
  36699. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  36700. * @return mixed
  36701. */
  36702. public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation)
  36703. {
  36704. if ($this->invocationMatcher === null) {
  36705. throw new PHPUnit_Framework_Exception(
  36706. 'No invocation matcher is set'
  36707. );
  36708. }
  36709. if ($this->methodNameMatcher === null) {
  36710. throw new PHPUnit_Framework_Exception('No method matcher is set');
  36711. }
  36712. if ($this->afterMatchBuilderId !== null) {
  36713. $builder = $invocation->object
  36714. ->__phpunit_getInvocationMocker()
  36715. ->lookupId($this->afterMatchBuilderId);
  36716. if (!$builder) {
  36717. throw new PHPUnit_Framework_Exception(
  36718. sprintf(
  36719. 'No builder found for match builder identification <%s>',
  36720. $this->afterMatchBuilderId
  36721. )
  36722. );
  36723. }
  36724. $matcher = $builder->getMatcher();
  36725. if ($matcher && $matcher->invocationMatcher->hasBeenInvoked()) {
  36726. $this->afterMatchBuilderIsInvoked = true;
  36727. }
  36728. }
  36729. $this->invocationMatcher->invoked($invocation);
  36730. try {
  36731. if ($this->parametersMatcher !== null &&
  36732. !$this->parametersMatcher->matches($invocation)) {
  36733. $this->parametersMatcher->verify();
  36734. }
  36735. } catch (PHPUnit_Framework_ExpectationFailedException $e) {
  36736. throw new PHPUnit_Framework_ExpectationFailedException(
  36737. sprintf(
  36738. "Expectation failed for %s when %s\n%s",
  36739. $this->methodNameMatcher->toString(),
  36740. $this->invocationMatcher->toString(),
  36741. $e->getMessage()
  36742. ),
  36743. $e->getComparisonFailure()
  36744. );
  36745. }
  36746. if ($this->stub) {
  36747. return $this->stub->invoke($invocation);
  36748. }
  36749. return;
  36750. }
  36751. /**
  36752. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  36753. * @return bool
  36754. */
  36755. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
  36756. {
  36757. if ($this->afterMatchBuilderId !== null) {
  36758. $builder = $invocation->object
  36759. ->__phpunit_getInvocationMocker()
  36760. ->lookupId($this->afterMatchBuilderId);
  36761. if (!$builder) {
  36762. throw new PHPUnit_Framework_Exception(
  36763. sprintf(
  36764. 'No builder found for match builder identification <%s>',
  36765. $this->afterMatchBuilderId
  36766. )
  36767. );
  36768. }
  36769. $matcher = $builder->getMatcher();
  36770. if (!$matcher) {
  36771. return false;
  36772. }
  36773. if (!$matcher->invocationMatcher->hasBeenInvoked()) {
  36774. return false;
  36775. }
  36776. }
  36777. if ($this->invocationMatcher === null) {
  36778. throw new PHPUnit_Framework_Exception(
  36779. 'No invocation matcher is set'
  36780. );
  36781. }
  36782. if ($this->methodNameMatcher === null) {
  36783. throw new PHPUnit_Framework_Exception('No method matcher is set');
  36784. }
  36785. if (!$this->invocationMatcher->matches($invocation)) {
  36786. return false;
  36787. }
  36788. try {
  36789. if (!$this->methodNameMatcher->matches($invocation)) {
  36790. return false;
  36791. }
  36792. } catch (PHPUnit_Framework_ExpectationFailedException $e) {
  36793. throw new PHPUnit_Framework_ExpectationFailedException(
  36794. sprintf(
  36795. "Expectation failed for %s when %s\n%s",
  36796. $this->methodNameMatcher->toString(),
  36797. $this->invocationMatcher->toString(),
  36798. $e->getMessage()
  36799. ),
  36800. $e->getComparisonFailure()
  36801. );
  36802. }
  36803. return true;
  36804. }
  36805. /**
  36806. * @throws PHPUnit_Framework_Exception
  36807. * @throws PHPUnit_Framework_ExpectationFailedException
  36808. */
  36809. public function verify()
  36810. {
  36811. if ($this->invocationMatcher === null) {
  36812. throw new PHPUnit_Framework_Exception(
  36813. 'No invocation matcher is set'
  36814. );
  36815. }
  36816. if ($this->methodNameMatcher === null) {
  36817. throw new PHPUnit_Framework_Exception('No method matcher is set');
  36818. }
  36819. try {
  36820. $this->invocationMatcher->verify();
  36821. if ($this->parametersMatcher === null) {
  36822. $this->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_AnyParameters;
  36823. }
  36824. $invocationIsAny = get_class($this->invocationMatcher) === 'PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount';
  36825. $invocationIsNever = get_class($this->invocationMatcher) === 'PHPUnit_Framework_MockObject_Matcher_InvokedCount' && $this->invocationMatcher->isNever();
  36826. if (!$invocationIsAny && !$invocationIsNever) {
  36827. $this->parametersMatcher->verify();
  36828. }
  36829. } catch (PHPUnit_Framework_ExpectationFailedException $e) {
  36830. throw new PHPUnit_Framework_ExpectationFailedException(
  36831. sprintf(
  36832. "Expectation failed for %s when %s.\n%s",
  36833. $this->methodNameMatcher->toString(),
  36834. $this->invocationMatcher->toString(),
  36835. PHPUnit_Framework_TestFailure::exceptionToString($e)
  36836. )
  36837. );
  36838. }
  36839. }
  36840. /**
  36841. * @since Method available since Release 1.2.4
  36842. */
  36843. public function hasMatchers()
  36844. {
  36845. if ($this->invocationMatcher !== null &&
  36846. !$this->invocationMatcher instanceof PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount) {
  36847. return true;
  36848. }
  36849. return false;
  36850. }
  36851. }
  36852. <?php
  36853. /*
  36854. * This file is part of the PHPUnit_MockObject package.
  36855. *
  36856. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36857. *
  36858. * For the full copyright and license information, please view the LICENSE
  36859. * file that was distributed with this source code.
  36860. */
  36861. /**
  36862. * Interface for classes which must verify a given expectation.
  36863. *
  36864. * @since Interface available since Release 1.0.0
  36865. */
  36866. interface PHPUnit_Framework_MockObject_Verifiable
  36867. {
  36868. /**
  36869. * Verifies that the current expectation is valid. If everything is OK the
  36870. * code should just return, if not it must throw an exception.
  36871. *
  36872. * @throws PHPUnit_Framework_ExpectationFailedException
  36873. */
  36874. public function verify();
  36875. }
  36876. <?php
  36877. /*
  36878. * This file is part of the PHPUnit_MockObject package.
  36879. *
  36880. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36881. *
  36882. * For the full copyright and license information, please view the LICENSE
  36883. * file that was distributed with this source code.
  36884. */
  36885. /**
  36886. * Interface for classes which can be invoked.
  36887. *
  36888. * The invocation will be taken from a mock object and passed to an object
  36889. * of this class.
  36890. *
  36891. * @since Interface available since Release 1.0.0
  36892. */
  36893. interface PHPUnit_Framework_MockObject_Invokable extends PHPUnit_Framework_MockObject_Verifiable
  36894. {
  36895. /**
  36896. * Invokes the invocation object $invocation so that it can be checked for
  36897. * expectations or matched against stubs.
  36898. *
  36899. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  36900. * The invocation object passed from mock object.
  36901. * @return object
  36902. */
  36903. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation);
  36904. /**
  36905. * Checks if the invocation matches.
  36906. *
  36907. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  36908. * The invocation object passed from mock object.
  36909. * @return bool
  36910. */
  36911. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation);
  36912. }
  36913. <?php
  36914. /*
  36915. * This file is part of the PHPUnit_MockObject package.
  36916. *
  36917. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  36918. *
  36919. * For the full copyright and license information, please view the LICENSE
  36920. * file that was distributed with this source code.
  36921. */
  36922. /**
  36923. * Implementation of the Builder pattern for Mock objects.
  36924. *
  36925. * @since File available since Release 1.0.0
  36926. */
  36927. class PHPUnit_Framework_MockObject_MockBuilder
  36928. {
  36929. /**
  36930. * @var PHPUnit_Framework_TestCase
  36931. */
  36932. private $testCase;
  36933. /**
  36934. * @var string
  36935. */
  36936. private $type;
  36937. /**
  36938. * @var array
  36939. */
  36940. private $methods = array();
  36941. /**
  36942. * @var string
  36943. */
  36944. private $mockClassName = '';
  36945. /**
  36946. * @var array
  36947. */
  36948. private $constructorArgs = array();
  36949. /**
  36950. * @var bool
  36951. */
  36952. private $originalConstructor = true;
  36953. /**
  36954. * @var bool
  36955. */
  36956. private $originalClone = true;
  36957. /**
  36958. * @var bool
  36959. */
  36960. private $autoload = true;
  36961. /**
  36962. * @var bool
  36963. */
  36964. private $cloneArguments = false;
  36965. /**
  36966. * @var bool
  36967. */
  36968. private $callOriginalMethods = false;
  36969. /**
  36970. * @var object
  36971. */
  36972. private $proxyTarget = null;
  36973. /**
  36974. * @param PHPUnit_Framework_TestCase $testCase
  36975. * @param array|string $type
  36976. */
  36977. public function __construct(PHPUnit_Framework_TestCase $testCase, $type)
  36978. {
  36979. $this->testCase = $testCase;
  36980. $this->type = $type;
  36981. }
  36982. /**
  36983. * Creates a mock object using a fluent interface.
  36984. *
  36985. * @return PHPUnit_Framework_MockObject_MockObject
  36986. */
  36987. public function getMock()
  36988. {
  36989. return $this->testCase->getMock(
  36990. $this->type,
  36991. $this->methods,
  36992. $this->constructorArgs,
  36993. $this->mockClassName,
  36994. $this->originalConstructor,
  36995. $this->originalClone,
  36996. $this->autoload,
  36997. $this->cloneArguments,
  36998. $this->callOriginalMethods,
  36999. $this->proxyTarget
  37000. );
  37001. }
  37002. /**
  37003. * Creates a mock object for an abstract class using a fluent interface.
  37004. *
  37005. * @return PHPUnit_Framework_MockObject_MockObject
  37006. */
  37007. public function getMockForAbstractClass()
  37008. {
  37009. return $this->testCase->getMockForAbstractClass(
  37010. $this->type,
  37011. $this->constructorArgs,
  37012. $this->mockClassName,
  37013. $this->originalConstructor,
  37014. $this->originalClone,
  37015. $this->autoload,
  37016. $this->methods,
  37017. $this->cloneArguments
  37018. );
  37019. }
  37020. /**
  37021. * Creates a mock object for a trait using a fluent interface.
  37022. *
  37023. * @return PHPUnit_Framework_MockObject_MockObject
  37024. */
  37025. public function getMockForTrait()
  37026. {
  37027. return $this->testCase->getMockForTrait(
  37028. $this->type,
  37029. $this->constructorArgs,
  37030. $this->mockClassName,
  37031. $this->originalConstructor,
  37032. $this->originalClone,
  37033. $this->autoload,
  37034. $this->methods,
  37035. $this->cloneArguments
  37036. );
  37037. }
  37038. /**
  37039. * Specifies the subset of methods to mock. Default is to mock all of them.
  37040. *
  37041. * @param array|null $methods
  37042. * @return PHPUnit_Framework_MockObject_MockBuilder
  37043. */
  37044. public function setMethods($methods)
  37045. {
  37046. $this->methods = $methods;
  37047. return $this;
  37048. }
  37049. /**
  37050. * Specifies the arguments for the constructor.
  37051. *
  37052. * @param array $args
  37053. * @return PHPUnit_Framework_MockObject_MockBuilder
  37054. */
  37055. public function setConstructorArgs(array $args)
  37056. {
  37057. $this->constructorArgs = $args;
  37058. return $this;
  37059. }
  37060. /**
  37061. * Specifies the name for the mock class.
  37062. *
  37063. * @param string $name
  37064. * @return PHPUnit_Framework_MockObject_MockBuilder
  37065. */
  37066. public function setMockClassName($name)
  37067. {
  37068. $this->mockClassName = $name;
  37069. return $this;
  37070. }
  37071. /**
  37072. * Disables the invocation of the original constructor.
  37073. *
  37074. * @return PHPUnit_Framework_MockObject_MockBuilder
  37075. */
  37076. public function disableOriginalConstructor()
  37077. {
  37078. $this->originalConstructor = false;
  37079. return $this;
  37080. }
  37081. /**
  37082. * Enables the invocation of the original constructor.
  37083. *
  37084. * @return PHPUnit_Framework_MockObject_MockBuilder
  37085. * @since Method available since Release 1.2.0
  37086. */
  37087. public function enableOriginalConstructor()
  37088. {
  37089. $this->originalConstructor = true;
  37090. return $this;
  37091. }
  37092. /**
  37093. * Disables the invocation of the original clone constructor.
  37094. *
  37095. * @return PHPUnit_Framework_MockObject_MockBuilder
  37096. */
  37097. public function disableOriginalClone()
  37098. {
  37099. $this->originalClone = false;
  37100. return $this;
  37101. }
  37102. /**
  37103. * Enables the invocation of the original clone constructor.
  37104. *
  37105. * @return PHPUnit_Framework_MockObject_MockBuilder
  37106. * @since Method available since Release 1.2.0
  37107. */
  37108. public function enableOriginalClone()
  37109. {
  37110. $this->originalClone = true;
  37111. return $this;
  37112. }
  37113. /**
  37114. * Disables the use of class autoloading while creating the mock object.
  37115. *
  37116. * @return PHPUnit_Framework_MockObject_MockBuilder
  37117. */
  37118. public function disableAutoload()
  37119. {
  37120. $this->autoload = false;
  37121. return $this;
  37122. }
  37123. /**
  37124. * Enables the use of class autoloading while creating the mock object.
  37125. *
  37126. * @return PHPUnit_Framework_MockObject_MockBuilder
  37127. * @since Method available since Release 1.2.0
  37128. */
  37129. public function enableAutoload()
  37130. {
  37131. $this->autoload = true;
  37132. return $this;
  37133. }
  37134. /**
  37135. * Disables the cloning of arguments passed to mocked methods.
  37136. *
  37137. * @return PHPUnit_Framework_MockObject_MockBuilder
  37138. * @since Method available since Release 1.2.0
  37139. */
  37140. public function disableArgumentCloning()
  37141. {
  37142. $this->cloneArguments = false;
  37143. return $this;
  37144. }
  37145. /**
  37146. * Enables the cloning of arguments passed to mocked methods.
  37147. *
  37148. * @return PHPUnit_Framework_MockObject_MockBuilder
  37149. * @since Method available since Release 1.2.0
  37150. */
  37151. public function enableArgumentCloning()
  37152. {
  37153. $this->cloneArguments = true;
  37154. return $this;
  37155. }
  37156. /**
  37157. * Enables the invocation of the original methods.
  37158. *
  37159. * @return PHPUnit_Framework_MockObject_MockBuilder
  37160. * @since Method available since Release 2.0.0
  37161. */
  37162. public function enableProxyingToOriginalMethods()
  37163. {
  37164. $this->callOriginalMethods = true;
  37165. return $this;
  37166. }
  37167. /**
  37168. * Disables the invocation of the original methods.
  37169. *
  37170. * @return PHPUnit_Framework_MockObject_MockBuilder
  37171. * @since Method available since Release 2.0.0
  37172. */
  37173. public function disableProxyingToOriginalMethods()
  37174. {
  37175. $this->callOriginalMethods = false;
  37176. $this->proxyTarget = null;
  37177. return $this;
  37178. }
  37179. /**
  37180. * Sets the proxy target.
  37181. *
  37182. * @param object $object
  37183. * @return PHPUnit_Framework_MockObject_MockBuilder
  37184. * @since Method available since Release 2.0.0
  37185. */
  37186. public function setProxyTarget($object)
  37187. {
  37188. $this->proxyTarget = $object;
  37189. return $this;
  37190. }
  37191. }
  37192. <?php
  37193. /*
  37194. * This file is part of the PHPUnit_MockObject package.
  37195. *
  37196. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37197. *
  37198. * For the full copyright and license information, please view the LICENSE
  37199. * file that was distributed with this source code.
  37200. */
  37201. /**
  37202. * Interface for exceptions used by PHPUnit_MockObject.
  37203. *
  37204. * @since Interface available since Release 2.0.6
  37205. */
  37206. interface PHPUnit_Framework_MockObject_Exception
  37207. {
  37208. }
  37209. <?php
  37210. /*
  37211. * This file is part of the PHPUnit_MockObject package.
  37212. *
  37213. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37214. *
  37215. * For the full copyright and license information, please view the LICENSE
  37216. * file that was distributed with this source code.
  37217. */
  37218. /**
  37219. * @since Class available since Release 2.0.6
  37220. */
  37221. class PHPUnit_Framework_MockObject_BadMethodCallException extends BadMethodCallException implements PHPUnit_Framework_MockObject_Exception
  37222. {
  37223. }
  37224. <?php
  37225. /*
  37226. * This file is part of the PHPUnit_MockObject package.
  37227. *
  37228. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37229. *
  37230. * For the full copyright and license information, please view the LICENSE
  37231. * file that was distributed with this source code.
  37232. */
  37233. /**
  37234. * @since Class available since Release 2.0.6
  37235. */
  37236. class PHPUnit_Framework_MockObject_RuntimeException extends RuntimeException implements PHPUnit_Framework_MockObject_Exception
  37237. {
  37238. }
  37239. <?php
  37240. /*
  37241. * This file is part of the PHPUnit_MockObject package.
  37242. *
  37243. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37244. *
  37245. * For the full copyright and license information, please view the LICENSE
  37246. * file that was distributed with this source code.
  37247. */
  37248. /**
  37249. * Interface for invocations.
  37250. *
  37251. * @since Interface available since Release 1.0.0
  37252. */
  37253. interface PHPUnit_Framework_MockObject_Invocation
  37254. {
  37255. }
  37256. <?php
  37257. /*
  37258. * This file is part of the PHPUnit_MockObject package.
  37259. *
  37260. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37261. *
  37262. * For the full copyright and license information, please view the LICENSE
  37263. * file that was distributed with this source code.
  37264. */
  37265. /**
  37266. * Interface for all mock objects which are generated by
  37267. * PHPUnit_Framework_MockObject_MockBuilder.
  37268. *
  37269. * @method PHPUnit_Framework_MockObject_Builder_InvocationMocker method($constraint)
  37270. * @since Interface available since Release 1.0.0
  37271. */
  37272. interface PHPUnit_Framework_MockObject_MockObject /*extends PHPUnit_Framework_MockObject_Verifiable*/
  37273. {
  37274. /**
  37275. * Registers a new expectation in the mock object and returns the match
  37276. * object which can be infused with further details.
  37277. *
  37278. * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher
  37279. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  37280. */
  37281. public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher);
  37282. /**
  37283. * @return PHPUnit_Framework_MockObject_InvocationMocker
  37284. * @since Method available since Release 2.0.0
  37285. */
  37286. public function __phpunit_setOriginalObject($originalObject);
  37287. /**
  37288. * @return PHPUnit_Framework_MockObject_InvocationMocker
  37289. */
  37290. public function __phpunit_getInvocationMocker();
  37291. /**
  37292. * Verifies that the current expectation is valid. If everything is OK the
  37293. * code should just return, if not it must throw an exception.
  37294. *
  37295. * @throws PHPUnit_Framework_ExpectationFailedException
  37296. */
  37297. public function __phpunit_verify();
  37298. }
  37299. <?php
  37300. /*
  37301. * This file is part of the PHPUnit_MockObject package.
  37302. *
  37303. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37304. *
  37305. * For the full copyright and license information, please view the LICENSE
  37306. * file that was distributed with this source code.
  37307. */
  37308. /**
  37309. * Mocker for invocations which are sent from
  37310. * PHPUnit_Framework_MockObject_MockObject objects.
  37311. *
  37312. * Keeps track of all expectations and stubs as well as registering
  37313. * identifications for builders.
  37314. *
  37315. * @since Class available since Release 1.0.0
  37316. */
  37317. class PHPUnit_Framework_MockObject_InvocationMocker implements PHPUnit_Framework_MockObject_Stub_MatcherCollection, PHPUnit_Framework_MockObject_Invokable, PHPUnit_Framework_MockObject_Builder_Namespace
  37318. {
  37319. /**
  37320. * @var PHPUnit_Framework_MockObject_Matcher_Invocation[]
  37321. */
  37322. protected $matchers = array();
  37323. /**
  37324. * @var PHPUnit_Framework_MockObject_Builder_Match[]
  37325. */
  37326. protected $builderMap = array();
  37327. /**
  37328. * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher
  37329. */
  37330. public function addMatcher(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
  37331. {
  37332. $this->matchers[] = $matcher;
  37333. }
  37334. /**
  37335. * @since Method available since Release 1.1.0
  37336. */
  37337. public function hasMatchers()
  37338. {
  37339. foreach ($this->matchers as $matcher) {
  37340. if ($matcher->hasMatchers()) {
  37341. return true;
  37342. }
  37343. }
  37344. return false;
  37345. }
  37346. /**
  37347. * @param mixed $id
  37348. * @return bool|null
  37349. */
  37350. public function lookupId($id)
  37351. {
  37352. if (isset($this->builderMap[$id])) {
  37353. return $this->builderMap[$id];
  37354. }
  37355. return;
  37356. }
  37357. /**
  37358. * @param mixed $id
  37359. * @param PHPUnit_Framework_MockObject_Builder_Match $builder
  37360. * @throws PHPUnit_Framework_Exception
  37361. */
  37362. public function registerId($id, PHPUnit_Framework_MockObject_Builder_Match $builder)
  37363. {
  37364. if (isset($this->builderMap[$id])) {
  37365. throw new PHPUnit_Framework_Exception(
  37366. 'Match builder with id <' . $id . '> is already registered.'
  37367. );
  37368. }
  37369. $this->builderMap[$id] = $builder;
  37370. }
  37371. /**
  37372. * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher
  37373. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  37374. */
  37375. public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
  37376. {
  37377. return new PHPUnit_Framework_MockObject_Builder_InvocationMocker(
  37378. $this,
  37379. $matcher
  37380. );
  37381. }
  37382. /**
  37383. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37384. * @return mixed
  37385. */
  37386. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
  37387. {
  37388. $exception = null;
  37389. $hasReturnValue = false;
  37390. if (strtolower($invocation->methodName) == '__tostring') {
  37391. $returnValue = '';
  37392. } else {
  37393. $returnValue = null;
  37394. }
  37395. foreach ($this->matchers as $match) {
  37396. try {
  37397. if ($match->matches($invocation)) {
  37398. $value = $match->invoked($invocation);
  37399. if (!$hasReturnValue) {
  37400. $returnValue = $value;
  37401. $hasReturnValue = true;
  37402. }
  37403. }
  37404. } catch (Exception $e) {
  37405. $exception = $e;
  37406. }
  37407. }
  37408. if ($exception !== null) {
  37409. throw $exception;
  37410. }
  37411. return $returnValue;
  37412. }
  37413. /**
  37414. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37415. * @return bool
  37416. */
  37417. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
  37418. {
  37419. foreach ($this->matchers as $matcher) {
  37420. if (!$matcher->matches($invocation)) {
  37421. return false;
  37422. }
  37423. }
  37424. return true;
  37425. }
  37426. /**
  37427. * @return bool
  37428. */
  37429. public function verify()
  37430. {
  37431. foreach ($this->matchers as $matcher) {
  37432. $matcher->verify();
  37433. }
  37434. }
  37435. }
  37436. <?php
  37437. /*
  37438. * This file is part of the PHPUnit_MockObject package.
  37439. *
  37440. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37441. *
  37442. * For the full copyright and license information, please view the LICENSE
  37443. * file that was distributed with this source code.
  37444. */
  37445. /**
  37446. * Invocation matcher which looks for a specific method name in the invocations.
  37447. *
  37448. * Checks the method name all incoming invocations, the name is checked against
  37449. * the defined constraint $constraint. If the constraint is met it will return
  37450. * true in matches().
  37451. *
  37452. * @since Class available since Release 1.0.0
  37453. */
  37454. class PHPUnit_Framework_MockObject_Matcher_MethodName extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation
  37455. {
  37456. /**
  37457. * @var PHPUnit_Framework_Constraint
  37458. */
  37459. protected $constraint;
  37460. /**
  37461. * @param PHPUnit_Framework_Constraint|string
  37462. * @throws PHPUnit_Framework_Constraint
  37463. */
  37464. public function __construct($constraint)
  37465. {
  37466. if (!$constraint instanceof PHPUnit_Framework_Constraint) {
  37467. if (!is_string($constraint)) {
  37468. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  37469. }
  37470. $constraint = new PHPUnit_Framework_Constraint_IsEqual(
  37471. $constraint,
  37472. 0,
  37473. 10,
  37474. false,
  37475. true
  37476. );
  37477. }
  37478. $this->constraint = $constraint;
  37479. }
  37480. /**
  37481. * @return string
  37482. */
  37483. public function toString()
  37484. {
  37485. return 'method name ' . $this->constraint->toString();
  37486. }
  37487. /**
  37488. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37489. * @return bool
  37490. */
  37491. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
  37492. {
  37493. return $this->constraint->evaluate($invocation->methodName, '', true);
  37494. }
  37495. }
  37496. <?php
  37497. /*
  37498. * This file is part of the PHPUnit_MockObject package.
  37499. *
  37500. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37501. *
  37502. * For the full copyright and license information, please view the LICENSE
  37503. * file that was distributed with this source code.
  37504. */
  37505. /**
  37506. * Invocation matcher which checks if a method has been invoked at least one
  37507. * time.
  37508. *
  37509. * If the number of invocations is 0 it will throw an exception in verify.
  37510. *
  37511. * @since Class available since Release 1.0.0
  37512. */
  37513. class PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
  37514. {
  37515. /**
  37516. * @return string
  37517. */
  37518. public function toString()
  37519. {
  37520. return 'invoked at least once';
  37521. }
  37522. /**
  37523. * Verifies that the current expectation is valid. If everything is OK the
  37524. * code should just return, if not it must throw an exception.
  37525. *
  37526. * @throws PHPUnit_Framework_ExpectationFailedException
  37527. */
  37528. public function verify()
  37529. {
  37530. $count = $this->getInvocationCount();
  37531. if ($count < 1) {
  37532. throw new PHPUnit_Framework_ExpectationFailedException(
  37533. 'Expected invocation at least once but it never occured.'
  37534. );
  37535. }
  37536. }
  37537. }
  37538. <?php
  37539. /*
  37540. * This file is part of the PHPUnit_MockObject package.
  37541. *
  37542. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37543. *
  37544. * For the full copyright and license information, please view the LICENSE
  37545. * file that was distributed with this source code.
  37546. */
  37547. /**
  37548. * Invocation matcher which allows any parameters to a method.
  37549. *
  37550. * @since Class available since Release 1.0.0
  37551. */
  37552. class PHPUnit_Framework_MockObject_Matcher_AnyParameters extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation
  37553. {
  37554. /**
  37555. * @return string
  37556. */
  37557. public function toString()
  37558. {
  37559. return 'with any parameters';
  37560. }
  37561. /**
  37562. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37563. * @return bool
  37564. */
  37565. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
  37566. {
  37567. return true;
  37568. }
  37569. }
  37570. <?php
  37571. /*
  37572. * This file is part of the PHPUnit_MockObject package.
  37573. *
  37574. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37575. *
  37576. * For the full copyright and license information, please view the LICENSE
  37577. * file that was distributed with this source code.
  37578. */
  37579. /**
  37580. * Invocation matcher which looks for specific parameters in the invocations.
  37581. *
  37582. * Checks the parameters of all incoming invocations, the parameter list is
  37583. * checked against the defined constraints in $parameters. If the constraint
  37584. * is met it will return true in matches().
  37585. *
  37586. * @since Class available since Release 1.0.0
  37587. */
  37588. class PHPUnit_Framework_MockObject_Matcher_Parameters extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation
  37589. {
  37590. /**
  37591. * @var PHPUnit_Framework_Constraint[]
  37592. */
  37593. protected $parameters = array();
  37594. /**
  37595. * @var PHPUnit_Framework_MockObject_Invocation
  37596. */
  37597. protected $invocation;
  37598. /**
  37599. * @param array $parameters
  37600. */
  37601. public function __construct(array $parameters)
  37602. {
  37603. foreach ($parameters as $parameter) {
  37604. if (!($parameter instanceof PHPUnit_Framework_Constraint)) {
  37605. $parameter = new PHPUnit_Framework_Constraint_IsEqual(
  37606. $parameter
  37607. );
  37608. }
  37609. $this->parameters[] = $parameter;
  37610. }
  37611. }
  37612. /**
  37613. * @return string
  37614. */
  37615. public function toString()
  37616. {
  37617. $text = 'with parameter';
  37618. foreach ($this->parameters as $index => $parameter) {
  37619. if ($index > 0) {
  37620. $text .= ' and';
  37621. }
  37622. $text .= ' ' . $index . ' ' . $parameter->toString();
  37623. }
  37624. return $text;
  37625. }
  37626. /**
  37627. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37628. * @return bool
  37629. */
  37630. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
  37631. {
  37632. $this->invocation = $invocation;
  37633. return $this->verify();
  37634. }
  37635. /**
  37636. * Checks if the invocation $invocation matches the current rules. If it
  37637. * does the matcher will get the invoked() method called which should check
  37638. * if an expectation is met.
  37639. *
  37640. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37641. * Object containing information on a mocked or stubbed method which
  37642. * was invoked.
  37643. * @return bool
  37644. * @throws PHPUnit_Framework_ExpectationFailedException
  37645. */
  37646. public function verify()
  37647. {
  37648. if ($this->invocation === null) {
  37649. throw new PHPUnit_Framework_ExpectationFailedException(
  37650. 'Mocked method does not exist.'
  37651. );
  37652. }
  37653. if (count($this->invocation->parameters) < count($this->parameters)) {
  37654. $message = 'Parameter count for invocation %s is too low.';
  37655. // The user called `->with($this->anything())`, but may have meant
  37656. // `->withAnyParameters()`.
  37657. //
  37658. // @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/199
  37659. if (count($this->parameters) === 1 &&
  37660. get_class($this->parameters[0]) === 'PHPUnit_Framework_Constraint_IsAnything') {
  37661. $message .= "\nTo allow 0 or more parameters with any value, omit ->with() or use ->withAnyParameters() instead.";
  37662. }
  37663. throw new PHPUnit_Framework_ExpectationFailedException(
  37664. sprintf($message, $this->invocation->toString())
  37665. );
  37666. }
  37667. foreach ($this->parameters as $i => $parameter) {
  37668. $parameter->evaluate(
  37669. $this->invocation->parameters[$i],
  37670. sprintf(
  37671. 'Parameter %s for invocation %s does not match expected ' .
  37672. 'value.',
  37673. $i,
  37674. $this->invocation->toString()
  37675. )
  37676. );
  37677. }
  37678. return true;
  37679. }
  37680. }
  37681. <?php
  37682. /*
  37683. * This file is part of the PHPUnit_MockObject package.
  37684. *
  37685. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37686. *
  37687. * For the full copyright and license information, please view the LICENSE
  37688. * file that was distributed with this source code.
  37689. */
  37690. /**
  37691. * Invocation matcher which checks if a method has been invoked zero or more
  37692. * times. This matcher will always match.
  37693. *
  37694. * @since Class available since Release 1.0.0
  37695. */
  37696. class PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
  37697. {
  37698. /**
  37699. * @return string
  37700. */
  37701. public function toString()
  37702. {
  37703. return 'invoked zero or more times';
  37704. }
  37705. /**
  37706. */
  37707. public function verify()
  37708. {
  37709. }
  37710. }
  37711. <?php
  37712. /*
  37713. * This file is part of the PHPUnit_MockObject package.
  37714. *
  37715. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37716. *
  37717. * For the full copyright and license information, please view the LICENSE
  37718. * file that was distributed with this source code.
  37719. */
  37720. /**
  37721. * Invocation matcher which checks if a method has been invoked at least
  37722. * N times.
  37723. *
  37724. * @since Class available since Release 2.2.0
  37725. */
  37726. class PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
  37727. {
  37728. /**
  37729. * @var int
  37730. */
  37731. private $requiredInvocations;
  37732. /**
  37733. * @param int $requiredInvocations
  37734. */
  37735. public function __construct($requiredInvocations)
  37736. {
  37737. $this->requiredInvocations = $requiredInvocations;
  37738. }
  37739. /**
  37740. * @return string
  37741. */
  37742. public function toString()
  37743. {
  37744. return 'invoked at least ' . $this->requiredInvocations . ' times';
  37745. }
  37746. /**
  37747. * Verifies that the current expectation is valid. If everything is OK the
  37748. * code should just return, if not it must throw an exception.
  37749. *
  37750. * @throws PHPUnit_Framework_ExpectationFailedException
  37751. */
  37752. public function verify()
  37753. {
  37754. $count = $this->getInvocationCount();
  37755. if ($count < $this->requiredInvocations) {
  37756. throw new PHPUnit_Framework_ExpectationFailedException(
  37757. 'Expected invocation at least ' . $this->requiredInvocations .
  37758. ' times but it occured ' . $count . ' time(s).'
  37759. );
  37760. }
  37761. }
  37762. }
  37763. <?php
  37764. /*
  37765. * This file is part of the PHPUnit_MockObject package.
  37766. *
  37767. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37768. *
  37769. * For the full copyright and license information, please view the LICENSE
  37770. * file that was distributed with this source code.
  37771. */
  37772. /**
  37773. * Interface for classes which matches an invocation based on its
  37774. * method name, argument, order or call count.
  37775. *
  37776. * @since Interface available since Release 1.0.0
  37777. */
  37778. interface PHPUnit_Framework_MockObject_Matcher_Invocation extends PHPUnit_Framework_SelfDescribing, PHPUnit_Framework_MockObject_Verifiable
  37779. {
  37780. /**
  37781. * Registers the invocation $invocation in the object as being invoked.
  37782. * This will only occur after matches() returns true which means the
  37783. * current invocation is the correct one.
  37784. *
  37785. * The matcher can store information from the invocation which can later
  37786. * be checked in verify(), or it can check the values directly and throw
  37787. * and exception if an expectation is not met.
  37788. *
  37789. * If the matcher is a stub it will also have a return value.
  37790. *
  37791. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37792. * Object containing information on a mocked or stubbed method which
  37793. * was invoked.
  37794. * @return mixed
  37795. */
  37796. public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation);
  37797. /**
  37798. * Checks if the invocation $invocation matches the current rules. If it does
  37799. * the matcher will get the invoked() method called which should check if an
  37800. * expectation is met.
  37801. *
  37802. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37803. * Object containing information on a mocked or stubbed method which
  37804. * was invoked.
  37805. * @return bool
  37806. */
  37807. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation);
  37808. }
  37809. <?php
  37810. /*
  37811. * This file is part of the PHPUnit_MockObject package.
  37812. *
  37813. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37814. *
  37815. * For the full copyright and license information, please view the LICENSE
  37816. * file that was distributed with this source code.
  37817. */
  37818. /**
  37819. * Invocation matcher which looks for sets of specific parameters in the invocations.
  37820. *
  37821. * Checks the parameters of the incoming invocations, the parameter list is
  37822. * checked against the defined constraints in $parameters. If the constraint
  37823. * is met it will return true in matches().
  37824. *
  37825. * It takes a list of match groups and and increases a call index after each invocation.
  37826. * So the first invocation uses the first group of constraints, the second the next and so on.
  37827. */
  37828. class PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation
  37829. {
  37830. /**
  37831. * @var array
  37832. */
  37833. private $_parameterGroups = array();
  37834. /**
  37835. * @var array
  37836. */
  37837. private $_invocations = array();
  37838. /**
  37839. * @param array $parameterGroups
  37840. */
  37841. public function __construct(array $parameterGroups)
  37842. {
  37843. foreach ($parameterGroups as $index => $parameters) {
  37844. foreach ($parameters as $parameter) {
  37845. if (!($parameter instanceof \PHPUnit_Framework_Constraint)) {
  37846. $parameter = new \PHPUnit_Framework_Constraint_IsEqual($parameter);
  37847. }
  37848. $this->_parameterGroups[$index][] = $parameter;
  37849. }
  37850. }
  37851. }
  37852. /**
  37853. * @return string
  37854. */
  37855. public function toString()
  37856. {
  37857. $text = 'with consecutive parameters';
  37858. return $text;
  37859. }
  37860. /**
  37861. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37862. * @return bool
  37863. */
  37864. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
  37865. {
  37866. $this->_invocations[] = $invocation;
  37867. $callIndex = count($this->_invocations) - 1;
  37868. $this->verifyInvocation($invocation, $callIndex);
  37869. return false;
  37870. }
  37871. public function verify()
  37872. {
  37873. foreach ($this->_invocations as $callIndex => $invocation) {
  37874. $this->verifyInvocation($invocation, $callIndex);
  37875. }
  37876. }
  37877. /**
  37878. * Verify a single invocation
  37879. *
  37880. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37881. * @param int $callIndex
  37882. * @throws PHPUnit_Framework_ExpectationFailedException
  37883. */
  37884. private function verifyInvocation(PHPUnit_Framework_MockObject_Invocation $invocation, $callIndex)
  37885. {
  37886. if (isset($this->_parameterGroups[$callIndex])) {
  37887. $parameters = $this->_parameterGroups[$callIndex];
  37888. } else {
  37889. // no parameter assertion for this call index
  37890. return;
  37891. }
  37892. if ($invocation === null) {
  37893. throw new PHPUnit_Framework_ExpectationFailedException(
  37894. 'Mocked method does not exist.'
  37895. );
  37896. }
  37897. if (count($invocation->parameters) < count($parameters)) {
  37898. throw new PHPUnit_Framework_ExpectationFailedException(
  37899. sprintf(
  37900. 'Parameter count for invocation %s is too low.',
  37901. $invocation->toString()
  37902. )
  37903. );
  37904. }
  37905. foreach ($parameters as $i => $parameter) {
  37906. $parameter->evaluate(
  37907. $invocation->parameters[$i],
  37908. sprintf(
  37909. 'Parameter %s for invocation #%d %s does not match expected ' .
  37910. 'value.',
  37911. $i,
  37912. $callIndex,
  37913. $invocation->toString()
  37914. )
  37915. );
  37916. }
  37917. }
  37918. }
  37919. <?php
  37920. /*
  37921. * This file is part of the PHPUnit_MockObject package.
  37922. *
  37923. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  37924. *
  37925. * For the full copyright and license information, please view the LICENSE
  37926. * file that was distributed with this source code.
  37927. */
  37928. /**
  37929. * Invocation matcher which checks if a method was invoked at a certain index.
  37930. *
  37931. * If the expected index number does not match the current invocation index it
  37932. * will not match which means it skips all method and parameter matching. Only
  37933. * once the index is reached will the method and parameter start matching and
  37934. * verifying.
  37935. *
  37936. * If the index is never reached it will throw an exception in index.
  37937. *
  37938. * @since Class available since Release 1.0.0
  37939. */
  37940. class PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex implements PHPUnit_Framework_MockObject_Matcher_Invocation
  37941. {
  37942. /**
  37943. * @var int
  37944. */
  37945. protected $sequenceIndex;
  37946. /**
  37947. * @var int
  37948. */
  37949. protected $currentIndex = -1;
  37950. /**
  37951. * @param int $sequenceIndex
  37952. */
  37953. public function __construct($sequenceIndex)
  37954. {
  37955. $this->sequenceIndex = $sequenceIndex;
  37956. }
  37957. /**
  37958. * @return string
  37959. */
  37960. public function toString()
  37961. {
  37962. return 'invoked at sequence index ' . $this->sequenceIndex;
  37963. }
  37964. /**
  37965. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37966. * @return bool
  37967. */
  37968. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
  37969. {
  37970. $this->currentIndex++;
  37971. return $this->currentIndex == $this->sequenceIndex;
  37972. }
  37973. /**
  37974. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  37975. */
  37976. public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation)
  37977. {
  37978. }
  37979. /**
  37980. * Verifies that the current expectation is valid. If everything is OK the
  37981. * code should just return, if not it must throw an exception.
  37982. *
  37983. * @throws PHPUnit_Framework_ExpectationFailedException
  37984. */
  37985. public function verify()
  37986. {
  37987. if ($this->currentIndex < $this->sequenceIndex) {
  37988. throw new PHPUnit_Framework_ExpectationFailedException(
  37989. sprintf(
  37990. 'The expected invocation at index %s was never reached.',
  37991. $this->sequenceIndex
  37992. )
  37993. );
  37994. }
  37995. }
  37996. }
  37997. <?php
  37998. /*
  37999. * This file is part of the PHPUnit_MockObject package.
  38000. *
  38001. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38002. *
  38003. * For the full copyright and license information, please view the LICENSE
  38004. * file that was distributed with this source code.
  38005. */
  38006. /**
  38007. * Invocation matcher which checks if a method has been invoked a certain amount
  38008. * of times.
  38009. * If the number of invocations exceeds the value it will immediately throw an
  38010. * exception,
  38011. * If the number is less it will later be checked in verify() and also throw an
  38012. * exception.
  38013. *
  38014. * @since Class available since Release 1.0.0
  38015. */
  38016. class PHPUnit_Framework_MockObject_Matcher_InvokedCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
  38017. {
  38018. /**
  38019. * @var int
  38020. */
  38021. protected $expectedCount;
  38022. /**
  38023. * @param int $expectedCount
  38024. */
  38025. public function __construct($expectedCount)
  38026. {
  38027. $this->expectedCount = $expectedCount;
  38028. }
  38029. /**
  38030. * @return bool
  38031. */
  38032. public function isNever()
  38033. {
  38034. return $this->expectedCount == 0;
  38035. }
  38036. /**
  38037. * @return string
  38038. */
  38039. public function toString()
  38040. {
  38041. return 'invoked ' . $this->expectedCount . ' time(s)';
  38042. }
  38043. /**
  38044. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  38045. * @throws PHPUnit_Framework_ExpectationFailedException
  38046. */
  38047. public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation)
  38048. {
  38049. parent::invoked($invocation);
  38050. $count = $this->getInvocationCount();
  38051. if ($count > $this->expectedCount) {
  38052. $message = $invocation->toString() . ' ';
  38053. switch ($this->expectedCount) {
  38054. case 0: {
  38055. $message .= 'was not expected to be called.';
  38056. }
  38057. break;
  38058. case 1: {
  38059. $message .= 'was not expected to be called more than once.';
  38060. }
  38061. break;
  38062. default: {
  38063. $message .= sprintf(
  38064. 'was not expected to be called more than %d times.',
  38065. $this->expectedCount
  38066. );
  38067. }
  38068. }
  38069. throw new PHPUnit_Framework_ExpectationFailedException($message);
  38070. }
  38071. }
  38072. /**
  38073. * Verifies that the current expectation is valid. If everything is OK the
  38074. * code should just return, if not it must throw an exception.
  38075. *
  38076. * @throws PHPUnit_Framework_ExpectationFailedException
  38077. */
  38078. public function verify()
  38079. {
  38080. $count = $this->getInvocationCount();
  38081. if ($count !== $this->expectedCount) {
  38082. throw new PHPUnit_Framework_ExpectationFailedException(
  38083. sprintf(
  38084. 'Method was expected to be called %d times, ' .
  38085. 'actually called %d times.',
  38086. $this->expectedCount,
  38087. $count
  38088. )
  38089. );
  38090. }
  38091. }
  38092. }
  38093. <?php
  38094. /*
  38095. * This file is part of the PHPUnit_MockObject package.
  38096. *
  38097. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38098. *
  38099. * For the full copyright and license information, please view the LICENSE
  38100. * file that was distributed with this source code.
  38101. */
  38102. /**
  38103. * Invocation matcher which checks if a method has been invoked at least
  38104. * N times.
  38105. *
  38106. * @since Class available since Release 2.2.0
  38107. */
  38108. class PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder
  38109. {
  38110. /**
  38111. * @var int
  38112. */
  38113. private $allowedInvocations;
  38114. /**
  38115. * @param int $allowedInvocations
  38116. */
  38117. public function __construct($allowedInvocations)
  38118. {
  38119. $this->allowedInvocations = $allowedInvocations;
  38120. }
  38121. /**
  38122. * @return string
  38123. */
  38124. public function toString()
  38125. {
  38126. return 'invoked at most ' . $this->allowedInvocations . ' times';
  38127. }
  38128. /**
  38129. * Verifies that the current expectation is valid. If everything is OK the
  38130. * code should just return, if not it must throw an exception.
  38131. *
  38132. * @throws PHPUnit_Framework_ExpectationFailedException
  38133. */
  38134. public function verify()
  38135. {
  38136. $count = $this->getInvocationCount();
  38137. if ($count > $this->allowedInvocations) {
  38138. throw new PHPUnit_Framework_ExpectationFailedException(
  38139. 'Expected invocation at most ' . $this->allowedInvocations .
  38140. ' times but it occured ' . $count . ' time(s).'
  38141. );
  38142. }
  38143. }
  38144. }
  38145. <?php
  38146. /*
  38147. * This file is part of the PHPUnit_MockObject package.
  38148. *
  38149. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38150. *
  38151. * For the full copyright and license information, please view the LICENSE
  38152. * file that was distributed with this source code.
  38153. */
  38154. /**
  38155. * Records invocations and provides convenience methods for checking them later
  38156. * on.
  38157. * This abstract class can be implemented by matchers which needs to check the
  38158. * number of times an invocation has occured.
  38159. *
  38160. * @since Class available since Release 1.0.0
  38161. * @abstract
  38162. */
  38163. abstract class PHPUnit_Framework_MockObject_Matcher_InvokedRecorder implements PHPUnit_Framework_MockObject_Matcher_Invocation
  38164. {
  38165. /**
  38166. * @var PHPUnit_Framework_MockObject_Invocation[]
  38167. */
  38168. protected $invocations = array();
  38169. /**
  38170. * @return int
  38171. */
  38172. public function getInvocationCount()
  38173. {
  38174. return count($this->invocations);
  38175. }
  38176. /**
  38177. * @return PHPUnit_Framework_MockObject_Invocation[]
  38178. */
  38179. public function getInvocations()
  38180. {
  38181. return $this->invocations;
  38182. }
  38183. /**
  38184. * @return bool
  38185. */
  38186. public function hasBeenInvoked()
  38187. {
  38188. return count($this->invocations) > 0;
  38189. }
  38190. /**
  38191. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  38192. */
  38193. public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation)
  38194. {
  38195. $this->invocations[] = $invocation;
  38196. }
  38197. /**
  38198. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  38199. * @return bool
  38200. */
  38201. public function matches(PHPUnit_Framework_MockObject_Invocation $invocation)
  38202. {
  38203. return true;
  38204. }
  38205. }
  38206. <?php
  38207. /*
  38208. * This file is part of the PHPUnit_MockObject package.
  38209. *
  38210. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38211. *
  38212. * For the full copyright and license information, please view the LICENSE
  38213. * file that was distributed with this source code.
  38214. */
  38215. /**
  38216. * Invocation matcher which does not care about previous state from earlier
  38217. * invocations.
  38218. *
  38219. * This abstract class can be implemented by matchers which does not care about
  38220. * state but only the current run-time value of the invocation itself.
  38221. *
  38222. * @since Class available since Release 1.0.0
  38223. * @abstract
  38224. */
  38225. abstract class PHPUnit_Framework_MockObject_Matcher_StatelessInvocation implements PHPUnit_Framework_MockObject_Matcher_Invocation
  38226. {
  38227. /**
  38228. * Registers the invocation $invocation in the object as being invoked.
  38229. * This will only occur after matches() returns true which means the
  38230. * current invocation is the correct one.
  38231. *
  38232. * The matcher can store information from the invocation which can later
  38233. * be checked in verify(), or it can check the values directly and throw
  38234. * and exception if an expectation is not met.
  38235. *
  38236. * If the matcher is a stub it will also have a return value.
  38237. *
  38238. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  38239. * Object containing information on a mocked or stubbed method which
  38240. * was invoked.
  38241. * @return mixed
  38242. */
  38243. public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation)
  38244. {
  38245. }
  38246. /**
  38247. * Checks if the invocation $invocation matches the current rules. If it does
  38248. * the matcher will get the invoked() method called which should check if an
  38249. * expectation is met.
  38250. *
  38251. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  38252. * Object containing information on a mocked or stubbed method which
  38253. * was invoked.
  38254. * @return bool
  38255. */
  38256. public function verify()
  38257. {
  38258. }
  38259. }
  38260. <?php
  38261. /*
  38262. * This file is part of the PHPUnit_MockObject package.
  38263. *
  38264. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  38265. *
  38266. * For the full copyright and license information, please view the LICENSE
  38267. * file that was distributed with this source code.
  38268. */
  38269. use Doctrine\Instantiator\Instantiator;
  38270. use Doctrine\Instantiator\Exception\InvalidArgumentException as InstantiatorInvalidArgumentException;
  38271. use Doctrine\Instantiator\Exception\UnexpectedValueException as InstantiatorUnexpectedValueException;
  38272. if (!function_exists('trait_exists')) {
  38273. function trait_exists($traitname, $autoload = true)
  38274. {
  38275. return false;
  38276. }
  38277. }
  38278. /**
  38279. * Mock Object Code Generator
  38280. *
  38281. * @since Class available since Release 1.0.0
  38282. */
  38283. class PHPUnit_Framework_MockObject_Generator
  38284. {
  38285. /**
  38286. * @var array
  38287. */
  38288. private static $cache = array();
  38289. /**
  38290. * @var array
  38291. */
  38292. protected $blacklistedMethodNames = array(
  38293. '__CLASS__' => true,
  38294. '__DIR__' => true,
  38295. '__FILE__' => true,
  38296. '__FUNCTION__' => true,
  38297. '__LINE__' => true,
  38298. '__METHOD__' => true,
  38299. '__NAMESPACE__' => true,
  38300. '__TRAIT__' => true,
  38301. '__clone' => true,
  38302. '__halt_compiler' => true,
  38303. 'abstract' => true,
  38304. 'and' => true,
  38305. 'array' => true,
  38306. 'as' => true,
  38307. 'break' => true,
  38308. 'callable' => true,
  38309. 'case' => true,
  38310. 'catch' => true,
  38311. 'class' => true,
  38312. 'clone' => true,
  38313. 'const' => true,
  38314. 'continue' => true,
  38315. 'declare' => true,
  38316. 'default' => true,
  38317. 'die' => true,
  38318. 'do' => true,
  38319. 'echo' => true,
  38320. 'else' => true,
  38321. 'elseif' => true,
  38322. 'empty' => true,
  38323. 'enddeclare' => true,
  38324. 'endfor' => true,
  38325. 'endforeach' => true,
  38326. 'endif' => true,
  38327. 'endswitch' => true,
  38328. 'endwhile' => true,
  38329. 'eval' => true,
  38330. 'exit' => true,
  38331. 'expects' => true,
  38332. 'extends' => true,
  38333. 'final' => true,
  38334. 'for' => true,
  38335. 'foreach' => true,
  38336. 'function' => true,
  38337. 'global' => true,
  38338. 'goto' => true,
  38339. 'if' => true,
  38340. 'implements' => true,
  38341. 'include' => true,
  38342. 'include_once' => true,
  38343. 'instanceof' => true,
  38344. 'insteadof' => true,
  38345. 'interface' => true,
  38346. 'isset' => true,
  38347. 'list' => true,
  38348. 'namespace' => true,
  38349. 'new' => true,
  38350. 'or' => true,
  38351. 'print' => true,
  38352. 'private' => true,
  38353. 'protected' => true,
  38354. 'public' => true,
  38355. 'require' => true,
  38356. 'require_once' => true,
  38357. 'return' => true,
  38358. 'static' => true,
  38359. 'switch' => true,
  38360. 'throw' => true,
  38361. 'trait' => true,
  38362. 'try' => true,
  38363. 'unset' => true,
  38364. 'use' => true,
  38365. 'var' => true,
  38366. 'while' => true,
  38367. 'xor' => true
  38368. );
  38369. /**
  38370. * Returns a mock object for the specified class.
  38371. *
  38372. * @param array|string $type
  38373. * @param array $methods
  38374. * @param array $arguments
  38375. * @param string $mockClassName
  38376. * @param bool $callOriginalConstructor
  38377. * @param bool $callOriginalClone
  38378. * @param bool $callAutoload
  38379. * @param bool $cloneArguments
  38380. * @param bool $callOriginalMethods
  38381. * @param object $proxyTarget
  38382. * @return object
  38383. * @throws InvalidArgumentException
  38384. * @throws PHPUnit_Framework_Exception
  38385. * @throws PHPUnit_Framework_MockObject_RuntimeException
  38386. * @since Method available since Release 1.0.0
  38387. */
  38388. public function getMock($type, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $cloneArguments = true, $callOriginalMethods = false, $proxyTarget = null)
  38389. {
  38390. if (!is_array($type) && !is_string($type)) {
  38391. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'array or string');
  38392. }
  38393. if (!is_string($mockClassName)) {
  38394. throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'string');
  38395. }
  38396. if (!is_array($methods) && !is_null($methods)) {
  38397. throw new InvalidArgumentException;
  38398. }
  38399. if ($type === 'Traversable' || $type === '\\Traversable') {
  38400. $type = 'Iterator';
  38401. }
  38402. if (is_array($type)) {
  38403. $type = array_unique(array_map(
  38404. function ($type) {
  38405. if ($type === 'Traversable' ||
  38406. $type === '\\Traversable' ||
  38407. $type === '\\Iterator') {
  38408. return 'Iterator';
  38409. }
  38410. return $type;
  38411. },
  38412. $type
  38413. ));
  38414. }
  38415. if (null !== $methods) {
  38416. foreach ($methods as $method) {
  38417. if (!preg_match('~[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*~', $method)) {
  38418. throw new PHPUnit_Framework_Exception(
  38419. sprintf(
  38420. 'Cannot stub or mock method with invalid name "%s"',
  38421. $method
  38422. )
  38423. );
  38424. }
  38425. }
  38426. if ($methods != array_unique($methods)) {
  38427. throw new PHPUnit_Framework_MockObject_RuntimeException(
  38428. sprintf(
  38429. 'Cannot stub or mock using a method list that contains duplicates: "%s"',
  38430. implode(', ', $methods)
  38431. )
  38432. );
  38433. }
  38434. }
  38435. if ($mockClassName != '' && class_exists($mockClassName, false)) {
  38436. $reflect = new ReflectionClass($mockClassName);
  38437. if (!$reflect->implementsInterface('PHPUnit_Framework_MockObject_MockObject')) {
  38438. throw new PHPUnit_Framework_MockObject_RuntimeException(
  38439. sprintf(
  38440. 'Class "%s" already exists.',
  38441. $mockClassName
  38442. )
  38443. );
  38444. }
  38445. }
  38446. $mock = $this->generate(
  38447. $type,
  38448. $methods,
  38449. $mockClassName,
  38450. $callOriginalClone,
  38451. $callAutoload,
  38452. $cloneArguments,
  38453. $callOriginalMethods
  38454. );
  38455. return $this->getObject(
  38456. $mock['code'],
  38457. $mock['mockClassName'],
  38458. $type,
  38459. $callOriginalConstructor,
  38460. $callAutoload,
  38461. $arguments,
  38462. $callOriginalMethods,
  38463. $proxyTarget
  38464. );
  38465. }
  38466. /**
  38467. * @param string $code
  38468. * @param string $className
  38469. * @param array|string $type
  38470. * @param bool $callOriginalConstructor
  38471. * @param bool $callAutoload
  38472. * @param array $arguments
  38473. * @param bool $callOriginalMethods
  38474. * @param object $proxyTarget
  38475. * @return object
  38476. */
  38477. protected function getObject($code, $className, $type = '', $callOriginalConstructor = false, $callAutoload = false, array $arguments = array(), $callOriginalMethods = false, $proxyTarget = null)
  38478. {
  38479. $this->evalClass($code, $className);
  38480. if ($callOriginalConstructor &&
  38481. is_string($type) &&
  38482. !interface_exists($type, $callAutoload)) {
  38483. if (count($arguments) == 0) {
  38484. $object = new $className;
  38485. } else {
  38486. $class = new ReflectionClass($className);
  38487. $object = $class->newInstanceArgs($arguments);
  38488. }
  38489. } else {
  38490. try {
  38491. $instantiator = new Instantiator;
  38492. $object = $instantiator->instantiate($className);
  38493. } catch (InstantiatorUnexpectedValueException $exception) {
  38494. if ($exception->getPrevious()) {
  38495. $exception = $exception->getPrevious();
  38496. }
  38497. throw new PHPUnit_Framework_MockObject_RuntimeException(
  38498. $exception->getMessage()
  38499. );
  38500. } catch (InstantiatorInvalidArgumentException $exception) {
  38501. throw new PHPUnit_Framework_MockObject_RuntimeException(
  38502. $exception->getMessage()
  38503. );
  38504. }
  38505. }
  38506. if ($callOriginalMethods) {
  38507. if (!is_object($proxyTarget)) {
  38508. if (count($arguments) == 0) {
  38509. $proxyTarget = new $type;
  38510. } else {
  38511. $class = new ReflectionClass($type);
  38512. $proxyTarget = $class->newInstanceArgs($arguments);
  38513. }
  38514. }
  38515. $object->__phpunit_setOriginalObject($proxyTarget);
  38516. }
  38517. return $object;
  38518. }
  38519. /**
  38520. * @param string $code
  38521. * @param string $className
  38522. */
  38523. protected function evalClass($code, $className)
  38524. {
  38525. if (!class_exists($className, false)) {
  38526. eval($code);
  38527. }
  38528. }
  38529. /**
  38530. * Returns a mock object for the specified abstract class with all abstract
  38531. * methods of the class mocked. Concrete methods to mock can be specified with
  38532. * the last parameter
  38533. *
  38534. * @param string $originalClassName
  38535. * @param array $arguments
  38536. * @param string $mockClassName
  38537. * @param bool $callOriginalConstructor
  38538. * @param bool $callOriginalClone
  38539. * @param bool $callAutoload
  38540. * @param array $mockedMethods
  38541. * @param bool $cloneArguments
  38542. * @return object
  38543. * @since Method available since Release 1.0.0
  38544. * @throws PHPUnit_Framework_MockObject_RuntimeException
  38545. * @throws PHPUnit_Framework_Exception
  38546. */
  38547. public function getMockForAbstractClass($originalClassName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = array(), $cloneArguments = true)
  38548. {
  38549. if (!is_string($originalClassName)) {
  38550. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  38551. }
  38552. if (!is_string($mockClassName)) {
  38553. throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'string');
  38554. }
  38555. if (class_exists($originalClassName, $callAutoload) ||
  38556. interface_exists($originalClassName, $callAutoload)) {
  38557. $reflector = new ReflectionClass($originalClassName);
  38558. $methods = $mockedMethods;
  38559. foreach ($reflector->getMethods(ReflectionMethod::IS_ABSTRACT) as $method) {
  38560. if (!in_array($method->getName(), $methods)) {
  38561. $methods[] = $method->getName();
  38562. }
  38563. }
  38564. if (empty($methods)) {
  38565. $methods = null;
  38566. }
  38567. return $this->getMock(
  38568. $originalClassName,
  38569. $methods,
  38570. $arguments,
  38571. $mockClassName,
  38572. $callOriginalConstructor,
  38573. $callOriginalClone,
  38574. $callAutoload,
  38575. $cloneArguments
  38576. );
  38577. } else {
  38578. throw new PHPUnit_Framework_MockObject_RuntimeException(
  38579. sprintf('Class "%s" does not exist.', $originalClassName)
  38580. );
  38581. }
  38582. }
  38583. /**
  38584. * Returns a mock object for the specified trait with all abstract methods
  38585. * of the trait mocked. Concrete methods to mock can be specified with the
  38586. * `$mockedMethods` parameter.
  38587. *
  38588. * @param string $traitName
  38589. * @param array $arguments
  38590. * @param string $mockClassName
  38591. * @param bool $callOriginalConstructor
  38592. * @param bool $callOriginalClone
  38593. * @param bool $callAutoload
  38594. * @param array $mockedMethods
  38595. * @param bool $cloneArguments
  38596. * @return object
  38597. * @since Method available since Release 1.2.3
  38598. * @throws PHPUnit_Framework_MockObject_RuntimeException
  38599. * @throws PHPUnit_Framework_Exception
  38600. */
  38601. public function getMockForTrait($traitName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = array(), $cloneArguments = true)
  38602. {
  38603. if (!is_string($traitName)) {
  38604. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  38605. }
  38606. if (!is_string($mockClassName)) {
  38607. throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'string');
  38608. }
  38609. if (!trait_exists($traitName, $callAutoload)) {
  38610. throw new PHPUnit_Framework_MockObject_RuntimeException(
  38611. sprintf(
  38612. 'Trait "%s" does not exist.',
  38613. $traitName
  38614. )
  38615. );
  38616. }
  38617. $className = $this->generateClassName(
  38618. $traitName,
  38619. '',
  38620. 'Trait_'
  38621. );
  38622. $templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' .
  38623. DIRECTORY_SEPARATOR;
  38624. $classTemplate = new Text_Template(
  38625. $templateDir . 'trait_class.tpl'
  38626. );
  38627. $classTemplate->setVar(
  38628. array(
  38629. 'prologue' => 'abstract ',
  38630. 'class_name' => $className['className'],
  38631. 'trait_name' => $traitName
  38632. )
  38633. );
  38634. $this->evalClass(
  38635. $classTemplate->render(),
  38636. $className['className']
  38637. );
  38638. return $this->getMockForAbstractClass($className['className'], $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments);
  38639. }
  38640. /**
  38641. * Returns an object for the specified trait.
  38642. *
  38643. * @param string $traitName
  38644. * @param array $arguments
  38645. * @param string $traitClassName
  38646. * @param bool $callOriginalConstructor
  38647. * @param bool $callOriginalClone
  38648. * @param bool $callAutoload
  38649. * @return object
  38650. * @since Method available since Release 1.1.0
  38651. * @throws PHPUnit_Framework_MockObject_RuntimeException
  38652. * @throws PHPUnit_Framework_Exception
  38653. */
  38654. public function getObjectForTrait($traitName, array $arguments = array(), $traitClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true)
  38655. {
  38656. if (!is_string($traitName)) {
  38657. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  38658. }
  38659. if (!is_string($traitClassName)) {
  38660. throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'string');
  38661. }
  38662. if (!trait_exists($traitName, $callAutoload)) {
  38663. throw new PHPUnit_Framework_MockObject_RuntimeException(
  38664. sprintf(
  38665. 'Trait "%s" does not exist.',
  38666. $traitName
  38667. )
  38668. );
  38669. }
  38670. $className = $this->generateClassName(
  38671. $traitName,
  38672. $traitClassName,
  38673. 'Trait_'
  38674. );
  38675. $templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' .
  38676. DIRECTORY_SEPARATOR;
  38677. $classTemplate = new Text_Template(
  38678. $templateDir . 'trait_class.tpl'
  38679. );
  38680. $classTemplate->setVar(
  38681. array(
  38682. 'prologue' => '',
  38683. 'class_name' => $className['className'],
  38684. 'trait_name' => $traitName
  38685. )
  38686. );
  38687. return $this->getObject(
  38688. $classTemplate->render(),
  38689. $className['className']
  38690. );
  38691. }
  38692. /**
  38693. * @param array|string $type
  38694. * @param array $methods
  38695. * @param string $mockClassName
  38696. * @param bool $callOriginalClone
  38697. * @param bool $callAutoload
  38698. * @param bool $cloneArguments
  38699. * @param bool $callOriginalMethods
  38700. * @return array
  38701. */
  38702. public function generate($type, array $methods = null, $mockClassName = '', $callOriginalClone = true, $callAutoload = true, $cloneArguments = true, $callOriginalMethods = false)
  38703. {
  38704. if (is_array($type)) {
  38705. sort($type);
  38706. }
  38707. if ($mockClassName == '') {
  38708. $key = md5(
  38709. is_array($type) ? implode('_', $type) : $type .
  38710. serialize($methods) .
  38711. serialize($callOriginalClone) .
  38712. serialize($cloneArguments) .
  38713. serialize($callOriginalMethods)
  38714. );
  38715. if (isset(self::$cache[$key])) {
  38716. return self::$cache[$key];
  38717. }
  38718. }
  38719. $mock = $this->generateMock(
  38720. $type,
  38721. $methods,
  38722. $mockClassName,
  38723. $callOriginalClone,
  38724. $callAutoload,
  38725. $cloneArguments,
  38726. $callOriginalMethods
  38727. );
  38728. if (isset($key)) {
  38729. self::$cache[$key] = $mock;
  38730. }
  38731. return $mock;
  38732. }
  38733. /**
  38734. * @param string $wsdlFile
  38735. * @param string $className
  38736. * @param array $methods
  38737. * @param array $options
  38738. * @return string
  38739. * @throws PHPUnit_Framework_MockObject_RuntimeException
  38740. */
  38741. public function generateClassFromWsdl($wsdlFile, $className, array $methods = array(), array $options = array())
  38742. {
  38743. if (!extension_loaded('soap')) {
  38744. throw new PHPUnit_Framework_MockObject_RuntimeException(
  38745. 'The SOAP extension is required to generate a mock object from WSDL.'
  38746. );
  38747. }
  38748. $options = array_merge($options, array('cache_wsdl' => WSDL_CACHE_NONE));
  38749. $client = new SoapClient($wsdlFile, $options);
  38750. $_methods = array_unique($client->__getFunctions());
  38751. unset($client);
  38752. sort($_methods);
  38753. $templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' . DIRECTORY_SEPARATOR;
  38754. $methodTemplate = new Text_Template($templateDir . 'wsdl_method.tpl');
  38755. $methodsBuffer = '';
  38756. foreach ($_methods as $method) {
  38757. $nameStart = strpos($method, ' ') + 1;
  38758. $nameEnd = strpos($method, '(');
  38759. $name = substr($method, $nameStart, $nameEnd - $nameStart);
  38760. if (empty($methods) || in_array($name, $methods)) {
  38761. $args = explode(
  38762. ',',
  38763. substr(
  38764. $method,
  38765. $nameEnd + 1,
  38766. strpos($method, ')') - $nameEnd - 1
  38767. )
  38768. );
  38769. $numArgs = count($args);
  38770. for ($i = 0; $i < $numArgs; $i++) {
  38771. $args[$i] = substr($args[$i], strpos($args[$i], '$'));
  38772. }
  38773. $methodTemplate->setVar(
  38774. array(
  38775. 'method_name' => $name,
  38776. 'arguments' => implode(', ', $args)
  38777. )
  38778. );
  38779. $methodsBuffer .= $methodTemplate->render();
  38780. }
  38781. }
  38782. $optionsBuffer = 'array(';
  38783. foreach ($options as $key => $value) {
  38784. $optionsBuffer .= $key . ' => ' . $value;
  38785. }
  38786. $optionsBuffer .= ')';
  38787. $classTemplate = new Text_Template($templateDir . 'wsdl_class.tpl');
  38788. $namespace = '';
  38789. if (strpos($className, '\\') !== false) {
  38790. $parts = explode('\\', $className);
  38791. $className = array_pop($parts);
  38792. $namespace = 'namespace ' . implode('\\', $parts) . ';' . "\n\n";
  38793. }
  38794. $classTemplate->setVar(
  38795. array(
  38796. 'namespace' => $namespace,
  38797. 'class_name' => $className,
  38798. 'wsdl' => $wsdlFile,
  38799. 'options' => $optionsBuffer,
  38800. 'methods' => $methodsBuffer
  38801. )
  38802. );
  38803. return $classTemplate->render();
  38804. }
  38805. /**
  38806. * @param array|string $type
  38807. * @param array|null $methods
  38808. * @param string $mockClassName
  38809. * @param bool $callOriginalClone
  38810. * @param bool $callAutoload
  38811. * @param bool $cloneArguments
  38812. * @param bool $callOriginalMethods
  38813. * @return array
  38814. * @throws PHPUnit_Framework_Exception
  38815. */
  38816. protected function generateMock($type, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods)
  38817. {
  38818. $templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' .
  38819. DIRECTORY_SEPARATOR;
  38820. $classTemplate = new Text_Template(
  38821. $templateDir . 'mocked_class.tpl'
  38822. );
  38823. $additionalInterfaces = array();
  38824. $cloneTemplate = '';
  38825. $isClass = false;
  38826. $isInterface = false;
  38827. $mockClassName = $this->generateClassName(
  38828. $type,
  38829. $mockClassName,
  38830. 'Mock_'
  38831. );
  38832. if (is_array($type)) {
  38833. foreach ($type as $_type) {
  38834. if (!interface_exists($_type, $callAutoload)) {
  38835. throw new PHPUnit_Framework_Exception(
  38836. sprintf(
  38837. 'Interface "%s" does not exist.',
  38838. $_type
  38839. )
  38840. );
  38841. }
  38842. $additionalInterfaces[] = $_type;
  38843. foreach ($this->getClassMethods($_type) as $method) {
  38844. if (in_array($method, $methods)) {
  38845. throw new PHPUnit_Framework_Exception(
  38846. sprintf(
  38847. 'Duplicate method "%s" not allowed.',
  38848. $method
  38849. )
  38850. );
  38851. }
  38852. $methods[] = $method;
  38853. }
  38854. }
  38855. }
  38856. if (class_exists($mockClassName['fullClassName'], $callAutoload)) {
  38857. $isClass = true;
  38858. } else {
  38859. if (interface_exists($mockClassName['fullClassName'], $callAutoload)) {
  38860. $isInterface = true;
  38861. }
  38862. }
  38863. if (!class_exists($mockClassName['fullClassName'], $callAutoload) &&
  38864. !interface_exists($mockClassName['fullClassName'], $callAutoload)) {
  38865. $prologue = 'class ' . $mockClassName['originalClassName'] . "\n{\n}\n\n";
  38866. if (!empty($mockClassName['namespaceName'])) {
  38867. $prologue = 'namespace ' . $mockClassName['namespaceName'] .
  38868. " {\n\n" . $prologue . "}\n\n" .
  38869. "namespace {\n\n";
  38870. $epilogue = "\n\n}";
  38871. }
  38872. $cloneTemplate = new Text_Template(
  38873. $templateDir . 'mocked_clone.tpl'
  38874. );
  38875. } else {
  38876. $class = new ReflectionClass($mockClassName['fullClassName']);
  38877. if ($class->isFinal()) {
  38878. throw new PHPUnit_Framework_Exception(
  38879. sprintf(
  38880. 'Class "%s" is declared "final" and cannot be mocked.',
  38881. $mockClassName['fullClassName']
  38882. )
  38883. );
  38884. }
  38885. if ($class->hasMethod('__clone')) {
  38886. $cloneMethod = $class->getMethod('__clone');
  38887. if (!$cloneMethod->isFinal()) {
  38888. if ($callOriginalClone && !$isInterface) {
  38889. $cloneTemplate = new Text_Template(
  38890. $templateDir . 'unmocked_clone.tpl'
  38891. );
  38892. } else {
  38893. $cloneTemplate = new Text_Template(
  38894. $templateDir . 'mocked_clone.tpl'
  38895. );
  38896. }
  38897. }
  38898. } else {
  38899. $cloneTemplate = new Text_Template(
  38900. $templateDir . 'mocked_clone.tpl'
  38901. );
  38902. }
  38903. }
  38904. if (is_object($cloneTemplate)) {
  38905. $cloneTemplate = $cloneTemplate->render();
  38906. }
  38907. if (is_array($methods) && empty($methods) &&
  38908. ($isClass || $isInterface)) {
  38909. $methods = $this->getClassMethods($mockClassName['fullClassName']);
  38910. }
  38911. if (!is_array($methods)) {
  38912. $methods = array();
  38913. }
  38914. $mockedMethods = '';
  38915. if (isset($class)) {
  38916. // https://github.com/sebastianbergmann/phpunit-mock-objects/issues/103
  38917. if ($isInterface && $class->implementsInterface('Traversable') &&
  38918. !$class->implementsInterface('Iterator') &&
  38919. !$class->implementsInterface('IteratorAggregate')) {
  38920. $additionalInterfaces[] = 'Iterator';
  38921. $methods = array_merge($methods, $this->getClassMethods('Iterator'));
  38922. }
  38923. foreach ($methods as $methodName) {
  38924. try {
  38925. $method = $class->getMethod($methodName);
  38926. if ($this->canMockMethod($method)) {
  38927. $mockedMethods .= $this->generateMockedMethodDefinitionFromExisting(
  38928. $templateDir,
  38929. $method,
  38930. $cloneArguments,
  38931. $callOriginalMethods
  38932. );
  38933. }
  38934. } catch (ReflectionException $e) {
  38935. $mockedMethods .= $this->generateMockedMethodDefinition(
  38936. $templateDir,
  38937. $mockClassName['fullClassName'],
  38938. $methodName,
  38939. $cloneArguments
  38940. );
  38941. }
  38942. }
  38943. } else {
  38944. foreach ($methods as $methodName) {
  38945. $mockedMethods .= $this->generateMockedMethodDefinition(
  38946. $templateDir,
  38947. $mockClassName['fullClassName'],
  38948. $methodName,
  38949. $cloneArguments
  38950. );
  38951. }
  38952. }
  38953. $method = '';
  38954. if (!in_array('method', $methods)) {
  38955. $methodTemplate = new Text_Template(
  38956. $templateDir . 'mocked_class_method.tpl'
  38957. );
  38958. $method = $methodTemplate->render();
  38959. }
  38960. $classTemplate->setVar(
  38961. array(
  38962. 'prologue' => isset($prologue) ? $prologue : '',
  38963. 'epilogue' => isset($epilogue) ? $epilogue : '',
  38964. 'class_declaration' => $this->generateMockClassDeclaration(
  38965. $mockClassName,
  38966. $isInterface,
  38967. $additionalInterfaces
  38968. ),
  38969. 'clone' => $cloneTemplate,
  38970. 'mock_class_name' => $mockClassName['className'],
  38971. 'mocked_methods' => $mockedMethods,
  38972. 'method' => $method
  38973. )
  38974. );
  38975. return array(
  38976. 'code' => $classTemplate->render(),
  38977. 'mockClassName' => $mockClassName['className']
  38978. );
  38979. }
  38980. /**
  38981. * @param array|string $type
  38982. * @param string $className
  38983. * @param string $prefix
  38984. * @return array
  38985. */
  38986. protected function generateClassName($type, $className, $prefix)
  38987. {
  38988. if (is_array($type)) {
  38989. $type = implode('_', $type);
  38990. }
  38991. if ($type[0] == '\\') {
  38992. $type = substr($type, 1);
  38993. }
  38994. $classNameParts = explode('\\', $type);
  38995. if (count($classNameParts) > 1) {
  38996. $type = array_pop($classNameParts);
  38997. $namespaceName = implode('\\', $classNameParts);
  38998. $fullClassName = $namespaceName . '\\' . $type;
  38999. } else {
  39000. $namespaceName = '';
  39001. $fullClassName = $type;
  39002. }
  39003. if ($className == '') {
  39004. do {
  39005. $className = $prefix . $type . '_' .
  39006. substr(md5(microtime()), 0, 8);
  39007. } while (class_exists($className, false));
  39008. }
  39009. return array(
  39010. 'className' => $className,
  39011. 'originalClassName' => $type,
  39012. 'fullClassName' => $fullClassName,
  39013. 'namespaceName' => $namespaceName
  39014. );
  39015. }
  39016. /**
  39017. * @param array $mockClassName
  39018. * @param bool $isInterface
  39019. * @param array $additionalInterfaces
  39020. * @return array
  39021. */
  39022. protected function generateMockClassDeclaration(array $mockClassName, $isInterface, array $additionalInterfaces = array())
  39023. {
  39024. $buffer = 'class ';
  39025. $additionalInterfaces[] = 'PHPUnit_Framework_MockObject_MockObject';
  39026. $interfaces = implode(', ', $additionalInterfaces);
  39027. if ($isInterface) {
  39028. $buffer .= sprintf(
  39029. '%s implements %s',
  39030. $mockClassName['className'],
  39031. $interfaces
  39032. );
  39033. if (!in_array($mockClassName['originalClassName'], $additionalInterfaces)) {
  39034. $buffer .= ', ';
  39035. if (!empty($mockClassName['namespaceName'])) {
  39036. $buffer .= $mockClassName['namespaceName'] . '\\';
  39037. }
  39038. $buffer .= $mockClassName['originalClassName'];
  39039. }
  39040. } else {
  39041. $buffer .= sprintf(
  39042. '%s extends %s%s implements %s',
  39043. $mockClassName['className'],
  39044. !empty($mockClassName['namespaceName']) ? $mockClassName['namespaceName'] . '\\' : '',
  39045. $mockClassName['originalClassName'],
  39046. $interfaces
  39047. );
  39048. }
  39049. return $buffer;
  39050. }
  39051. /**
  39052. * @param string $templateDir
  39053. * @param ReflectionMethod $method
  39054. * @param bool $cloneArguments
  39055. * @param bool $callOriginalMethods
  39056. * @return string
  39057. */
  39058. protected function generateMockedMethodDefinitionFromExisting($templateDir, ReflectionMethod $method, $cloneArguments, $callOriginalMethods)
  39059. {
  39060. if ($method->isPrivate()) {
  39061. $modifier = 'private';
  39062. } elseif ($method->isProtected()) {
  39063. $modifier = 'protected';
  39064. } else {
  39065. $modifier = 'public';
  39066. }
  39067. if ($method->isStatic()) {
  39068. $modifier .= ' static';
  39069. }
  39070. if ($method->returnsReference()) {
  39071. $reference = '&';
  39072. } else {
  39073. $reference = '';
  39074. }
  39075. return $this->generateMockedMethodDefinition(
  39076. $templateDir,
  39077. $method->getDeclaringClass()->getName(),
  39078. $method->getName(),
  39079. $cloneArguments,
  39080. $modifier,
  39081. $this->getMethodParameters($method),
  39082. $this->getMethodParameters($method, true),
  39083. $reference,
  39084. $callOriginalMethods,
  39085. $method->isStatic()
  39086. );
  39087. }
  39088. /**
  39089. * @param string $templateDir
  39090. * @param string $className
  39091. * @param string $methodName
  39092. * @param bool $cloneArguments
  39093. * @param string $modifier
  39094. * @param string $arguments_decl
  39095. * @param string $arguments_call
  39096. * @param string $reference
  39097. * @param bool $callOriginalMethods
  39098. * @param bool $static
  39099. * @return string
  39100. */
  39101. protected function generateMockedMethodDefinition($templateDir, $className, $methodName, $cloneArguments = true, $modifier = 'public', $arguments_decl = '', $arguments_call = '', $reference = '', $callOriginalMethods = false, $static = false)
  39102. {
  39103. if ($static) {
  39104. $templateFile = 'mocked_static_method.tpl';
  39105. } else {
  39106. $templateFile = sprintf(
  39107. '%s_method.tpl',
  39108. $callOriginalMethods ? 'proxied' : 'mocked'
  39109. );
  39110. }
  39111. $template = new Text_Template($templateDir . $templateFile);
  39112. $template->setVar(
  39113. array(
  39114. 'arguments_decl' => $arguments_decl,
  39115. 'arguments_call' => $arguments_call,
  39116. 'arguments_count' => !empty($arguments_call) ? count(explode(',', $arguments_call)) : 0,
  39117. 'class_name' => $className,
  39118. 'method_name' => $methodName,
  39119. 'modifier' => $modifier,
  39120. 'reference' => $reference,
  39121. 'clone_arguments' => $cloneArguments ? 'TRUE' : 'FALSE'
  39122. )
  39123. );
  39124. return $template->render();
  39125. }
  39126. /**
  39127. * @param ReflectionMethod $method
  39128. * @return bool
  39129. */
  39130. protected function canMockMethod(ReflectionMethod $method)
  39131. {
  39132. if ($method->isConstructor() ||
  39133. $method->isFinal() ||
  39134. $method->isPrivate() ||
  39135. isset($this->blacklistedMethodNames[$method->getName()])) {
  39136. return false;
  39137. }
  39138. return true;
  39139. }
  39140. /**
  39141. * Returns the parameters of a function or method.
  39142. *
  39143. * @param ReflectionMethod $method
  39144. * @param bool $forCall
  39145. * @return string
  39146. * @throws PHPUnit_Framework_MockObject_RuntimeException
  39147. * @since Method available since Release 2.0.0
  39148. */
  39149. protected function getMethodParameters(ReflectionMethod $method, $forCall = false)
  39150. {
  39151. $parameters = array();
  39152. foreach ($method->getParameters() as $i => $parameter) {
  39153. $name = '$' . $parameter->getName();
  39154. /* Note: PHP extensions may use empty names for reference arguments
  39155. * or "..." for methods taking a variable number of arguments.
  39156. */
  39157. if ($name === '$' || $name === '$...') {
  39158. $name = '$arg' . $i;
  39159. }
  39160. if ($this->isVariadic($parameter)) {
  39161. if ($forCall) {
  39162. continue;
  39163. } else {
  39164. $name = '...' . $name;
  39165. }
  39166. }
  39167. $default = '';
  39168. $reference = '';
  39169. $typeDeclaration = '';
  39170. if (!$forCall) {
  39171. if ($this->hasType($parameter)) {
  39172. $typeDeclaration = (string) $parameter->getType() . ' ';
  39173. } elseif ($parameter->isArray()) {
  39174. $typeDeclaration = 'array ';
  39175. } elseif ((defined('HHVM_VERSION') || version_compare(PHP_VERSION, '5.4.0', '>='))
  39176. && $parameter->isCallable()) {
  39177. $typeDeclaration = 'callable ';
  39178. } else {
  39179. try {
  39180. $class = $parameter->getClass();
  39181. } catch (ReflectionException $e) {
  39182. throw new PHPUnit_Framework_MockObject_RuntimeException(
  39183. sprintf(
  39184. 'Cannot mock %s::%s() because a class or ' .
  39185. 'interface used in the signature is not loaded',
  39186. $method->getDeclaringClass()->getName(),
  39187. $method->getName()
  39188. ),
  39189. 0,
  39190. $e
  39191. );
  39192. }
  39193. if ($class !== null) {
  39194. $typeDeclaration = $class->getName() . ' ';
  39195. }
  39196. }
  39197. if (!$this->isVariadic($parameter)) {
  39198. if ($parameter->isDefaultValueAvailable()) {
  39199. $value = $parameter->getDefaultValue();
  39200. $default = ' = ' . var_export($value, true);
  39201. } elseif ($parameter->isOptional()) {
  39202. $default = ' = null';
  39203. }
  39204. }
  39205. }
  39206. if ($parameter->isPassedByReference()) {
  39207. $reference = '&';
  39208. }
  39209. $parameters[] = $typeDeclaration . $reference . $name . $default;
  39210. }
  39211. return implode(', ', $parameters);
  39212. }
  39213. /**
  39214. * @param ReflectionParameter $parameter
  39215. * @return bool
  39216. * @since Method available since Release 2.2.1
  39217. */
  39218. private function isVariadic(ReflectionParameter $parameter)
  39219. {
  39220. return method_exists('ReflectionParameter', 'isVariadic') && $parameter->isVariadic();
  39221. }
  39222. /**
  39223. * @param ReflectionParameter $parameter
  39224. * @return bool
  39225. * @since Method available since Release 2.3.4
  39226. */
  39227. private function hasType(ReflectionParameter $parameter)
  39228. {
  39229. return method_exists('ReflectionParameter', 'hasType') && $parameter->hasType();
  39230. }
  39231. /**
  39232. * @param string $className
  39233. * @return array
  39234. * @since Method available since Release 2.3.2
  39235. */
  39236. private function getClassMethods($className)
  39237. {
  39238. $class = new ReflectionClass($className);
  39239. $methods = array();
  39240. foreach ($class->getMethods() as $method) {
  39241. if ($method->isPublic() || $method->isAbstract()) {
  39242. $methods[] = $method->getName();
  39243. }
  39244. }
  39245. return $methods;
  39246. }
  39247. }
  39248. public function {method_name}({arguments})
  39249. {
  39250. }
  39251. public function __clone()
  39252. {
  39253. $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
  39254. parent::__clone();
  39255. }
  39256. {prologue}{class_declaration}
  39257. {
  39258. private $__phpunit_invocationMocker;
  39259. private $__phpunit_originalObject;
  39260. {clone}{mocked_methods}
  39261. public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher)
  39262. {
  39263. return $this->__phpunit_getInvocationMocker()->expects($matcher);
  39264. }
  39265. {method}
  39266. public function __phpunit_setOriginalObject($originalObject)
  39267. {
  39268. $this->__phpunit_originalObject = $originalObject;
  39269. }
  39270. public function __phpunit_getInvocationMocker()
  39271. {
  39272. if ($this->__phpunit_invocationMocker === NULL) {
  39273. $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker;
  39274. }
  39275. return $this->__phpunit_invocationMocker;
  39276. }
  39277. public function __phpunit_hasMatchers()
  39278. {
  39279. return $this->__phpunit_getInvocationMocker()->hasMatchers();
  39280. }
  39281. public function __phpunit_verify()
  39282. {
  39283. $this->__phpunit_getInvocationMocker()->verify();
  39284. $this->__phpunit_invocationMocker = NULL;
  39285. }
  39286. }{epilogue}
  39287. public function __clone()
  39288. {
  39289. $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker();
  39290. }
  39291. {modifier} function {reference}{method_name}({arguments_decl})
  39292. {
  39293. $arguments = array({arguments_call});
  39294. $count = func_num_args();
  39295. if ($count > {arguments_count}) {
  39296. $_arguments = func_get_args();
  39297. for ($i = {arguments_count}; $i < $count; $i++) {
  39298. $arguments[] = $_arguments[$i];
  39299. }
  39300. }
  39301. $this->__phpunit_getInvocationMocker()->invoke(
  39302. new PHPUnit_Framework_MockObject_Invocation_Object(
  39303. '{class_name}', '{method_name}', $arguments, $this, {clone_arguments}
  39304. )
  39305. );
  39306. return call_user_func_array(array($this->__phpunit_originalObject, "{method_name}"), $arguments);
  39307. }
  39308. {namespace}class {class_name} extends \SoapClient
  39309. {
  39310. public function __construct($wsdl, array $options)
  39311. {
  39312. parent::__construct('{wsdl}', $options);
  39313. }
  39314. {methods}}
  39315. {prologue}class {class_name}
  39316. {
  39317. use {trait_name};
  39318. }
  39319. {modifier} function {reference}{method_name}({arguments_decl})
  39320. {
  39321. $arguments = array({arguments_call});
  39322. $count = func_num_args();
  39323. if ($count > {arguments_count}) {
  39324. $_arguments = func_get_args();
  39325. for ($i = {arguments_count}; $i < $count; $i++) {
  39326. $arguments[] = $_arguments[$i];
  39327. }
  39328. }
  39329. $result = $this->__phpunit_getInvocationMocker()->invoke(
  39330. new PHPUnit_Framework_MockObject_Invocation_Object(
  39331. '{class_name}', '{method_name}', $arguments, $this, {clone_arguments}
  39332. )
  39333. );
  39334. return $result;
  39335. }
  39336. public function method()
  39337. {
  39338. $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
  39339. $expects = $this->expects($any);
  39340. return call_user_func_array(array($expects, 'method'), func_get_args());
  39341. }
  39342. {modifier} function {reference}{method_name}({arguments_decl})
  39343. {
  39344. throw new PHPUnit_Framework_MockObject_BadMethodCallException;
  39345. }
  39346. <?php
  39347. /*
  39348. * This file is part of the PHPUnit_MockObject package.
  39349. *
  39350. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39351. *
  39352. * For the full copyright and license information, please view the LICENSE
  39353. * file that was distributed with this source code.
  39354. */
  39355. /**
  39356. * Builder interface for invocation order matches.
  39357. *
  39358. * @since Interface available since Release 1.0.0
  39359. */
  39360. interface PHPUnit_Framework_MockObject_Builder_Match extends PHPUnit_Framework_MockObject_Builder_Stub
  39361. {
  39362. /**
  39363. * Defines the expectation which must occur before the current is valid.
  39364. *
  39365. * @param string $id The identification of the expectation that should
  39366. * occur before this one.
  39367. * @return PHPUnit_Framework_MockObject_Builder_Stub
  39368. */
  39369. public function after($id);
  39370. }
  39371. <?php
  39372. /*
  39373. * This file is part of the PHPUnit_MockObject package.
  39374. *
  39375. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39376. *
  39377. * For the full copyright and license information, please view the LICENSE
  39378. * file that was distributed with this source code.
  39379. */
  39380. /**
  39381. * Builder interface for unique identifiers.
  39382. *
  39383. * Defines the interface for recording unique identifiers. The identifiers
  39384. * can be used to define the invocation order of expectations. The expectation
  39385. * is recorded using id() and then defined in order using
  39386. * PHPUnit_Framework_MockObject_Builder_Match::after().
  39387. *
  39388. * @since Interface available since Release 1.0.0
  39389. */
  39390. interface PHPUnit_Framework_MockObject_Builder_Identity
  39391. {
  39392. /**
  39393. * Sets the identification of the expectation to $id.
  39394. *
  39395. * @note The identifier is unique per mock object.
  39396. * @param string $id Unique identifiation of expectation.
  39397. */
  39398. public function id($id);
  39399. }
  39400. <?php
  39401. /*
  39402. * This file is part of the PHPUnit_MockObject package.
  39403. *
  39404. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39405. *
  39406. * For the full copyright and license information, please view the LICENSE
  39407. * file that was distributed with this source code.
  39408. */
  39409. /**
  39410. * Builder for mocked or stubbed invocations.
  39411. *
  39412. * Provides methods for building expectations without having to resort to
  39413. * instantiating the various matchers manually. These methods also form a
  39414. * more natural way of reading the expectation. This class should be together
  39415. * with the test case PHPUnit_Framework_MockObject_TestCase.
  39416. *
  39417. * @since Class available since Release 1.0.0
  39418. */
  39419. class PHPUnit_Framework_MockObject_Builder_InvocationMocker implements PHPUnit_Framework_MockObject_Builder_MethodNameMatch
  39420. {
  39421. /**
  39422. * @var PHPUnit_Framework_MockObject_Stub_MatcherCollection
  39423. */
  39424. protected $collection;
  39425. /**
  39426. * @var PHPUnit_Framework_MockObject_Matcher
  39427. */
  39428. protected $matcher;
  39429. /**
  39430. * @param PHPUnit_Framework_MockObject_Stub_MatcherCollection $collection
  39431. * @param PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher
  39432. */
  39433. public function __construct(PHPUnit_Framework_MockObject_Stub_MatcherCollection $collection, PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher)
  39434. {
  39435. $this->collection = $collection;
  39436. $this->matcher = new PHPUnit_Framework_MockObject_Matcher(
  39437. $invocationMatcher
  39438. );
  39439. $this->collection->addMatcher($this->matcher);
  39440. }
  39441. /**
  39442. * @return PHPUnit_Framework_MockObject_Matcher
  39443. */
  39444. public function getMatcher()
  39445. {
  39446. return $this->matcher;
  39447. }
  39448. /**
  39449. * @param mixed $id
  39450. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39451. */
  39452. public function id($id)
  39453. {
  39454. $this->collection->registerId($id, $this);
  39455. return $this;
  39456. }
  39457. /**
  39458. * @param PHPUnit_Framework_MockObject_Stub $stub
  39459. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39460. */
  39461. public function will(PHPUnit_Framework_MockObject_Stub $stub)
  39462. {
  39463. $this->matcher->stub = $stub;
  39464. return $this;
  39465. }
  39466. /**
  39467. * @param mixed $value
  39468. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39469. */
  39470. public function willReturn($value)
  39471. {
  39472. $stub = new PHPUnit_Framework_MockObject_Stub_Return(
  39473. $value
  39474. );
  39475. return $this->will($stub);
  39476. }
  39477. /**
  39478. * @param array $valueMap
  39479. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39480. */
  39481. public function willReturnMap(array $valueMap)
  39482. {
  39483. $stub = new PHPUnit_Framework_MockObject_Stub_ReturnValueMap(
  39484. $valueMap
  39485. );
  39486. return $this->will($stub);
  39487. }
  39488. /**
  39489. * @param mixed $argumentIndex
  39490. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39491. */
  39492. public function willReturnArgument($argumentIndex)
  39493. {
  39494. $stub = new PHPUnit_Framework_MockObject_Stub_ReturnArgument(
  39495. $argumentIndex
  39496. );
  39497. return $this->will($stub);
  39498. }
  39499. /**
  39500. * @param callable $callback
  39501. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39502. */
  39503. public function willReturnCallback($callback)
  39504. {
  39505. $stub = new PHPUnit_Framework_MockObject_Stub_ReturnCallback(
  39506. $callback
  39507. );
  39508. return $this->will($stub);
  39509. }
  39510. /**
  39511. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39512. */
  39513. public function willReturnSelf()
  39514. {
  39515. $stub = new PHPUnit_Framework_MockObject_Stub_ReturnSelf();
  39516. return $this->will($stub);
  39517. }
  39518. /**
  39519. * @param mixed $value, ...
  39520. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39521. */
  39522. public function willReturnOnConsecutiveCalls()
  39523. {
  39524. $args = func_get_args();
  39525. $stub = new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls($args);
  39526. return $this->will($stub);
  39527. }
  39528. /**
  39529. * @param Exception $exception
  39530. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39531. */
  39532. public function willThrowException(Exception $exception)
  39533. {
  39534. $stub = new PHPUnit_Framework_MockObject_Stub_Exception($exception);
  39535. return $this->will($stub);
  39536. }
  39537. /**
  39538. * @param mixed $id
  39539. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39540. */
  39541. public function after($id)
  39542. {
  39543. $this->matcher->afterMatchBuilderId = $id;
  39544. return $this;
  39545. }
  39546. /**
  39547. * Validate that a parameters matcher can be defined, throw exceptions otherwise.
  39548. *
  39549. * @throws PHPUnit_Framework_Exception
  39550. */
  39551. private function canDefineParameters()
  39552. {
  39553. if ($this->matcher->methodNameMatcher === null) {
  39554. throw new PHPUnit_Framework_Exception(
  39555. 'Method name matcher is not defined, cannot define parameter ' .
  39556. ' matcher without one'
  39557. );
  39558. }
  39559. if ($this->matcher->parametersMatcher !== null) {
  39560. throw new PHPUnit_Framework_Exception(
  39561. 'Parameter matcher is already defined, cannot redefine'
  39562. );
  39563. }
  39564. }
  39565. /**
  39566. * @param mixed $argument, ...
  39567. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39568. */
  39569. public function with()
  39570. {
  39571. $args = func_get_args();
  39572. $this->canDefineParameters();
  39573. $this->matcher->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_Parameters($args);
  39574. return $this;
  39575. }
  39576. /**
  39577. * @param mixed ...$argument
  39578. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39579. */
  39580. public function withConsecutive()
  39581. {
  39582. $args = func_get_args();
  39583. $this->canDefineParameters();
  39584. $this->matcher->parametersMatcher =
  39585. new PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters($args);
  39586. return $this;
  39587. }
  39588. /**
  39589. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39590. */
  39591. public function withAnyParameters()
  39592. {
  39593. $this->canDefineParameters();
  39594. $this->matcher->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_AnyParameters;
  39595. return $this;
  39596. }
  39597. /**
  39598. * @param PHPUnit_Framework_Constraint|string $constraint
  39599. * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker
  39600. */
  39601. public function method($constraint)
  39602. {
  39603. if ($this->matcher->methodNameMatcher !== null) {
  39604. throw new PHPUnit_Framework_Exception(
  39605. 'Method name matcher is already defined, cannot redefine'
  39606. );
  39607. }
  39608. $this->matcher->methodNameMatcher = new PHPUnit_Framework_MockObject_Matcher_MethodName($constraint);
  39609. return $this;
  39610. }
  39611. }
  39612. <?php
  39613. /*
  39614. * This file is part of the PHPUnit_MockObject package.
  39615. *
  39616. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39617. *
  39618. * For the full copyright and license information, please view the LICENSE
  39619. * file that was distributed with this source code.
  39620. */
  39621. /**
  39622. * Builder interface for parameter matchers.
  39623. *
  39624. * @since Interface available since Release 1.0.0
  39625. */
  39626. interface PHPUnit_Framework_MockObject_Builder_ParametersMatch extends PHPUnit_Framework_MockObject_Builder_Match
  39627. {
  39628. /**
  39629. * Sets the parameters to match for, each parameter to this funtion will
  39630. * be part of match. To perform specific matches or constraints create a
  39631. * new PHPUnit_Framework_Constraint and use it for the parameter.
  39632. * If the parameter value is not a constraint it will use the
  39633. * PHPUnit_Framework_Constraint_IsEqual for the value.
  39634. *
  39635. * Some examples:
  39636. * <code>
  39637. * // match first parameter with value 2
  39638. * $b->with(2);
  39639. * // match first parameter with value 'smock' and second identical to 42
  39640. * $b->with('smock', new PHPUnit_Framework_Constraint_IsEqual(42));
  39641. * </code>
  39642. *
  39643. * @return PHPUnit_Framework_MockObject_Builder_ParametersMatch
  39644. */
  39645. public function with();
  39646. /**
  39647. * Sets a matcher which allows any kind of parameters.
  39648. *
  39649. * Some examples:
  39650. * <code>
  39651. * // match any number of parameters
  39652. * $b->withAnyParamers();
  39653. * </code>
  39654. *
  39655. * @return PHPUnit_Framework_MockObject_Matcher_AnyParameters
  39656. */
  39657. public function withAnyParameters();
  39658. }
  39659. <?php
  39660. /*
  39661. * This file is part of the PHPUnit_MockObject package.
  39662. *
  39663. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39664. *
  39665. * For the full copyright and license information, please view the LICENSE
  39666. * file that was distributed with this source code.
  39667. */
  39668. /**
  39669. * Interface for builders which can register builders with a given identification.
  39670. *
  39671. * This interface relates to PHPUnit_Framework_MockObject_Builder_Identity.
  39672. *
  39673. * @since Interface available since Release 1.0.0
  39674. */
  39675. interface PHPUnit_Framework_MockObject_Builder_Namespace
  39676. {
  39677. /**
  39678. * Looks up the match builder with identification $id and returns it.
  39679. *
  39680. * @param string $id The identifiction of the match builder.
  39681. * @return PHPUnit_Framework_MockObject_Builder_Match
  39682. */
  39683. public function lookupId($id);
  39684. /**
  39685. * Registers the match builder $builder with the identification $id. The
  39686. * builder can later be looked up using lookupId() to figure out if it
  39687. * has been invoked.
  39688. *
  39689. * @param string $id
  39690. * The identification of the match builder.
  39691. * @param PHPUnit_Framework_MockObject_Builder_Match $builder
  39692. * The builder which is being registered.
  39693. */
  39694. public function registerId($id, PHPUnit_Framework_MockObject_Builder_Match $builder);
  39695. }
  39696. <?php
  39697. /*
  39698. * This file is part of the PHPUnit_MockObject package.
  39699. *
  39700. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39701. *
  39702. * For the full copyright and license information, please view the LICENSE
  39703. * file that was distributed with this source code.
  39704. */
  39705. /**
  39706. * Builder interface for matcher of method names.
  39707. *
  39708. * @since Interface available since Release 1.0.0
  39709. */
  39710. interface PHPUnit_Framework_MockObject_Builder_MethodNameMatch extends PHPUnit_Framework_MockObject_Builder_ParametersMatch
  39711. {
  39712. /**
  39713. * Adds a new method name match and returns the parameter match object for
  39714. * further matching possibilities.
  39715. *
  39716. * @param PHPUnit_Framework_Constraint $name
  39717. * Constraint for matching method, if a string is passed it will use
  39718. * the PHPUnit_Framework_Constraint_IsEqual.
  39719. * @return PHPUnit_Framework_MockObject_Builder_ParametersMatch
  39720. */
  39721. public function method($name);
  39722. }
  39723. <?php
  39724. /*
  39725. * This file is part of the PHPUnit_MockObject package.
  39726. *
  39727. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39728. *
  39729. * For the full copyright and license information, please view the LICENSE
  39730. * file that was distributed with this source code.
  39731. */
  39732. /**
  39733. * Builder interface for stubs which are actions replacing an invocation.
  39734. *
  39735. * @since Interface available since Release 1.0.0
  39736. */
  39737. interface PHPUnit_Framework_MockObject_Builder_Stub extends PHPUnit_Framework_MockObject_Builder_Identity
  39738. {
  39739. /**
  39740. * Stubs the matching method with the stub object $stub. Any invocations of
  39741. * the matched method will now be handled by the stub instead.
  39742. *
  39743. * @param PHPUnit_Framework_MockObject_Stub $stub The stub object.
  39744. * @return PHPUnit_Framework_MockObject_Builder_Identity
  39745. */
  39746. public function will(PHPUnit_Framework_MockObject_Stub $stub);
  39747. }
  39748. <?php
  39749. /*
  39750. * This file is part of the PHPUnit_MockObject package.
  39751. *
  39752. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39753. *
  39754. * For the full copyright and license information, please view the LICENSE
  39755. * file that was distributed with this source code.
  39756. */
  39757. /**
  39758. * Represents a non-static invocation.
  39759. *
  39760. * @since Class available since Release 1.0.0
  39761. */
  39762. class PHPUnit_Framework_MockObject_Invocation_Object extends PHPUnit_Framework_MockObject_Invocation_Static
  39763. {
  39764. /**
  39765. * @var object
  39766. */
  39767. public $object;
  39768. /**
  39769. * @param string $className
  39770. * @param string $methodname
  39771. * @param array $parameters
  39772. * @param object $object
  39773. * @param object $cloneObjects
  39774. */
  39775. public function __construct($className, $methodName, array $parameters, $object, $cloneObjects = false)
  39776. {
  39777. parent::__construct($className, $methodName, $parameters, $cloneObjects);
  39778. $this->object = $object;
  39779. }
  39780. }
  39781. <?php
  39782. /*
  39783. * This file is part of the PHPUnit_MockObject package.
  39784. *
  39785. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39786. *
  39787. * For the full copyright and license information, please view the LICENSE
  39788. * file that was distributed with this source code.
  39789. */
  39790. use SebastianBergmann\Exporter\Exporter;
  39791. /**
  39792. * Represents a static invocation.
  39793. *
  39794. * @since Class available since Release 1.0.0
  39795. */
  39796. class PHPUnit_Framework_MockObject_Invocation_Static implements PHPUnit_Framework_MockObject_Invocation, PHPUnit_Framework_SelfDescribing
  39797. {
  39798. /**
  39799. * @var array
  39800. */
  39801. protected static $uncloneableExtensions = array(
  39802. 'mysqli' => true,
  39803. 'SQLite' => true,
  39804. 'sqlite3' => true,
  39805. 'tidy' => true,
  39806. 'xmlwriter' => true,
  39807. 'xsl' => true
  39808. );
  39809. /**
  39810. * @var array
  39811. */
  39812. protected static $uncloneableClasses = array(
  39813. 'Closure',
  39814. 'COMPersistHelper',
  39815. 'IteratorIterator',
  39816. 'RecursiveIteratorIterator',
  39817. 'SplFileObject',
  39818. 'PDORow',
  39819. 'ZipArchive'
  39820. );
  39821. /**
  39822. * @var string
  39823. */
  39824. public $className;
  39825. /**
  39826. * @var string
  39827. */
  39828. public $methodName;
  39829. /**
  39830. * @var array
  39831. */
  39832. public $parameters;
  39833. /**
  39834. * @param string $className
  39835. * @param string $methodname
  39836. * @param array $parameters
  39837. * @param bool $cloneObjects
  39838. */
  39839. public function __construct($className, $methodName, array $parameters, $cloneObjects = false)
  39840. {
  39841. $this->className = $className;
  39842. $this->methodName = $methodName;
  39843. $this->parameters = $parameters;
  39844. if (!$cloneObjects) {
  39845. return;
  39846. }
  39847. foreach ($this->parameters as $key => $value) {
  39848. if (is_object($value)) {
  39849. $this->parameters[$key] = $this->cloneObject($value);
  39850. }
  39851. }
  39852. }
  39853. /**
  39854. * @return string
  39855. */
  39856. public function toString()
  39857. {
  39858. $exporter = new Exporter;
  39859. return sprintf(
  39860. '%s::%s(%s)',
  39861. $this->className,
  39862. $this->methodName,
  39863. implode(
  39864. ', ',
  39865. array_map(
  39866. array($exporter, 'shortenedExport'),
  39867. $this->parameters
  39868. )
  39869. )
  39870. );
  39871. }
  39872. /**
  39873. * @param object $original
  39874. * @return object
  39875. */
  39876. protected function cloneObject($original)
  39877. {
  39878. $cloneable = null;
  39879. $object = new ReflectionObject($original);
  39880. // Check the blacklist before asking PHP reflection to work around
  39881. // https://bugs.php.net/bug.php?id=53967
  39882. if ($object->isInternal() &&
  39883. isset(self::$uncloneableExtensions[$object->getExtensionName()])) {
  39884. $cloneable = false;
  39885. }
  39886. if ($cloneable === null) {
  39887. foreach (self::$uncloneableClasses as $class) {
  39888. if ($original instanceof $class) {
  39889. $cloneable = false;
  39890. break;
  39891. }
  39892. }
  39893. }
  39894. if ($cloneable === null && method_exists($object, 'isCloneable')) {
  39895. $cloneable = $object->isCloneable();
  39896. }
  39897. if ($cloneable === null && $object->hasMethod('__clone')) {
  39898. $method = $object->getMethod('__clone');
  39899. $cloneable = $method->isPublic();
  39900. }
  39901. if ($cloneable === null) {
  39902. $cloneable = true;
  39903. }
  39904. if ($cloneable) {
  39905. try {
  39906. return clone $original;
  39907. } catch (Exception $e) {
  39908. return $original;
  39909. }
  39910. } else {
  39911. return $original;
  39912. }
  39913. }
  39914. }
  39915. <?php
  39916. /*
  39917. * This file is part of the PHPUnit_MockObject package.
  39918. *
  39919. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39920. *
  39921. * For the full copyright and license information, please view the LICENSE
  39922. * file that was distributed with this source code.
  39923. */
  39924. /**
  39925. * An object that stubs the process of a normal method for a mock object.
  39926. *
  39927. * The stub object will replace the code for the stubbed method and return a
  39928. * specific value instead of the original value.
  39929. *
  39930. * @since Interface available since Release 1.0.0
  39931. */
  39932. interface PHPUnit_Framework_MockObject_Stub extends PHPUnit_Framework_SelfDescribing
  39933. {
  39934. /**
  39935. * Fakes the processing of the invocation $invocation by returning a
  39936. * specific value.
  39937. *
  39938. * @param PHPUnit_Framework_MockObject_Invocation $invocation
  39939. * The invocation which was mocked and matched by the current method
  39940. * and argument matchers.
  39941. * @return mixed
  39942. */
  39943. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation);
  39944. }
  39945. <?php
  39946. /*
  39947. * This file is part of the PHPUnit_MockObject package.
  39948. *
  39949. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39950. *
  39951. * For the full copyright and license information, please view the LICENSE
  39952. * file that was distributed with this source code.
  39953. */
  39954. /**
  39955. * Stubs a method by raising a user-defined exception.
  39956. *
  39957. * @since Class available since Release 1.0.0
  39958. */
  39959. class PHPUnit_Framework_MockObject_Stub_Exception implements PHPUnit_Framework_MockObject_Stub
  39960. {
  39961. protected $exception;
  39962. public function __construct(Exception $exception)
  39963. {
  39964. $this->exception = $exception;
  39965. }
  39966. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
  39967. {
  39968. throw $this->exception;
  39969. }
  39970. public function toString()
  39971. {
  39972. return sprintf(
  39973. 'raise user-specified exception %s',
  39974. PHPUnit_Util_Type::export($this->exception)
  39975. );
  39976. }
  39977. }
  39978. <?php
  39979. /*
  39980. * This file is part of the PHPUnit_MockObject package.
  39981. *
  39982. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  39983. *
  39984. * For the full copyright and license information, please view the LICENSE
  39985. * file that was distributed with this source code.
  39986. */
  39987. /**
  39988. * Stubs a method by returning a user-defined value.
  39989. *
  39990. * @since Class available since Release 1.0.0
  39991. */
  39992. class PHPUnit_Framework_MockObject_Stub_Return implements PHPUnit_Framework_MockObject_Stub
  39993. {
  39994. protected $value;
  39995. public function __construct($value)
  39996. {
  39997. $this->value = $value;
  39998. }
  39999. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
  40000. {
  40001. return $this->value;
  40002. }
  40003. public function toString()
  40004. {
  40005. return sprintf(
  40006. 'return user-specified value %s',
  40007. PHPUnit_Util_Type::export($this->value)
  40008. );
  40009. }
  40010. }
  40011. <?php
  40012. /*
  40013. * This file is part of the PHPUnit_MockObject package.
  40014. *
  40015. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40016. *
  40017. * For the full copyright and license information, please view the LICENSE
  40018. * file that was distributed with this source code.
  40019. */
  40020. /**
  40021. * Stubs a method by returning the current object.
  40022. *
  40023. * @since Class available since Release 1.1.0
  40024. */
  40025. class PHPUnit_Framework_MockObject_Stub_ReturnSelf implements PHPUnit_Framework_MockObject_Stub
  40026. {
  40027. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
  40028. {
  40029. if (!$invocation instanceof PHPUnit_Framework_MockObject_Invocation_Object) {
  40030. throw new PHPUnit_Framework_Exception(
  40031. 'The current object can only be returned when mocking an ' .
  40032. 'object, not a static class.'
  40033. );
  40034. }
  40035. return $invocation->object;
  40036. }
  40037. public function toString()
  40038. {
  40039. return 'return the current object';
  40040. }
  40041. }
  40042. <?php
  40043. /*
  40044. * This file is part of the PHPUnit_MockObject package.
  40045. *
  40046. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40047. *
  40048. * For the full copyright and license information, please view the LICENSE
  40049. * file that was distributed with this source code.
  40050. */
  40051. /**
  40052. * Stubs a method by returning a value from a map.
  40053. *
  40054. * @since Class available since Release 1.1.0
  40055. */
  40056. class PHPUnit_Framework_MockObject_Stub_ReturnValueMap implements PHPUnit_Framework_MockObject_Stub
  40057. {
  40058. protected $valueMap;
  40059. public function __construct(array $valueMap)
  40060. {
  40061. $this->valueMap = $valueMap;
  40062. }
  40063. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
  40064. {
  40065. $parameterCount = count($invocation->parameters);
  40066. foreach ($this->valueMap as $map) {
  40067. if (!is_array($map) || $parameterCount != count($map) - 1) {
  40068. continue;
  40069. }
  40070. $return = array_pop($map);
  40071. if ($invocation->parameters === $map) {
  40072. return $return;
  40073. }
  40074. }
  40075. return;
  40076. }
  40077. public function toString()
  40078. {
  40079. return 'return value from a map';
  40080. }
  40081. }
  40082. <?php
  40083. /*
  40084. * This file is part of the PHPUnit_MockObject package.
  40085. *
  40086. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40087. *
  40088. * For the full copyright and license information, please view the LICENSE
  40089. * file that was distributed with this source code.
  40090. */
  40091. /**
  40092. * Stubs a method by returning a user-defined stack of values.
  40093. *
  40094. * @since Class available since Release 1.0.0
  40095. */
  40096. class PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls implements PHPUnit_Framework_MockObject_Stub
  40097. {
  40098. protected $stack;
  40099. protected $value;
  40100. public function __construct($stack)
  40101. {
  40102. $this->stack = $stack;
  40103. }
  40104. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
  40105. {
  40106. $this->value = array_shift($this->stack);
  40107. if ($this->value instanceof PHPUnit_Framework_MockObject_Stub) {
  40108. $this->value = $this->value->invoke($invocation);
  40109. }
  40110. return $this->value;
  40111. }
  40112. public function toString()
  40113. {
  40114. return sprintf(
  40115. 'return user-specified value %s',
  40116. PHPUnit_Util_Type::export($this->value)
  40117. );
  40118. }
  40119. }
  40120. <?php
  40121. /*
  40122. * This file is part of the PHPUnit_MockObject package.
  40123. *
  40124. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40125. *
  40126. * For the full copyright and license information, please view the LICENSE
  40127. * file that was distributed with this source code.
  40128. */
  40129. /**
  40130. * Stubs a method by returning a user-defined value.
  40131. *
  40132. * @since Interface available since Release 1.0.0
  40133. */
  40134. interface PHPUnit_Framework_MockObject_Stub_MatcherCollection
  40135. {
  40136. /**
  40137. * Adds a new matcher to the collection which can be used as an expectation
  40138. * or a stub.
  40139. *
  40140. * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher
  40141. * Matcher for invocations to mock objects.
  40142. */
  40143. public function addMatcher(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher);
  40144. }
  40145. <?php
  40146. /*
  40147. * This file is part of the PHPUnit_MockObject package.
  40148. *
  40149. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40150. *
  40151. * For the full copyright and license information, please view the LICENSE
  40152. * file that was distributed with this source code.
  40153. */
  40154. /**
  40155. * @since Class available since Release 1.0.0
  40156. */
  40157. class PHPUnit_Framework_MockObject_Stub_ReturnCallback implements PHPUnit_Framework_MockObject_Stub
  40158. {
  40159. protected $callback;
  40160. public function __construct($callback)
  40161. {
  40162. $this->callback = $callback;
  40163. }
  40164. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
  40165. {
  40166. return call_user_func_array($this->callback, $invocation->parameters);
  40167. }
  40168. public function toString()
  40169. {
  40170. if (is_array($this->callback)) {
  40171. if (is_object($this->callback[0])) {
  40172. $class = get_class($this->callback[0]);
  40173. $type = '->';
  40174. } else {
  40175. $class = $this->callback[0];
  40176. $type = '::';
  40177. }
  40178. return sprintf(
  40179. 'return result of user defined callback %s%s%s() with the ' .
  40180. 'passed arguments',
  40181. $class,
  40182. $type,
  40183. $this->callback[1]
  40184. );
  40185. } else {
  40186. return 'return result of user defined callback ' . $this->callback .
  40187. ' with the passed arguments';
  40188. }
  40189. }
  40190. }
  40191. <?php
  40192. /*
  40193. * This file is part of the PHPUnit_MockObject package.
  40194. *
  40195. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40196. *
  40197. * For the full copyright and license information, please view the LICENSE
  40198. * file that was distributed with this source code.
  40199. */
  40200. /**
  40201. * Stubs a method by returning an argument that was passed to the mocked method.
  40202. *
  40203. * @since Class available since Release 1.0.0
  40204. */
  40205. class PHPUnit_Framework_MockObject_Stub_ReturnArgument extends PHPUnit_Framework_MockObject_Stub_Return
  40206. {
  40207. protected $argumentIndex;
  40208. public function __construct($argumentIndex)
  40209. {
  40210. $this->argumentIndex = $argumentIndex;
  40211. }
  40212. public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation)
  40213. {
  40214. if (isset($invocation->parameters[$this->argumentIndex])) {
  40215. return $invocation->parameters[$this->argumentIndex];
  40216. } else {
  40217. return;
  40218. }
  40219. }
  40220. public function toString()
  40221. {
  40222. return sprintf('return argument #%d', $this->argumentIndex);
  40223. }
  40224. }
  40225. <?php
  40226. /*
  40227. * This file is part of PHPUnit.
  40228. *
  40229. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40230. *
  40231. * For the full copyright and license information, please view the LICENSE
  40232. * file that was distributed with this source code.
  40233. */
  40234. /**
  40235. * Marker interface for PHPUnit exceptions.
  40236. *
  40237. * @since Interface available since Release 4.0.0
  40238. */
  40239. interface PHPUnit_Exception
  40240. {
  40241. }
  40242. <?php
  40243. /*
  40244. * This file is part of PHPUnit.
  40245. *
  40246. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40247. *
  40248. * For the full copyright and license information, please view the LICENSE
  40249. * file that was distributed with this source code.
  40250. */
  40251. /**
  40252. * A Test can be run and collect its results.
  40253. *
  40254. * @since Interface available since Release 2.0.0
  40255. */
  40256. interface PHPUnit_Framework_Test extends Countable
  40257. {
  40258. /**
  40259. * Runs a test and collects its result in a TestResult instance.
  40260. *
  40261. * @param PHPUnit_Framework_TestResult $result
  40262. * @return PHPUnit_Framework_TestResult
  40263. */
  40264. public function run(PHPUnit_Framework_TestResult $result = null);
  40265. }
  40266. <?php
  40267. /*
  40268. * This file is part of PHPUnit.
  40269. *
  40270. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40271. *
  40272. * For the full copyright and license information, please view the LICENSE
  40273. * file that was distributed with this source code.
  40274. */
  40275. /**
  40276. * Base class for all PHPUnit Framework exceptions.
  40277. *
  40278. * Ensures that exceptions thrown during a test run do not leave stray
  40279. * references behind.
  40280. *
  40281. * Every Exception contains a stack trace. Each stack frame contains the 'args'
  40282. * of the called function. The function arguments can contain references to
  40283. * instantiated objects. The references prevent the objects from being
  40284. * destructed (until test results are eventually printed), so memory cannot be
  40285. * freed up.
  40286. *
  40287. * With enabled process isolation, test results are serialized in the child
  40288. * process and unserialized in the parent process. The stack trace of Exceptions
  40289. * may contain objects that cannot be serialized or unserialized (e.g., PDO
  40290. * connections). Unserializing user-space objects from the child process into
  40291. * the parent would break the intended encapsulation of process isolation.
  40292. *
  40293. * @see http://fabien.potencier.org/article/9/php-serialization-stack-traces-and-exceptions
  40294. *
  40295. * @since Class available since Release 3.4.0
  40296. */
  40297. class PHPUnit_Framework_Exception extends RuntimeException implements PHPUnit_Exception
  40298. {
  40299. /**
  40300. * @var array
  40301. */
  40302. protected $serializableTrace;
  40303. public function __construct($message = '', $code = 0, Exception $previous = null)
  40304. {
  40305. parent::__construct($message, $code, $previous);
  40306. $this->serializableTrace = $this->getTrace();
  40307. foreach ($this->serializableTrace as $i => $call) {
  40308. unset($this->serializableTrace[$i]['args']);
  40309. }
  40310. }
  40311. /**
  40312. * Returns the serializable trace (without 'args').
  40313. *
  40314. * @return array
  40315. */
  40316. public function getSerializableTrace()
  40317. {
  40318. return $this->serializableTrace;
  40319. }
  40320. /**
  40321. * @return string
  40322. */
  40323. public function __toString()
  40324. {
  40325. $string = PHPUnit_Framework_TestFailure::exceptionToString($this);
  40326. if ($trace = PHPUnit_Util_Filter::getFilteredStacktrace($this)) {
  40327. $string .= "\n" . $trace;
  40328. }
  40329. return $string;
  40330. }
  40331. public function __sleep()
  40332. {
  40333. return array_keys(get_object_vars($this));
  40334. }
  40335. }
  40336. <?php
  40337. /*
  40338. * This file is part of PHPUnit.
  40339. *
  40340. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40341. *
  40342. * For the full copyright and license information, please view the LICENSE
  40343. * file that was distributed with this source code.
  40344. */
  40345. /**
  40346. * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
  40347. * case of a test that printed output.
  40348. *
  40349. * @since Class available since Release 3.6.0
  40350. */
  40351. class PHPUnit_Framework_OutputError extends PHPUnit_Framework_AssertionFailedError
  40352. {
  40353. }
  40354. <?php
  40355. /*
  40356. * This file is part of PHPUnit.
  40357. *
  40358. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  40359. *
  40360. * For the full copyright and license information, please view the LICENSE
  40361. * file that was distributed with this source code.
  40362. */
  40363. /**
  40364. * A set of assert methods.
  40365. *
  40366. * @since Class available since Release 2.0.0
  40367. */
  40368. abstract class PHPUnit_Framework_Assert
  40369. {
  40370. /**
  40371. * @var int
  40372. */
  40373. private static $count = 0;
  40374. /**
  40375. * Asserts that an array has a specified key.
  40376. *
  40377. * @param mixed $key
  40378. * @param array|ArrayAccess $array
  40379. * @param string $message
  40380. * @since Method available since Release 3.0.0
  40381. */
  40382. public static function assertArrayHasKey($key, $array, $message = '')
  40383. {
  40384. if (!(is_integer($key) || is_string($key))) {
  40385. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40386. 1,
  40387. 'integer or string'
  40388. );
  40389. }
  40390. if (!(is_array($array) || $array instanceof ArrayAccess)) {
  40391. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40392. 2,
  40393. 'array or ArrayAccess'
  40394. );
  40395. }
  40396. $constraint = new PHPUnit_Framework_Constraint_ArrayHasKey($key);
  40397. self::assertThat($array, $constraint, $message);
  40398. }
  40399. /**
  40400. * Asserts that an array has a specified subset.
  40401. *
  40402. * @param array|ArrayAccess $subset
  40403. * @param array|ArrayAccess $array
  40404. * @param bool $strict Check for object identity
  40405. * @param string $message
  40406. * @since Method available since Release 4.4.0
  40407. */
  40408. public static function assertArraySubset($subset, $array, $strict = false, $message = '')
  40409. {
  40410. if (!is_array($subset)) {
  40411. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40412. 1,
  40413. 'array or ArrayAccess'
  40414. );
  40415. }
  40416. if (!is_array($array)) {
  40417. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40418. 2,
  40419. 'array or ArrayAccess'
  40420. );
  40421. }
  40422. $constraint = new PHPUnit_Framework_Constraint_ArraySubset($subset, $strict);
  40423. self::assertThat($array, $constraint, $message);
  40424. }
  40425. /**
  40426. * Asserts that an array does not have a specified key.
  40427. *
  40428. * @param mixed $key
  40429. * @param array|ArrayAccess $array
  40430. * @param string $message
  40431. * @since Method available since Release 3.0.0
  40432. */
  40433. public static function assertArrayNotHasKey($key, $array, $message = '')
  40434. {
  40435. if (!(is_integer($key) || is_string($key))) {
  40436. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40437. 1,
  40438. 'integer or string'
  40439. );
  40440. }
  40441. if (!(is_array($array) || $array instanceof ArrayAccess)) {
  40442. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40443. 2,
  40444. 'array or ArrayAccess'
  40445. );
  40446. }
  40447. $constraint = new PHPUnit_Framework_Constraint_Not(
  40448. new PHPUnit_Framework_Constraint_ArrayHasKey($key)
  40449. );
  40450. self::assertThat($array, $constraint, $message);
  40451. }
  40452. /**
  40453. * Asserts that a haystack contains a needle.
  40454. *
  40455. * @param mixed $needle
  40456. * @param mixed $haystack
  40457. * @param string $message
  40458. * @param bool $ignoreCase
  40459. * @param bool $checkForObjectIdentity
  40460. * @param bool $checkForNonObjectIdentity
  40461. * @since Method available since Release 2.1.0
  40462. */
  40463. public static function assertContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  40464. {
  40465. if (is_array($haystack) ||
  40466. is_object($haystack) && $haystack instanceof Traversable) {
  40467. $constraint = new PHPUnit_Framework_Constraint_TraversableContains(
  40468. $needle,
  40469. $checkForObjectIdentity,
  40470. $checkForNonObjectIdentity
  40471. );
  40472. } elseif (is_string($haystack)) {
  40473. $constraint = new PHPUnit_Framework_Constraint_StringContains(
  40474. $needle,
  40475. $ignoreCase
  40476. );
  40477. } else {
  40478. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40479. 2,
  40480. 'array, traversable or string'
  40481. );
  40482. }
  40483. self::assertThat($haystack, $constraint, $message);
  40484. }
  40485. /**
  40486. * Asserts that a haystack that is stored in a static attribute of a class
  40487. * or an attribute of an object contains a needle.
  40488. *
  40489. * @param mixed $needle
  40490. * @param string $haystackAttributeName
  40491. * @param mixed $haystackClassOrObject
  40492. * @param string $message
  40493. * @param bool $ignoreCase
  40494. * @param bool $checkForObjectIdentity
  40495. * @param bool $checkForNonObjectIdentity
  40496. * @since Method available since Release 3.0.0
  40497. */
  40498. public static function assertAttributeContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  40499. {
  40500. self::assertContains(
  40501. $needle,
  40502. self::readAttribute($haystackClassOrObject, $haystackAttributeName),
  40503. $message,
  40504. $ignoreCase,
  40505. $checkForObjectIdentity,
  40506. $checkForNonObjectIdentity
  40507. );
  40508. }
  40509. /**
  40510. * Asserts that a haystack does not contain a needle.
  40511. *
  40512. * @param mixed $needle
  40513. * @param mixed $haystack
  40514. * @param string $message
  40515. * @param bool $ignoreCase
  40516. * @param bool $checkForObjectIdentity
  40517. * @param bool $checkForNonObjectIdentity
  40518. * @since Method available since Release 2.1.0
  40519. */
  40520. public static function assertNotContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  40521. {
  40522. if (is_array($haystack) ||
  40523. is_object($haystack) && $haystack instanceof Traversable) {
  40524. $constraint = new PHPUnit_Framework_Constraint_Not(
  40525. new PHPUnit_Framework_Constraint_TraversableContains(
  40526. $needle,
  40527. $checkForObjectIdentity,
  40528. $checkForNonObjectIdentity
  40529. )
  40530. );
  40531. } elseif (is_string($haystack)) {
  40532. $constraint = new PHPUnit_Framework_Constraint_Not(
  40533. new PHPUnit_Framework_Constraint_StringContains(
  40534. $needle,
  40535. $ignoreCase
  40536. )
  40537. );
  40538. } else {
  40539. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40540. 2,
  40541. 'array, traversable or string'
  40542. );
  40543. }
  40544. self::assertThat($haystack, $constraint, $message);
  40545. }
  40546. /**
  40547. * Asserts that a haystack that is stored in a static attribute of a class
  40548. * or an attribute of an object does not contain a needle.
  40549. *
  40550. * @param mixed $needle
  40551. * @param string $haystackAttributeName
  40552. * @param mixed $haystackClassOrObject
  40553. * @param string $message
  40554. * @param bool $ignoreCase
  40555. * @param bool $checkForObjectIdentity
  40556. * @param bool $checkForNonObjectIdentity
  40557. * @since Method available since Release 3.0.0
  40558. */
  40559. public static function assertAttributeNotContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  40560. {
  40561. self::assertNotContains(
  40562. $needle,
  40563. self::readAttribute($haystackClassOrObject, $haystackAttributeName),
  40564. $message,
  40565. $ignoreCase,
  40566. $checkForObjectIdentity,
  40567. $checkForNonObjectIdentity
  40568. );
  40569. }
  40570. /**
  40571. * Asserts that a haystack contains only values of a given type.
  40572. *
  40573. * @param string $type
  40574. * @param mixed $haystack
  40575. * @param bool $isNativeType
  40576. * @param string $message
  40577. * @since Method available since Release 3.1.4
  40578. */
  40579. public static function assertContainsOnly($type, $haystack, $isNativeType = null, $message = '')
  40580. {
  40581. if (!(is_array($haystack) ||
  40582. is_object($haystack) && $haystack instanceof Traversable)) {
  40583. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40584. 2,
  40585. 'array or traversable'
  40586. );
  40587. }
  40588. if ($isNativeType == null) {
  40589. $isNativeType = PHPUnit_Util_Type::isType($type);
  40590. }
  40591. self::assertThat(
  40592. $haystack,
  40593. new PHPUnit_Framework_Constraint_TraversableContainsOnly(
  40594. $type,
  40595. $isNativeType
  40596. ),
  40597. $message
  40598. );
  40599. }
  40600. /**
  40601. * Asserts that a haystack contains only instances of a given classname
  40602. *
  40603. * @param string $classname
  40604. * @param array|Traversable $haystack
  40605. * @param string $message
  40606. */
  40607. public static function assertContainsOnlyInstancesOf($classname, $haystack, $message = '')
  40608. {
  40609. if (!(is_array($haystack) ||
  40610. is_object($haystack) && $haystack instanceof Traversable)) {
  40611. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40612. 2,
  40613. 'array or traversable'
  40614. );
  40615. }
  40616. self::assertThat(
  40617. $haystack,
  40618. new PHPUnit_Framework_Constraint_TraversableContainsOnly(
  40619. $classname,
  40620. false
  40621. ),
  40622. $message
  40623. );
  40624. }
  40625. /**
  40626. * Asserts that a haystack that is stored in a static attribute of a class
  40627. * or an attribute of an object contains only values of a given type.
  40628. *
  40629. * @param string $type
  40630. * @param string $haystackAttributeName
  40631. * @param mixed $haystackClassOrObject
  40632. * @param bool $isNativeType
  40633. * @param string $message
  40634. * @since Method available since Release 3.1.4
  40635. */
  40636. public static function assertAttributeContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = null, $message = '')
  40637. {
  40638. self::assertContainsOnly(
  40639. $type,
  40640. self::readAttribute($haystackClassOrObject, $haystackAttributeName),
  40641. $isNativeType,
  40642. $message
  40643. );
  40644. }
  40645. /**
  40646. * Asserts that a haystack does not contain only values of a given type.
  40647. *
  40648. * @param string $type
  40649. * @param mixed $haystack
  40650. * @param bool $isNativeType
  40651. * @param string $message
  40652. * @since Method available since Release 3.1.4
  40653. */
  40654. public static function assertNotContainsOnly($type, $haystack, $isNativeType = null, $message = '')
  40655. {
  40656. if (!(is_array($haystack) ||
  40657. is_object($haystack) && $haystack instanceof Traversable)) {
  40658. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  40659. 2,
  40660. 'array or traversable'
  40661. );
  40662. }
  40663. if ($isNativeType == null) {
  40664. $isNativeType = PHPUnit_Util_Type::isType($type);
  40665. }
  40666. self::assertThat(
  40667. $haystack,
  40668. new PHPUnit_Framework_Constraint_Not(
  40669. new PHPUnit_Framework_Constraint_TraversableContainsOnly(
  40670. $type,
  40671. $isNativeType
  40672. )
  40673. ),
  40674. $message
  40675. );
  40676. }
  40677. /**
  40678. * Asserts that a haystack that is stored in a static attribute of a class
  40679. * or an attribute of an object does not contain only values of a given
  40680. * type.
  40681. *
  40682. * @param string $type
  40683. * @param string $haystackAttributeName
  40684. * @param mixed $haystackClassOrObject
  40685. * @param bool $isNativeType
  40686. * @param string $message
  40687. * @since Method available since Release 3.1.4
  40688. */
  40689. public static function assertAttributeNotContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = null, $message = '')
  40690. {
  40691. self::assertNotContainsOnly(
  40692. $type,
  40693. self::readAttribute($haystackClassOrObject, $haystackAttributeName),
  40694. $isNativeType,
  40695. $message
  40696. );
  40697. }
  40698. /**
  40699. * Asserts the number of elements of an array, Countable or Traversable.
  40700. *
  40701. * @param int $expectedCount
  40702. * @param mixed $haystack
  40703. * @param string $message
  40704. */
  40705. public static function assertCount($expectedCount, $haystack, $message = '')
  40706. {
  40707. if (!is_int($expectedCount)) {
  40708. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  40709. }
  40710. if (!$haystack instanceof Countable &&
  40711. !$haystack instanceof Traversable &&
  40712. !is_array($haystack)) {
  40713. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable');
  40714. }
  40715. self::assertThat(
  40716. $haystack,
  40717. new PHPUnit_Framework_Constraint_Count($expectedCount),
  40718. $message
  40719. );
  40720. }
  40721. /**
  40722. * Asserts the number of elements of an array, Countable or Traversable
  40723. * that is stored in an attribute.
  40724. *
  40725. * @param int $expectedCount
  40726. * @param string $haystackAttributeName
  40727. * @param mixed $haystackClassOrObject
  40728. * @param string $message
  40729. * @since Method available since Release 3.6.0
  40730. */
  40731. public static function assertAttributeCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '')
  40732. {
  40733. self::assertCount(
  40734. $expectedCount,
  40735. self::readAttribute($haystackClassOrObject, $haystackAttributeName),
  40736. $message
  40737. );
  40738. }
  40739. /**
  40740. * Asserts the number of elements of an array, Countable or Traversable.
  40741. *
  40742. * @param int $expectedCount
  40743. * @param mixed $haystack
  40744. * @param string $message
  40745. */
  40746. public static function assertNotCount($expectedCount, $haystack, $message = '')
  40747. {
  40748. if (!is_int($expectedCount)) {
  40749. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  40750. }
  40751. if (!$haystack instanceof Countable &&
  40752. !$haystack instanceof Traversable &&
  40753. !is_array($haystack)) {
  40754. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable');
  40755. }
  40756. $constraint = new PHPUnit_Framework_Constraint_Not(
  40757. new PHPUnit_Framework_Constraint_Count($expectedCount)
  40758. );
  40759. self::assertThat($haystack, $constraint, $message);
  40760. }
  40761. /**
  40762. * Asserts the number of elements of an array, Countable or Traversable
  40763. * that is stored in an attribute.
  40764. *
  40765. * @param int $expectedCount
  40766. * @param string $haystackAttributeName
  40767. * @param mixed $haystackClassOrObject
  40768. * @param string $message
  40769. * @since Method available since Release 3.6.0
  40770. */
  40771. public static function assertAttributeNotCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '')
  40772. {
  40773. self::assertNotCount(
  40774. $expectedCount,
  40775. self::readAttribute($haystackClassOrObject, $haystackAttributeName),
  40776. $message
  40777. );
  40778. }
  40779. /**
  40780. * Asserts that two variables are equal.
  40781. *
  40782. * @param mixed $expected
  40783. * @param mixed $actual
  40784. * @param string $message
  40785. * @param float $delta
  40786. * @param int $maxDepth
  40787. * @param bool $canonicalize
  40788. * @param bool $ignoreCase
  40789. */
  40790. public static function assertEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  40791. {
  40792. $constraint = new PHPUnit_Framework_Constraint_IsEqual(
  40793. $expected,
  40794. $delta,
  40795. $maxDepth,
  40796. $canonicalize,
  40797. $ignoreCase
  40798. );
  40799. self::assertThat($actual, $constraint, $message);
  40800. }
  40801. /**
  40802. * Asserts that a variable is equal to an attribute of an object.
  40803. *
  40804. * @param mixed $expected
  40805. * @param string $actualAttributeName
  40806. * @param string $actualClassOrObject
  40807. * @param string $message
  40808. * @param float $delta
  40809. * @param int $maxDepth
  40810. * @param bool $canonicalize
  40811. * @param bool $ignoreCase
  40812. */
  40813. public static function assertAttributeEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  40814. {
  40815. self::assertEquals(
  40816. $expected,
  40817. self::readAttribute($actualClassOrObject, $actualAttributeName),
  40818. $message,
  40819. $delta,
  40820. $maxDepth,
  40821. $canonicalize,
  40822. $ignoreCase
  40823. );
  40824. }
  40825. /**
  40826. * Asserts that two variables are not equal.
  40827. *
  40828. * @param mixed $expected
  40829. * @param mixed $actual
  40830. * @param string $message
  40831. * @param float $delta
  40832. * @param int $maxDepth
  40833. * @param bool $canonicalize
  40834. * @param bool $ignoreCase
  40835. * @since Method available since Release 2.3.0
  40836. */
  40837. public static function assertNotEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  40838. {
  40839. $constraint = new PHPUnit_Framework_Constraint_Not(
  40840. new PHPUnit_Framework_Constraint_IsEqual(
  40841. $expected,
  40842. $delta,
  40843. $maxDepth,
  40844. $canonicalize,
  40845. $ignoreCase
  40846. )
  40847. );
  40848. self::assertThat($actual, $constraint, $message);
  40849. }
  40850. /**
  40851. * Asserts that a variable is not equal to an attribute of an object.
  40852. *
  40853. * @param mixed $expected
  40854. * @param string $actualAttributeName
  40855. * @param string $actualClassOrObject
  40856. * @param string $message
  40857. * @param float $delta
  40858. * @param int $maxDepth
  40859. * @param bool $canonicalize
  40860. * @param bool $ignoreCase
  40861. */
  40862. public static function assertAttributeNotEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  40863. {
  40864. self::assertNotEquals(
  40865. $expected,
  40866. self::readAttribute($actualClassOrObject, $actualAttributeName),
  40867. $message,
  40868. $delta,
  40869. $maxDepth,
  40870. $canonicalize,
  40871. $ignoreCase
  40872. );
  40873. }
  40874. /**
  40875. * Asserts that a variable is empty.
  40876. *
  40877. * @param mixed $actual
  40878. * @param string $message
  40879. * @throws PHPUnit_Framework_AssertionFailedError
  40880. */
  40881. public static function assertEmpty($actual, $message = '')
  40882. {
  40883. self::assertThat($actual, self::isEmpty(), $message);
  40884. }
  40885. /**
  40886. * Asserts that a static attribute of a class or an attribute of an object
  40887. * is empty.
  40888. *
  40889. * @param string $haystackAttributeName
  40890. * @param mixed $haystackClassOrObject
  40891. * @param string $message
  40892. * @since Method available since Release 3.5.0
  40893. */
  40894. public static function assertAttributeEmpty($haystackAttributeName, $haystackClassOrObject, $message = '')
  40895. {
  40896. self::assertEmpty(
  40897. self::readAttribute($haystackClassOrObject, $haystackAttributeName),
  40898. $message
  40899. );
  40900. }
  40901. /**
  40902. * Asserts that a variable is not empty.
  40903. *
  40904. * @param mixed $actual
  40905. * @param string $message
  40906. * @throws PHPUnit_Framework_AssertionFailedError
  40907. */
  40908. public static function assertNotEmpty($actual, $message = '')
  40909. {
  40910. self::assertThat($actual, self::logicalNot(self::isEmpty()), $message);
  40911. }
  40912. /**
  40913. * Asserts that a static attribute of a class or an attribute of an object
  40914. * is not empty.
  40915. *
  40916. * @param string $haystackAttributeName
  40917. * @param mixed $haystackClassOrObject
  40918. * @param string $message
  40919. * @since Method available since Release 3.5.0
  40920. */
  40921. public static function assertAttributeNotEmpty($haystackAttributeName, $haystackClassOrObject, $message = '')
  40922. {
  40923. self::assertNotEmpty(
  40924. self::readAttribute($haystackClassOrObject, $haystackAttributeName),
  40925. $message
  40926. );
  40927. }
  40928. /**
  40929. * Asserts that a value is greater than another value.
  40930. *
  40931. * @param mixed $expected
  40932. * @param mixed $actual
  40933. * @param string $message
  40934. * @since Method available since Release 3.1.0
  40935. */
  40936. public static function assertGreaterThan($expected, $actual, $message = '')
  40937. {
  40938. self::assertThat($actual, self::greaterThan($expected), $message);
  40939. }
  40940. /**
  40941. * Asserts that an attribute is greater than another value.
  40942. *
  40943. * @param mixed $expected
  40944. * @param string $actualAttributeName
  40945. * @param string $actualClassOrObject
  40946. * @param string $message
  40947. * @since Method available since Release 3.1.0
  40948. */
  40949. public static function assertAttributeGreaterThan($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  40950. {
  40951. self::assertGreaterThan(
  40952. $expected,
  40953. self::readAttribute($actualClassOrObject, $actualAttributeName),
  40954. $message
  40955. );
  40956. }
  40957. /**
  40958. * Asserts that a value is greater than or equal to another value.
  40959. *
  40960. * @param mixed $expected
  40961. * @param mixed $actual
  40962. * @param string $message
  40963. * @since Method available since Release 3.1.0
  40964. */
  40965. public static function assertGreaterThanOrEqual($expected, $actual, $message = '')
  40966. {
  40967. self::assertThat(
  40968. $actual,
  40969. self::greaterThanOrEqual($expected),
  40970. $message
  40971. );
  40972. }
  40973. /**
  40974. * Asserts that an attribute is greater than or equal to another value.
  40975. *
  40976. * @param mixed $expected
  40977. * @param string $actualAttributeName
  40978. * @param string $actualClassOrObject
  40979. * @param string $message
  40980. * @since Method available since Release 3.1.0
  40981. */
  40982. public static function assertAttributeGreaterThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  40983. {
  40984. self::assertGreaterThanOrEqual(
  40985. $expected,
  40986. self::readAttribute($actualClassOrObject, $actualAttributeName),
  40987. $message
  40988. );
  40989. }
  40990. /**
  40991. * Asserts that a value is smaller than another value.
  40992. *
  40993. * @param mixed $expected
  40994. * @param mixed $actual
  40995. * @param string $message
  40996. * @since Method available since Release 3.1.0
  40997. */
  40998. public static function assertLessThan($expected, $actual, $message = '')
  40999. {
  41000. self::assertThat($actual, self::lessThan($expected), $message);
  41001. }
  41002. /**
  41003. * Asserts that an attribute is smaller than another value.
  41004. *
  41005. * @param mixed $expected
  41006. * @param string $actualAttributeName
  41007. * @param string $actualClassOrObject
  41008. * @param string $message
  41009. * @since Method available since Release 3.1.0
  41010. */
  41011. public static function assertAttributeLessThan($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  41012. {
  41013. self::assertLessThan(
  41014. $expected,
  41015. self::readAttribute($actualClassOrObject, $actualAttributeName),
  41016. $message
  41017. );
  41018. }
  41019. /**
  41020. * Asserts that a value is smaller than or equal to another value.
  41021. *
  41022. * @param mixed $expected
  41023. * @param mixed $actual
  41024. * @param string $message
  41025. * @since Method available since Release 3.1.0
  41026. */
  41027. public static function assertLessThanOrEqual($expected, $actual, $message = '')
  41028. {
  41029. self::assertThat($actual, self::lessThanOrEqual($expected), $message);
  41030. }
  41031. /**
  41032. * Asserts that an attribute is smaller than or equal to another value.
  41033. *
  41034. * @param mixed $expected
  41035. * @param string $actualAttributeName
  41036. * @param string $actualClassOrObject
  41037. * @param string $message
  41038. * @since Method available since Release 3.1.0
  41039. */
  41040. public static function assertAttributeLessThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  41041. {
  41042. self::assertLessThanOrEqual(
  41043. $expected,
  41044. self::readAttribute($actualClassOrObject, $actualAttributeName),
  41045. $message
  41046. );
  41047. }
  41048. /**
  41049. * Asserts that the contents of one file is equal to the contents of another
  41050. * file.
  41051. *
  41052. * @param string $expected
  41053. * @param string $actual
  41054. * @param string $message
  41055. * @param bool $canonicalize
  41056. * @param bool $ignoreCase
  41057. * @since Method available since Release 3.2.14
  41058. */
  41059. public static function assertFileEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false)
  41060. {
  41061. self::assertFileExists($expected, $message);
  41062. self::assertFileExists($actual, $message);
  41063. self::assertEquals(
  41064. file_get_contents($expected),
  41065. file_get_contents($actual),
  41066. $message,
  41067. 0,
  41068. 10,
  41069. $canonicalize,
  41070. $ignoreCase
  41071. );
  41072. }
  41073. /**
  41074. * Asserts that the contents of one file is not equal to the contents of
  41075. * another file.
  41076. *
  41077. * @param string $expected
  41078. * @param string $actual
  41079. * @param string $message
  41080. * @param bool $canonicalize
  41081. * @param bool $ignoreCase
  41082. * @since Method available since Release 3.2.14
  41083. */
  41084. public static function assertFileNotEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false)
  41085. {
  41086. self::assertFileExists($expected, $message);
  41087. self::assertFileExists($actual, $message);
  41088. self::assertNotEquals(
  41089. file_get_contents($expected),
  41090. file_get_contents($actual),
  41091. $message,
  41092. 0,
  41093. 10,
  41094. $canonicalize,
  41095. $ignoreCase
  41096. );
  41097. }
  41098. /**
  41099. * Asserts that the contents of a string is equal
  41100. * to the contents of a file.
  41101. *
  41102. * @param string $expectedFile
  41103. * @param string $actualString
  41104. * @param string $message
  41105. * @param bool $canonicalize
  41106. * @param bool $ignoreCase
  41107. * @since Method available since Release 3.3.0
  41108. */
  41109. public static function assertStringEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false)
  41110. {
  41111. self::assertFileExists($expectedFile, $message);
  41112. self::assertEquals(
  41113. file_get_contents($expectedFile),
  41114. $actualString,
  41115. $message,
  41116. 0,
  41117. 10,
  41118. $canonicalize,
  41119. $ignoreCase
  41120. );
  41121. }
  41122. /**
  41123. * Asserts that the contents of a string is not equal
  41124. * to the contents of a file.
  41125. *
  41126. * @param string $expectedFile
  41127. * @param string $actualString
  41128. * @param string $message
  41129. * @param bool $canonicalize
  41130. * @param bool $ignoreCase
  41131. * @since Method available since Release 3.3.0
  41132. */
  41133. public static function assertStringNotEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false)
  41134. {
  41135. self::assertFileExists($expectedFile, $message);
  41136. self::assertNotEquals(
  41137. file_get_contents($expectedFile),
  41138. $actualString,
  41139. $message,
  41140. 0,
  41141. 10,
  41142. $canonicalize,
  41143. $ignoreCase
  41144. );
  41145. }
  41146. /**
  41147. * Asserts that a file exists.
  41148. *
  41149. * @param string $filename
  41150. * @param string $message
  41151. * @since Method available since Release 3.0.0
  41152. */
  41153. public static function assertFileExists($filename, $message = '')
  41154. {
  41155. if (!is_string($filename)) {
  41156. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41157. }
  41158. $constraint = new PHPUnit_Framework_Constraint_FileExists;
  41159. self::assertThat($filename, $constraint, $message);
  41160. }
  41161. /**
  41162. * Asserts that a file does not exist.
  41163. *
  41164. * @param string $filename
  41165. * @param string $message
  41166. * @since Method available since Release 3.0.0
  41167. */
  41168. public static function assertFileNotExists($filename, $message = '')
  41169. {
  41170. if (!is_string($filename)) {
  41171. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41172. }
  41173. $constraint = new PHPUnit_Framework_Constraint_Not(
  41174. new PHPUnit_Framework_Constraint_FileExists
  41175. );
  41176. self::assertThat($filename, $constraint, $message);
  41177. }
  41178. /**
  41179. * Asserts that a condition is true.
  41180. *
  41181. * @param bool $condition
  41182. * @param string $message
  41183. * @throws PHPUnit_Framework_AssertionFailedError
  41184. */
  41185. public static function assertTrue($condition, $message = '')
  41186. {
  41187. self::assertThat($condition, self::isTrue(), $message);
  41188. }
  41189. /**
  41190. * Asserts that a condition is not true.
  41191. *
  41192. * @param bool $condition
  41193. * @param string $message
  41194. * @throws PHPUnit_Framework_AssertionFailedError
  41195. */
  41196. public static function assertNotTrue($condition, $message = '')
  41197. {
  41198. self::assertThat($condition, self::logicalNot(self::isTrue()), $message);
  41199. }
  41200. /**
  41201. * Asserts that a condition is false.
  41202. *
  41203. * @param bool $condition
  41204. * @param string $message
  41205. * @throws PHPUnit_Framework_AssertionFailedError
  41206. */
  41207. public static function assertFalse($condition, $message = '')
  41208. {
  41209. self::assertThat($condition, self::isFalse(), $message);
  41210. }
  41211. /**
  41212. * Asserts that a condition is not false.
  41213. *
  41214. * @param bool $condition
  41215. * @param string $message
  41216. * @throws PHPUnit_Framework_AssertionFailedError
  41217. */
  41218. public static function assertNotFalse($condition, $message = '')
  41219. {
  41220. self::assertThat($condition, self::logicalNot(self::isFalse()), $message);
  41221. }
  41222. /**
  41223. * Asserts that a variable is not null.
  41224. *
  41225. * @param mixed $actual
  41226. * @param string $message
  41227. */
  41228. public static function assertNotNull($actual, $message = '')
  41229. {
  41230. self::assertThat($actual, self::logicalNot(self::isNull()), $message);
  41231. }
  41232. /**
  41233. * Asserts that a variable is null.
  41234. *
  41235. * @param mixed $actual
  41236. * @param string $message
  41237. */
  41238. public static function assertNull($actual, $message = '')
  41239. {
  41240. self::assertThat($actual, self::isNull(), $message);
  41241. }
  41242. /**
  41243. * Asserts that a class has a specified attribute.
  41244. *
  41245. * @param string $attributeName
  41246. * @param string $className
  41247. * @param string $message
  41248. * @since Method available since Release 3.1.0
  41249. */
  41250. public static function assertClassHasAttribute($attributeName, $className, $message = '')
  41251. {
  41252. if (!is_string($attributeName)) {
  41253. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41254. }
  41255. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  41256. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
  41257. }
  41258. if (!is_string($className) || !class_exists($className)) {
  41259. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name', $className);
  41260. }
  41261. $constraint = new PHPUnit_Framework_Constraint_ClassHasAttribute(
  41262. $attributeName
  41263. );
  41264. self::assertThat($className, $constraint, $message);
  41265. }
  41266. /**
  41267. * Asserts that a class does not have a specified attribute.
  41268. *
  41269. * @param string $attributeName
  41270. * @param string $className
  41271. * @param string $message
  41272. * @since Method available since Release 3.1.0
  41273. */
  41274. public static function assertClassNotHasAttribute($attributeName, $className, $message = '')
  41275. {
  41276. if (!is_string($attributeName)) {
  41277. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41278. }
  41279. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  41280. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
  41281. }
  41282. if (!is_string($className) || !class_exists($className)) {
  41283. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name', $className);
  41284. }
  41285. $constraint = new PHPUnit_Framework_Constraint_Not(
  41286. new PHPUnit_Framework_Constraint_ClassHasAttribute($attributeName)
  41287. );
  41288. self::assertThat($className, $constraint, $message);
  41289. }
  41290. /**
  41291. * Asserts that a class has a specified static attribute.
  41292. *
  41293. * @param string $attributeName
  41294. * @param string $className
  41295. * @param string $message
  41296. * @since Method available since Release 3.1.0
  41297. */
  41298. public static function assertClassHasStaticAttribute($attributeName, $className, $message = '')
  41299. {
  41300. if (!is_string($attributeName)) {
  41301. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41302. }
  41303. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  41304. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
  41305. }
  41306. if (!is_string($className) || !class_exists($className)) {
  41307. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name', $className);
  41308. }
  41309. $constraint = new PHPUnit_Framework_Constraint_ClassHasStaticAttribute(
  41310. $attributeName
  41311. );
  41312. self::assertThat($className, $constraint, $message);
  41313. }
  41314. /**
  41315. * Asserts that a class does not have a specified static attribute.
  41316. *
  41317. * @param string $attributeName
  41318. * @param string $className
  41319. * @param string $message
  41320. * @since Method available since Release 3.1.0
  41321. */
  41322. public static function assertClassNotHasStaticAttribute($attributeName, $className, $message = '')
  41323. {
  41324. if (!is_string($attributeName)) {
  41325. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41326. }
  41327. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  41328. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
  41329. }
  41330. if (!is_string($className) || !class_exists($className)) {
  41331. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name', $className);
  41332. }
  41333. $constraint = new PHPUnit_Framework_Constraint_Not(
  41334. new PHPUnit_Framework_Constraint_ClassHasStaticAttribute(
  41335. $attributeName
  41336. )
  41337. );
  41338. self::assertThat($className, $constraint, $message);
  41339. }
  41340. /**
  41341. * Asserts that an object has a specified attribute.
  41342. *
  41343. * @param string $attributeName
  41344. * @param object $object
  41345. * @param string $message
  41346. * @since Method available since Release 3.0.0
  41347. */
  41348. public static function assertObjectHasAttribute($attributeName, $object, $message = '')
  41349. {
  41350. if (!is_string($attributeName)) {
  41351. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41352. }
  41353. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  41354. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
  41355. }
  41356. if (!is_object($object)) {
  41357. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'object');
  41358. }
  41359. $constraint = new PHPUnit_Framework_Constraint_ObjectHasAttribute(
  41360. $attributeName
  41361. );
  41362. self::assertThat($object, $constraint, $message);
  41363. }
  41364. /**
  41365. * Asserts that an object does not have a specified attribute.
  41366. *
  41367. * @param string $attributeName
  41368. * @param object $object
  41369. * @param string $message
  41370. * @since Method available since Release 3.0.0
  41371. */
  41372. public static function assertObjectNotHasAttribute($attributeName, $object, $message = '')
  41373. {
  41374. if (!is_string($attributeName)) {
  41375. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41376. }
  41377. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  41378. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name');
  41379. }
  41380. if (!is_object($object)) {
  41381. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'object');
  41382. }
  41383. $constraint = new PHPUnit_Framework_Constraint_Not(
  41384. new PHPUnit_Framework_Constraint_ObjectHasAttribute($attributeName)
  41385. );
  41386. self::assertThat($object, $constraint, $message);
  41387. }
  41388. /**
  41389. * Asserts that two variables have the same type and value.
  41390. * Used on objects, it asserts that two variables reference
  41391. * the same object.
  41392. *
  41393. * @param mixed $expected
  41394. * @param mixed $actual
  41395. * @param string $message
  41396. */
  41397. public static function assertSame($expected, $actual, $message = '')
  41398. {
  41399. if (is_bool($expected) && is_bool($actual)) {
  41400. self::assertEquals($expected, $actual, $message);
  41401. } else {
  41402. $constraint = new PHPUnit_Framework_Constraint_IsIdentical(
  41403. $expected
  41404. );
  41405. self::assertThat($actual, $constraint, $message);
  41406. }
  41407. }
  41408. /**
  41409. * Asserts that a variable and an attribute of an object have the same type
  41410. * and value.
  41411. *
  41412. * @param mixed $expected
  41413. * @param string $actualAttributeName
  41414. * @param object $actualClassOrObject
  41415. * @param string $message
  41416. */
  41417. public static function assertAttributeSame($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  41418. {
  41419. self::assertSame(
  41420. $expected,
  41421. self::readAttribute($actualClassOrObject, $actualAttributeName),
  41422. $message
  41423. );
  41424. }
  41425. /**
  41426. * Asserts that two variables do not have the same type and value.
  41427. * Used on objects, it asserts that two variables do not reference
  41428. * the same object.
  41429. *
  41430. * @param mixed $expected
  41431. * @param mixed $actual
  41432. * @param string $message
  41433. */
  41434. public static function assertNotSame($expected, $actual, $message = '')
  41435. {
  41436. if (is_bool($expected) && is_bool($actual)) {
  41437. self::assertNotEquals($expected, $actual, $message);
  41438. } else {
  41439. $constraint = new PHPUnit_Framework_Constraint_Not(
  41440. new PHPUnit_Framework_Constraint_IsIdentical($expected)
  41441. );
  41442. self::assertThat($actual, $constraint, $message);
  41443. }
  41444. }
  41445. /**
  41446. * Asserts that a variable and an attribute of an object do not have the
  41447. * same type and value.
  41448. *
  41449. * @param mixed $expected
  41450. * @param string $actualAttributeName
  41451. * @param object $actualClassOrObject
  41452. * @param string $message
  41453. */
  41454. public static function assertAttributeNotSame($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  41455. {
  41456. self::assertNotSame(
  41457. $expected,
  41458. self::readAttribute($actualClassOrObject, $actualAttributeName),
  41459. $message
  41460. );
  41461. }
  41462. /**
  41463. * Asserts that a variable is of a given type.
  41464. *
  41465. * @param string $expected
  41466. * @param mixed $actual
  41467. * @param string $message
  41468. * @since Method available since Release 3.5.0
  41469. */
  41470. public static function assertInstanceOf($expected, $actual, $message = '')
  41471. {
  41472. if (!(is_string($expected) && (class_exists($expected) || interface_exists($expected)))) {
  41473. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class or interface name');
  41474. }
  41475. $constraint = new PHPUnit_Framework_Constraint_IsInstanceOf(
  41476. $expected
  41477. );
  41478. self::assertThat($actual, $constraint, $message);
  41479. }
  41480. /**
  41481. * Asserts that an attribute is of a given type.
  41482. *
  41483. * @param string $expected
  41484. * @param string $attributeName
  41485. * @param mixed $classOrObject
  41486. * @param string $message
  41487. * @since Method available since Release 3.5.0
  41488. */
  41489. public static function assertAttributeInstanceOf($expected, $attributeName, $classOrObject, $message = '')
  41490. {
  41491. self::assertInstanceOf(
  41492. $expected,
  41493. self::readAttribute($classOrObject, $attributeName),
  41494. $message
  41495. );
  41496. }
  41497. /**
  41498. * Asserts that a variable is not of a given type.
  41499. *
  41500. * @param string $expected
  41501. * @param mixed $actual
  41502. * @param string $message
  41503. * @since Method available since Release 3.5.0
  41504. */
  41505. public static function assertNotInstanceOf($expected, $actual, $message = '')
  41506. {
  41507. if (!(is_string($expected) && (class_exists($expected) || interface_exists($expected)))) {
  41508. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class or interface name');
  41509. }
  41510. $constraint = new PHPUnit_Framework_Constraint_Not(
  41511. new PHPUnit_Framework_Constraint_IsInstanceOf($expected)
  41512. );
  41513. self::assertThat($actual, $constraint, $message);
  41514. }
  41515. /**
  41516. * Asserts that an attribute is of a given type.
  41517. *
  41518. * @param string $expected
  41519. * @param string $attributeName
  41520. * @param mixed $classOrObject
  41521. * @param string $message
  41522. * @since Method available since Release 3.5.0
  41523. */
  41524. public static function assertAttributeNotInstanceOf($expected, $attributeName, $classOrObject, $message = '')
  41525. {
  41526. self::assertNotInstanceOf(
  41527. $expected,
  41528. self::readAttribute($classOrObject, $attributeName),
  41529. $message
  41530. );
  41531. }
  41532. /**
  41533. * Asserts that a variable is of a given type.
  41534. *
  41535. * @param string $expected
  41536. * @param mixed $actual
  41537. * @param string $message
  41538. * @since Method available since Release 3.5.0
  41539. */
  41540. public static function assertInternalType($expected, $actual, $message = '')
  41541. {
  41542. if (!is_string($expected)) {
  41543. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41544. }
  41545. $constraint = new PHPUnit_Framework_Constraint_IsType(
  41546. $expected
  41547. );
  41548. self::assertThat($actual, $constraint, $message);
  41549. }
  41550. /**
  41551. * Asserts that an attribute is of a given type.
  41552. *
  41553. * @param string $expected
  41554. * @param string $attributeName
  41555. * @param mixed $classOrObject
  41556. * @param string $message
  41557. * @since Method available since Release 3.5.0
  41558. */
  41559. public static function assertAttributeInternalType($expected, $attributeName, $classOrObject, $message = '')
  41560. {
  41561. self::assertInternalType(
  41562. $expected,
  41563. self::readAttribute($classOrObject, $attributeName),
  41564. $message
  41565. );
  41566. }
  41567. /**
  41568. * Asserts that a variable is not of a given type.
  41569. *
  41570. * @param string $expected
  41571. * @param mixed $actual
  41572. * @param string $message
  41573. * @since Method available since Release 3.5.0
  41574. */
  41575. public static function assertNotInternalType($expected, $actual, $message = '')
  41576. {
  41577. if (!is_string($expected)) {
  41578. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41579. }
  41580. $constraint = new PHPUnit_Framework_Constraint_Not(
  41581. new PHPUnit_Framework_Constraint_IsType($expected)
  41582. );
  41583. self::assertThat($actual, $constraint, $message);
  41584. }
  41585. /**
  41586. * Asserts that an attribute is of a given type.
  41587. *
  41588. * @param string $expected
  41589. * @param string $attributeName
  41590. * @param mixed $classOrObject
  41591. * @param string $message
  41592. * @since Method available since Release 3.5.0
  41593. */
  41594. public static function assertAttributeNotInternalType($expected, $attributeName, $classOrObject, $message = '')
  41595. {
  41596. self::assertNotInternalType(
  41597. $expected,
  41598. self::readAttribute($classOrObject, $attributeName),
  41599. $message
  41600. );
  41601. }
  41602. /**
  41603. * Asserts that a string matches a given regular expression.
  41604. *
  41605. * @param string $pattern
  41606. * @param string $string
  41607. * @param string $message
  41608. */
  41609. public static function assertRegExp($pattern, $string, $message = '')
  41610. {
  41611. if (!is_string($pattern)) {
  41612. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41613. }
  41614. if (!is_string($string)) {
  41615. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  41616. }
  41617. $constraint = new PHPUnit_Framework_Constraint_PCREMatch($pattern);
  41618. self::assertThat($string, $constraint, $message);
  41619. }
  41620. /**
  41621. * Asserts that a string does not match a given regular expression.
  41622. *
  41623. * @param string $pattern
  41624. * @param string $string
  41625. * @param string $message
  41626. * @since Method available since Release 2.1.0
  41627. */
  41628. public static function assertNotRegExp($pattern, $string, $message = '')
  41629. {
  41630. if (!is_string($pattern)) {
  41631. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41632. }
  41633. if (!is_string($string)) {
  41634. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  41635. }
  41636. $constraint = new PHPUnit_Framework_Constraint_Not(
  41637. new PHPUnit_Framework_Constraint_PCREMatch($pattern)
  41638. );
  41639. self::assertThat($string, $constraint, $message);
  41640. }
  41641. /**
  41642. * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
  41643. * is the same.
  41644. *
  41645. * @param array|Countable|Traversable $expected
  41646. * @param array|Countable|Traversable $actual
  41647. * @param string $message
  41648. */
  41649. public static function assertSameSize($expected, $actual, $message = '')
  41650. {
  41651. if (!$expected instanceof Countable &&
  41652. !$expected instanceof Traversable &&
  41653. !is_array($expected)) {
  41654. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'countable or traversable');
  41655. }
  41656. if (!$actual instanceof Countable &&
  41657. !$actual instanceof Traversable &&
  41658. !is_array($actual)) {
  41659. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable');
  41660. }
  41661. self::assertThat(
  41662. $actual,
  41663. new PHPUnit_Framework_Constraint_SameSize($expected),
  41664. $message
  41665. );
  41666. }
  41667. /**
  41668. * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
  41669. * is not the same.
  41670. *
  41671. * @param array|Countable|Traversable $expected
  41672. * @param array|Countable|Traversable $actual
  41673. * @param string $message
  41674. */
  41675. public static function assertNotSameSize($expected, $actual, $message = '')
  41676. {
  41677. if (!$expected instanceof Countable &&
  41678. !$expected instanceof Traversable &&
  41679. !is_array($expected)) {
  41680. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'countable or traversable');
  41681. }
  41682. if (!$actual instanceof Countable &&
  41683. !$actual instanceof Traversable &&
  41684. !is_array($actual)) {
  41685. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable');
  41686. }
  41687. $constraint = new PHPUnit_Framework_Constraint_Not(
  41688. new PHPUnit_Framework_Constraint_SameSize($expected)
  41689. );
  41690. self::assertThat($actual, $constraint, $message);
  41691. }
  41692. /**
  41693. * Asserts that a string matches a given format string.
  41694. *
  41695. * @param string $format
  41696. * @param string $string
  41697. * @param string $message
  41698. * @since Method available since Release 3.5.0
  41699. */
  41700. public static function assertStringMatchesFormat($format, $string, $message = '')
  41701. {
  41702. if (!is_string($format)) {
  41703. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41704. }
  41705. if (!is_string($string)) {
  41706. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  41707. }
  41708. $constraint = new PHPUnit_Framework_Constraint_StringMatches($format);
  41709. self::assertThat($string, $constraint, $message);
  41710. }
  41711. /**
  41712. * Asserts that a string does not match a given format string.
  41713. *
  41714. * @param string $format
  41715. * @param string $string
  41716. * @param string $message
  41717. * @since Method available since Release 3.5.0
  41718. */
  41719. public static function assertStringNotMatchesFormat($format, $string, $message = '')
  41720. {
  41721. if (!is_string($format)) {
  41722. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41723. }
  41724. if (!is_string($string)) {
  41725. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  41726. }
  41727. $constraint = new PHPUnit_Framework_Constraint_Not(
  41728. new PHPUnit_Framework_Constraint_StringMatches($format)
  41729. );
  41730. self::assertThat($string, $constraint, $message);
  41731. }
  41732. /**
  41733. * Asserts that a string matches a given format file.
  41734. *
  41735. * @param string $formatFile
  41736. * @param string $string
  41737. * @param string $message
  41738. * @since Method available since Release 3.5.0
  41739. */
  41740. public static function assertStringMatchesFormatFile($formatFile, $string, $message = '')
  41741. {
  41742. self::assertFileExists($formatFile, $message);
  41743. if (!is_string($string)) {
  41744. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  41745. }
  41746. $constraint = new PHPUnit_Framework_Constraint_StringMatches(
  41747. file_get_contents($formatFile)
  41748. );
  41749. self::assertThat($string, $constraint, $message);
  41750. }
  41751. /**
  41752. * Asserts that a string does not match a given format string.
  41753. *
  41754. * @param string $formatFile
  41755. * @param string $string
  41756. * @param string $message
  41757. * @since Method available since Release 3.5.0
  41758. */
  41759. public static function assertStringNotMatchesFormatFile($formatFile, $string, $message = '')
  41760. {
  41761. self::assertFileExists($formatFile, $message);
  41762. if (!is_string($string)) {
  41763. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  41764. }
  41765. $constraint = new PHPUnit_Framework_Constraint_Not(
  41766. new PHPUnit_Framework_Constraint_StringMatches(
  41767. file_get_contents($formatFile)
  41768. )
  41769. );
  41770. self::assertThat($string, $constraint, $message);
  41771. }
  41772. /**
  41773. * Asserts that a string starts with a given prefix.
  41774. *
  41775. * @param string $prefix
  41776. * @param string $string
  41777. * @param string $message
  41778. * @since Method available since Release 3.4.0
  41779. */
  41780. public static function assertStringStartsWith($prefix, $string, $message = '')
  41781. {
  41782. if (!is_string($prefix)) {
  41783. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41784. }
  41785. if (!is_string($string)) {
  41786. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  41787. }
  41788. $constraint = new PHPUnit_Framework_Constraint_StringStartsWith(
  41789. $prefix
  41790. );
  41791. self::assertThat($string, $constraint, $message);
  41792. }
  41793. /**
  41794. * Asserts that a string starts not with a given prefix.
  41795. *
  41796. * @param string $prefix
  41797. * @param string $string
  41798. * @param string $message
  41799. * @since Method available since Release 3.4.0
  41800. */
  41801. public static function assertStringStartsNotWith($prefix, $string, $message = '')
  41802. {
  41803. if (!is_string($prefix)) {
  41804. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41805. }
  41806. if (!is_string($string)) {
  41807. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  41808. }
  41809. $constraint = new PHPUnit_Framework_Constraint_Not(
  41810. new PHPUnit_Framework_Constraint_StringStartsWith($prefix)
  41811. );
  41812. self::assertThat($string, $constraint, $message);
  41813. }
  41814. /**
  41815. * Asserts that a string ends with a given suffix.
  41816. *
  41817. * @param string $suffix
  41818. * @param string $string
  41819. * @param string $message
  41820. * @since Method available since Release 3.4.0
  41821. */
  41822. public static function assertStringEndsWith($suffix, $string, $message = '')
  41823. {
  41824. if (!is_string($suffix)) {
  41825. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41826. }
  41827. if (!is_string($string)) {
  41828. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  41829. }
  41830. $constraint = new PHPUnit_Framework_Constraint_StringEndsWith($suffix);
  41831. self::assertThat($string, $constraint, $message);
  41832. }
  41833. /**
  41834. * Asserts that a string ends not with a given suffix.
  41835. *
  41836. * @param string $suffix
  41837. * @param string $string
  41838. * @param string $message
  41839. * @since Method available since Release 3.4.0
  41840. */
  41841. public static function assertStringEndsNotWith($suffix, $string, $message = '')
  41842. {
  41843. if (!is_string($suffix)) {
  41844. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  41845. }
  41846. if (!is_string($string)) {
  41847. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  41848. }
  41849. $constraint = new PHPUnit_Framework_Constraint_Not(
  41850. new PHPUnit_Framework_Constraint_StringEndsWith($suffix)
  41851. );
  41852. self::assertThat($string, $constraint, $message);
  41853. }
  41854. /**
  41855. * Asserts that two XML files are equal.
  41856. *
  41857. * @param string $expectedFile
  41858. * @param string $actualFile
  41859. * @param string $message
  41860. * @since Method available since Release 3.1.0
  41861. */
  41862. public static function assertXmlFileEqualsXmlFile($expectedFile, $actualFile, $message = '')
  41863. {
  41864. self::assertFileExists($expectedFile);
  41865. self::assertFileExists($actualFile);
  41866. $expected = new DOMDocument;
  41867. $expected->preserveWhiteSpace = false;
  41868. $expected->load($expectedFile);
  41869. $actual = new DOMDocument;
  41870. $actual->preserveWhiteSpace = false;
  41871. $actual->load($actualFile);
  41872. self::assertEquals($expected, $actual, $message);
  41873. }
  41874. /**
  41875. * Asserts that two XML files are not equal.
  41876. *
  41877. * @param string $expectedFile
  41878. * @param string $actualFile
  41879. * @param string $message
  41880. * @since Method available since Release 3.1.0
  41881. */
  41882. public static function assertXmlFileNotEqualsXmlFile($expectedFile, $actualFile, $message = '')
  41883. {
  41884. self::assertFileExists($expectedFile);
  41885. self::assertFileExists($actualFile);
  41886. $expected = new DOMDocument;
  41887. $expected->preserveWhiteSpace = false;
  41888. $expected->load($expectedFile);
  41889. $actual = new DOMDocument;
  41890. $actual->preserveWhiteSpace = false;
  41891. $actual->load($actualFile);
  41892. self::assertNotEquals($expected, $actual, $message);
  41893. }
  41894. /**
  41895. * Asserts that two XML documents are equal.
  41896. *
  41897. * @param string $expectedFile
  41898. * @param string $actualXml
  41899. * @param string $message
  41900. * @since Method available since Release 3.3.0
  41901. */
  41902. public static function assertXmlStringEqualsXmlFile($expectedFile, $actualXml, $message = '')
  41903. {
  41904. self::assertFileExists($expectedFile);
  41905. $expected = new DOMDocument;
  41906. $expected->preserveWhiteSpace = false;
  41907. $expected->load($expectedFile);
  41908. $actual = new DOMDocument;
  41909. $actual->preserveWhiteSpace = false;
  41910. $actual->loadXML($actualXml);
  41911. self::assertEquals($expected, $actual, $message);
  41912. }
  41913. /**
  41914. * Asserts that two XML documents are not equal.
  41915. *
  41916. * @param string $expectedFile
  41917. * @param string $actualXml
  41918. * @param string $message
  41919. * @since Method available since Release 3.3.0
  41920. */
  41921. public static function assertXmlStringNotEqualsXmlFile($expectedFile, $actualXml, $message = '')
  41922. {
  41923. self::assertFileExists($expectedFile);
  41924. $expected = new DOMDocument;
  41925. $expected->preserveWhiteSpace = false;
  41926. $expected->load($expectedFile);
  41927. $actual = new DOMDocument;
  41928. $actual->preserveWhiteSpace = false;
  41929. $actual->loadXML($actualXml);
  41930. self::assertNotEquals($expected, $actual, $message);
  41931. }
  41932. /**
  41933. * Asserts that two XML documents are equal.
  41934. *
  41935. * @param string $expectedXml
  41936. * @param string $actualXml
  41937. * @param string $message
  41938. * @since Method available since Release 3.1.0
  41939. */
  41940. public static function assertXmlStringEqualsXmlString($expectedXml, $actualXml, $message = '')
  41941. {
  41942. $expected = new DOMDocument;
  41943. $expected->preserveWhiteSpace = false;
  41944. $expected->loadXML($expectedXml);
  41945. $actual = new DOMDocument;
  41946. $actual->preserveWhiteSpace = false;
  41947. $actual->loadXML($actualXml);
  41948. self::assertEquals($expected, $actual, $message);
  41949. }
  41950. /**
  41951. * Asserts that two XML documents are not equal.
  41952. *
  41953. * @param string $expectedXml
  41954. * @param string $actualXml
  41955. * @param string $message
  41956. * @since Method available since Release 3.1.0
  41957. */
  41958. public static function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, $message = '')
  41959. {
  41960. $expected = new DOMDocument;
  41961. $expected->preserveWhiteSpace = false;
  41962. $expected->loadXML($expectedXml);
  41963. $actual = new DOMDocument;
  41964. $actual->preserveWhiteSpace = false;
  41965. $actual->loadXML($actualXml);
  41966. self::assertNotEquals($expected, $actual, $message);
  41967. }
  41968. /**
  41969. * Asserts that a hierarchy of DOMElements matches.
  41970. *
  41971. * @param DOMElement $expectedElement
  41972. * @param DOMElement $actualElement
  41973. * @param bool $checkAttributes
  41974. * @param string $message
  41975. * @since Method available since Release 3.3.0
  41976. */
  41977. public static function assertEqualXMLStructure(DOMElement $expectedElement, DOMElement $actualElement, $checkAttributes = false, $message = '')
  41978. {
  41979. $expectedElement = clone $expectedElement;
  41980. $actualElement = clone $actualElement;
  41981. self::assertEquals(
  41982. $expectedElement->tagName,
  41983. $actualElement->tagName,
  41984. $message
  41985. );
  41986. if ($checkAttributes) {
  41987. self::assertEquals(
  41988. $expectedElement->attributes->length,
  41989. $actualElement->attributes->length,
  41990. sprintf(
  41991. '%s%sNumber of attributes on node "%s" does not match',
  41992. $message,
  41993. !empty($message) ? "\n" : '',
  41994. $expectedElement->tagName
  41995. )
  41996. );
  41997. for ($i = 0; $i < $expectedElement->attributes->length; $i++) {
  41998. $expectedAttribute = $expectedElement->attributes->item($i);
  41999. $actualAttribute = $actualElement->attributes->getNamedItem(
  42000. $expectedAttribute->name
  42001. );
  42002. if (!$actualAttribute) {
  42003. self::fail(
  42004. sprintf(
  42005. '%s%sCould not find attribute "%s" on node "%s"',
  42006. $message,
  42007. !empty($message) ? "\n" : '',
  42008. $expectedAttribute->name,
  42009. $expectedElement->tagName
  42010. )
  42011. );
  42012. }
  42013. }
  42014. }
  42015. PHPUnit_Util_XML::removeCharacterDataNodes($expectedElement);
  42016. PHPUnit_Util_XML::removeCharacterDataNodes($actualElement);
  42017. self::assertEquals(
  42018. $expectedElement->childNodes->length,
  42019. $actualElement->childNodes->length,
  42020. sprintf(
  42021. '%s%sNumber of child nodes of "%s" differs',
  42022. $message,
  42023. !empty($message) ? "\n" : '',
  42024. $expectedElement->tagName
  42025. )
  42026. );
  42027. for ($i = 0; $i < $expectedElement->childNodes->length; $i++) {
  42028. self::assertEqualXMLStructure(
  42029. $expectedElement->childNodes->item($i),
  42030. $actualElement->childNodes->item($i),
  42031. $checkAttributes,
  42032. $message
  42033. );
  42034. }
  42035. }
  42036. /**
  42037. * Assert the presence, absence, or count of elements in a document matching
  42038. * the CSS $selector, regardless of the contents of those elements.
  42039. *
  42040. * The first argument, $selector, is the CSS selector used to match
  42041. * the elements in the $actual document.
  42042. *
  42043. * The second argument, $count, can be either boolean or numeric.
  42044. * When boolean, it asserts for presence of elements matching the selector
  42045. * (true) or absence of elements (false).
  42046. * When numeric, it asserts the count of elements.
  42047. *
  42048. * assertSelectCount("#binder", true, $xml); // any?
  42049. * assertSelectCount(".binder", 3, $xml); // exactly 3?
  42050. *
  42051. * @param array $selector
  42052. * @param int|bool|array $count
  42053. * @param mixed $actual
  42054. * @param string $message
  42055. * @param bool $isHtml
  42056. * @since Method available since Release 3.3.0
  42057. * @deprecated
  42058. * @codeCoverageIgnore
  42059. */
  42060. public static function assertSelectCount($selector, $count, $actual, $message = '', $isHtml = true)
  42061. {
  42062. trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED);
  42063. self::assertSelectEquals(
  42064. $selector,
  42065. true,
  42066. $count,
  42067. $actual,
  42068. $message,
  42069. $isHtml
  42070. );
  42071. }
  42072. /**
  42073. * assertSelectRegExp("#binder .name", "/Mike|Derek/", true, $xml); // any?
  42074. * assertSelectRegExp("#binder .name", "/Mike|Derek/", 3, $xml); // 3?
  42075. *
  42076. * @param array $selector
  42077. * @param string $pattern
  42078. * @param int|bool|array $count
  42079. * @param mixed $actual
  42080. * @param string $message
  42081. * @param bool $isHtml
  42082. * @since Method available since Release 3.3.0
  42083. * @deprecated
  42084. * @codeCoverageIgnore
  42085. */
  42086. public static function assertSelectRegExp($selector, $pattern, $count, $actual, $message = '', $isHtml = true)
  42087. {
  42088. trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED);
  42089. self::assertSelectEquals(
  42090. $selector,
  42091. "regexp:$pattern",
  42092. $count,
  42093. $actual,
  42094. $message,
  42095. $isHtml
  42096. );
  42097. }
  42098. /**
  42099. * assertSelectEquals("#binder .name", "Chuck", true, $xml); // any?
  42100. * assertSelectEquals("#binder .name", "Chuck", false, $xml); // none?
  42101. *
  42102. * @param array $selector
  42103. * @param string $content
  42104. * @param int|bool|array $count
  42105. * @param mixed $actual
  42106. * @param string $message
  42107. * @param bool $isHtml
  42108. * @since Method available since Release 3.3.0
  42109. * @deprecated
  42110. * @codeCoverageIgnore
  42111. */
  42112. public static function assertSelectEquals($selector, $content, $count, $actual, $message = '', $isHtml = true)
  42113. {
  42114. trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED);
  42115. $tags = PHPUnit_Util_XML::cssSelect(
  42116. $selector,
  42117. $content,
  42118. $actual,
  42119. $isHtml
  42120. );
  42121. // assert specific number of elements
  42122. if (is_numeric($count)) {
  42123. $counted = $tags ? count($tags) : 0;
  42124. self::assertEquals($count, $counted, $message);
  42125. } // assert any elements exist if true, assert no elements exist if false
  42126. elseif (is_bool($count)) {
  42127. $any = count($tags) > 0 && $tags[0] instanceof DOMNode;
  42128. if ($count) {
  42129. self::assertTrue($any, $message);
  42130. } else {
  42131. self::assertFalse($any, $message);
  42132. }
  42133. } // check for range number of elements
  42134. elseif (is_array($count) &&
  42135. (isset($count['>']) || isset($count['<']) ||
  42136. isset($count['>=']) || isset($count['<=']))) {
  42137. $counted = $tags ? count($tags) : 0;
  42138. if (isset($count['>'])) {
  42139. self::assertTrue($counted > $count['>'], $message);
  42140. }
  42141. if (isset($count['>='])) {
  42142. self::assertTrue($counted >= $count['>='], $message);
  42143. }
  42144. if (isset($count['<'])) {
  42145. self::assertTrue($counted < $count['<'], $message);
  42146. }
  42147. if (isset($count['<='])) {
  42148. self::assertTrue($counted <= $count['<='], $message);
  42149. }
  42150. } else {
  42151. throw new PHPUnit_Framework_Exception;
  42152. }
  42153. }
  42154. /**
  42155. * Evaluate an HTML or XML string and assert its structure and/or contents.
  42156. *
  42157. * The first argument ($matcher) is an associative array that specifies the
  42158. * match criteria for the assertion:
  42159. *
  42160. * - `id` : the node with the given id attribute must match the
  42161. * corresponding value.
  42162. * - `tag` : the node type must match the corresponding value.
  42163. * - `attributes` : a hash. The node's attributes must match the
  42164. * corresponding values in the hash.
  42165. * - `content` : The text content must match the given value.
  42166. * - `parent` : a hash. The node's parent must match the
  42167. * corresponding hash.
  42168. * - `child` : a hash. At least one of the node's immediate children
  42169. * must meet the criteria described by the hash.
  42170. * - `ancestor` : a hash. At least one of the node's ancestors must
  42171. * meet the criteria described by the hash.
  42172. * - `descendant` : a hash. At least one of the node's descendants must
  42173. * meet the criteria described by the hash.
  42174. * - `children` : a hash, for counting children of a node.
  42175. * Accepts the keys:
  42176. * - `count` : a number which must equal the number of children
  42177. * that match
  42178. * - `less_than` : the number of matching children must be greater
  42179. * than this number
  42180. * - `greater_than` : the number of matching children must be less than
  42181. * this number
  42182. * - `only` : another hash consisting of the keys to use to match
  42183. * on the children, and only matching children will be
  42184. * counted
  42185. *
  42186. * <code>
  42187. * // Matcher that asserts that there is an element with an id="my_id".
  42188. * $matcher = array('id' => 'my_id');
  42189. *
  42190. * // Matcher that asserts that there is a "span" tag.
  42191. * $matcher = array('tag' => 'span');
  42192. *
  42193. * // Matcher that asserts that there is a "span" tag with the content
  42194. * // "Hello World".
  42195. * $matcher = array('tag' => 'span', 'content' => 'Hello World');
  42196. *
  42197. * // Matcher that asserts that there is a "span" tag with content matching
  42198. * // the regular expression pattern.
  42199. * $matcher = array('tag' => 'span', 'content' => 'regexp:/Try P(HP|ython)/');
  42200. *
  42201. * // Matcher that asserts that there is a "span" with an "list" class
  42202. * // attribute.
  42203. * $matcher = array(
  42204. * 'tag' => 'span',
  42205. * 'attributes' => array('class' => 'list')
  42206. * );
  42207. *
  42208. * // Matcher that asserts that there is a "span" inside of a "div".
  42209. * $matcher = array(
  42210. * 'tag' => 'span',
  42211. * 'parent' => array('tag' => 'div')
  42212. * );
  42213. *
  42214. * // Matcher that asserts that there is a "span" somewhere inside a
  42215. * // "table".
  42216. * $matcher = array(
  42217. * 'tag' => 'span',
  42218. * 'ancestor' => array('tag' => 'table')
  42219. * );
  42220. *
  42221. * // Matcher that asserts that there is a "span" with at least one "em"
  42222. * // child.
  42223. * $matcher = array(
  42224. * 'tag' => 'span',
  42225. * 'child' => array('tag' => 'em')
  42226. * );
  42227. *
  42228. * // Matcher that asserts that there is a "span" containing a (possibly
  42229. * // nested) "strong" tag.
  42230. * $matcher = array(
  42231. * 'tag' => 'span',
  42232. * 'descendant' => array('tag' => 'strong')
  42233. * );
  42234. *
  42235. * // Matcher that asserts that there is a "span" containing 5-10 "em" tags
  42236. * // as immediate children.
  42237. * $matcher = array(
  42238. * 'tag' => 'span',
  42239. * 'children' => array(
  42240. * 'less_than' => 11,
  42241. * 'greater_than' => 4,
  42242. * 'only' => array('tag' => 'em')
  42243. * )
  42244. * );
  42245. *
  42246. * // Matcher that asserts that there is a "div", with an "ul" ancestor and
  42247. * // a "li" parent (with class="enum"), and containing a "span" descendant
  42248. * // that contains an element with id="my_test" and the text "Hello World".
  42249. * $matcher = array(
  42250. * 'tag' => 'div',
  42251. * 'ancestor' => array('tag' => 'ul'),
  42252. * 'parent' => array(
  42253. * 'tag' => 'li',
  42254. * 'attributes' => array('class' => 'enum')
  42255. * ),
  42256. * 'descendant' => array(
  42257. * 'tag' => 'span',
  42258. * 'child' => array(
  42259. * 'id' => 'my_test',
  42260. * 'content' => 'Hello World'
  42261. * )
  42262. * )
  42263. * );
  42264. *
  42265. * // Use assertTag() to apply a $matcher to a piece of $html.
  42266. * $this->assertTag($matcher, $html);
  42267. *
  42268. * // Use assertTag() to apply a $matcher to a piece of $xml.
  42269. * $this->assertTag($matcher, $xml, '', false);
  42270. * </code>
  42271. *
  42272. * The second argument ($actual) is a string containing either HTML or
  42273. * XML text to be tested.
  42274. *
  42275. * The third argument ($message) is an optional message that will be
  42276. * used if the assertion fails.
  42277. *
  42278. * The fourth argument ($html) is an optional flag specifying whether
  42279. * to load the $actual string into a DOMDocument using the HTML or
  42280. * XML load strategy. It is true by default, which assumes the HTML
  42281. * load strategy. In many cases, this will be acceptable for XML as well.
  42282. *
  42283. * @param array $matcher
  42284. * @param string $actual
  42285. * @param string $message
  42286. * @param bool $isHtml
  42287. * @since Method available since Release 3.3.0
  42288. * @deprecated
  42289. * @codeCoverageIgnore
  42290. */
  42291. public static function assertTag($matcher, $actual, $message = '', $isHtml = true)
  42292. {
  42293. trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED);
  42294. $dom = PHPUnit_Util_XML::load($actual, $isHtml);
  42295. $tags = PHPUnit_Util_XML::findNodes($dom, $matcher, $isHtml);
  42296. $matched = count($tags) > 0 && $tags[0] instanceof DOMNode;
  42297. self::assertTrue($matched, $message);
  42298. }
  42299. /**
  42300. * This assertion is the exact opposite of assertTag().
  42301. *
  42302. * Rather than asserting that $matcher results in a match, it asserts that
  42303. * $matcher does not match.
  42304. *
  42305. * @param array $matcher
  42306. * @param string $actual
  42307. * @param string $message
  42308. * @param bool $isHtml
  42309. * @since Method available since Release 3.3.0
  42310. * @deprecated
  42311. * @codeCoverageIgnore
  42312. */
  42313. public static function assertNotTag($matcher, $actual, $message = '', $isHtml = true)
  42314. {
  42315. trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED);
  42316. $dom = PHPUnit_Util_XML::load($actual, $isHtml);
  42317. $tags = PHPUnit_Util_XML::findNodes($dom, $matcher, $isHtml);
  42318. $matched = count($tags) > 0 && $tags[0] instanceof DOMNode;
  42319. self::assertFalse($matched, $message);
  42320. }
  42321. /**
  42322. * Evaluates a PHPUnit_Framework_Constraint matcher object.
  42323. *
  42324. * @param mixed $value
  42325. * @param PHPUnit_Framework_Constraint $constraint
  42326. * @param string $message
  42327. * @since Method available since Release 3.0.0
  42328. */
  42329. public static function assertThat($value, PHPUnit_Framework_Constraint $constraint, $message = '')
  42330. {
  42331. self::$count += count($constraint);
  42332. $constraint->evaluate($value, $message);
  42333. }
  42334. /**
  42335. * Asserts that a string is a valid JSON string.
  42336. *
  42337. * @param string $actualJson
  42338. * @param string $message
  42339. * @since Method available since Release 3.7.20
  42340. */
  42341. public static function assertJson($actualJson, $message = '')
  42342. {
  42343. if (!is_string($actualJson)) {
  42344. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  42345. }
  42346. self::assertThat($actualJson, self::isJson(), $message);
  42347. }
  42348. /**
  42349. * Asserts that two given JSON encoded objects or arrays are equal.
  42350. *
  42351. * @param string $expectedJson
  42352. * @param string $actualJson
  42353. * @param string $message
  42354. */
  42355. public static function assertJsonStringEqualsJsonString($expectedJson, $actualJson, $message = '')
  42356. {
  42357. self::assertJson($expectedJson, $message);
  42358. self::assertJson($actualJson, $message);
  42359. $expected = json_decode($expectedJson);
  42360. $actual = json_decode($actualJson);
  42361. self::assertEquals($expected, $actual, $message);
  42362. }
  42363. /**
  42364. * Asserts that two given JSON encoded objects or arrays are not equal.
  42365. *
  42366. * @param string $expectedJson
  42367. * @param string $actualJson
  42368. * @param string $message
  42369. */
  42370. public static function assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, $message = '')
  42371. {
  42372. self::assertJson($expectedJson, $message);
  42373. self::assertJson($actualJson, $message);
  42374. $expected = json_decode($expectedJson);
  42375. $actual = json_decode($actualJson);
  42376. self::assertNotEquals($expected, $actual, $message);
  42377. }
  42378. /**
  42379. * Asserts that the generated JSON encoded object and the content of the given file are equal.
  42380. *
  42381. * @param string $expectedFile
  42382. * @param string $actualJson
  42383. * @param string $message
  42384. */
  42385. public static function assertJsonStringEqualsJsonFile($expectedFile, $actualJson, $message = '')
  42386. {
  42387. self::assertFileExists($expectedFile, $message);
  42388. $expectedJson = file_get_contents($expectedFile);
  42389. self::assertJson($expectedJson, $message);
  42390. self::assertJson($actualJson, $message);
  42391. // call constraint
  42392. $constraint = new PHPUnit_Framework_Constraint_JsonMatches(
  42393. $expectedJson
  42394. );
  42395. self::assertThat($actualJson, $constraint, $message);
  42396. }
  42397. /**
  42398. * Asserts that the generated JSON encoded object and the content of the given file are not equal.
  42399. *
  42400. * @param string $expectedFile
  42401. * @param string $actualJson
  42402. * @param string $message
  42403. */
  42404. public static function assertJsonStringNotEqualsJsonFile($expectedFile, $actualJson, $message = '')
  42405. {
  42406. self::assertFileExists($expectedFile, $message);
  42407. $expectedJson = file_get_contents($expectedFile);
  42408. self::assertJson($expectedJson, $message);
  42409. self::assertJson($actualJson, $message);
  42410. // call constraint
  42411. $constraint = new PHPUnit_Framework_Constraint_JsonMatches(
  42412. $expectedJson
  42413. );
  42414. self::assertThat($actualJson, new PHPUnit_Framework_Constraint_Not($constraint), $message);
  42415. }
  42416. /**
  42417. * Asserts that two JSON files are not equal.
  42418. *
  42419. * @param string $expectedFile
  42420. * @param string $actualFile
  42421. * @param string $message
  42422. */
  42423. public static function assertJsonFileNotEqualsJsonFile($expectedFile, $actualFile, $message = '')
  42424. {
  42425. self::assertFileExists($expectedFile, $message);
  42426. self::assertFileExists($actualFile, $message);
  42427. $actualJson = file_get_contents($actualFile);
  42428. $expectedJson = file_get_contents($expectedFile);
  42429. self::assertJson($expectedJson, $message);
  42430. self::assertJson($actualJson, $message);
  42431. // call constraint
  42432. $constraintExpected = new PHPUnit_Framework_Constraint_JsonMatches(
  42433. $expectedJson
  42434. );
  42435. $constraintActual = new PHPUnit_Framework_Constraint_JsonMatches($actualJson);
  42436. self::assertThat($expectedJson, new PHPUnit_Framework_Constraint_Not($constraintActual), $message);
  42437. self::assertThat($actualJson, new PHPUnit_Framework_Constraint_Not($constraintExpected), $message);
  42438. }
  42439. /**
  42440. * Asserts that two JSON files are equal.
  42441. *
  42442. * @param string $expectedFile
  42443. * @param string $actualFile
  42444. * @param string $message
  42445. */
  42446. public static function assertJsonFileEqualsJsonFile($expectedFile, $actualFile, $message = '')
  42447. {
  42448. self::assertFileExists($expectedFile, $message);
  42449. self::assertFileExists($actualFile, $message);
  42450. $actualJson = file_get_contents($actualFile);
  42451. $expectedJson = file_get_contents($expectedFile);
  42452. self::assertJson($expectedJson, $message);
  42453. self::assertJson($actualJson, $message);
  42454. // call constraint
  42455. $constraintExpected = new PHPUnit_Framework_Constraint_JsonMatches(
  42456. $expectedJson
  42457. );
  42458. $constraintActual = new PHPUnit_Framework_Constraint_JsonMatches($actualJson);
  42459. self::assertThat($expectedJson, $constraintActual, $message);
  42460. self::assertThat($actualJson, $constraintExpected, $message);
  42461. }
  42462. /**
  42463. * Returns a PHPUnit_Framework_Constraint_And matcher object.
  42464. *
  42465. * @return PHPUnit_Framework_Constraint_And
  42466. * @since Method available since Release 3.0.0
  42467. */
  42468. public static function logicalAnd()
  42469. {
  42470. $constraints = func_get_args();
  42471. $constraint = new PHPUnit_Framework_Constraint_And;
  42472. $constraint->setConstraints($constraints);
  42473. return $constraint;
  42474. }
  42475. /**
  42476. * Returns a PHPUnit_Framework_Constraint_Or matcher object.
  42477. *
  42478. * @return PHPUnit_Framework_Constraint_Or
  42479. * @since Method available since Release 3.0.0
  42480. */
  42481. public static function logicalOr()
  42482. {
  42483. $constraints = func_get_args();
  42484. $constraint = new PHPUnit_Framework_Constraint_Or;
  42485. $constraint->setConstraints($constraints);
  42486. return $constraint;
  42487. }
  42488. /**
  42489. * Returns a PHPUnit_Framework_Constraint_Not matcher object.
  42490. *
  42491. * @param PHPUnit_Framework_Constraint $constraint
  42492. * @return PHPUnit_Framework_Constraint_Not
  42493. * @since Method available since Release 3.0.0
  42494. */
  42495. public static function logicalNot(PHPUnit_Framework_Constraint $constraint)
  42496. {
  42497. return new PHPUnit_Framework_Constraint_Not($constraint);
  42498. }
  42499. /**
  42500. * Returns a PHPUnit_Framework_Constraint_Xor matcher object.
  42501. *
  42502. * @return PHPUnit_Framework_Constraint_Xor
  42503. * @since Method available since Release 3.0.0
  42504. */
  42505. public static function logicalXor()
  42506. {
  42507. $constraints = func_get_args();
  42508. $constraint = new PHPUnit_Framework_Constraint_Xor;
  42509. $constraint->setConstraints($constraints);
  42510. return $constraint;
  42511. }
  42512. /**
  42513. * Returns a PHPUnit_Framework_Constraint_IsAnything matcher object.
  42514. *
  42515. * @return PHPUnit_Framework_Constraint_IsAnything
  42516. * @since Method available since Release 3.0.0
  42517. */
  42518. public static function anything()
  42519. {
  42520. return new PHPUnit_Framework_Constraint_IsAnything;
  42521. }
  42522. /**
  42523. * Returns a PHPUnit_Framework_Constraint_IsTrue matcher object.
  42524. *
  42525. * @return PHPUnit_Framework_Constraint_IsTrue
  42526. * @since Method available since Release 3.3.0
  42527. */
  42528. public static function isTrue()
  42529. {
  42530. return new PHPUnit_Framework_Constraint_IsTrue;
  42531. }
  42532. /**
  42533. * Returns a PHPUnit_Framework_Constraint_Callback matcher object.
  42534. *
  42535. * @param callable $callback
  42536. * @return PHPUnit_Framework_Constraint_Callback
  42537. */
  42538. public static function callback($callback)
  42539. {
  42540. return new PHPUnit_Framework_Constraint_Callback($callback);
  42541. }
  42542. /**
  42543. * Returns a PHPUnit_Framework_Constraint_IsFalse matcher object.
  42544. *
  42545. * @return PHPUnit_Framework_Constraint_IsFalse
  42546. * @since Method available since Release 3.3.0
  42547. */
  42548. public static function isFalse()
  42549. {
  42550. return new PHPUnit_Framework_Constraint_IsFalse;
  42551. }
  42552. /**
  42553. * Returns a PHPUnit_Framework_Constraint_IsJson matcher object.
  42554. *
  42555. * @return PHPUnit_Framework_Constraint_IsJson
  42556. * @since Method available since Release 3.7.20
  42557. */
  42558. public static function isJson()
  42559. {
  42560. return new PHPUnit_Framework_Constraint_IsJson;
  42561. }
  42562. /**
  42563. * Returns a PHPUnit_Framework_Constraint_IsNull matcher object.
  42564. *
  42565. * @return PHPUnit_Framework_Constraint_IsNull
  42566. * @since Method available since Release 3.3.0
  42567. */
  42568. public static function isNull()
  42569. {
  42570. return new PHPUnit_Framework_Constraint_IsNull;
  42571. }
  42572. /**
  42573. * Returns a PHPUnit_Framework_Constraint_Attribute matcher object.
  42574. *
  42575. * @param PHPUnit_Framework_Constraint $constraint
  42576. * @param string $attributeName
  42577. * @return PHPUnit_Framework_Constraint_Attribute
  42578. * @since Method available since Release 3.1.0
  42579. */
  42580. public static function attribute(PHPUnit_Framework_Constraint $constraint, $attributeName)
  42581. {
  42582. return new PHPUnit_Framework_Constraint_Attribute(
  42583. $constraint,
  42584. $attributeName
  42585. );
  42586. }
  42587. /**
  42588. * Returns a PHPUnit_Framework_Constraint_TraversableContains matcher
  42589. * object.
  42590. *
  42591. * @param mixed $value
  42592. * @param bool $checkForObjectIdentity
  42593. * @param bool $checkForNonObjectIdentity
  42594. * @return PHPUnit_Framework_Constraint_TraversableContains
  42595. * @since Method available since Release 3.0.0
  42596. */
  42597. public static function contains($value, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  42598. {
  42599. return new PHPUnit_Framework_Constraint_TraversableContains($value, $checkForObjectIdentity, $checkForNonObjectIdentity);
  42600. }
  42601. /**
  42602. * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher
  42603. * object.
  42604. *
  42605. * @param string $type
  42606. * @return PHPUnit_Framework_Constraint_TraversableContainsOnly
  42607. * @since Method available since Release 3.1.4
  42608. */
  42609. public static function containsOnly($type)
  42610. {
  42611. return new PHPUnit_Framework_Constraint_TraversableContainsOnly($type);
  42612. }
  42613. /**
  42614. * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher
  42615. * object.
  42616. *
  42617. * @param string $classname
  42618. * @return PHPUnit_Framework_Constraint_TraversableContainsOnly
  42619. */
  42620. public static function containsOnlyInstancesOf($classname)
  42621. {
  42622. return new PHPUnit_Framework_Constraint_TraversableContainsOnly($classname, false);
  42623. }
  42624. /**
  42625. * Returns a PHPUnit_Framework_Constraint_ArrayHasKey matcher object.
  42626. *
  42627. * @param mixed $key
  42628. * @return PHPUnit_Framework_Constraint_ArrayHasKey
  42629. * @since Method available since Release 3.0.0
  42630. */
  42631. public static function arrayHasKey($key)
  42632. {
  42633. return new PHPUnit_Framework_Constraint_ArrayHasKey($key);
  42634. }
  42635. /**
  42636. * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object.
  42637. *
  42638. * @param mixed $value
  42639. * @param float $delta
  42640. * @param int $maxDepth
  42641. * @param bool $canonicalize
  42642. * @param bool $ignoreCase
  42643. * @return PHPUnit_Framework_Constraint_IsEqual
  42644. * @since Method available since Release 3.0.0
  42645. */
  42646. public static function equalTo($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  42647. {
  42648. return new PHPUnit_Framework_Constraint_IsEqual(
  42649. $value,
  42650. $delta,
  42651. $maxDepth,
  42652. $canonicalize,
  42653. $ignoreCase
  42654. );
  42655. }
  42656. /**
  42657. * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object
  42658. * that is wrapped in a PHPUnit_Framework_Constraint_Attribute matcher
  42659. * object.
  42660. *
  42661. * @param string $attributeName
  42662. * @param mixed $value
  42663. * @param float $delta
  42664. * @param int $maxDepth
  42665. * @param bool $canonicalize
  42666. * @param bool $ignoreCase
  42667. * @return PHPUnit_Framework_Constraint_Attribute
  42668. * @since Method available since Release 3.1.0
  42669. */
  42670. public static function attributeEqualTo($attributeName, $value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  42671. {
  42672. return self::attribute(
  42673. self::equalTo(
  42674. $value,
  42675. $delta,
  42676. $maxDepth,
  42677. $canonicalize,
  42678. $ignoreCase
  42679. ),
  42680. $attributeName
  42681. );
  42682. }
  42683. /**
  42684. * Returns a PHPUnit_Framework_Constraint_IsEmpty matcher object.
  42685. *
  42686. * @return PHPUnit_Framework_Constraint_IsEmpty
  42687. * @since Method available since Release 3.5.0
  42688. */
  42689. public static function isEmpty()
  42690. {
  42691. return new PHPUnit_Framework_Constraint_IsEmpty;
  42692. }
  42693. /**
  42694. * Returns a PHPUnit_Framework_Constraint_FileExists matcher object.
  42695. *
  42696. * @return PHPUnit_Framework_Constraint_FileExists
  42697. * @since Method available since Release 3.0.0
  42698. */
  42699. public static function fileExists()
  42700. {
  42701. return new PHPUnit_Framework_Constraint_FileExists;
  42702. }
  42703. /**
  42704. * Returns a PHPUnit_Framework_Constraint_GreaterThan matcher object.
  42705. *
  42706. * @param mixed $value
  42707. * @return PHPUnit_Framework_Constraint_GreaterThan
  42708. * @since Method available since Release 3.0.0
  42709. */
  42710. public static function greaterThan($value)
  42711. {
  42712. return new PHPUnit_Framework_Constraint_GreaterThan($value);
  42713. }
  42714. /**
  42715. * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps
  42716. * a PHPUnit_Framework_Constraint_IsEqual and a
  42717. * PHPUnit_Framework_Constraint_GreaterThan matcher object.
  42718. *
  42719. * @param mixed $value
  42720. * @return PHPUnit_Framework_Constraint_Or
  42721. * @since Method available since Release 3.1.0
  42722. */
  42723. public static function greaterThanOrEqual($value)
  42724. {
  42725. return self::logicalOr(
  42726. new PHPUnit_Framework_Constraint_IsEqual($value),
  42727. new PHPUnit_Framework_Constraint_GreaterThan($value)
  42728. );
  42729. }
  42730. /**
  42731. * Returns a PHPUnit_Framework_Constraint_ClassHasAttribute matcher object.
  42732. *
  42733. * @param string $attributeName
  42734. * @return PHPUnit_Framework_Constraint_ClassHasAttribute
  42735. * @since Method available since Release 3.1.0
  42736. */
  42737. public static function classHasAttribute($attributeName)
  42738. {
  42739. return new PHPUnit_Framework_Constraint_ClassHasAttribute(
  42740. $attributeName
  42741. );
  42742. }
  42743. /**
  42744. * Returns a PHPUnit_Framework_Constraint_ClassHasStaticAttribute matcher
  42745. * object.
  42746. *
  42747. * @param string $attributeName
  42748. * @return PHPUnit_Framework_Constraint_ClassHasStaticAttribute
  42749. * @since Method available since Release 3.1.0
  42750. */
  42751. public static function classHasStaticAttribute($attributeName)
  42752. {
  42753. return new PHPUnit_Framework_Constraint_ClassHasStaticAttribute(
  42754. $attributeName
  42755. );
  42756. }
  42757. /**
  42758. * Returns a PHPUnit_Framework_Constraint_ObjectHasAttribute matcher object.
  42759. *
  42760. * @param string $attributeName
  42761. * @return PHPUnit_Framework_Constraint_ObjectHasAttribute
  42762. * @since Method available since Release 3.0.0
  42763. */
  42764. public static function objectHasAttribute($attributeName)
  42765. {
  42766. return new PHPUnit_Framework_Constraint_ObjectHasAttribute(
  42767. $attributeName
  42768. );
  42769. }
  42770. /**
  42771. * Returns a PHPUnit_Framework_Constraint_IsIdentical matcher object.
  42772. *
  42773. * @param mixed $value
  42774. * @return PHPUnit_Framework_Constraint_IsIdentical
  42775. * @since Method available since Release 3.0.0
  42776. */
  42777. public static function identicalTo($value)
  42778. {
  42779. return new PHPUnit_Framework_Constraint_IsIdentical($value);
  42780. }
  42781. /**
  42782. * Returns a PHPUnit_Framework_Constraint_IsInstanceOf matcher object.
  42783. *
  42784. * @param string $className
  42785. * @return PHPUnit_Framework_Constraint_IsInstanceOf
  42786. * @since Method available since Release 3.0.0
  42787. */
  42788. public static function isInstanceOf($className)
  42789. {
  42790. return new PHPUnit_Framework_Constraint_IsInstanceOf($className);
  42791. }
  42792. /**
  42793. * Returns a PHPUnit_Framework_Constraint_IsType matcher object.
  42794. *
  42795. * @param string $type
  42796. * @return PHPUnit_Framework_Constraint_IsType
  42797. * @since Method available since Release 3.0.0
  42798. */
  42799. public static function isType($type)
  42800. {
  42801. return new PHPUnit_Framework_Constraint_IsType($type);
  42802. }
  42803. /**
  42804. * Returns a PHPUnit_Framework_Constraint_LessThan matcher object.
  42805. *
  42806. * @param mixed $value
  42807. * @return PHPUnit_Framework_Constraint_LessThan
  42808. * @since Method available since Release 3.0.0
  42809. */
  42810. public static function lessThan($value)
  42811. {
  42812. return new PHPUnit_Framework_Constraint_LessThan($value);
  42813. }
  42814. /**
  42815. * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps
  42816. * a PHPUnit_Framework_Constraint_IsEqual and a
  42817. * PHPUnit_Framework_Constraint_LessThan matcher object.
  42818. *
  42819. * @param mixed $value
  42820. * @return PHPUnit_Framework_Constraint_Or
  42821. * @since Method available since Release 3.1.0
  42822. */
  42823. public static function lessThanOrEqual($value)
  42824. {
  42825. return self::logicalOr(
  42826. new PHPUnit_Framework_Constraint_IsEqual($value),
  42827. new PHPUnit_Framework_Constraint_LessThan($value)
  42828. );
  42829. }
  42830. /**
  42831. * Returns a PHPUnit_Framework_Constraint_PCREMatch matcher object.
  42832. *
  42833. * @param string $pattern
  42834. * @return PHPUnit_Framework_Constraint_PCREMatch
  42835. * @since Method available since Release 3.0.0
  42836. */
  42837. public static function matchesRegularExpression($pattern)
  42838. {
  42839. return new PHPUnit_Framework_Constraint_PCREMatch($pattern);
  42840. }
  42841. /**
  42842. * Returns a PHPUnit_Framework_Constraint_StringMatches matcher object.
  42843. *
  42844. * @param string $string
  42845. * @return PHPUnit_Framework_Constraint_StringMatches
  42846. * @since Method available since Release 3.5.0
  42847. */
  42848. public static function matches($string)
  42849. {
  42850. return new PHPUnit_Framework_Constraint_StringMatches($string);
  42851. }
  42852. /**
  42853. * Returns a PHPUnit_Framework_Constraint_StringStartsWith matcher object.
  42854. *
  42855. * @param mixed $prefix
  42856. * @return PHPUnit_Framework_Constraint_StringStartsWith
  42857. * @since Method available since Release 3.4.0
  42858. */
  42859. public static function stringStartsWith($prefix)
  42860. {
  42861. return new PHPUnit_Framework_Constraint_StringStartsWith($prefix);
  42862. }
  42863. /**
  42864. * Returns a PHPUnit_Framework_Constraint_StringContains matcher object.
  42865. *
  42866. * @param string $string
  42867. * @param bool $case
  42868. * @return PHPUnit_Framework_Constraint_StringContains
  42869. * @since Method available since Release 3.0.0
  42870. */
  42871. public static function stringContains($string, $case = true)
  42872. {
  42873. return new PHPUnit_Framework_Constraint_StringContains($string, $case);
  42874. }
  42875. /**
  42876. * Returns a PHPUnit_Framework_Constraint_StringEndsWith matcher object.
  42877. *
  42878. * @param mixed $suffix
  42879. * @return PHPUnit_Framework_Constraint_StringEndsWith
  42880. * @since Method available since Release 3.4.0
  42881. */
  42882. public static function stringEndsWith($suffix)
  42883. {
  42884. return new PHPUnit_Framework_Constraint_StringEndsWith($suffix);
  42885. }
  42886. /**
  42887. * Returns a PHPUnit_Framework_Constraint_Count matcher object.
  42888. *
  42889. * @param int $count
  42890. * @return PHPUnit_Framework_Constraint_Count
  42891. */
  42892. public static function countOf($count)
  42893. {
  42894. return new PHPUnit_Framework_Constraint_Count($count);
  42895. }
  42896. /**
  42897. * Fails a test with the given message.
  42898. *
  42899. * @param string $message
  42900. * @throws PHPUnit_Framework_AssertionFailedError
  42901. */
  42902. public static function fail($message = '')
  42903. {
  42904. throw new PHPUnit_Framework_AssertionFailedError($message);
  42905. }
  42906. /**
  42907. * Returns the value of an attribute of a class or an object.
  42908. * This also works for attributes that are declared protected or private.
  42909. *
  42910. * @param mixed $classOrObject
  42911. * @param string $attributeName
  42912. * @return mixed
  42913. * @throws PHPUnit_Framework_Exception
  42914. */
  42915. public static function readAttribute($classOrObject, $attributeName)
  42916. {
  42917. if (!is_string($attributeName)) {
  42918. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  42919. }
  42920. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  42921. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'valid attribute name');
  42922. }
  42923. if (is_string($classOrObject)) {
  42924. if (!class_exists($classOrObject)) {
  42925. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  42926. 1,
  42927. 'class name'
  42928. );
  42929. }
  42930. return self::getStaticAttribute(
  42931. $classOrObject,
  42932. $attributeName
  42933. );
  42934. } elseif (is_object($classOrObject)) {
  42935. return self::getObjectAttribute(
  42936. $classOrObject,
  42937. $attributeName
  42938. );
  42939. } else {
  42940. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  42941. 1,
  42942. 'class name or object'
  42943. );
  42944. }
  42945. }
  42946. /**
  42947. * Returns the value of a static attribute.
  42948. * This also works for attributes that are declared protected or private.
  42949. *
  42950. * @param string $className
  42951. * @param string $attributeName
  42952. * @return mixed
  42953. * @throws PHPUnit_Framework_Exception
  42954. * @since Method available since Release 4.0.0
  42955. */
  42956. public static function getStaticAttribute($className, $attributeName)
  42957. {
  42958. if (!is_string($className)) {
  42959. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  42960. }
  42961. if (!class_exists($className)) {
  42962. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class name');
  42963. }
  42964. if (!is_string($attributeName)) {
  42965. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  42966. }
  42967. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  42968. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'valid attribute name');
  42969. }
  42970. $class = new ReflectionClass($className);
  42971. while ($class) {
  42972. $attributes = $class->getStaticProperties();
  42973. if (array_key_exists($attributeName, $attributes)) {
  42974. return $attributes[$attributeName];
  42975. }
  42976. $class = $class->getParentClass();
  42977. }
  42978. throw new PHPUnit_Framework_Exception(
  42979. sprintf(
  42980. 'Attribute "%s" not found in class.',
  42981. $attributeName
  42982. )
  42983. );
  42984. }
  42985. /**
  42986. * Returns the value of an object's attribute.
  42987. * This also works for attributes that are declared protected or private.
  42988. *
  42989. * @param object $object
  42990. * @param string $attributeName
  42991. * @return mixed
  42992. * @throws PHPUnit_Framework_Exception
  42993. * @since Method available since Release 4.0.0
  42994. */
  42995. public static function getObjectAttribute($object, $attributeName)
  42996. {
  42997. if (!is_object($object)) {
  42998. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'object');
  42999. }
  43000. if (!is_string($attributeName)) {
  43001. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string');
  43002. }
  43003. if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) {
  43004. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'valid attribute name');
  43005. }
  43006. try {
  43007. $attribute = new ReflectionProperty($object, $attributeName);
  43008. } catch (ReflectionException $e) {
  43009. $reflector = new ReflectionObject($object);
  43010. while ($reflector = $reflector->getParentClass()) {
  43011. try {
  43012. $attribute = $reflector->getProperty($attributeName);
  43013. break;
  43014. } catch (ReflectionException $e) {
  43015. }
  43016. }
  43017. }
  43018. if (isset($attribute)) {
  43019. if (!$attribute || $attribute->isPublic()) {
  43020. return $object->$attributeName;
  43021. }
  43022. $attribute->setAccessible(true);
  43023. $value = $attribute->getValue($object);
  43024. $attribute->setAccessible(false);
  43025. return $value;
  43026. }
  43027. throw new PHPUnit_Framework_Exception(
  43028. sprintf(
  43029. 'Attribute "%s" not found in object.',
  43030. $attributeName
  43031. )
  43032. );
  43033. }
  43034. /**
  43035. * Mark the test as incomplete.
  43036. *
  43037. * @param string $message
  43038. * @throws PHPUnit_Framework_IncompleteTestError
  43039. * @since Method available since Release 3.0.0
  43040. */
  43041. public static function markTestIncomplete($message = '')
  43042. {
  43043. throw new PHPUnit_Framework_IncompleteTestError($message);
  43044. }
  43045. /**
  43046. * Mark the test as skipped.
  43047. *
  43048. * @param string $message
  43049. * @throws PHPUnit_Framework_SkippedTestError
  43050. * @since Method available since Release 3.0.0
  43051. */
  43052. public static function markTestSkipped($message = '')
  43053. {
  43054. throw new PHPUnit_Framework_SkippedTestError($message);
  43055. }
  43056. /**
  43057. * Return the current assertion count.
  43058. *
  43059. * @return int
  43060. * @since Method available since Release 3.3.3
  43061. */
  43062. public static function getCount()
  43063. {
  43064. return self::$count;
  43065. }
  43066. /**
  43067. * Reset the assertion counter.
  43068. *
  43069. * @since Method available since Release 3.3.3
  43070. */
  43071. public static function resetCount()
  43072. {
  43073. self::$count = 0;
  43074. }
  43075. }
  43076. <?php
  43077. /*
  43078. * This file is part of PHPUnit.
  43079. *
  43080. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43081. *
  43082. * For the full copyright and license information, please view the LICENSE
  43083. * file that was distributed with this source code.
  43084. */
  43085. /**
  43086. * @since Class available since Release 4.0.0
  43087. */
  43088. class PHPUnit_Framework_CodeCoverageException extends PHPUnit_Framework_Exception
  43089. {
  43090. }
  43091. <?php
  43092. /*
  43093. * This file is part of PHPUnit.
  43094. *
  43095. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43096. *
  43097. * For the full copyright and license information, please view the LICENSE
  43098. * file that was distributed with this source code.
  43099. */
  43100. /**
  43101. * A TestSuite is a composite of Tests. It runs a collection of test cases.
  43102. *
  43103. * Here is an example using the dynamic test definition.
  43104. *
  43105. * <code>
  43106. * <?php
  43107. * $suite = new PHPUnit_Framework_TestSuite;
  43108. * $suite->addTest(new MathTest('testPass'));
  43109. * ?>
  43110. * </code>
  43111. *
  43112. * Alternatively, a TestSuite can extract the tests to be run automatically.
  43113. * To do so you pass a ReflectionClass instance for your
  43114. * PHPUnit_Framework_TestCase class to the PHPUnit_Framework_TestSuite
  43115. * constructor.
  43116. *
  43117. * <code>
  43118. * <?php
  43119. * $suite = new PHPUnit_Framework_TestSuite(
  43120. * new ReflectionClass('MathTest')
  43121. * );
  43122. * ?>
  43123. * </code>
  43124. *
  43125. * This constructor creates a suite with all the methods starting with
  43126. * "test" that take no arguments.
  43127. *
  43128. * @since Class available since Release 2.0.0
  43129. */
  43130. class PHPUnit_Framework_TestSuite implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing, IteratorAggregate
  43131. {
  43132. /**
  43133. * Last count of tests in this suite.
  43134. *
  43135. * @var int|null
  43136. */
  43137. private $cachedNumTests;
  43138. /**
  43139. * Enable or disable the backup and restoration of the $GLOBALS array.
  43140. *
  43141. * @var bool
  43142. */
  43143. protected $backupGlobals = null;
  43144. /**
  43145. * Enable or disable the backup and restoration of static attributes.
  43146. *
  43147. * @var bool
  43148. */
  43149. protected $backupStaticAttributes = null;
  43150. /**
  43151. * @var bool
  43152. */
  43153. private $disallowChangesToGlobalState = null;
  43154. /**
  43155. * @var bool
  43156. */
  43157. protected $runTestInSeparateProcess = false;
  43158. /**
  43159. * The name of the test suite.
  43160. *
  43161. * @var string
  43162. */
  43163. protected $name = '';
  43164. /**
  43165. * The test groups of the test suite.
  43166. *
  43167. * @var array
  43168. */
  43169. protected $groups = array();
  43170. /**
  43171. * The tests in the test suite.
  43172. *
  43173. * @var array
  43174. */
  43175. protected $tests = array();
  43176. /**
  43177. * The number of tests in the test suite.
  43178. *
  43179. * @var int
  43180. */
  43181. protected $numTests = -1;
  43182. /**
  43183. * @var bool
  43184. */
  43185. protected $testCase = false;
  43186. /**
  43187. * @var array
  43188. */
  43189. protected $foundClasses = array();
  43190. /**
  43191. * @var PHPUnit_Runner_Filter_Factory
  43192. */
  43193. private $iteratorFilter = null;
  43194. /**
  43195. * Constructs a new TestSuite:
  43196. *
  43197. * - PHPUnit_Framework_TestSuite() constructs an empty TestSuite.
  43198. *
  43199. * - PHPUnit_Framework_TestSuite(ReflectionClass) constructs a
  43200. * TestSuite from the given class.
  43201. *
  43202. * - PHPUnit_Framework_TestSuite(ReflectionClass, String)
  43203. * constructs a TestSuite from the given class with the given
  43204. * name.
  43205. *
  43206. * - PHPUnit_Framework_TestSuite(String) either constructs a
  43207. * TestSuite from the given class (if the passed string is the
  43208. * name of an existing class) or constructs an empty TestSuite
  43209. * with the given name.
  43210. *
  43211. * @param mixed $theClass
  43212. * @param string $name
  43213. * @throws PHPUnit_Framework_Exception
  43214. */
  43215. public function __construct($theClass = '', $name = '')
  43216. {
  43217. $argumentsValid = false;
  43218. if (is_object($theClass) &&
  43219. $theClass instanceof ReflectionClass) {
  43220. $argumentsValid = true;
  43221. } elseif (is_string($theClass) &&
  43222. $theClass !== '' &&
  43223. class_exists($theClass, false)) {
  43224. $argumentsValid = true;
  43225. if ($name == '') {
  43226. $name = $theClass;
  43227. }
  43228. $theClass = new ReflectionClass($theClass);
  43229. } elseif (is_string($theClass)) {
  43230. $this->setName($theClass);
  43231. return;
  43232. }
  43233. if (!$argumentsValid) {
  43234. throw new PHPUnit_Framework_Exception;
  43235. }
  43236. if (!$theClass->isSubclassOf('PHPUnit_Framework_TestCase')) {
  43237. throw new PHPUnit_Framework_Exception(
  43238. 'Class "' . $theClass->name . '" does not extend PHPUnit_Framework_TestCase.'
  43239. );
  43240. }
  43241. if ($name != '') {
  43242. $this->setName($name);
  43243. } else {
  43244. $this->setName($theClass->getName());
  43245. }
  43246. $constructor = $theClass->getConstructor();
  43247. if ($constructor !== null &&
  43248. !$constructor->isPublic()) {
  43249. $this->addTest(
  43250. self::warning(
  43251. sprintf(
  43252. 'Class "%s" has no public constructor.',
  43253. $theClass->getName()
  43254. )
  43255. )
  43256. );
  43257. return;
  43258. }
  43259. foreach ($theClass->getMethods() as $method) {
  43260. $this->addTestMethod($theClass, $method);
  43261. }
  43262. if (empty($this->tests)) {
  43263. $this->addTest(
  43264. self::warning(
  43265. sprintf(
  43266. 'No tests found in class "%s".',
  43267. $theClass->getName()
  43268. )
  43269. )
  43270. );
  43271. }
  43272. $this->testCase = true;
  43273. }
  43274. /**
  43275. * Returns a string representation of the test suite.
  43276. *
  43277. * @return string
  43278. */
  43279. public function toString()
  43280. {
  43281. return $this->getName();
  43282. }
  43283. /**
  43284. * Adds a test to the suite.
  43285. *
  43286. * @param PHPUnit_Framework_Test $test
  43287. * @param array $groups
  43288. */
  43289. public function addTest(PHPUnit_Framework_Test $test, $groups = array())
  43290. {
  43291. $class = new ReflectionClass($test);
  43292. if (!$class->isAbstract()) {
  43293. $this->tests[] = $test;
  43294. $this->numTests = -1;
  43295. if ($test instanceof self &&
  43296. empty($groups)) {
  43297. $groups = $test->getGroups();
  43298. }
  43299. if (empty($groups)) {
  43300. $groups = array('__nogroup__');
  43301. }
  43302. foreach ($groups as $group) {
  43303. if (!isset($this->groups[$group])) {
  43304. $this->groups[$group] = array($test);
  43305. } else {
  43306. $this->groups[$group][] = $test;
  43307. }
  43308. }
  43309. }
  43310. }
  43311. /**
  43312. * Adds the tests from the given class to the suite.
  43313. *
  43314. * @param mixed $testClass
  43315. * @throws PHPUnit_Framework_Exception
  43316. */
  43317. public function addTestSuite($testClass)
  43318. {
  43319. if (is_string($testClass) && class_exists($testClass)) {
  43320. $testClass = new ReflectionClass($testClass);
  43321. }
  43322. if (!is_object($testClass)) {
  43323. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  43324. 1,
  43325. 'class name or object'
  43326. );
  43327. }
  43328. if ($testClass instanceof self) {
  43329. $this->addTest($testClass);
  43330. } elseif ($testClass instanceof ReflectionClass) {
  43331. $suiteMethod = false;
  43332. if (!$testClass->isAbstract()) {
  43333. if ($testClass->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) {
  43334. $method = $testClass->getMethod(
  43335. PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME
  43336. );
  43337. if ($method->isStatic()) {
  43338. $this->addTest(
  43339. $method->invoke(null, $testClass->getName())
  43340. );
  43341. $suiteMethod = true;
  43342. }
  43343. }
  43344. }
  43345. if (!$suiteMethod && !$testClass->isAbstract()) {
  43346. $this->addTest(new self($testClass));
  43347. }
  43348. } else {
  43349. throw new PHPUnit_Framework_Exception;
  43350. }
  43351. }
  43352. /**
  43353. * Wraps both <code>addTest()</code> and <code>addTestSuite</code>
  43354. * as well as the separate import statements for the user's convenience.
  43355. *
  43356. * If the named file cannot be read or there are no new tests that can be
  43357. * added, a <code>PHPUnit_Framework_Warning</code> will be created instead,
  43358. * leaving the current test run untouched.
  43359. *
  43360. * @param string $filename
  43361. * @param array $phptOptions Array with ini settings for the php instance
  43362. * run, key being the name if the setting,
  43363. * value the ini value.
  43364. * @throws PHPUnit_Framework_Exception
  43365. * @since Method available since Release 2.3.0
  43366. */
  43367. public function addTestFile($filename, $phptOptions = array())
  43368. {
  43369. if (!is_string($filename)) {
  43370. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  43371. }
  43372. if (file_exists($filename) && substr($filename, -5) == '.phpt') {
  43373. $this->addTest(
  43374. new PHPUnit_Extensions_PhptTestCase($filename, $phptOptions)
  43375. );
  43376. return;
  43377. }
  43378. // The given file may contain further stub classes in addition to the
  43379. // test class itself. Figure out the actual test class.
  43380. $classes = get_declared_classes();
  43381. $filename = PHPUnit_Util_Fileloader::checkAndLoad($filename);
  43382. $newClasses = array_diff(get_declared_classes(), $classes);
  43383. // The diff is empty in case a parent class (with test methods) is added
  43384. // AFTER a child class that inherited from it. To account for that case,
  43385. // cumulate all discovered classes, so the parent class may be found in
  43386. // a later invocation.
  43387. if ($newClasses) {
  43388. // On the assumption that test classes are defined first in files,
  43389. // process discovered classes in approximate LIFO order, so as to
  43390. // avoid unnecessary reflection.
  43391. $this->foundClasses = array_merge($newClasses, $this->foundClasses);
  43392. }
  43393. // The test class's name must match the filename, either in full, or as
  43394. // a PEAR/PSR-0 prefixed shortname ('NameSpace_ShortName'), or as a
  43395. // PSR-1 local shortname ('NameSpace\ShortName'). The comparison must be
  43396. // anchored to prevent false-positive matches (e.g., 'OtherShortName').
  43397. $shortname = basename($filename, '.php');
  43398. $shortnameRegEx = '/(?:^|_|\\\\)' . preg_quote($shortname, '/') . '$/';
  43399. foreach ($this->foundClasses as $i => $className) {
  43400. if (preg_match($shortnameRegEx, $className)) {
  43401. $class = new ReflectionClass($className);
  43402. if ($class->getFileName() == $filename) {
  43403. $newClasses = array($className);
  43404. unset($this->foundClasses[$i]);
  43405. break;
  43406. }
  43407. }
  43408. }
  43409. foreach ($newClasses as $className) {
  43410. $class = new ReflectionClass($className);
  43411. if (!$class->isAbstract()) {
  43412. if ($class->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) {
  43413. $method = $class->getMethod(
  43414. PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME
  43415. );
  43416. if ($method->isStatic()) {
  43417. $this->addTest($method->invoke(null, $className));
  43418. }
  43419. } elseif ($class->implementsInterface('PHPUnit_Framework_Test')) {
  43420. $this->addTestSuite($class);
  43421. }
  43422. }
  43423. }
  43424. $this->numTests = -1;
  43425. }
  43426. /**
  43427. * Wrapper for addTestFile() that adds multiple test files.
  43428. *
  43429. * @param array|Iterator $filenames
  43430. * @throws PHPUnit_Framework_Exception
  43431. * @since Method available since Release 2.3.0
  43432. */
  43433. public function addTestFiles($filenames)
  43434. {
  43435. if (!(is_array($filenames) ||
  43436. (is_object($filenames) && $filenames instanceof Iterator))) {
  43437. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  43438. 1,
  43439. 'array or iterator'
  43440. );
  43441. }
  43442. foreach ($filenames as $filename) {
  43443. $this->addTestFile((string) $filename);
  43444. }
  43445. }
  43446. /**
  43447. * Counts the number of test cases that will be run by this test.
  43448. *
  43449. * @param bool $preferCache Indicates if cache is preferred.
  43450. * @return int
  43451. */
  43452. public function count($preferCache = false)
  43453. {
  43454. if ($preferCache && $this->cachedNumTests != null) {
  43455. $numTests = $this->cachedNumTests;
  43456. } else {
  43457. $numTests = 0;
  43458. foreach ($this as $test) {
  43459. $numTests += count($test);
  43460. }
  43461. $this->cachedNumTests = $numTests;
  43462. }
  43463. return $numTests;
  43464. }
  43465. /**
  43466. * @param ReflectionClass $theClass
  43467. * @param string $name
  43468. * @return PHPUnit_Framework_Test
  43469. * @throws PHPUnit_Framework_Exception
  43470. */
  43471. public static function createTest(ReflectionClass $theClass, $name)
  43472. {
  43473. $className = $theClass->getName();
  43474. if (!$theClass->isInstantiable()) {
  43475. return self::warning(
  43476. sprintf('Cannot instantiate class "%s".', $className)
  43477. );
  43478. }
  43479. $backupSettings = PHPUnit_Util_Test::getBackupSettings(
  43480. $className,
  43481. $name
  43482. );
  43483. $preserveGlobalState = PHPUnit_Util_Test::getPreserveGlobalStateSettings(
  43484. $className,
  43485. $name
  43486. );
  43487. $runTestInSeparateProcess = PHPUnit_Util_Test::getProcessIsolationSettings(
  43488. $className,
  43489. $name
  43490. );
  43491. $constructor = $theClass->getConstructor();
  43492. if ($constructor !== null) {
  43493. $parameters = $constructor->getParameters();
  43494. // TestCase() or TestCase($name)
  43495. if (count($parameters) < 2) {
  43496. $test = new $className;
  43497. } // TestCase($name, $data)
  43498. else {
  43499. try {
  43500. $data = PHPUnit_Util_Test::getProvidedData(
  43501. $className,
  43502. $name
  43503. );
  43504. } catch (PHPUnit_Framework_IncompleteTestError $e) {
  43505. $message = sprintf(
  43506. 'Test for %s::%s marked incomplete by data provider',
  43507. $className,
  43508. $name
  43509. );
  43510. $_message = $e->getMessage();
  43511. if (!empty($_message)) {
  43512. $message .= "\n" . $_message;
  43513. }
  43514. $data = self::incompleteTest($className, $name, $message);
  43515. } catch (PHPUnit_Framework_SkippedTestError $e) {
  43516. $message = sprintf(
  43517. 'Test for %s::%s skipped by data provider',
  43518. $className,
  43519. $name
  43520. );
  43521. $_message = $e->getMessage();
  43522. if (!empty($_message)) {
  43523. $message .= "\n" . $_message;
  43524. }
  43525. $data = self::skipTest($className, $name, $message);
  43526. } catch (Throwable $_t) {
  43527. $t = $_t;
  43528. } catch (Exception $_t) {
  43529. $t = $_t;
  43530. }
  43531. if (isset($t)) {
  43532. $message = sprintf(
  43533. 'The data provider specified for %s::%s is invalid.',
  43534. $className,
  43535. $name
  43536. );
  43537. $_message = $t->getMessage();
  43538. if (!empty($_message)) {
  43539. $message .= "\n" . $_message;
  43540. }
  43541. $data = self::warning($message);
  43542. }
  43543. // Test method with @dataProvider.
  43544. if (isset($data)) {
  43545. $test = new PHPUnit_Framework_TestSuite_DataProvider(
  43546. $className . '::' . $name
  43547. );
  43548. if (empty($data)) {
  43549. $data = self::warning(
  43550. sprintf(
  43551. 'No tests found in suite "%s".',
  43552. $test->getName()
  43553. )
  43554. );
  43555. }
  43556. $groups = PHPUnit_Util_Test::getGroups($className, $name);
  43557. if ($data instanceof PHPUnit_Framework_Warning ||
  43558. $data instanceof PHPUnit_Framework_SkippedTestCase ||
  43559. $data instanceof PHPUnit_Framework_IncompleteTestCase) {
  43560. $test->addTest($data, $groups);
  43561. } else {
  43562. foreach ($data as $_dataName => $_data) {
  43563. $_test = new $className($name, $_data, $_dataName);
  43564. if ($runTestInSeparateProcess) {
  43565. $_test->setRunTestInSeparateProcess(true);
  43566. if ($preserveGlobalState !== null) {
  43567. $_test->setPreserveGlobalState($preserveGlobalState);
  43568. }
  43569. }
  43570. if ($backupSettings['backupGlobals'] !== null) {
  43571. $_test->setBackupGlobals(
  43572. $backupSettings['backupGlobals']
  43573. );
  43574. }
  43575. if ($backupSettings['backupStaticAttributes'] !== null) {
  43576. $_test->setBackupStaticAttributes(
  43577. $backupSettings['backupStaticAttributes']
  43578. );
  43579. }
  43580. $test->addTest($_test, $groups);
  43581. }
  43582. }
  43583. } else {
  43584. $test = new $className;
  43585. }
  43586. }
  43587. }
  43588. if (!isset($test)) {
  43589. throw new PHPUnit_Framework_Exception('No valid test provided.');
  43590. }
  43591. if ($test instanceof PHPUnit_Framework_TestCase) {
  43592. $test->setName($name);
  43593. if ($runTestInSeparateProcess) {
  43594. $test->setRunTestInSeparateProcess(true);
  43595. if ($preserveGlobalState !== null) {
  43596. $test->setPreserveGlobalState($preserveGlobalState);
  43597. }
  43598. }
  43599. if ($backupSettings['backupGlobals'] !== null) {
  43600. $test->setBackupGlobals($backupSettings['backupGlobals']);
  43601. }
  43602. if ($backupSettings['backupStaticAttributes'] !== null) {
  43603. $test->setBackupStaticAttributes(
  43604. $backupSettings['backupStaticAttributes']
  43605. );
  43606. }
  43607. }
  43608. return $test;
  43609. }
  43610. /**
  43611. * Creates a default TestResult object.
  43612. *
  43613. * @return PHPUnit_Framework_TestResult
  43614. */
  43615. protected function createResult()
  43616. {
  43617. return new PHPUnit_Framework_TestResult;
  43618. }
  43619. /**
  43620. * Returns the name of the suite.
  43621. *
  43622. * @return string
  43623. */
  43624. public function getName()
  43625. {
  43626. return $this->name;
  43627. }
  43628. /**
  43629. * Returns the test groups of the suite.
  43630. *
  43631. * @return array
  43632. * @since Method available since Release 3.2.0
  43633. */
  43634. public function getGroups()
  43635. {
  43636. return array_keys($this->groups);
  43637. }
  43638. public function getGroupDetails()
  43639. {
  43640. return $this->groups;
  43641. }
  43642. /**
  43643. * Set tests groups of the test case
  43644. *
  43645. * @param array $groups
  43646. * @since Method available since Release 4.0.0
  43647. */
  43648. public function setGroupDetails(array $groups)
  43649. {
  43650. $this->groups = $groups;
  43651. }
  43652. /**
  43653. * Runs the tests and collects their result in a TestResult.
  43654. *
  43655. * @param PHPUnit_Framework_TestResult $result
  43656. * @return PHPUnit_Framework_TestResult
  43657. */
  43658. public function run(PHPUnit_Framework_TestResult $result = null)
  43659. {
  43660. if ($result === null) {
  43661. $result = $this->createResult();
  43662. }
  43663. if (count($this) == 0) {
  43664. return $result;
  43665. }
  43666. $hookMethods = PHPUnit_Util_Test::getHookMethods($this->name);
  43667. $result->startTestSuite($this);
  43668. try {
  43669. $this->setUp();
  43670. foreach ($hookMethods['beforeClass'] as $beforeClassMethod) {
  43671. if ($this->testCase === true &&
  43672. class_exists($this->name, false) &&
  43673. method_exists($this->name, $beforeClassMethod)) {
  43674. if ($missingRequirements = PHPUnit_Util_Test::getMissingRequirements($this->name, $beforeClassMethod)) {
  43675. $this->markTestSuiteSkipped(implode(PHP_EOL, $missingRequirements));
  43676. }
  43677. call_user_func(array($this->name, $beforeClassMethod));
  43678. }
  43679. }
  43680. } catch (PHPUnit_Framework_SkippedTestSuiteError $e) {
  43681. $numTests = count($this);
  43682. for ($i = 0; $i < $numTests; $i++) {
  43683. $result->startTest($this);
  43684. $result->addFailure($this, $e, 0);
  43685. $result->endTest($this, 0);
  43686. }
  43687. $this->tearDown();
  43688. $result->endTestSuite($this);
  43689. return $result;
  43690. } catch (Throwable $_t) {
  43691. $t = $_t;
  43692. } catch (Exception $_t) {
  43693. $t = $_t;
  43694. }
  43695. if (isset($t)) {
  43696. $numTests = count($this);
  43697. for ($i = 0; $i < $numTests; $i++) {
  43698. $result->startTest($this);
  43699. $result->addError($this, $t, 0);
  43700. $result->endTest($this, 0);
  43701. }
  43702. $this->tearDown();
  43703. $result->endTestSuite($this);
  43704. return $result;
  43705. }
  43706. foreach ($this as $test) {
  43707. if ($result->shouldStop()) {
  43708. break;
  43709. }
  43710. if ($test instanceof PHPUnit_Framework_TestCase ||
  43711. $test instanceof self) {
  43712. $test->setDisallowChangesToGlobalState($this->disallowChangesToGlobalState);
  43713. $test->setBackupGlobals($this->backupGlobals);
  43714. $test->setBackupStaticAttributes($this->backupStaticAttributes);
  43715. $test->setRunTestInSeparateProcess($this->runTestInSeparateProcess);
  43716. }
  43717. $test->run($result);
  43718. }
  43719. foreach ($hookMethods['afterClass'] as $afterClassMethod) {
  43720. if ($this->testCase === true && class_exists($this->name, false) && method_exists($this->name, $afterClassMethod)) {
  43721. call_user_func(array($this->name, $afterClassMethod));
  43722. }
  43723. }
  43724. $this->tearDown();
  43725. $result->endTestSuite($this);
  43726. return $result;
  43727. }
  43728. /**
  43729. * @param bool $runTestInSeparateProcess
  43730. * @throws PHPUnit_Framework_Exception
  43731. * @since Method available since Release 3.7.0
  43732. */
  43733. public function setRunTestInSeparateProcess($runTestInSeparateProcess)
  43734. {
  43735. if (is_bool($runTestInSeparateProcess)) {
  43736. $this->runTestInSeparateProcess = $runTestInSeparateProcess;
  43737. } else {
  43738. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  43739. }
  43740. }
  43741. /**
  43742. * Runs a test.
  43743. *
  43744. * @deprecated
  43745. * @param PHPUnit_Framework_Test $test
  43746. * @param PHPUnit_Framework_TestResult $result
  43747. */
  43748. public function runTest(PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result)
  43749. {
  43750. $test->run($result);
  43751. }
  43752. /**
  43753. * Sets the name of the suite.
  43754. *
  43755. * @param string
  43756. */
  43757. public function setName($name)
  43758. {
  43759. $this->name = $name;
  43760. }
  43761. /**
  43762. * Returns the test at the given index.
  43763. *
  43764. * @param int
  43765. * @return PHPUnit_Framework_Test
  43766. */
  43767. public function testAt($index)
  43768. {
  43769. if (isset($this->tests[$index])) {
  43770. return $this->tests[$index];
  43771. } else {
  43772. return false;
  43773. }
  43774. }
  43775. /**
  43776. * Returns the tests as an enumeration.
  43777. *
  43778. * @return array
  43779. */
  43780. public function tests()
  43781. {
  43782. return $this->tests;
  43783. }
  43784. /**
  43785. * Set tests of the test suite
  43786. *
  43787. * @param array $tests
  43788. * @since Method available since Release 4.0.0
  43789. */
  43790. public function setTests(array $tests)
  43791. {
  43792. $this->tests = $tests;
  43793. }
  43794. /**
  43795. * Mark the test suite as skipped.
  43796. *
  43797. * @param string $message
  43798. * @throws PHPUnit_Framework_SkippedTestSuiteError
  43799. * @since Method available since Release 3.0.0
  43800. */
  43801. public function markTestSuiteSkipped($message = '')
  43802. {
  43803. throw new PHPUnit_Framework_SkippedTestSuiteError($message);
  43804. }
  43805. /**
  43806. * @param ReflectionClass $class
  43807. * @param ReflectionMethod $method
  43808. */
  43809. protected function addTestMethod(ReflectionClass $class, ReflectionMethod $method)
  43810. {
  43811. if (!$this->isTestMethod($method)) {
  43812. return;
  43813. }
  43814. $name = $method->getName();
  43815. if (!$method->isPublic()) {
  43816. $this->addTest(
  43817. self::warning(
  43818. sprintf(
  43819. 'Test method "%s" in test class "%s" is not public.',
  43820. $name,
  43821. $class->getName()
  43822. )
  43823. )
  43824. );
  43825. return;
  43826. }
  43827. $test = self::createTest($class, $name);
  43828. if ($test instanceof PHPUnit_Framework_TestCase ||
  43829. $test instanceof PHPUnit_Framework_TestSuite_DataProvider) {
  43830. $test->setDependencies(
  43831. PHPUnit_Util_Test::getDependencies($class->getName(), $name)
  43832. );
  43833. }
  43834. $this->addTest(
  43835. $test,
  43836. PHPUnit_Util_Test::getGroups($class->getName(), $name)
  43837. );
  43838. }
  43839. /**
  43840. * @param ReflectionMethod $method
  43841. * @return bool
  43842. */
  43843. public static function isTestMethod(ReflectionMethod $method)
  43844. {
  43845. if (strpos($method->name, 'test') === 0) {
  43846. return true;
  43847. }
  43848. // @scenario on TestCase::testMethod()
  43849. // @test on TestCase::testMethod()
  43850. $doc_comment = $method->getDocComment();
  43851. return strpos($doc_comment, '@test') !== false ||
  43852. strpos($doc_comment, '@scenario') !== false;
  43853. }
  43854. /**
  43855. * @param string $message
  43856. * @return PHPUnit_Framework_Warning
  43857. */
  43858. protected static function warning($message)
  43859. {
  43860. return new PHPUnit_Framework_Warning($message);
  43861. }
  43862. /**
  43863. * @param string $class
  43864. * @param string $methodName
  43865. * @param string $message
  43866. * @return PHPUnit_Framework_SkippedTestCase
  43867. * @since Method available since Release 4.3.0
  43868. */
  43869. protected static function skipTest($class, $methodName, $message)
  43870. {
  43871. return new PHPUnit_Framework_SkippedTestCase($class, $methodName, $message);
  43872. }
  43873. /**
  43874. * @param string $class
  43875. * @param string $methodName
  43876. * @param string $message
  43877. * @return PHPUnit_Framework_IncompleteTestCase
  43878. * @since Method available since Release 4.3.0
  43879. */
  43880. protected static function incompleteTest($class, $methodName, $message)
  43881. {
  43882. return new PHPUnit_Framework_IncompleteTestCase($class, $methodName, $message);
  43883. }
  43884. /**
  43885. * @param bool $disallowChangesToGlobalState
  43886. * @since Method available since Release 4.6.0
  43887. */
  43888. public function setDisallowChangesToGlobalState($disallowChangesToGlobalState)
  43889. {
  43890. if (is_null($this->disallowChangesToGlobalState) && is_bool($disallowChangesToGlobalState)) {
  43891. $this->disallowChangesToGlobalState = $disallowChangesToGlobalState;
  43892. }
  43893. }
  43894. /**
  43895. * @param bool $backupGlobals
  43896. * @since Method available since Release 3.3.0
  43897. */
  43898. public function setBackupGlobals($backupGlobals)
  43899. {
  43900. if (is_null($this->backupGlobals) && is_bool($backupGlobals)) {
  43901. $this->backupGlobals = $backupGlobals;
  43902. }
  43903. }
  43904. /**
  43905. * @param bool $backupStaticAttributes
  43906. * @since Method available since Release 3.4.0
  43907. */
  43908. public function setBackupStaticAttributes($backupStaticAttributes)
  43909. {
  43910. if (is_null($this->backupStaticAttributes) &&
  43911. is_bool($backupStaticAttributes)) {
  43912. $this->backupStaticAttributes = $backupStaticAttributes;
  43913. }
  43914. }
  43915. /**
  43916. * Returns an iterator for this test suite.
  43917. *
  43918. * @return RecursiveIteratorIterator
  43919. * @since Method available since Release 3.1.0
  43920. */
  43921. public function getIterator()
  43922. {
  43923. $iterator = new PHPUnit_Util_TestSuiteIterator($this);
  43924. if ($this->iteratorFilter !== null) {
  43925. $iterator = $this->iteratorFilter->factory($iterator, $this);
  43926. }
  43927. return $iterator;
  43928. }
  43929. public function injectFilter(PHPUnit_Runner_Filter_Factory $filter)
  43930. {
  43931. $this->iteratorFilter = $filter;
  43932. foreach ($this as $test) {
  43933. if ($test instanceof self) {
  43934. $test->injectFilter($filter);
  43935. }
  43936. }
  43937. }
  43938. /**
  43939. * Template Method that is called before the tests
  43940. * of this test suite are run.
  43941. *
  43942. * @since Method available since Release 3.1.0
  43943. */
  43944. protected function setUp()
  43945. {
  43946. }
  43947. /**
  43948. * Template Method that is called after the tests
  43949. * of this test suite have finished running.
  43950. *
  43951. * @since Method available since Release 3.1.0
  43952. */
  43953. protected function tearDown()
  43954. {
  43955. }
  43956. }
  43957. <?php
  43958. /*
  43959. * This file is part of PHPUnit.
  43960. *
  43961. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43962. *
  43963. * For the full copyright and license information, please view the LICENSE
  43964. * file that was distributed with this source code.
  43965. */
  43966. /**
  43967. * A marker interface for marking any exception/error as result of an unit
  43968. * test as risky.
  43969. *
  43970. * @since Interface available since Release 4.0.0
  43971. */
  43972. interface PHPUnit_Framework_RiskyTest
  43973. {
  43974. }
  43975. <?php
  43976. /*
  43977. * This file is part of PHPUnit.
  43978. *
  43979. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  43980. *
  43981. * For the full copyright and license information, please view the LICENSE
  43982. * file that was distributed with this source code.
  43983. */
  43984. /**
  43985. * Interface for classes that can return a description of itself.
  43986. *
  43987. * @since Interface available since Release 3.0.0
  43988. */
  43989. interface PHPUnit_Framework_SelfDescribing
  43990. {
  43991. /**
  43992. * Returns a string representation of the object.
  43993. *
  43994. * @return string
  43995. */
  43996. public function toString();
  43997. }
  43998. <?php
  43999. /*
  44000. * This file is part of PHPUnit.
  44001. *
  44002. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  44003. *
  44004. * For the full copyright and license information, please view the LICENSE
  44005. * file that was distributed with this source code.
  44006. */
  44007. /**
  44008. * Returns a matcher that matches when the method is executed
  44009. * zero or more times.
  44010. *
  44011. * @return PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount
  44012. * @since Method available since Release 3.0.0
  44013. */
  44014. function any()
  44015. {
  44016. return call_user_func_array(
  44017. 'PHPUnit_Framework_TestCase::any',
  44018. func_get_args()
  44019. );
  44020. }
  44021. /**
  44022. * Returns a PHPUnit_Framework_Constraint_IsAnything matcher object.
  44023. *
  44024. * @return PHPUnit_Framework_Constraint_IsAnything
  44025. * @since Method available since Release 3.0.0
  44026. */
  44027. function anything()
  44028. {
  44029. return call_user_func_array(
  44030. 'PHPUnit_Framework_Assert::anything',
  44031. func_get_args()
  44032. );
  44033. }
  44034. /**
  44035. * Returns a PHPUnit_Framework_Constraint_ArrayHasKey matcher object.
  44036. *
  44037. * @param mixed $key
  44038. * @return PHPUnit_Framework_Constraint_ArrayHasKey
  44039. * @since Method available since Release 3.0.0
  44040. */
  44041. function arrayHasKey($key)
  44042. {
  44043. return call_user_func_array(
  44044. 'PHPUnit_Framework_Assert::arrayHasKey',
  44045. func_get_args()
  44046. );
  44047. }
  44048. /**
  44049. * Asserts that an array has a specified key.
  44050. *
  44051. * @param mixed $key
  44052. * @param array|ArrayAccess $array
  44053. * @param string $message
  44054. * @since Method available since Release 3.0.0
  44055. */
  44056. function assertArrayHasKey($key, $array, $message = '')
  44057. {
  44058. return call_user_func_array(
  44059. 'PHPUnit_Framework_Assert::assertArrayHasKey',
  44060. func_get_args()
  44061. );
  44062. }
  44063. /**
  44064. * Asserts that an array has a specified subset.
  44065. *
  44066. * @param array|ArrayAccess $subset
  44067. * @param array|ArrayAccess $array
  44068. * @param bool $strict Check for object identity
  44069. * @param string $message
  44070. * @since Method available since Release 4.4.0
  44071. */
  44072. function assertArraySubset($subset, $array, $strict = false, $message = '')
  44073. {
  44074. return call_user_func_array(
  44075. 'PHPUnit_Framework_Assert::assertArraySubset',
  44076. func_get_args()
  44077. );
  44078. }
  44079. /**
  44080. * Asserts that an array does not have a specified key.
  44081. *
  44082. * @param mixed $key
  44083. * @param array|ArrayAccess $array
  44084. * @param string $message
  44085. * @since Method available since Release 3.0.0
  44086. */
  44087. function assertArrayNotHasKey($key, $array, $message = '')
  44088. {
  44089. return call_user_func_array(
  44090. 'PHPUnit_Framework_Assert::assertArrayNotHasKey',
  44091. func_get_args()
  44092. );
  44093. }
  44094. /**
  44095. * Asserts that a haystack that is stored in a static attribute of a class
  44096. * or an attribute of an object contains a needle.
  44097. *
  44098. * @param mixed $needle
  44099. * @param string $haystackAttributeName
  44100. * @param mixed $haystackClassOrObject
  44101. * @param string $message
  44102. * @param bool $ignoreCase
  44103. * @param bool $checkForObjectIdentity
  44104. * @param bool $checkForNonObjectIdentity
  44105. * @since Method available since Release 3.0.0
  44106. */
  44107. function assertAttributeContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  44108. {
  44109. return call_user_func_array(
  44110. 'PHPUnit_Framework_Assert::assertAttributeContains',
  44111. func_get_args()
  44112. );
  44113. }
  44114. /**
  44115. * Asserts that a haystack that is stored in a static attribute of a class
  44116. * or an attribute of an object contains only values of a given type.
  44117. *
  44118. * @param string $type
  44119. * @param string $haystackAttributeName
  44120. * @param mixed $haystackClassOrObject
  44121. * @param bool $isNativeType
  44122. * @param string $message
  44123. * @since Method available since Release 3.1.4
  44124. */
  44125. function assertAttributeContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = null, $message = '')
  44126. {
  44127. return call_user_func_array(
  44128. 'PHPUnit_Framework_Assert::assertAttributeContainsOnly',
  44129. func_get_args()
  44130. );
  44131. }
  44132. /**
  44133. * Asserts the number of elements of an array, Countable or Traversable
  44134. * that is stored in an attribute.
  44135. *
  44136. * @param int $expectedCount
  44137. * @param string $haystackAttributeName
  44138. * @param mixed $haystackClassOrObject
  44139. * @param string $message
  44140. * @since Method available since Release 3.6.0
  44141. */
  44142. function assertAttributeCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '')
  44143. {
  44144. return call_user_func_array(
  44145. 'PHPUnit_Framework_Assert::assertAttributeCount',
  44146. func_get_args()
  44147. );
  44148. }
  44149. /**
  44150. * Asserts that a static attribute of a class or an attribute of an object
  44151. * is empty.
  44152. *
  44153. * @param string $haystackAttributeName
  44154. * @param mixed $haystackClassOrObject
  44155. * @param string $message
  44156. * @since Method available since Release 3.5.0
  44157. */
  44158. function assertAttributeEmpty($haystackAttributeName, $haystackClassOrObject, $message = '')
  44159. {
  44160. return call_user_func_array(
  44161. 'PHPUnit_Framework_Assert::assertAttributeEmpty',
  44162. func_get_args()
  44163. );
  44164. }
  44165. /**
  44166. * Asserts that a variable is equal to an attribute of an object.
  44167. *
  44168. * @param mixed $expected
  44169. * @param string $actualAttributeName
  44170. * @param string $actualClassOrObject
  44171. * @param string $message
  44172. * @param float $delta
  44173. * @param int $maxDepth
  44174. * @param bool $canonicalize
  44175. * @param bool $ignoreCase
  44176. */
  44177. function assertAttributeEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  44178. {
  44179. return call_user_func_array(
  44180. 'PHPUnit_Framework_Assert::assertAttributeEquals',
  44181. func_get_args()
  44182. );
  44183. }
  44184. /**
  44185. * Asserts that an attribute is greater than another value.
  44186. *
  44187. * @param mixed $expected
  44188. * @param string $actualAttributeName
  44189. * @param string $actualClassOrObject
  44190. * @param string $message
  44191. * @since Method available since Release 3.1.0
  44192. */
  44193. function assertAttributeGreaterThan($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  44194. {
  44195. return call_user_func_array(
  44196. 'PHPUnit_Framework_Assert::assertAttributeGreaterThan',
  44197. func_get_args()
  44198. );
  44199. }
  44200. /**
  44201. * Asserts that an attribute is greater than or equal to another value.
  44202. *
  44203. * @param mixed $expected
  44204. * @param string $actualAttributeName
  44205. * @param string $actualClassOrObject
  44206. * @param string $message
  44207. * @since Method available since Release 3.1.0
  44208. */
  44209. function assertAttributeGreaterThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  44210. {
  44211. return call_user_func_array(
  44212. 'PHPUnit_Framework_Assert::assertAttributeGreaterThanOrEqual',
  44213. func_get_args()
  44214. );
  44215. }
  44216. /**
  44217. * Asserts that an attribute is of a given type.
  44218. *
  44219. * @param string $expected
  44220. * @param string $attributeName
  44221. * @param mixed $classOrObject
  44222. * @param string $message
  44223. * @since Method available since Release 3.5.0
  44224. */
  44225. function assertAttributeInstanceOf($expected, $attributeName, $classOrObject, $message = '')
  44226. {
  44227. return call_user_func_array(
  44228. 'PHPUnit_Framework_Assert::assertAttributeInstanceOf',
  44229. func_get_args()
  44230. );
  44231. }
  44232. /**
  44233. * Asserts that an attribute is of a given type.
  44234. *
  44235. * @param string $expected
  44236. * @param string $attributeName
  44237. * @param mixed $classOrObject
  44238. * @param string $message
  44239. * @since Method available since Release 3.5.0
  44240. */
  44241. function assertAttributeInternalType($expected, $attributeName, $classOrObject, $message = '')
  44242. {
  44243. return call_user_func_array(
  44244. 'PHPUnit_Framework_Assert::assertAttributeInternalType',
  44245. func_get_args()
  44246. );
  44247. }
  44248. /**
  44249. * Asserts that an attribute is smaller than another value.
  44250. *
  44251. * @param mixed $expected
  44252. * @param string $actualAttributeName
  44253. * @param string $actualClassOrObject
  44254. * @param string $message
  44255. * @since Method available since Release 3.1.0
  44256. */
  44257. function assertAttributeLessThan($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  44258. {
  44259. return call_user_func_array(
  44260. 'PHPUnit_Framework_Assert::assertAttributeLessThan',
  44261. func_get_args()
  44262. );
  44263. }
  44264. /**
  44265. * Asserts that an attribute is smaller than or equal to another value.
  44266. *
  44267. * @param mixed $expected
  44268. * @param string $actualAttributeName
  44269. * @param string $actualClassOrObject
  44270. * @param string $message
  44271. * @since Method available since Release 3.1.0
  44272. */
  44273. function assertAttributeLessThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  44274. {
  44275. return call_user_func_array(
  44276. 'PHPUnit_Framework_Assert::assertAttributeLessThanOrEqual',
  44277. func_get_args()
  44278. );
  44279. }
  44280. /**
  44281. * Asserts that a haystack that is stored in a static attribute of a class
  44282. * or an attribute of an object does not contain a needle.
  44283. *
  44284. * @param mixed $needle
  44285. * @param string $haystackAttributeName
  44286. * @param mixed $haystackClassOrObject
  44287. * @param string $message
  44288. * @param bool $ignoreCase
  44289. * @param bool $checkForObjectIdentity
  44290. * @param bool $checkForNonObjectIdentity
  44291. * @since Method available since Release 3.0.0
  44292. */
  44293. function assertAttributeNotContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  44294. {
  44295. return call_user_func_array(
  44296. 'PHPUnit_Framework_Assert::assertAttributeNotContains',
  44297. func_get_args()
  44298. );
  44299. }
  44300. /**
  44301. * Asserts that a haystack that is stored in a static attribute of a class
  44302. * or an attribute of an object does not contain only values of a given
  44303. * type.
  44304. *
  44305. * @param string $type
  44306. * @param string $haystackAttributeName
  44307. * @param mixed $haystackClassOrObject
  44308. * @param bool $isNativeType
  44309. * @param string $message
  44310. * @since Method available since Release 3.1.4
  44311. */
  44312. function assertAttributeNotContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = null, $message = '')
  44313. {
  44314. return call_user_func_array(
  44315. 'PHPUnit_Framework_Assert::assertAttributeNotContainsOnly',
  44316. func_get_args()
  44317. );
  44318. }
  44319. /**
  44320. * Asserts the number of elements of an array, Countable or Traversable
  44321. * that is stored in an attribute.
  44322. *
  44323. * @param int $expectedCount
  44324. * @param string $haystackAttributeName
  44325. * @param mixed $haystackClassOrObject
  44326. * @param string $message
  44327. * @since Method available since Release 3.6.0
  44328. */
  44329. function assertAttributeNotCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '')
  44330. {
  44331. return call_user_func_array(
  44332. 'PHPUnit_Framework_Assert::assertAttributeNotCount',
  44333. func_get_args()
  44334. );
  44335. }
  44336. /**
  44337. * Asserts that a static attribute of a class or an attribute of an object
  44338. * is not empty.
  44339. *
  44340. * @param string $haystackAttributeName
  44341. * @param mixed $haystackClassOrObject
  44342. * @param string $message
  44343. * @since Method available since Release 3.5.0
  44344. */
  44345. function assertAttributeNotEmpty($haystackAttributeName, $haystackClassOrObject, $message = '')
  44346. {
  44347. return call_user_func_array(
  44348. 'PHPUnit_Framework_Assert::assertAttributeNotEmpty',
  44349. func_get_args()
  44350. );
  44351. }
  44352. /**
  44353. * Asserts that a variable is not equal to an attribute of an object.
  44354. *
  44355. * @param mixed $expected
  44356. * @param string $actualAttributeName
  44357. * @param string $actualClassOrObject
  44358. * @param string $message
  44359. * @param float $delta
  44360. * @param int $maxDepth
  44361. * @param bool $canonicalize
  44362. * @param bool $ignoreCase
  44363. */
  44364. function assertAttributeNotEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  44365. {
  44366. return call_user_func_array(
  44367. 'PHPUnit_Framework_Assert::assertAttributeNotEquals',
  44368. func_get_args()
  44369. );
  44370. }
  44371. /**
  44372. * Asserts that an attribute is of a given type.
  44373. *
  44374. * @param string $expected
  44375. * @param string $attributeName
  44376. * @param mixed $classOrObject
  44377. * @param string $message
  44378. * @since Method available since Release 3.5.0
  44379. */
  44380. function assertAttributeNotInstanceOf($expected, $attributeName, $classOrObject, $message = '')
  44381. {
  44382. return call_user_func_array(
  44383. 'PHPUnit_Framework_Assert::assertAttributeNotInstanceOf',
  44384. func_get_args()
  44385. );
  44386. }
  44387. /**
  44388. * Asserts that an attribute is of a given type.
  44389. *
  44390. * @param string $expected
  44391. * @param string $attributeName
  44392. * @param mixed $classOrObject
  44393. * @param string $message
  44394. * @since Method available since Release 3.5.0
  44395. */
  44396. function assertAttributeNotInternalType($expected, $attributeName, $classOrObject, $message = '')
  44397. {
  44398. return call_user_func_array(
  44399. 'PHPUnit_Framework_Assert::assertAttributeNotInternalType',
  44400. func_get_args()
  44401. );
  44402. }
  44403. /**
  44404. * Asserts that a variable and an attribute of an object do not have the
  44405. * same type and value.
  44406. *
  44407. * @param mixed $expected
  44408. * @param string $actualAttributeName
  44409. * @param object $actualClassOrObject
  44410. * @param string $message
  44411. */
  44412. function assertAttributeNotSame($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  44413. {
  44414. return call_user_func_array(
  44415. 'PHPUnit_Framework_Assert::assertAttributeNotSame',
  44416. func_get_args()
  44417. );
  44418. }
  44419. /**
  44420. * Asserts that a variable and an attribute of an object have the same type
  44421. * and value.
  44422. *
  44423. * @param mixed $expected
  44424. * @param string $actualAttributeName
  44425. * @param object $actualClassOrObject
  44426. * @param string $message
  44427. */
  44428. function assertAttributeSame($expected, $actualAttributeName, $actualClassOrObject, $message = '')
  44429. {
  44430. return call_user_func_array(
  44431. 'PHPUnit_Framework_Assert::assertAttributeSame',
  44432. func_get_args()
  44433. );
  44434. }
  44435. /**
  44436. * Asserts that a class has a specified attribute.
  44437. *
  44438. * @param string $attributeName
  44439. * @param string $className
  44440. * @param string $message
  44441. * @since Method available since Release 3.1.0
  44442. */
  44443. function assertClassHasAttribute($attributeName, $className, $message = '')
  44444. {
  44445. return call_user_func_array(
  44446. 'PHPUnit_Framework_Assert::assertClassHasAttribute',
  44447. func_get_args()
  44448. );
  44449. }
  44450. /**
  44451. * Asserts that a class has a specified static attribute.
  44452. *
  44453. * @param string $attributeName
  44454. * @param string $className
  44455. * @param string $message
  44456. * @since Method available since Release 3.1.0
  44457. */
  44458. function assertClassHasStaticAttribute($attributeName, $className, $message = '')
  44459. {
  44460. return call_user_func_array(
  44461. 'PHPUnit_Framework_Assert::assertClassHasStaticAttribute',
  44462. func_get_args()
  44463. );
  44464. }
  44465. /**
  44466. * Asserts that a class does not have a specified attribute.
  44467. *
  44468. * @param string $attributeName
  44469. * @param string $className
  44470. * @param string $message
  44471. * @since Method available since Release 3.1.0
  44472. */
  44473. function assertClassNotHasAttribute($attributeName, $className, $message = '')
  44474. {
  44475. return call_user_func_array(
  44476. 'PHPUnit_Framework_Assert::assertClassNotHasAttribute',
  44477. func_get_args()
  44478. );
  44479. }
  44480. /**
  44481. * Asserts that a class does not have a specified static attribute.
  44482. *
  44483. * @param string $attributeName
  44484. * @param string $className
  44485. * @param string $message
  44486. * @since Method available since Release 3.1.0
  44487. */
  44488. function assertClassNotHasStaticAttribute($attributeName, $className, $message = '')
  44489. {
  44490. return call_user_func_array(
  44491. 'PHPUnit_Framework_Assert::assertClassNotHasStaticAttribute',
  44492. func_get_args()
  44493. );
  44494. }
  44495. /**
  44496. * Asserts that a haystack contains a needle.
  44497. *
  44498. * @param mixed $needle
  44499. * @param mixed $haystack
  44500. * @param string $message
  44501. * @param bool $ignoreCase
  44502. * @param bool $checkForObjectIdentity
  44503. * @param bool $checkForNonObjectIdentity
  44504. * @since Method available since Release 2.1.0
  44505. */
  44506. function assertContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  44507. {
  44508. return call_user_func_array(
  44509. 'PHPUnit_Framework_Assert::assertContains',
  44510. func_get_args()
  44511. );
  44512. }
  44513. /**
  44514. * Asserts that a haystack contains only values of a given type.
  44515. *
  44516. * @param string $type
  44517. * @param mixed $haystack
  44518. * @param bool $isNativeType
  44519. * @param string $message
  44520. * @since Method available since Release 3.1.4
  44521. */
  44522. function assertContainsOnly($type, $haystack, $isNativeType = null, $message = '')
  44523. {
  44524. return call_user_func_array(
  44525. 'PHPUnit_Framework_Assert::assertContainsOnly',
  44526. func_get_args()
  44527. );
  44528. }
  44529. /**
  44530. * Asserts that a haystack contains only instances of a given classname
  44531. *
  44532. * @param string $classname
  44533. * @param array|Traversable $haystack
  44534. * @param string $message
  44535. */
  44536. function assertContainsOnlyInstancesOf($classname, $haystack, $message = '')
  44537. {
  44538. return call_user_func_array(
  44539. 'PHPUnit_Framework_Assert::assertContainsOnlyInstancesOf',
  44540. func_get_args()
  44541. );
  44542. }
  44543. /**
  44544. * Asserts the number of elements of an array, Countable or Traversable.
  44545. *
  44546. * @param int $expectedCount
  44547. * @param mixed $haystack
  44548. * @param string $message
  44549. */
  44550. function assertCount($expectedCount, $haystack, $message = '')
  44551. {
  44552. return call_user_func_array(
  44553. 'PHPUnit_Framework_Assert::assertCount',
  44554. func_get_args()
  44555. );
  44556. }
  44557. /**
  44558. * Asserts that a variable is empty.
  44559. *
  44560. * @param mixed $actual
  44561. * @param string $message
  44562. * @throws PHPUnit_Framework_AssertionFailedError
  44563. */
  44564. function assertEmpty($actual, $message = '')
  44565. {
  44566. return call_user_func_array(
  44567. 'PHPUnit_Framework_Assert::assertEmpty',
  44568. func_get_args()
  44569. );
  44570. }
  44571. /**
  44572. * Asserts that a hierarchy of DOMElements matches.
  44573. *
  44574. * @param DOMElement $expectedElement
  44575. * @param DOMElement $actualElement
  44576. * @param bool $checkAttributes
  44577. * @param string $message
  44578. * @since Method available since Release 3.3.0
  44579. */
  44580. function assertEqualXMLStructure(DOMElement $expectedElement, DOMElement $actualElement, $checkAttributes = false, $message = '')
  44581. {
  44582. return call_user_func_array(
  44583. 'PHPUnit_Framework_Assert::assertEqualXMLStructure',
  44584. func_get_args()
  44585. );
  44586. }
  44587. /**
  44588. * Asserts that two variables are equal.
  44589. *
  44590. * @param mixed $expected
  44591. * @param mixed $actual
  44592. * @param string $message
  44593. * @param float $delta
  44594. * @param int $maxDepth
  44595. * @param bool $canonicalize
  44596. * @param bool $ignoreCase
  44597. */
  44598. function assertEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  44599. {
  44600. return call_user_func_array(
  44601. 'PHPUnit_Framework_Assert::assertEquals',
  44602. func_get_args()
  44603. );
  44604. }
  44605. /**
  44606. * Asserts that a condition is not true.
  44607. *
  44608. * @param bool $condition
  44609. * @param string $message
  44610. * @throws PHPUnit_Framework_AssertionFailedError
  44611. */
  44612. function assertNotTrue($condition, $message = '')
  44613. {
  44614. return call_user_func_array(
  44615. 'PHPUnit_Framework_Assert::assertNotTrue',
  44616. func_get_args()
  44617. );
  44618. }
  44619. /**
  44620. * Asserts that a condition is false.
  44621. *
  44622. * @param bool $condition
  44623. * @param string $message
  44624. * @throws PHPUnit_Framework_AssertionFailedError
  44625. */
  44626. function assertFalse($condition, $message = '')
  44627. {
  44628. return call_user_func_array(
  44629. 'PHPUnit_Framework_Assert::assertFalse',
  44630. func_get_args()
  44631. );
  44632. }
  44633. /**
  44634. * Asserts that the contents of one file is equal to the contents of another
  44635. * file.
  44636. *
  44637. * @param string $expected
  44638. * @param string $actual
  44639. * @param string $message
  44640. * @param bool $canonicalize
  44641. * @param bool $ignoreCase
  44642. * @since Method available since Release 3.2.14
  44643. */
  44644. function assertFileEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false)
  44645. {
  44646. return call_user_func_array(
  44647. 'PHPUnit_Framework_Assert::assertFileEquals',
  44648. func_get_args()
  44649. );
  44650. }
  44651. /**
  44652. * Asserts that a file exists.
  44653. *
  44654. * @param string $filename
  44655. * @param string $message
  44656. * @since Method available since Release 3.0.0
  44657. */
  44658. function assertFileExists($filename, $message = '')
  44659. {
  44660. return call_user_func_array(
  44661. 'PHPUnit_Framework_Assert::assertFileExists',
  44662. func_get_args()
  44663. );
  44664. }
  44665. /**
  44666. * Asserts that the contents of one file is not equal to the contents of
  44667. * another file.
  44668. *
  44669. * @param string $expected
  44670. * @param string $actual
  44671. * @param string $message
  44672. * @param bool $canonicalize
  44673. * @param bool $ignoreCase
  44674. * @since Method available since Release 3.2.14
  44675. */
  44676. function assertFileNotEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false)
  44677. {
  44678. return call_user_func_array(
  44679. 'PHPUnit_Framework_Assert::assertFileNotEquals',
  44680. func_get_args()
  44681. );
  44682. }
  44683. /**
  44684. * Asserts that a file does not exist.
  44685. *
  44686. * @param string $filename
  44687. * @param string $message
  44688. * @since Method available since Release 3.0.0
  44689. */
  44690. function assertFileNotExists($filename, $message = '')
  44691. {
  44692. return call_user_func_array(
  44693. 'PHPUnit_Framework_Assert::assertFileNotExists',
  44694. func_get_args()
  44695. );
  44696. }
  44697. /**
  44698. * Asserts that a value is greater than another value.
  44699. *
  44700. * @param mixed $expected
  44701. * @param mixed $actual
  44702. * @param string $message
  44703. * @since Method available since Release 3.1.0
  44704. */
  44705. function assertGreaterThan($expected, $actual, $message = '')
  44706. {
  44707. return call_user_func_array(
  44708. 'PHPUnit_Framework_Assert::assertGreaterThan',
  44709. func_get_args()
  44710. );
  44711. }
  44712. /**
  44713. * Asserts that a value is greater than or equal to another value.
  44714. *
  44715. * @param mixed $expected
  44716. * @param mixed $actual
  44717. * @param string $message
  44718. * @since Method available since Release 3.1.0
  44719. */
  44720. function assertGreaterThanOrEqual($expected, $actual, $message = '')
  44721. {
  44722. return call_user_func_array(
  44723. 'PHPUnit_Framework_Assert::assertGreaterThanOrEqual',
  44724. func_get_args()
  44725. );
  44726. }
  44727. /**
  44728. * Asserts that a variable is of a given type.
  44729. *
  44730. * @param string $expected
  44731. * @param mixed $actual
  44732. * @param string $message
  44733. * @since Method available since Release 3.5.0
  44734. */
  44735. function assertInstanceOf($expected, $actual, $message = '')
  44736. {
  44737. return call_user_func_array(
  44738. 'PHPUnit_Framework_Assert::assertInstanceOf',
  44739. func_get_args()
  44740. );
  44741. }
  44742. /**
  44743. * Asserts that a variable is of a given type.
  44744. *
  44745. * @param string $expected
  44746. * @param mixed $actual
  44747. * @param string $message
  44748. * @since Method available since Release 3.5.0
  44749. */
  44750. function assertInternalType($expected, $actual, $message = '')
  44751. {
  44752. return call_user_func_array(
  44753. 'PHPUnit_Framework_Assert::assertInternalType',
  44754. func_get_args()
  44755. );
  44756. }
  44757. /**
  44758. * Asserts that a string is a valid JSON string.
  44759. *
  44760. * @param string $filename
  44761. * @param string $message
  44762. * @since Method available since Release 3.7.20
  44763. */
  44764. function assertJson($expectedJson, $message = '')
  44765. {
  44766. return call_user_func_array(
  44767. 'PHPUnit_Framework_Assert::assertJson',
  44768. func_get_args()
  44769. );
  44770. }
  44771. /**
  44772. * Asserts that two JSON files are equal.
  44773. *
  44774. * @param string $expectedFile
  44775. * @param string $actualFile
  44776. * @param string $message
  44777. */
  44778. function assertJsonFileEqualsJsonFile($expectedFile, $actualFile, $message = '')
  44779. {
  44780. return call_user_func_array(
  44781. 'PHPUnit_Framework_Assert::assertJsonFileEqualsJsonFile',
  44782. func_get_args()
  44783. );
  44784. }
  44785. /**
  44786. * Asserts that two JSON files are not equal.
  44787. *
  44788. * @param string $expectedFile
  44789. * @param string $actualFile
  44790. * @param string $message
  44791. */
  44792. function assertJsonFileNotEqualsJsonFile($expectedFile, $actualFile, $message = '')
  44793. {
  44794. return call_user_func_array(
  44795. 'PHPUnit_Framework_Assert::assertJsonFileNotEqualsJsonFile',
  44796. func_get_args()
  44797. );
  44798. }
  44799. /**
  44800. * Asserts that the generated JSON encoded object and the content of the given file are equal.
  44801. *
  44802. * @param string $expectedFile
  44803. * @param string $actualJson
  44804. * @param string $message
  44805. */
  44806. function assertJsonStringEqualsJsonFile($expectedFile, $actualJson, $message = '')
  44807. {
  44808. return call_user_func_array(
  44809. 'PHPUnit_Framework_Assert::assertJsonStringEqualsJsonFile',
  44810. func_get_args()
  44811. );
  44812. }
  44813. /**
  44814. * Asserts that two given JSON encoded objects or arrays are equal.
  44815. *
  44816. * @param string $expectedJson
  44817. * @param string $actualJson
  44818. * @param string $message
  44819. */
  44820. function assertJsonStringEqualsJsonString($expectedJson, $actualJson, $message = '')
  44821. {
  44822. return call_user_func_array(
  44823. 'PHPUnit_Framework_Assert::assertJsonStringEqualsJsonString',
  44824. func_get_args()
  44825. );
  44826. }
  44827. /**
  44828. * Asserts that the generated JSON encoded object and the content of the given file are not equal.
  44829. *
  44830. * @param string $expectedFile
  44831. * @param string $actualJson
  44832. * @param string $message
  44833. */
  44834. function assertJsonStringNotEqualsJsonFile($expectedFile, $actualJson, $message = '')
  44835. {
  44836. return call_user_func_array(
  44837. 'PHPUnit_Framework_Assert::assertJsonStringNotEqualsJsonFile',
  44838. func_get_args()
  44839. );
  44840. }
  44841. /**
  44842. * Asserts that two given JSON encoded objects or arrays are not equal.
  44843. *
  44844. * @param string $expectedJson
  44845. * @param string $actualJson
  44846. * @param string $message
  44847. */
  44848. function assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, $message = '')
  44849. {
  44850. return call_user_func_array(
  44851. 'PHPUnit_Framework_Assert::assertJsonStringNotEqualsJsonString',
  44852. func_get_args()
  44853. );
  44854. }
  44855. /**
  44856. * Asserts that a value is smaller than another value.
  44857. *
  44858. * @param mixed $expected
  44859. * @param mixed $actual
  44860. * @param string $message
  44861. * @since Method available since Release 3.1.0
  44862. */
  44863. function assertLessThan($expected, $actual, $message = '')
  44864. {
  44865. return call_user_func_array(
  44866. 'PHPUnit_Framework_Assert::assertLessThan',
  44867. func_get_args()
  44868. );
  44869. }
  44870. /**
  44871. * Asserts that a value is smaller than or equal to another value.
  44872. *
  44873. * @param mixed $expected
  44874. * @param mixed $actual
  44875. * @param string $message
  44876. * @since Method available since Release 3.1.0
  44877. */
  44878. function assertLessThanOrEqual($expected, $actual, $message = '')
  44879. {
  44880. return call_user_func_array(
  44881. 'PHPUnit_Framework_Assert::assertLessThanOrEqual',
  44882. func_get_args()
  44883. );
  44884. }
  44885. /**
  44886. * Asserts that a haystack does not contain a needle.
  44887. *
  44888. * @param mixed $needle
  44889. * @param mixed $haystack
  44890. * @param string $message
  44891. * @param bool $ignoreCase
  44892. * @param bool $checkForObjectIdentity
  44893. * @param bool $checkForNonObjectIdentity
  44894. * @since Method available since Release 2.1.0
  44895. */
  44896. function assertNotContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  44897. {
  44898. return call_user_func_array(
  44899. 'PHPUnit_Framework_Assert::assertNotContains',
  44900. func_get_args()
  44901. );
  44902. }
  44903. /**
  44904. * Asserts that a haystack does not contain only values of a given type.
  44905. *
  44906. * @param string $type
  44907. * @param mixed $haystack
  44908. * @param bool $isNativeType
  44909. * @param string $message
  44910. * @since Method available since Release 3.1.4
  44911. */
  44912. function assertNotContainsOnly($type, $haystack, $isNativeType = null, $message = '')
  44913. {
  44914. return call_user_func_array(
  44915. 'PHPUnit_Framework_Assert::assertNotContainsOnly',
  44916. func_get_args()
  44917. );
  44918. }
  44919. /**
  44920. * Asserts the number of elements of an array, Countable or Traversable.
  44921. *
  44922. * @param int $expectedCount
  44923. * @param mixed $haystack
  44924. * @param string $message
  44925. */
  44926. function assertNotCount($expectedCount, $haystack, $message = '')
  44927. {
  44928. return call_user_func_array(
  44929. 'PHPUnit_Framework_Assert::assertNotCount',
  44930. func_get_args()
  44931. );
  44932. }
  44933. /**
  44934. * Asserts that a variable is not empty.
  44935. *
  44936. * @param mixed $actual
  44937. * @param string $message
  44938. * @throws PHPUnit_Framework_AssertionFailedError
  44939. */
  44940. function assertNotEmpty($actual, $message = '')
  44941. {
  44942. return call_user_func_array(
  44943. 'PHPUnit_Framework_Assert::assertNotEmpty',
  44944. func_get_args()
  44945. );
  44946. }
  44947. /**
  44948. * Asserts that two variables are not equal.
  44949. *
  44950. * @param mixed $expected
  44951. * @param mixed $actual
  44952. * @param string $message
  44953. * @param float $delta
  44954. * @param int $maxDepth
  44955. * @param bool $canonicalize
  44956. * @param bool $ignoreCase
  44957. * @since Method available since Release 2.3.0
  44958. */
  44959. function assertNotEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  44960. {
  44961. return call_user_func_array(
  44962. 'PHPUnit_Framework_Assert::assertNotEquals',
  44963. func_get_args()
  44964. );
  44965. }
  44966. /**
  44967. * Asserts that a variable is not of a given type.
  44968. *
  44969. * @param string $expected
  44970. * @param mixed $actual
  44971. * @param string $message
  44972. * @since Method available since Release 3.5.0
  44973. */
  44974. function assertNotInstanceOf($expected, $actual, $message = '')
  44975. {
  44976. return call_user_func_array(
  44977. 'PHPUnit_Framework_Assert::assertNotInstanceOf',
  44978. func_get_args()
  44979. );
  44980. }
  44981. /**
  44982. * Asserts that a variable is not of a given type.
  44983. *
  44984. * @param string $expected
  44985. * @param mixed $actual
  44986. * @param string $message
  44987. * @since Method available since Release 3.5.0
  44988. */
  44989. function assertNotInternalType($expected, $actual, $message = '')
  44990. {
  44991. return call_user_func_array(
  44992. 'PHPUnit_Framework_Assert::assertNotInternalType',
  44993. func_get_args()
  44994. );
  44995. }
  44996. /**
  44997. * Asserts that a condition is not false.
  44998. *
  44999. * @param bool $condition
  45000. * @param string $message
  45001. * @throws PHPUnit_Framework_AssertionFailedError
  45002. */
  45003. function assertNotFalse($condition, $message = '')
  45004. {
  45005. return call_user_func_array(
  45006. 'PHPUnit_Framework_Assert::assertNotFalse',
  45007. func_get_args()
  45008. );
  45009. }
  45010. /**
  45011. * Asserts that a variable is not null.
  45012. *
  45013. * @param mixed $actual
  45014. * @param string $message
  45015. */
  45016. function assertNotNull($actual, $message = '')
  45017. {
  45018. return call_user_func_array(
  45019. 'PHPUnit_Framework_Assert::assertNotNull',
  45020. func_get_args()
  45021. );
  45022. }
  45023. /**
  45024. * Asserts that a string does not match a given regular expression.
  45025. *
  45026. * @param string $pattern
  45027. * @param string $string
  45028. * @param string $message
  45029. * @since Method available since Release 2.1.0
  45030. */
  45031. function assertNotRegExp($pattern, $string, $message = '')
  45032. {
  45033. return call_user_func_array(
  45034. 'PHPUnit_Framework_Assert::assertNotRegExp',
  45035. func_get_args()
  45036. );
  45037. }
  45038. /**
  45039. * Asserts that two variables do not have the same type and value.
  45040. * Used on objects, it asserts that two variables do not reference
  45041. * the same object.
  45042. *
  45043. * @param mixed $expected
  45044. * @param mixed $actual
  45045. * @param string $message
  45046. */
  45047. function assertNotSame($expected, $actual, $message = '')
  45048. {
  45049. return call_user_func_array(
  45050. 'PHPUnit_Framework_Assert::assertNotSame',
  45051. func_get_args()
  45052. );
  45053. }
  45054. /**
  45055. * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
  45056. * is not the same.
  45057. *
  45058. * @param array|Countable|Traversable $expected
  45059. * @param array|Countable|Traversable $actual
  45060. * @param string $message
  45061. */
  45062. function assertNotSameSize($expected, $actual, $message = '')
  45063. {
  45064. return call_user_func_array(
  45065. 'PHPUnit_Framework_Assert::assertNotSameSize',
  45066. func_get_args()
  45067. );
  45068. }
  45069. /**
  45070. * This assertion is the exact opposite of assertTag().
  45071. *
  45072. * Rather than asserting that $matcher results in a match, it asserts that
  45073. * $matcher does not match.
  45074. *
  45075. * @param array $matcher
  45076. * @param string $actual
  45077. * @param string $message
  45078. * @param bool $isHtml
  45079. * @since Method available since Release 3.3.0
  45080. */
  45081. function assertNotTag($matcher, $actual, $message = '', $isHtml = true)
  45082. {
  45083. return call_user_func_array(
  45084. 'PHPUnit_Framework_Assert::assertNotTag',
  45085. func_get_args()
  45086. );
  45087. }
  45088. /**
  45089. * Asserts that a variable is null.
  45090. *
  45091. * @param mixed $actual
  45092. * @param string $message
  45093. */
  45094. function assertNull($actual, $message = '')
  45095. {
  45096. return call_user_func_array(
  45097. 'PHPUnit_Framework_Assert::assertNull',
  45098. func_get_args()
  45099. );
  45100. }
  45101. /**
  45102. * Asserts that an object has a specified attribute.
  45103. *
  45104. * @param string $attributeName
  45105. * @param object $object
  45106. * @param string $message
  45107. * @since Method available since Release 3.0.0
  45108. */
  45109. function assertObjectHasAttribute($attributeName, $object, $message = '')
  45110. {
  45111. return call_user_func_array(
  45112. 'PHPUnit_Framework_Assert::assertObjectHasAttribute',
  45113. func_get_args()
  45114. );
  45115. }
  45116. /**
  45117. * Asserts that an object does not have a specified attribute.
  45118. *
  45119. * @param string $attributeName
  45120. * @param object $object
  45121. * @param string $message
  45122. * @since Method available since Release 3.0.0
  45123. */
  45124. function assertObjectNotHasAttribute($attributeName, $object, $message = '')
  45125. {
  45126. return call_user_func_array(
  45127. 'PHPUnit_Framework_Assert::assertObjectNotHasAttribute',
  45128. func_get_args()
  45129. );
  45130. }
  45131. /**
  45132. * Asserts that a string matches a given regular expression.
  45133. *
  45134. * @param string $pattern
  45135. * @param string $string
  45136. * @param string $message
  45137. */
  45138. function assertRegExp($pattern, $string, $message = '')
  45139. {
  45140. return call_user_func_array(
  45141. 'PHPUnit_Framework_Assert::assertRegExp',
  45142. func_get_args()
  45143. );
  45144. }
  45145. /**
  45146. * Asserts that two variables have the same type and value.
  45147. * Used on objects, it asserts that two variables reference
  45148. * the same object.
  45149. *
  45150. * @param mixed $expected
  45151. * @param mixed $actual
  45152. * @param string $message
  45153. */
  45154. function assertSame($expected, $actual, $message = '')
  45155. {
  45156. return call_user_func_array(
  45157. 'PHPUnit_Framework_Assert::assertSame',
  45158. func_get_args()
  45159. );
  45160. }
  45161. /**
  45162. * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
  45163. * is the same.
  45164. *
  45165. * @param array|Countable|Traversable $expected
  45166. * @param array|Countable|Traversable $actual
  45167. * @param string $message
  45168. */
  45169. function assertSameSize($expected, $actual, $message = '')
  45170. {
  45171. return call_user_func_array(
  45172. 'PHPUnit_Framework_Assert::assertSameSize',
  45173. func_get_args()
  45174. );
  45175. }
  45176. /**
  45177. * Assert the presence, absence, or count of elements in a document matching
  45178. * the CSS $selector, regardless of the contents of those elements.
  45179. *
  45180. * The first argument, $selector, is the CSS selector used to match
  45181. * the elements in the $actual document.
  45182. *
  45183. * The second argument, $count, can be either boolean or numeric.
  45184. * When boolean, it asserts for presence of elements matching the selector
  45185. * (true) or absence of elements (false).
  45186. * When numeric, it asserts the count of elements.
  45187. *
  45188. * assertSelectCount("#binder", true, $xml); // any?
  45189. * assertSelectCount(".binder", 3, $xml); // exactly 3?
  45190. *
  45191. * @param array $selector
  45192. * @param int $count
  45193. * @param mixed $actual
  45194. * @param string $message
  45195. * @param bool $isHtml
  45196. * @since Method available since Release 3.3.0
  45197. */
  45198. function assertSelectCount($selector, $count, $actual, $message = '', $isHtml = true)
  45199. {
  45200. return call_user_func_array(
  45201. 'PHPUnit_Framework_Assert::assertSelectCount',
  45202. func_get_args()
  45203. );
  45204. }
  45205. /**
  45206. * assertSelectEquals("#binder .name", "Chuck", true, $xml); // any?
  45207. * assertSelectEquals("#binder .name", "Chuck", false, $xml); // none?
  45208. *
  45209. * @param array $selector
  45210. * @param string $content
  45211. * @param int $count
  45212. * @param mixed $actual
  45213. * @param string $message
  45214. * @param bool $isHtml
  45215. * @since Method available since Release 3.3.0
  45216. */
  45217. function assertSelectEquals($selector, $content, $count, $actual, $message = '', $isHtml = true)
  45218. {
  45219. return call_user_func_array(
  45220. 'PHPUnit_Framework_Assert::assertSelectEquals',
  45221. func_get_args()
  45222. );
  45223. }
  45224. /**
  45225. * assertSelectRegExp("#binder .name", "/Mike|Derek/", true, $xml); // any?
  45226. * assertSelectRegExp("#binder .name", "/Mike|Derek/", 3, $xml);// 3?
  45227. *
  45228. * @param array $selector
  45229. * @param string $pattern
  45230. * @param int $count
  45231. * @param mixed $actual
  45232. * @param string $message
  45233. * @param bool $isHtml
  45234. * @since Method available since Release 3.3.0
  45235. */
  45236. function assertSelectRegExp($selector, $pattern, $count, $actual, $message = '', $isHtml = true)
  45237. {
  45238. return call_user_func_array(
  45239. 'PHPUnit_Framework_Assert::assertSelectRegExp',
  45240. func_get_args()
  45241. );
  45242. }
  45243. /**
  45244. * Asserts that a string ends not with a given prefix.
  45245. *
  45246. * @param string $suffix
  45247. * @param string $string
  45248. * @param string $message
  45249. * @since Method available since Release 3.4.0
  45250. */
  45251. function assertStringEndsNotWith($suffix, $string, $message = '')
  45252. {
  45253. return call_user_func_array(
  45254. 'PHPUnit_Framework_Assert::assertStringEndsNotWith',
  45255. func_get_args()
  45256. );
  45257. }
  45258. /**
  45259. * Asserts that a string ends with a given prefix.
  45260. *
  45261. * @param string $suffix
  45262. * @param string $string
  45263. * @param string $message
  45264. * @since Method available since Release 3.4.0
  45265. */
  45266. function assertStringEndsWith($suffix, $string, $message = '')
  45267. {
  45268. return call_user_func_array(
  45269. 'PHPUnit_Framework_Assert::assertStringEndsWith',
  45270. func_get_args()
  45271. );
  45272. }
  45273. /**
  45274. * Asserts that the contents of a string is equal
  45275. * to the contents of a file.
  45276. *
  45277. * @param string $expectedFile
  45278. * @param string $actualString
  45279. * @param string $message
  45280. * @param bool $canonicalize
  45281. * @param bool $ignoreCase
  45282. * @since Method available since Release 3.3.0
  45283. */
  45284. function assertStringEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false)
  45285. {
  45286. return call_user_func_array(
  45287. 'PHPUnit_Framework_Assert::assertStringEqualsFile',
  45288. func_get_args()
  45289. );
  45290. }
  45291. /**
  45292. * Asserts that a string matches a given format string.
  45293. *
  45294. * @param string $format
  45295. * @param string $string
  45296. * @param string $message
  45297. * @since Method available since Release 3.5.0
  45298. */
  45299. function assertStringMatchesFormat($format, $string, $message = '')
  45300. {
  45301. return call_user_func_array(
  45302. 'PHPUnit_Framework_Assert::assertStringMatchesFormat',
  45303. func_get_args()
  45304. );
  45305. }
  45306. /**
  45307. * Asserts that a string matches a given format file.
  45308. *
  45309. * @param string $formatFile
  45310. * @param string $string
  45311. * @param string $message
  45312. * @since Method available since Release 3.5.0
  45313. */
  45314. function assertStringMatchesFormatFile($formatFile, $string, $message = '')
  45315. {
  45316. return call_user_func_array(
  45317. 'PHPUnit_Framework_Assert::assertStringMatchesFormatFile',
  45318. func_get_args()
  45319. );
  45320. }
  45321. /**
  45322. * Asserts that the contents of a string is not equal
  45323. * to the contents of a file.
  45324. *
  45325. * @param string $expectedFile
  45326. * @param string $actualString
  45327. * @param string $message
  45328. * @param bool $canonicalize
  45329. * @param bool $ignoreCase
  45330. * @since Method available since Release 3.3.0
  45331. */
  45332. function assertStringNotEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false)
  45333. {
  45334. return call_user_func_array(
  45335. 'PHPUnit_Framework_Assert::assertStringNotEqualsFile',
  45336. func_get_args()
  45337. );
  45338. }
  45339. /**
  45340. * Asserts that a string does not match a given format string.
  45341. *
  45342. * @param string $format
  45343. * @param string $string
  45344. * @param string $message
  45345. * @since Method available since Release 3.5.0
  45346. */
  45347. function assertStringNotMatchesFormat($format, $string, $message = '')
  45348. {
  45349. return call_user_func_array(
  45350. 'PHPUnit_Framework_Assert::assertStringNotMatchesFormat',
  45351. func_get_args()
  45352. );
  45353. }
  45354. /**
  45355. * Asserts that a string does not match a given format string.
  45356. *
  45357. * @param string $formatFile
  45358. * @param string $string
  45359. * @param string $message
  45360. * @since Method available since Release 3.5.0
  45361. */
  45362. function assertStringNotMatchesFormatFile($formatFile, $string, $message = '')
  45363. {
  45364. return call_user_func_array(
  45365. 'PHPUnit_Framework_Assert::assertStringNotMatchesFormatFile',
  45366. func_get_args()
  45367. );
  45368. }
  45369. /**
  45370. * Asserts that a string starts not with a given prefix.
  45371. *
  45372. * @param string $prefix
  45373. * @param string $string
  45374. * @param string $message
  45375. * @since Method available since Release 3.4.0
  45376. */
  45377. function assertStringStartsNotWith($prefix, $string, $message = '')
  45378. {
  45379. return call_user_func_array(
  45380. 'PHPUnit_Framework_Assert::assertStringStartsNotWith',
  45381. func_get_args()
  45382. );
  45383. }
  45384. /**
  45385. * Asserts that a string starts with a given prefix.
  45386. *
  45387. * @param string $prefix
  45388. * @param string $string
  45389. * @param string $message
  45390. * @since Method available since Release 3.4.0
  45391. */
  45392. function assertStringStartsWith($prefix, $string, $message = '')
  45393. {
  45394. return call_user_func_array(
  45395. 'PHPUnit_Framework_Assert::assertStringStartsWith',
  45396. func_get_args()
  45397. );
  45398. }
  45399. /**
  45400. * Evaluate an HTML or XML string and assert its structure and/or contents.
  45401. *
  45402. * The first argument ($matcher) is an associative array that specifies the
  45403. * match criteria for the assertion:
  45404. *
  45405. * - `id` : the node with the given id attribute must match the
  45406. * corresponding value.
  45407. * - `tag` : the node type must match the corresponding value.
  45408. * - `attributes` : a hash. The node's attributes must match the
  45409. * corresponding values in the hash.
  45410. * - `content` : The text content must match the given value.
  45411. * - `parent` : a hash. The node's parent must match the
  45412. * corresponding hash.
  45413. * - `child`: a hash. At least one of the node's immediate children
  45414. * must meet the criteria described by the hash.
  45415. * - `ancestor` : a hash. At least one of the node's ancestors must
  45416. * meet the criteria described by the hash.
  45417. * - `descendant` : a hash. At least one of the node's descendants must
  45418. * meet the criteria described by the hash.
  45419. * - `children` : a hash, for counting children of a node.
  45420. * Accepts the keys:
  45421. *- `count`: a number which must equal the number of children
  45422. * that match
  45423. *- `less_than`: the number of matching children must be greater
  45424. * than this number
  45425. *- `greater_than` : the number of matching children must be less than
  45426. * this number
  45427. *- `only` : another hash consisting of the keys to use to match
  45428. * on the children, and only matching children will be
  45429. * counted
  45430. *
  45431. * <code>
  45432. * // Matcher that asserts that there is an element with an id="my_id".
  45433. * $matcher = array('id' => 'my_id');
  45434. *
  45435. * // Matcher that asserts that there is a "span" tag.
  45436. * $matcher = array('tag' => 'span');
  45437. *
  45438. * // Matcher that asserts that there is a "span" tag with the content
  45439. * // "Hello World".
  45440. * $matcher = array('tag' => 'span', 'content' => 'Hello World');
  45441. *
  45442. * // Matcher that asserts that there is a "span" tag with content matching
  45443. * // the regular expression pattern.
  45444. * $matcher = array('tag' => 'span', 'content' => 'regexp:/Try P(HP|ython)/');
  45445. *
  45446. * // Matcher that asserts that there is a "span" with an "list" class
  45447. * // attribute.
  45448. * $matcher = array(
  45449. * 'tag'=> 'span',
  45450. * 'attributes' => array('class' => 'list')
  45451. * );
  45452. *
  45453. * // Matcher that asserts that there is a "span" inside of a "div".
  45454. * $matcher = array(
  45455. * 'tag'=> 'span',
  45456. * 'parent' => array('tag' => 'div')
  45457. * );
  45458. *
  45459. * // Matcher that asserts that there is a "span" somewhere inside a
  45460. * // "table".
  45461. * $matcher = array(
  45462. * 'tag' => 'span',
  45463. * 'ancestor' => array('tag' => 'table')
  45464. * );
  45465. *
  45466. * // Matcher that asserts that there is a "span" with at least one "em"
  45467. * // child.
  45468. * $matcher = array(
  45469. * 'tag' => 'span',
  45470. * 'child' => array('tag' => 'em')
  45471. * );
  45472. *
  45473. * // Matcher that asserts that there is a "span" containing a (possibly
  45474. * // nested) "strong" tag.
  45475. * $matcher = array(
  45476. * 'tag'=> 'span',
  45477. * 'descendant' => array('tag' => 'strong')
  45478. * );
  45479. *
  45480. * // Matcher that asserts that there is a "span" containing 5-10 "em" tags
  45481. * // as immediate children.
  45482. * $matcher = array(
  45483. * 'tag' => 'span',
  45484. * 'children' => array(
  45485. * 'less_than'=> 11,
  45486. * 'greater_than' => 4,
  45487. * 'only' => array('tag' => 'em')
  45488. * )
  45489. * );
  45490. *
  45491. * // Matcher that asserts that there is a "div", with an "ul" ancestor and
  45492. * // a "li" parent (with class="enum"), and containing a "span" descendant
  45493. * // that contains an element with id="my_test" and the text "Hello World".
  45494. * $matcher = array(
  45495. * 'tag'=> 'div',
  45496. * 'ancestor' => array('tag' => 'ul'),
  45497. * 'parent' => array(
  45498. * 'tag'=> 'li',
  45499. * 'attributes' => array('class' => 'enum')
  45500. * ),
  45501. * 'descendant' => array(
  45502. * 'tag' => 'span',
  45503. * 'child' => array(
  45504. * 'id' => 'my_test',
  45505. * 'content' => 'Hello World'
  45506. * )
  45507. * )
  45508. * );
  45509. *
  45510. * // Use assertTag() to apply a $matcher to a piece of $html.
  45511. * $this->assertTag($matcher, $html);
  45512. *
  45513. * // Use assertTag() to apply a $matcher to a piece of $xml.
  45514. * $this->assertTag($matcher, $xml, '', false);
  45515. * </code>
  45516. *
  45517. * The second argument ($actual) is a string containing either HTML or
  45518. * XML text to be tested.
  45519. *
  45520. * The third argument ($message) is an optional message that will be
  45521. * used if the assertion fails.
  45522. *
  45523. * The fourth argument ($html) is an optional flag specifying whether
  45524. * to load the $actual string into a DOMDocument using the HTML or
  45525. * XML load strategy. It is true by default, which assumes the HTML
  45526. * load strategy. In many cases, this will be acceptable for XML as well.
  45527. *
  45528. * @param array $matcher
  45529. * @param string $actual
  45530. * @param string $message
  45531. * @param bool $isHtml
  45532. * @since Method available since Release 3.3.0
  45533. */
  45534. function assertTag($matcher, $actual, $message = '', $isHtml = true)
  45535. {
  45536. return call_user_func_array(
  45537. 'PHPUnit_Framework_Assert::assertTag',
  45538. func_get_args()
  45539. );
  45540. }
  45541. /**
  45542. * Evaluates a PHPUnit_Framework_Constraint matcher object.
  45543. *
  45544. * @param mixed$value
  45545. * @param PHPUnit_Framework_Constraint $constraint
  45546. * @param string $message
  45547. * @since Method available since Release 3.0.0
  45548. */
  45549. function assertThat($value, PHPUnit_Framework_Constraint $constraint, $message = '')
  45550. {
  45551. return call_user_func_array(
  45552. 'PHPUnit_Framework_Assert::assertThat',
  45553. func_get_args()
  45554. );
  45555. }
  45556. /**
  45557. * Asserts that a condition is true.
  45558. *
  45559. * @param bool $condition
  45560. * @param string $message
  45561. * @throws PHPUnit_Framework_AssertionFailedError
  45562. */
  45563. function assertTrue($condition, $message = '')
  45564. {
  45565. return call_user_func_array(
  45566. 'PHPUnit_Framework_Assert::assertTrue',
  45567. func_get_args()
  45568. );
  45569. }
  45570. /**
  45571. * Asserts that two XML files are equal.
  45572. *
  45573. * @param string $expectedFile
  45574. * @param string $actualFile
  45575. * @param string $message
  45576. * @since Method available since Release 3.1.0
  45577. */
  45578. function assertXmlFileEqualsXmlFile($expectedFile, $actualFile, $message = '')
  45579. {
  45580. return call_user_func_array(
  45581. 'PHPUnit_Framework_Assert::assertXmlFileEqualsXmlFile',
  45582. func_get_args()
  45583. );
  45584. }
  45585. /**
  45586. * Asserts that two XML files are not equal.
  45587. *
  45588. * @param string $expectedFile
  45589. * @param string $actualFile
  45590. * @param string $message
  45591. * @since Method available since Release 3.1.0
  45592. */
  45593. function assertXmlFileNotEqualsXmlFile($expectedFile, $actualFile, $message = '')
  45594. {
  45595. return call_user_func_array(
  45596. 'PHPUnit_Framework_Assert::assertXmlFileNotEqualsXmlFile',
  45597. func_get_args()
  45598. );
  45599. }
  45600. /**
  45601. * Asserts that two XML documents are equal.
  45602. *
  45603. * @param string $expectedFile
  45604. * @param string $actualXml
  45605. * @param string $message
  45606. * @since Method available since Release 3.3.0
  45607. */
  45608. function assertXmlStringEqualsXmlFile($expectedFile, $actualXml, $message = '')
  45609. {
  45610. return call_user_func_array(
  45611. 'PHPUnit_Framework_Assert::assertXmlStringEqualsXmlFile',
  45612. func_get_args()
  45613. );
  45614. }
  45615. /**
  45616. * Asserts that two XML documents are equal.
  45617. *
  45618. * @param string $expectedXml
  45619. * @param string $actualXml
  45620. * @param string $message
  45621. * @since Method available since Release 3.1.0
  45622. */
  45623. function assertXmlStringEqualsXmlString($expectedXml, $actualXml, $message = '')
  45624. {
  45625. return call_user_func_array(
  45626. 'PHPUnit_Framework_Assert::assertXmlStringEqualsXmlString',
  45627. func_get_args()
  45628. );
  45629. }
  45630. /**
  45631. * Asserts that two XML documents are not equal.
  45632. *
  45633. * @param string $expectedFile
  45634. * @param string $actualXml
  45635. * @param string $message
  45636. * @since Method available since Release 3.3.0
  45637. */
  45638. function assertXmlStringNotEqualsXmlFile($expectedFile, $actualXml, $message = '')
  45639. {
  45640. return call_user_func_array(
  45641. 'PHPUnit_Framework_Assert::assertXmlStringNotEqualsXmlFile',
  45642. func_get_args()
  45643. );
  45644. }
  45645. /**
  45646. * Asserts that two XML documents are not equal.
  45647. *
  45648. * @param string $expectedXml
  45649. * @param string $actualXml
  45650. * @param string $message
  45651. * @since Method available since Release 3.1.0
  45652. */
  45653. function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, $message = '')
  45654. {
  45655. return call_user_func_array(
  45656. 'PHPUnit_Framework_Assert::assertXmlStringNotEqualsXmlString',
  45657. func_get_args()
  45658. );
  45659. }
  45660. /**
  45661. * Returns a matcher that matches when the method is executed
  45662. * at the given $index.
  45663. *
  45664. * @param int $index
  45665. * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex
  45666. * @since Method available since Release 3.0.0
  45667. */
  45668. function at($index)
  45669. {
  45670. return call_user_func_array(
  45671. 'PHPUnit_Framework_TestCase::at',
  45672. func_get_args()
  45673. );
  45674. }
  45675. /**
  45676. * Returns a matcher that matches when the method is executed at least once.
  45677. *
  45678. * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce
  45679. * @since Method available since Release 3.0.0
  45680. */
  45681. function atLeastOnce()
  45682. {
  45683. return call_user_func_array(
  45684. 'PHPUnit_Framework_TestCase::atLeastOnce',
  45685. func_get_args()
  45686. );
  45687. }
  45688. /**
  45689. * Returns a PHPUnit_Framework_Constraint_Attribute matcher object.
  45690. *
  45691. * @param PHPUnit_Framework_Constraint $constraint
  45692. * @param string $attributeName
  45693. * @return PHPUnit_Framework_Constraint_Attribute
  45694. * @since Method available since Release 3.1.0
  45695. */
  45696. function attribute(PHPUnit_Framework_Constraint $constraint, $attributeName)
  45697. {
  45698. return call_user_func_array(
  45699. 'PHPUnit_Framework_Assert::attribute',
  45700. func_get_args()
  45701. );
  45702. }
  45703. /**
  45704. * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object
  45705. * that is wrapped in a PHPUnit_Framework_Constraint_Attribute matcher
  45706. * object.
  45707. *
  45708. * @param string $attributeName
  45709. * @param mixed $value
  45710. * @param float $delta
  45711. * @param int $maxDepth
  45712. * @param bool $canonicalize
  45713. * @param bool $ignoreCase
  45714. * @return PHPUnit_Framework_Constraint_Attribute
  45715. * @since Method available since Release 3.1.0
  45716. */
  45717. function attributeEqualTo($attributeName, $value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  45718. {
  45719. return call_user_func_array(
  45720. 'PHPUnit_Framework_Assert::attributeEqualTo',
  45721. func_get_args()
  45722. );
  45723. }
  45724. /**
  45725. * Returns a PHPUnit_Framework_Constraint_Callback matcher object.
  45726. *
  45727. * @param callable $callback
  45728. * @return PHPUnit_Framework_Constraint_Callback
  45729. */
  45730. function callback($callback)
  45731. {
  45732. return call_user_func_array(
  45733. 'PHPUnit_Framework_Assert::callback',
  45734. func_get_args()
  45735. );
  45736. }
  45737. /**
  45738. * Returns a PHPUnit_Framework_Constraint_ClassHasAttribute matcher object.
  45739. *
  45740. * @param string $attributeName
  45741. * @return PHPUnit_Framework_Constraint_ClassHasAttribute
  45742. * @since Method available since Release 3.1.0
  45743. */
  45744. function classHasAttribute($attributeName)
  45745. {
  45746. return call_user_func_array(
  45747. 'PHPUnit_Framework_Assert::classHasAttribute',
  45748. func_get_args()
  45749. );
  45750. }
  45751. /**
  45752. * Returns a PHPUnit_Framework_Constraint_ClassHasStaticAttribute matcher
  45753. * object.
  45754. *
  45755. * @param string $attributeName
  45756. * @return PHPUnit_Framework_Constraint_ClassHasStaticAttribute
  45757. * @since Method available since Release 3.1.0
  45758. */
  45759. function classHasStaticAttribute($attributeName)
  45760. {
  45761. return call_user_func_array(
  45762. 'PHPUnit_Framework_Assert::classHasStaticAttribute',
  45763. func_get_args()
  45764. );
  45765. }
  45766. /**
  45767. * Returns a PHPUnit_Framework_Constraint_TraversableContains matcher
  45768. * object.
  45769. *
  45770. * @param mixed $value
  45771. * @param bool $checkForObjectIdentity
  45772. * @param bool $checkForNonObjectIdentity
  45773. * @return PHPUnit_Framework_Constraint_TraversableContains
  45774. * @since Method available since Release 3.0.0
  45775. */
  45776. function contains($value, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  45777. {
  45778. return call_user_func_array(
  45779. 'PHPUnit_Framework_Assert::contains',
  45780. func_get_args()
  45781. );
  45782. }
  45783. /**
  45784. * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher
  45785. * object.
  45786. *
  45787. * @param string $type
  45788. * @return PHPUnit_Framework_Constraint_TraversableContainsOnly
  45789. * @since Method available since Release 3.1.4
  45790. */
  45791. function containsOnly($type)
  45792. {
  45793. return call_user_func_array(
  45794. 'PHPUnit_Framework_Assert::containsOnly',
  45795. func_get_args()
  45796. );
  45797. }
  45798. /**
  45799. * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher
  45800. * object.
  45801. *
  45802. * @param string $classname
  45803. * @return PHPUnit_Framework_Constraint_TraversableContainsOnly
  45804. */
  45805. function containsOnlyInstancesOf($classname)
  45806. {
  45807. return call_user_func_array(
  45808. 'PHPUnit_Framework_Assert::containsOnlyInstancesOf',
  45809. func_get_args()
  45810. );
  45811. }
  45812. /**
  45813. * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object.
  45814. *
  45815. * @param mixed $value
  45816. * @param float $delta
  45817. * @param int $maxDepth
  45818. * @param bool $canonicalize
  45819. * @param bool $ignoreCase
  45820. * @return PHPUnit_Framework_Constraint_IsEqual
  45821. * @since Method available since Release 3.0.0
  45822. */
  45823. function equalTo($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  45824. {
  45825. return call_user_func_array(
  45826. 'PHPUnit_Framework_Assert::equalTo',
  45827. func_get_args()
  45828. );
  45829. }
  45830. /**
  45831. * Returns a matcher that matches when the method is executed
  45832. * exactly $count times.
  45833. *
  45834. * @param int $count
  45835. * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
  45836. * @since Method available since Release 3.0.0
  45837. */
  45838. function exactly($count)
  45839. {
  45840. return call_user_func_array(
  45841. 'PHPUnit_Framework_TestCase::exactly',
  45842. func_get_args()
  45843. );
  45844. }
  45845. /**
  45846. * Returns a PHPUnit_Framework_Constraint_FileExists matcher object.
  45847. *
  45848. * @return PHPUnit_Framework_Constraint_FileExists
  45849. * @since Method available since Release 3.0.0
  45850. */
  45851. function fileExists()
  45852. {
  45853. return call_user_func_array(
  45854. 'PHPUnit_Framework_Assert::fileExists',
  45855. func_get_args()
  45856. );
  45857. }
  45858. /**
  45859. * Returns a PHPUnit_Framework_Constraint_GreaterThan matcher object.
  45860. *
  45861. * @param mixed $value
  45862. * @return PHPUnit_Framework_Constraint_GreaterThan
  45863. * @since Method available since Release 3.0.0
  45864. */
  45865. function greaterThan($value)
  45866. {
  45867. return call_user_func_array(
  45868. 'PHPUnit_Framework_Assert::greaterThan',
  45869. func_get_args()
  45870. );
  45871. }
  45872. /**
  45873. * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps
  45874. * a PHPUnit_Framework_Constraint_IsEqual and a
  45875. * PHPUnit_Framework_Constraint_GreaterThan matcher object.
  45876. *
  45877. * @param mixed $value
  45878. * @return PHPUnit_Framework_Constraint_Or
  45879. * @since Method available since Release 3.1.0
  45880. */
  45881. function greaterThanOrEqual($value)
  45882. {
  45883. return call_user_func_array(
  45884. 'PHPUnit_Framework_Assert::greaterThanOrEqual',
  45885. func_get_args()
  45886. );
  45887. }
  45888. /**
  45889. * Returns a PHPUnit_Framework_Constraint_IsIdentical matcher object.
  45890. *
  45891. * @param mixed $value
  45892. * @return PHPUnit_Framework_Constraint_IsIdentical
  45893. * @since Method available since Release 3.0.0
  45894. */
  45895. function identicalTo($value)
  45896. {
  45897. return call_user_func_array(
  45898. 'PHPUnit_Framework_Assert::identicalTo',
  45899. func_get_args()
  45900. );
  45901. }
  45902. /**
  45903. * Returns a PHPUnit_Framework_Constraint_IsEmpty matcher object.
  45904. *
  45905. * @return PHPUnit_Framework_Constraint_IsEmpty
  45906. * @since Method available since Release 3.5.0
  45907. */
  45908. function isEmpty()
  45909. {
  45910. return call_user_func_array(
  45911. 'PHPUnit_Framework_Assert::isEmpty',
  45912. func_get_args()
  45913. );
  45914. }
  45915. /**
  45916. * Returns a PHPUnit_Framework_Constraint_IsFalse matcher object.
  45917. *
  45918. * @return PHPUnit_Framework_Constraint_IsFalse
  45919. * @since Method available since Release 3.3.0
  45920. */
  45921. function isFalse()
  45922. {
  45923. return call_user_func_array(
  45924. 'PHPUnit_Framework_Assert::isFalse',
  45925. func_get_args()
  45926. );
  45927. }
  45928. /**
  45929. * Returns a PHPUnit_Framework_Constraint_IsInstanceOf matcher object.
  45930. *
  45931. * @param string $className
  45932. * @return PHPUnit_Framework_Constraint_IsInstanceOf
  45933. * @since Method available since Release 3.0.0
  45934. */
  45935. function isInstanceOf($className)
  45936. {
  45937. return call_user_func_array(
  45938. 'PHPUnit_Framework_Assert::isInstanceOf',
  45939. func_get_args()
  45940. );
  45941. }
  45942. /**
  45943. * Returns a PHPUnit_Framework_Constraint_IsJson matcher object.
  45944. *
  45945. * @return PHPUnit_Framework_Constraint_IsJson
  45946. * @since Method available since Release 3.7.20
  45947. */
  45948. function isJson()
  45949. {
  45950. return call_user_func_array(
  45951. 'PHPUnit_Framework_Assert::isJson',
  45952. func_get_args()
  45953. );
  45954. }
  45955. /**
  45956. * Returns a PHPUnit_Framework_Constraint_IsNull matcher object.
  45957. *
  45958. * @return PHPUnit_Framework_Constraint_IsNull
  45959. * @since Method available since Release 3.3.0
  45960. */
  45961. function isNull()
  45962. {
  45963. return call_user_func_array(
  45964. 'PHPUnit_Framework_Assert::isNull',
  45965. func_get_args()
  45966. );
  45967. }
  45968. /**
  45969. * Returns a PHPUnit_Framework_Constraint_IsTrue matcher object.
  45970. *
  45971. * @return PHPUnit_Framework_Constraint_IsTrue
  45972. * @since Method available since Release 3.3.0
  45973. */
  45974. function isTrue()
  45975. {
  45976. return call_user_func_array(
  45977. 'PHPUnit_Framework_Assert::isTrue',
  45978. func_get_args()
  45979. );
  45980. }
  45981. /**
  45982. * Returns a PHPUnit_Framework_Constraint_IsType matcher object.
  45983. *
  45984. * @param string $type
  45985. * @return PHPUnit_Framework_Constraint_IsType
  45986. * @since Method available since Release 3.0.0
  45987. */
  45988. function isType($type)
  45989. {
  45990. return call_user_func_array(
  45991. 'PHPUnit_Framework_Assert::isType',
  45992. func_get_args()
  45993. );
  45994. }
  45995. /**
  45996. * Returns a PHPUnit_Framework_Constraint_LessThan matcher object.
  45997. *
  45998. * @param mixed $value
  45999. * @return PHPUnit_Framework_Constraint_LessThan
  46000. * @since Method available since Release 3.0.0
  46001. */
  46002. function lessThan($value)
  46003. {
  46004. return call_user_func_array(
  46005. 'PHPUnit_Framework_Assert::lessThan',
  46006. func_get_args()
  46007. );
  46008. }
  46009. /**
  46010. * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps
  46011. * a PHPUnit_Framework_Constraint_IsEqual and a
  46012. * PHPUnit_Framework_Constraint_LessThan matcher object.
  46013. *
  46014. * @param mixed $value
  46015. * @return PHPUnit_Framework_Constraint_Or
  46016. * @since Method available since Release 3.1.0
  46017. */
  46018. function lessThanOrEqual($value)
  46019. {
  46020. return call_user_func_array(
  46021. 'PHPUnit_Framework_Assert::lessThanOrEqual',
  46022. func_get_args()
  46023. );
  46024. }
  46025. /**
  46026. * Returns a PHPUnit_Framework_Constraint_And matcher object.
  46027. *
  46028. * @return PHPUnit_Framework_Constraint_And
  46029. * @since Method available since Release 3.0.0
  46030. */
  46031. function logicalAnd()
  46032. {
  46033. return call_user_func_array(
  46034. 'PHPUnit_Framework_Assert::logicalAnd',
  46035. func_get_args()
  46036. );
  46037. }
  46038. /**
  46039. * Returns a PHPUnit_Framework_Constraint_Not matcher object.
  46040. *
  46041. * @param PHPUnit_Framework_Constraint $constraint
  46042. * @return PHPUnit_Framework_Constraint_Not
  46043. * @since Method available since Release 3.0.0
  46044. */
  46045. function logicalNot(PHPUnit_Framework_Constraint $constraint)
  46046. {
  46047. return call_user_func_array(
  46048. 'PHPUnit_Framework_Assert::logicalNot',
  46049. func_get_args()
  46050. );
  46051. }
  46052. /**
  46053. * Returns a PHPUnit_Framework_Constraint_Or matcher object.
  46054. *
  46055. * @return PHPUnit_Framework_Constraint_Or
  46056. * @since Method available since Release 3.0.0
  46057. */
  46058. function logicalOr()
  46059. {
  46060. return call_user_func_array(
  46061. 'PHPUnit_Framework_Assert::logicalOr',
  46062. func_get_args()
  46063. );
  46064. }
  46065. /**
  46066. * Returns a PHPUnit_Framework_Constraint_Xor matcher object.
  46067. *
  46068. * @return PHPUnit_Framework_Constraint_Xor
  46069. * @since Method available since Release 3.0.0
  46070. */
  46071. function logicalXor()
  46072. {
  46073. return call_user_func_array(
  46074. 'PHPUnit_Framework_Assert::logicalXor',
  46075. func_get_args()
  46076. );
  46077. }
  46078. /**
  46079. * Returns a PHPUnit_Framework_Constraint_StringMatches matcher object.
  46080. *
  46081. * @param string $string
  46082. * @return PHPUnit_Framework_Constraint_StringMatches
  46083. * @since Method available since Release 3.5.0
  46084. */
  46085. function matches($string)
  46086. {
  46087. return call_user_func_array(
  46088. 'PHPUnit_Framework_Assert::matches',
  46089. func_get_args()
  46090. );
  46091. }
  46092. /**
  46093. * Returns a PHPUnit_Framework_Constraint_PCREMatch matcher object.
  46094. *
  46095. * @param string $pattern
  46096. * @return PHPUnit_Framework_Constraint_PCREMatch
  46097. * @since Method available since Release 3.0.0
  46098. */
  46099. function matchesRegularExpression($pattern)
  46100. {
  46101. return call_user_func_array(
  46102. 'PHPUnit_Framework_Assert::matchesRegularExpression',
  46103. func_get_args()
  46104. );
  46105. }
  46106. /**
  46107. * Returns a matcher that matches when the method is never executed.
  46108. *
  46109. * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
  46110. * @since Method available since Release 3.0.0
  46111. */
  46112. function never()
  46113. {
  46114. return call_user_func_array(
  46115. 'PHPUnit_Framework_TestCase::never',
  46116. func_get_args()
  46117. );
  46118. }
  46119. /**
  46120. * Returns a PHPUnit_Framework_Constraint_ObjectHasAttribute matcher object.
  46121. *
  46122. * @param string $attributeName
  46123. * @return PHPUnit_Framework_Constraint_ObjectHasAttribute
  46124. * @since Method available since Release 3.0.0
  46125. */
  46126. function objectHasAttribute($attributeName)
  46127. {
  46128. return call_user_func_array(
  46129. 'PHPUnit_Framework_Assert::objectHasAttribute',
  46130. func_get_args()
  46131. );
  46132. }
  46133. /**
  46134. * @param mixed $value, ...
  46135. * @return PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls
  46136. * @since Method available since Release 3.0.0
  46137. */
  46138. function onConsecutiveCalls()
  46139. {
  46140. return call_user_func_array(
  46141. 'PHPUnit_Framework_TestCase::onConsecutiveCalls',
  46142. func_get_args()
  46143. );
  46144. }
  46145. /**
  46146. * Returns a matcher that matches when the method is executed exactly once.
  46147. *
  46148. * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
  46149. * @since Method available since Release 3.0.0
  46150. */
  46151. function once()
  46152. {
  46153. return call_user_func_array(
  46154. 'PHPUnit_Framework_TestCase::once',
  46155. func_get_args()
  46156. );
  46157. }
  46158. /**
  46159. * @param int $argumentIndex
  46160. * @return PHPUnit_Framework_MockObject_Stub_ReturnArgument
  46161. * @since Method available since Release 3.3.0
  46162. */
  46163. function returnArgument($argumentIndex)
  46164. {
  46165. return call_user_func_array(
  46166. 'PHPUnit_Framework_TestCase::returnArgument',
  46167. func_get_args()
  46168. );
  46169. }
  46170. /**
  46171. * @param mixed $callback
  46172. * @return PHPUnit_Framework_MockObject_Stub_ReturnCallback
  46173. * @since Method available since Release 3.3.0
  46174. */
  46175. function returnCallback($callback)
  46176. {
  46177. return call_user_func_array(
  46178. 'PHPUnit_Framework_TestCase::returnCallback',
  46179. func_get_args()
  46180. );
  46181. }
  46182. /**
  46183. * Returns the current object.
  46184. *
  46185. * This method is useful when mocking a fluent interface.
  46186. *
  46187. * @return PHPUnit_Framework_MockObject_Stub_ReturnSelf
  46188. * @since Method available since Release 3.6.0
  46189. */
  46190. function returnSelf()
  46191. {
  46192. return call_user_func_array(
  46193. 'PHPUnit_Framework_TestCase::returnSelf',
  46194. func_get_args()
  46195. );
  46196. }
  46197. /**
  46198. * @param mixed $value
  46199. * @return PHPUnit_Framework_MockObject_Stub_Return
  46200. * @since Method available since Release 3.0.0
  46201. */
  46202. function returnValue($value)
  46203. {
  46204. return call_user_func_array(
  46205. 'PHPUnit_Framework_TestCase::returnValue',
  46206. func_get_args()
  46207. );
  46208. }
  46209. /**
  46210. * @param array $valueMap
  46211. * @return PHPUnit_Framework_MockObject_Stub_ReturnValueMap
  46212. * @since Method available since Release 3.6.0
  46213. */
  46214. function returnValueMap(array $valueMap)
  46215. {
  46216. return call_user_func_array(
  46217. 'PHPUnit_Framework_TestCase::returnValueMap',
  46218. func_get_args()
  46219. );
  46220. }
  46221. /**
  46222. * Returns a PHPUnit_Framework_Constraint_StringContains matcher object.
  46223. *
  46224. * @param string $string
  46225. * @param bool $case
  46226. * @return PHPUnit_Framework_Constraint_StringContains
  46227. * @since Method available since Release 3.0.0
  46228. */
  46229. function stringContains($string, $case = true)
  46230. {
  46231. return call_user_func_array(
  46232. 'PHPUnit_Framework_Assert::stringContains',
  46233. func_get_args()
  46234. );
  46235. }
  46236. /**
  46237. * Returns a PHPUnit_Framework_Constraint_StringEndsWith matcher object.
  46238. *
  46239. * @param mixed $suffix
  46240. * @return PHPUnit_Framework_Constraint_StringEndsWith
  46241. * @since Method available since Release 3.4.0
  46242. */
  46243. function stringEndsWith($suffix)
  46244. {
  46245. return call_user_func_array(
  46246. 'PHPUnit_Framework_Assert::stringEndsWith',
  46247. func_get_args()
  46248. );
  46249. }
  46250. /**
  46251. * Returns a PHPUnit_Framework_Constraint_StringStartsWith matcher object.
  46252. *
  46253. * @param mixed $prefix
  46254. * @return PHPUnit_Framework_Constraint_StringStartsWith
  46255. * @since Method available since Release 3.4.0
  46256. */
  46257. function stringStartsWith($prefix)
  46258. {
  46259. return call_user_func_array(
  46260. 'PHPUnit_Framework_Assert::stringStartsWith',
  46261. func_get_args()
  46262. );
  46263. }
  46264. /**
  46265. * @param Exception $exception
  46266. * @return PHPUnit_Framework_MockObject_Stub_Exception
  46267. * @since Method available since Release 3.1.0
  46268. */
  46269. function throwException(Exception $exception)
  46270. {
  46271. return call_user_func_array(
  46272. 'PHPUnit_Framework_TestCase::throwException',
  46273. func_get_args()
  46274. );
  46275. }
  46276. <?php
  46277. /*
  46278. * This file is part of PHPUnit.
  46279. *
  46280. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  46281. *
  46282. * For the full copyright and license information, please view the LICENSE
  46283. * file that was distributed with this source code.
  46284. */
  46285. /**
  46286. * Creates a synthetic failed assertion.
  46287. *
  46288. * @since Class available since Release 3.5.0
  46289. */
  46290. class PHPUnit_Framework_SyntheticError extends PHPUnit_Framework_AssertionFailedError
  46291. {
  46292. /**
  46293. * The synthetic file.
  46294. *
  46295. * @var string
  46296. */
  46297. protected $syntheticFile = '';
  46298. /**
  46299. * The synthetic line number.
  46300. *
  46301. * @var int
  46302. */
  46303. protected $syntheticLine = 0;
  46304. /**
  46305. * The synthetic trace.
  46306. *
  46307. * @var array
  46308. */
  46309. protected $syntheticTrace = array();
  46310. /**
  46311. * Constructor.
  46312. *
  46313. * @param string $message
  46314. * @param int $code
  46315. * @param string $file
  46316. * @param int $line
  46317. * @param array $trace
  46318. */
  46319. public function __construct($message, $code, $file, $line, $trace)
  46320. {
  46321. parent::__construct($message, $code);
  46322. $this->syntheticFile = $file;
  46323. $this->syntheticLine = $line;
  46324. $this->syntheticTrace = $trace;
  46325. }
  46326. /**
  46327. * @return string
  46328. */
  46329. public function getSyntheticFile()
  46330. {
  46331. return $this->syntheticFile;
  46332. }
  46333. /**
  46334. * @return int
  46335. */
  46336. public function getSyntheticLine()
  46337. {
  46338. return $this->syntheticLine;
  46339. }
  46340. /**
  46341. * @return array
  46342. */
  46343. public function getSyntheticTrace()
  46344. {
  46345. return $this->syntheticTrace;
  46346. }
  46347. }
  46348. <?php
  46349. /*
  46350. * This file is part of PHPUnit.
  46351. *
  46352. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  46353. *
  46354. * For the full copyright and license information, please view the LICENSE
  46355. * file that was distributed with this source code.
  46356. */
  46357. /**
  46358. * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
  46359. * case of a risky test.
  46360. *
  46361. * @since Class available since Release 4.0.0
  46362. */
  46363. class PHPUnit_Framework_RiskyTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_RiskyTest
  46364. {
  46365. }
  46366. <?php
  46367. /*
  46368. * This file is part of PHPUnit.
  46369. *
  46370. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  46371. *
  46372. * For the full copyright and license information, please view the LICENSE
  46373. * file that was distributed with this source code.
  46374. */
  46375. /**
  46376. * A Listener for test progress.
  46377. *
  46378. * @since Interface available since Release 2.0.0
  46379. */
  46380. interface PHPUnit_Framework_TestListener
  46381. {
  46382. /**
  46383. * An error occurred.
  46384. *
  46385. * @param PHPUnit_Framework_Test $test
  46386. * @param Exception $e
  46387. * @param float $time
  46388. */
  46389. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time);
  46390. /**
  46391. * A failure occurred.
  46392. *
  46393. * @param PHPUnit_Framework_Test $test
  46394. * @param PHPUnit_Framework_AssertionFailedError $e
  46395. * @param float $time
  46396. */
  46397. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time);
  46398. /**
  46399. * Incomplete test.
  46400. *
  46401. * @param PHPUnit_Framework_Test $test
  46402. * @param Exception $e
  46403. * @param float $time
  46404. */
  46405. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time);
  46406. /**
  46407. * Risky test.
  46408. *
  46409. * @param PHPUnit_Framework_Test $test
  46410. * @param Exception $e
  46411. * @param float $time
  46412. * @since Method available since Release 4.0.0
  46413. */
  46414. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time);
  46415. /**
  46416. * Skipped test.
  46417. *
  46418. * @param PHPUnit_Framework_Test $test
  46419. * @param Exception $e
  46420. * @param float $time
  46421. * @since Method available since Release 3.0.0
  46422. */
  46423. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time);
  46424. /**
  46425. * A test suite started.
  46426. *
  46427. * @param PHPUnit_Framework_TestSuite $suite
  46428. * @since Method available since Release 2.2.0
  46429. */
  46430. public function startTestSuite(PHPUnit_Framework_TestSuite $suite);
  46431. /**
  46432. * A test suite ended.
  46433. *
  46434. * @param PHPUnit_Framework_TestSuite $suite
  46435. * @since Method available since Release 2.2.0
  46436. */
  46437. public function endTestSuite(PHPUnit_Framework_TestSuite $suite);
  46438. /**
  46439. * A test started.
  46440. *
  46441. * @param PHPUnit_Framework_Test $test
  46442. */
  46443. public function startTest(PHPUnit_Framework_Test $test);
  46444. /**
  46445. * A test ended.
  46446. *
  46447. * @param PHPUnit_Framework_Test $test
  46448. * @param float $time
  46449. */
  46450. public function endTest(PHPUnit_Framework_Test $test, $time);
  46451. }
  46452. <?php
  46453. /*
  46454. * This file is part of PHPUnit.
  46455. *
  46456. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  46457. *
  46458. * For the full copyright and license information, please view the LICENSE
  46459. * file that was distributed with this source code.
  46460. */
  46461. /**
  46462. * Wraps Exceptions thrown by code under test.
  46463. *
  46464. * Re-instantiates Exceptions thrown by user-space code to retain their original
  46465. * class names, properties, and stack traces (but without arguments).
  46466. *
  46467. * Unlike PHPUnit_Framework_Exception, the complete stack of previous Exceptions
  46468. * is processed.
  46469. *
  46470. * @since Class available since Release 4.3.0
  46471. */
  46472. class PHPUnit_Framework_ExceptionWrapper extends PHPUnit_Framework_Exception
  46473. {
  46474. /**
  46475. * @var string
  46476. */
  46477. protected $classname;
  46478. /**
  46479. * @var PHPUnit_Framework_ExceptionWrapper|null
  46480. */
  46481. protected $previous;
  46482. /**
  46483. * @param Throwable|Exception $e
  46484. */
  46485. public function __construct($e)
  46486. {
  46487. // PDOException::getCode() is a string.
  46488. // @see http://php.net/manual/en/class.pdoexception.php#95812
  46489. parent::__construct($e->getMessage(), (int) $e->getCode());
  46490. $this->classname = get_class($e);
  46491. $this->file = $e->getFile();
  46492. $this->line = $e->getLine();
  46493. $this->serializableTrace = $e->getTrace();
  46494. foreach ($this->serializableTrace as $i => $call) {
  46495. unset($this->serializableTrace[$i]['args']);
  46496. }
  46497. if ($e->getPrevious()) {
  46498. $this->previous = new self($e->getPrevious());
  46499. }
  46500. }
  46501. /**
  46502. * @return string
  46503. */
  46504. public function getClassname()
  46505. {
  46506. return $this->classname;
  46507. }
  46508. /**
  46509. * @return PHPUnit_Framework_ExceptionWrapper
  46510. */
  46511. public function getPreviousWrapped()
  46512. {
  46513. return $this->previous;
  46514. }
  46515. /**
  46516. * @return string
  46517. */
  46518. public function __toString()
  46519. {
  46520. $string = PHPUnit_Framework_TestFailure::exceptionToString($this);
  46521. if ($trace = PHPUnit_Util_Filter::getFilteredStacktrace($this)) {
  46522. $string .= "\n" . $trace;
  46523. }
  46524. if ($this->previous) {
  46525. $string .= "\nCaused by\n" . $this->previous;
  46526. }
  46527. return $string;
  46528. }
  46529. }
  46530. <?php
  46531. /*
  46532. * This file is part of PHPUnit.
  46533. *
  46534. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  46535. *
  46536. * For the full copyright and license information, please view the LICENSE
  46537. * file that was distributed with this source code.
  46538. */
  46539. /**
  46540. * A marker interface for marking a unit test as being skipped.
  46541. *
  46542. * @since Interface available since Release 3.0.0
  46543. */
  46544. interface PHPUnit_Framework_SkippedTest
  46545. {
  46546. }
  46547. <?php
  46548. /*
  46549. * This file is part of PHPUnit.
  46550. *
  46551. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  46552. *
  46553. * For the full copyright and license information, please view the LICENSE
  46554. * file that was distributed with this source code.
  46555. */
  46556. /**
  46557. * @since Class available since Release 4.0.0
  46558. */
  46559. class PHPUnit_Framework_InvalidCoversTargetException extends PHPUnit_Framework_CodeCoverageException
  46560. {
  46561. }
  46562. <?php
  46563. /*
  46564. * This file is part of PHPUnit.
  46565. *
  46566. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  46567. *
  46568. * For the full copyright and license information, please view the LICENSE
  46569. * file that was distributed with this source code.
  46570. */
  46571. use SebastianBergmann\GlobalState\Snapshot;
  46572. use SebastianBergmann\GlobalState\Restorer;
  46573. use SebastianBergmann\GlobalState\Blacklist;
  46574. use SebastianBergmann\Diff\Differ;
  46575. use SebastianBergmann\Exporter\Exporter;
  46576. use Prophecy\Exception\Prediction\PredictionException;
  46577. use Prophecy\Prophet;
  46578. /**
  46579. * A TestCase defines the fixture to run multiple tests.
  46580. *
  46581. * To define a TestCase
  46582. *
  46583. * 1) Implement a subclass of PHPUnit_Framework_TestCase.
  46584. * 2) Define instance variables that store the state of the fixture.
  46585. * 3) Initialize the fixture state by overriding setUp().
  46586. * 4) Clean-up after a test by overriding tearDown().
  46587. *
  46588. * Each test runs in its own fixture so there can be no side effects
  46589. * among test runs.
  46590. *
  46591. * Here is an example:
  46592. *
  46593. * <code>
  46594. * <?php
  46595. * class MathTest extends PHPUnit_Framework_TestCase
  46596. * {
  46597. * public $value1;
  46598. * public $value2;
  46599. *
  46600. * protected function setUp()
  46601. * {
  46602. * $this->value1 = 2;
  46603. * $this->value2 = 3;
  46604. * }
  46605. * }
  46606. * ?>
  46607. * </code>
  46608. *
  46609. * For each test implement a method which interacts with the fixture.
  46610. * Verify the expected results with assertions specified by calling
  46611. * assert with a boolean.
  46612. *
  46613. * <code>
  46614. * <?php
  46615. * public function testPass()
  46616. * {
  46617. * $this->assertTrue($this->value1 + $this->value2 == 5);
  46618. * }
  46619. * ?>
  46620. * </code>
  46621. *
  46622. * @since Class available since Release 2.0.0
  46623. */
  46624. abstract class PHPUnit_Framework_TestCase extends PHPUnit_Framework_Assert implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing
  46625. {
  46626. /**
  46627. * Enable or disable the backup and restoration of the $GLOBALS array.
  46628. * Overwrite this attribute in a child class of TestCase.
  46629. * Setting this attribute in setUp() has no effect!
  46630. *
  46631. * @var bool
  46632. */
  46633. protected $backupGlobals = null;
  46634. /**
  46635. * @var array
  46636. */
  46637. protected $backupGlobalsBlacklist = array();
  46638. /**
  46639. * Enable or disable the backup and restoration of static attributes.
  46640. * Overwrite this attribute in a child class of TestCase.
  46641. * Setting this attribute in setUp() has no effect!
  46642. *
  46643. * @var bool
  46644. */
  46645. protected $backupStaticAttributes = null;
  46646. /**
  46647. * @var array
  46648. */
  46649. protected $backupStaticAttributesBlacklist = array();
  46650. /**
  46651. * Whether or not this test is to be run in a separate PHP process.
  46652. *
  46653. * @var bool
  46654. */
  46655. protected $runTestInSeparateProcess = null;
  46656. /**
  46657. * Whether or not this test should preserve the global state when
  46658. * running in a separate PHP process.
  46659. *
  46660. * @var bool
  46661. */
  46662. protected $preserveGlobalState = true;
  46663. /**
  46664. * Whether or not this test is running in a separate PHP process.
  46665. *
  46666. * @var bool
  46667. */
  46668. private $inIsolation = false;
  46669. /**
  46670. * @var array
  46671. */
  46672. private $data = array();
  46673. /**
  46674. * @var string
  46675. */
  46676. private $dataName = '';
  46677. /**
  46678. * @var bool
  46679. */
  46680. private $useErrorHandler = null;
  46681. /**
  46682. * The name of the expected Exception.
  46683. *
  46684. * @var mixed
  46685. */
  46686. private $expectedException = null;
  46687. /**
  46688. * The message of the expected Exception.
  46689. *
  46690. * @var string
  46691. */
  46692. private $expectedExceptionMessage = '';
  46693. /**
  46694. * The regex pattern to validate the expected Exception message.
  46695. *
  46696. * @var string
  46697. */
  46698. private $expectedExceptionMessageRegExp = '';
  46699. /**
  46700. * The code of the expected Exception.
  46701. *
  46702. * @var int
  46703. */
  46704. private $expectedExceptionCode;
  46705. /**
  46706. * The name of the test case.
  46707. *
  46708. * @var string
  46709. */
  46710. private $name = null;
  46711. /**
  46712. * @var array
  46713. */
  46714. private $dependencies = array();
  46715. /**
  46716. * @var array
  46717. */
  46718. private $dependencyInput = array();
  46719. /**
  46720. * @var array
  46721. */
  46722. private $iniSettings = array();
  46723. /**
  46724. * @var array
  46725. */
  46726. private $locale = array();
  46727. /**
  46728. * @var array
  46729. */
  46730. private $mockObjects = array();
  46731. /**
  46732. * @var array
  46733. */
  46734. private $mockObjectGenerator = null;
  46735. /**
  46736. * @var int
  46737. */
  46738. private $status;
  46739. /**
  46740. * @var string
  46741. */
  46742. private $statusMessage = '';
  46743. /**
  46744. * @var int
  46745. */
  46746. private $numAssertions = 0;
  46747. /**
  46748. * @var PHPUnit_Framework_TestResult
  46749. */
  46750. private $result;
  46751. /**
  46752. * @var mixed
  46753. */
  46754. private $testResult;
  46755. /**
  46756. * @var string
  46757. */
  46758. private $output = '';
  46759. /**
  46760. * @var string
  46761. */
  46762. private $outputExpectedRegex = null;
  46763. /**
  46764. * @var string
  46765. */
  46766. private $outputExpectedString = null;
  46767. /**
  46768. * @var mixed
  46769. */
  46770. private $outputCallback = false;
  46771. /**
  46772. * @var bool
  46773. */
  46774. private $outputBufferingActive = false;
  46775. /**
  46776. * @var int
  46777. */
  46778. private $outputBufferingLevel;
  46779. /**
  46780. * @var SebastianBergmann\GlobalState\Snapshot
  46781. */
  46782. private $snapshot;
  46783. /**
  46784. * @var Prophecy\Prophet
  46785. */
  46786. private $prophet;
  46787. /**
  46788. * @var bool
  46789. */
  46790. private $disallowChangesToGlobalState = false;
  46791. /**
  46792. * Constructs a test case with the given name.
  46793. *
  46794. * @param string $name
  46795. * @param array $data
  46796. * @param string $dataName
  46797. */
  46798. public function __construct($name = null, array $data = array(), $dataName = '')
  46799. {
  46800. if ($name !== null) {
  46801. $this->setName($name);
  46802. }
  46803. $this->data = $data;
  46804. $this->dataName = $dataName;
  46805. }
  46806. /**
  46807. * Returns a string representation of the test case.
  46808. *
  46809. * @return string
  46810. */
  46811. public function toString()
  46812. {
  46813. $class = new ReflectionClass($this);
  46814. $buffer = sprintf(
  46815. '%s::%s',
  46816. $class->name,
  46817. $this->getName(false)
  46818. );
  46819. return $buffer . $this->getDataSetAsString();
  46820. }
  46821. /**
  46822. * Counts the number of test cases executed by run(TestResult result).
  46823. *
  46824. * @return int
  46825. */
  46826. public function count()
  46827. {
  46828. return 1;
  46829. }
  46830. /**
  46831. * Returns the annotations for this test.
  46832. *
  46833. * @return array
  46834. * @since Method available since Release 3.4.0
  46835. */
  46836. public function getAnnotations()
  46837. {
  46838. return PHPUnit_Util_Test::parseTestMethodAnnotations(
  46839. get_class($this),
  46840. $this->name
  46841. );
  46842. }
  46843. /**
  46844. * Gets the name of a TestCase.
  46845. *
  46846. * @param bool $withDataSet
  46847. * @return string
  46848. */
  46849. public function getName($withDataSet = true)
  46850. {
  46851. if ($withDataSet) {
  46852. return $this->name . $this->getDataSetAsString(false);
  46853. } else {
  46854. return $this->name;
  46855. }
  46856. }
  46857. /**
  46858. * Returns the size of the test.
  46859. *
  46860. * @return int
  46861. * @since Method available since Release 3.6.0
  46862. */
  46863. public function getSize()
  46864. {
  46865. return PHPUnit_Util_Test::getSize(
  46866. get_class($this),
  46867. $this->getName(false)
  46868. );
  46869. }
  46870. /**
  46871. * @return string
  46872. * @since Method available since Release 3.6.0
  46873. */
  46874. public function getActualOutput()
  46875. {
  46876. if (!$this->outputBufferingActive) {
  46877. return $this->output;
  46878. } else {
  46879. return ob_get_contents();
  46880. }
  46881. }
  46882. /**
  46883. * @return bool
  46884. * @since Method available since Release 3.6.0
  46885. */
  46886. public function hasOutput()
  46887. {
  46888. if (strlen($this->output) === 0) {
  46889. return false;
  46890. }
  46891. if ($this->hasExpectationOnOutput()) {
  46892. return false;
  46893. }
  46894. return true;
  46895. }
  46896. /**
  46897. * @param string $expectedRegex
  46898. * @since Method available since Release 3.6.0
  46899. * @throws PHPUnit_Framework_Exception
  46900. */
  46901. public function expectOutputRegex($expectedRegex)
  46902. {
  46903. if ($this->outputExpectedString !== null) {
  46904. throw new PHPUnit_Framework_Exception;
  46905. }
  46906. if (is_string($expectedRegex) || is_null($expectedRegex)) {
  46907. $this->outputExpectedRegex = $expectedRegex;
  46908. }
  46909. }
  46910. /**
  46911. * @param string $expectedString
  46912. * @since Method available since Release 3.6.0
  46913. */
  46914. public function expectOutputString($expectedString)
  46915. {
  46916. if ($this->outputExpectedRegex !== null) {
  46917. throw new PHPUnit_Framework_Exception;
  46918. }
  46919. if (is_string($expectedString) || is_null($expectedString)) {
  46920. $this->outputExpectedString = $expectedString;
  46921. }
  46922. }
  46923. /**
  46924. * @return bool
  46925. * @since Method available since Release 3.6.5
  46926. * @deprecated
  46927. */
  46928. public function hasPerformedExpectationsOnOutput()
  46929. {
  46930. return $this->hasExpectationOnOutput();
  46931. }
  46932. /**
  46933. * @return bool
  46934. * @since Method available since Release 4.3.3
  46935. */
  46936. public function hasExpectationOnOutput()
  46937. {
  46938. return is_string($this->outputExpectedString) || is_string($this->outputExpectedRegex);
  46939. }
  46940. /**
  46941. * @return string
  46942. * @since Method available since Release 3.2.0
  46943. */
  46944. public function getExpectedException()
  46945. {
  46946. return $this->expectedException;
  46947. }
  46948. /**
  46949. * @param mixed $exceptionName
  46950. * @param string $exceptionMessage
  46951. * @param int $exceptionCode
  46952. * @since Method available since Release 3.2.0
  46953. */
  46954. public function setExpectedException($exceptionName, $exceptionMessage = '', $exceptionCode = null)
  46955. {
  46956. $this->expectedException = $exceptionName;
  46957. $this->expectedExceptionMessage = $exceptionMessage;
  46958. $this->expectedExceptionCode = $exceptionCode;
  46959. }
  46960. /**
  46961. * @param mixed $exceptionName
  46962. * @param string $exceptionMessageRegExp
  46963. * @param int $exceptionCode
  46964. * @since Method available since Release 4.3.0
  46965. */
  46966. public function setExpectedExceptionRegExp($exceptionName, $exceptionMessageRegExp = '', $exceptionCode = null)
  46967. {
  46968. $this->expectedException = $exceptionName;
  46969. $this->expectedExceptionMessageRegExp = $exceptionMessageRegExp;
  46970. $this->expectedExceptionCode = $exceptionCode;
  46971. }
  46972. /**
  46973. * @since Method available since Release 3.4.0
  46974. */
  46975. protected function setExpectedExceptionFromAnnotation()
  46976. {
  46977. try {
  46978. $expectedException = PHPUnit_Util_Test::getExpectedException(
  46979. get_class($this),
  46980. $this->name
  46981. );
  46982. if ($expectedException !== false) {
  46983. $this->setExpectedException(
  46984. $expectedException['class'],
  46985. $expectedException['message'],
  46986. $expectedException['code']
  46987. );
  46988. if (!empty($expectedException['message_regex'])) {
  46989. $this->setExpectedExceptionRegExp(
  46990. $expectedException['class'],
  46991. $expectedException['message_regex'],
  46992. $expectedException['code']
  46993. );
  46994. }
  46995. }
  46996. } catch (ReflectionException $e) {
  46997. }
  46998. }
  46999. /**
  47000. * @param bool $useErrorHandler
  47001. * @since Method available since Release 3.4.0
  47002. */
  47003. public function setUseErrorHandler($useErrorHandler)
  47004. {
  47005. $this->useErrorHandler = $useErrorHandler;
  47006. }
  47007. /**
  47008. * @since Method available since Release 3.4.0
  47009. */
  47010. protected function setUseErrorHandlerFromAnnotation()
  47011. {
  47012. try {
  47013. $useErrorHandler = PHPUnit_Util_Test::getErrorHandlerSettings(
  47014. get_class($this),
  47015. $this->name
  47016. );
  47017. if ($useErrorHandler !== null) {
  47018. $this->setUseErrorHandler($useErrorHandler);
  47019. }
  47020. } catch (ReflectionException $e) {
  47021. }
  47022. }
  47023. /**
  47024. * @since Method available since Release 3.6.0
  47025. */
  47026. protected function checkRequirements()
  47027. {
  47028. if (!$this->name || !method_exists($this, $this->name)) {
  47029. return;
  47030. }
  47031. $missingRequirements = PHPUnit_Util_Test::getMissingRequirements(
  47032. get_class($this),
  47033. $this->name
  47034. );
  47035. if ($missingRequirements) {
  47036. $this->markTestSkipped(implode(PHP_EOL, $missingRequirements));
  47037. }
  47038. }
  47039. /**
  47040. * Returns the status of this test.
  47041. *
  47042. * @return int
  47043. * @since Method available since Release 3.1.0
  47044. */
  47045. public function getStatus()
  47046. {
  47047. return $this->status;
  47048. }
  47049. /**
  47050. * Returns the status message of this test.
  47051. *
  47052. * @return string
  47053. * @since Method available since Release 3.3.0
  47054. */
  47055. public function getStatusMessage()
  47056. {
  47057. return $this->statusMessage;
  47058. }
  47059. /**
  47060. * Returns whether or not this test has failed.
  47061. *
  47062. * @return bool
  47063. * @since Method available since Release 3.0.0
  47064. */
  47065. public function hasFailed()
  47066. {
  47067. $status = $this->getStatus();
  47068. return $status == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE ||
  47069. $status == PHPUnit_Runner_BaseTestRunner::STATUS_ERROR;
  47070. }
  47071. /**
  47072. * Runs the test case and collects the results in a TestResult object.
  47073. * If no TestResult object is passed a new one will be created.
  47074. *
  47075. * @param PHPUnit_Framework_TestResult $result
  47076. * @return PHPUnit_Framework_TestResult
  47077. * @throws PHPUnit_Framework_Exception
  47078. */
  47079. public function run(PHPUnit_Framework_TestResult $result = null)
  47080. {
  47081. if ($result === null) {
  47082. $result = $this->createResult();
  47083. }
  47084. if (!$this instanceof PHPUnit_Framework_Warning) {
  47085. $this->setTestResultObject($result);
  47086. $this->setUseErrorHandlerFromAnnotation();
  47087. }
  47088. if ($this->useErrorHandler !== null) {
  47089. $oldErrorHandlerSetting = $result->getConvertErrorsToExceptions();
  47090. $result->convertErrorsToExceptions($this->useErrorHandler);
  47091. }
  47092. if (!$this instanceof PHPUnit_Framework_Warning && !$this->handleDependencies()) {
  47093. return;
  47094. }
  47095. if ($this->runTestInSeparateProcess === true &&
  47096. $this->inIsolation !== true &&
  47097. !$this instanceof PHPUnit_Extensions_SeleniumTestCase &&
  47098. !$this instanceof PHPUnit_Extensions_PhptTestCase) {
  47099. $class = new ReflectionClass($this);
  47100. $template = new Text_Template(
  47101. __DIR__ . '/../Util/PHP/Template/TestCaseMethod.tpl'
  47102. );
  47103. if ($this->preserveGlobalState) {
  47104. $constants = PHPUnit_Util_GlobalState::getConstantsAsString();
  47105. $globals = PHPUnit_Util_GlobalState::getGlobalsAsString();
  47106. $includedFiles = PHPUnit_Util_GlobalState::getIncludedFilesAsString();
  47107. $iniSettings = PHPUnit_Util_GlobalState::getIniSettingsAsString();
  47108. } else {
  47109. $constants = '';
  47110. if (!empty($GLOBALS['__PHPUNIT_BOOTSTRAP'])) {
  47111. $globals = '$GLOBALS[\'__PHPUNIT_BOOTSTRAP\'] = ' . var_export($GLOBALS['__PHPUNIT_BOOTSTRAP'], true) . ";\n";
  47112. } else {
  47113. $globals = '';
  47114. }
  47115. $includedFiles = '';
  47116. $iniSettings = '';
  47117. }
  47118. $coverage = $result->getCollectCodeCoverageInformation() ? 'true' : 'false';
  47119. $isStrictAboutTestsThatDoNotTestAnything = $result->isStrictAboutTestsThatDoNotTestAnything() ? 'true' : 'false';
  47120. $isStrictAboutOutputDuringTests = $result->isStrictAboutOutputDuringTests() ? 'true' : 'false';
  47121. $isStrictAboutTestSize = $result->isStrictAboutTestSize() ? 'true' : 'false';
  47122. $isStrictAboutTodoAnnotatedTests = $result->isStrictAboutTodoAnnotatedTests() ? 'true' : 'false';
  47123. if (defined('PHPUNIT_COMPOSER_INSTALL')) {
  47124. $composerAutoload = var_export(PHPUNIT_COMPOSER_INSTALL, true);
  47125. } else {
  47126. $composerAutoload = '\'\'';
  47127. }
  47128. if (defined('__PHPUNIT_PHAR__')) {
  47129. $phar = var_export(__PHPUNIT_PHAR__, true);
  47130. } else {
  47131. $phar = '\'\'';
  47132. }
  47133. if ($result->getCodeCoverage()) {
  47134. $codeCoverageFilter = $result->getCodeCoverage()->filter();
  47135. } else {
  47136. $codeCoverageFilter = null;
  47137. }
  47138. $data = var_export(serialize($this->data), true);
  47139. $dataName = var_export($this->dataName, true);
  47140. $dependencyInput = var_export(serialize($this->dependencyInput), true);
  47141. $includePath = var_export(get_include_path(), true);
  47142. $codeCoverageFilter = var_export(serialize($codeCoverageFilter), true);
  47143. // must do these fixes because TestCaseMethod.tpl has unserialize('{data}') in it, and we can't break BC
  47144. // the lines above used to use addcslashes() rather than var_export(), which breaks null byte escape sequences
  47145. $data = "'." . $data . ".'";
  47146. $dataName = "'.(" . $dataName . ").'";
  47147. $dependencyInput = "'." . $dependencyInput . ".'";
  47148. $includePath = "'." . $includePath . ".'";
  47149. $codeCoverageFilter = "'." . $codeCoverageFilter . ".'";
  47150. $template->setVar(
  47151. array(
  47152. 'composerAutoload' => $composerAutoload,
  47153. 'phar' => $phar,
  47154. 'filename' => $class->getFileName(),
  47155. 'className' => $class->getName(),
  47156. 'methodName' => $this->name,
  47157. 'collectCodeCoverageInformation' => $coverage,
  47158. 'data' => $data,
  47159. 'dataName' => $dataName,
  47160. 'dependencyInput' => $dependencyInput,
  47161. 'constants' => $constants,
  47162. 'globals' => $globals,
  47163. 'include_path' => $includePath,
  47164. 'included_files' => $includedFiles,
  47165. 'iniSettings' => $iniSettings,
  47166. 'isStrictAboutTestsThatDoNotTestAnything' => $isStrictAboutTestsThatDoNotTestAnything,
  47167. 'isStrictAboutOutputDuringTests' => $isStrictAboutOutputDuringTests,
  47168. 'isStrictAboutTestSize' => $isStrictAboutTestSize,
  47169. 'isStrictAboutTodoAnnotatedTests' => $isStrictAboutTodoAnnotatedTests,
  47170. 'codeCoverageFilter' => $codeCoverageFilter
  47171. )
  47172. );
  47173. $this->prepareTemplate($template);
  47174. $php = PHPUnit_Util_PHP::factory();
  47175. $php->runTestJob($template->render(), $this, $result);
  47176. } else {
  47177. $result->run($this);
  47178. }
  47179. if ($this->useErrorHandler !== null) {
  47180. $result->convertErrorsToExceptions($oldErrorHandlerSetting);
  47181. }
  47182. $this->result = null;
  47183. return $result;
  47184. }
  47185. /**
  47186. * Runs the bare test sequence.
  47187. */
  47188. public function runBare()
  47189. {
  47190. $this->numAssertions = 0;
  47191. $this->snapshotGlobalState();
  47192. $this->startOutputBuffering();
  47193. clearstatcache();
  47194. $currentWorkingDirectory = getcwd();
  47195. $hookMethods = PHPUnit_Util_Test::getHookMethods(get_class($this));
  47196. try {
  47197. $hasMetRequirements = false;
  47198. $this->checkRequirements();
  47199. $hasMetRequirements = true;
  47200. if ($this->inIsolation) {
  47201. foreach ($hookMethods['beforeClass'] as $method) {
  47202. $this->$method();
  47203. }
  47204. }
  47205. $this->setExpectedExceptionFromAnnotation();
  47206. foreach ($hookMethods['before'] as $method) {
  47207. $this->$method();
  47208. }
  47209. $this->assertPreConditions();
  47210. $this->testResult = $this->runTest();
  47211. $this->verifyMockObjects();
  47212. $this->assertPostConditions();
  47213. $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_PASSED;
  47214. } catch (PHPUnit_Framework_IncompleteTest $e) {
  47215. $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE;
  47216. $this->statusMessage = $e->getMessage();
  47217. } catch (PHPUnit_Framework_SkippedTest $e) {
  47218. $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED;
  47219. $this->statusMessage = $e->getMessage();
  47220. } catch (PHPUnit_Framework_AssertionFailedError $e) {
  47221. $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
  47222. $this->statusMessage = $e->getMessage();
  47223. } catch (PredictionException $e) {
  47224. $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
  47225. $this->statusMessage = $e->getMessage();
  47226. } catch (Throwable $_e) {
  47227. $e = $_e;
  47228. } catch (Exception $_e) {
  47229. $e = $_e;
  47230. }
  47231. if (isset($e)) {
  47232. $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_ERROR;
  47233. $this->statusMessage = $e->getMessage();
  47234. }
  47235. // Clean up the mock objects.
  47236. $this->mockObjects = array();
  47237. $this->prophet = null;
  47238. // Tear down the fixture. An exception raised in tearDown() will be
  47239. // caught and passed on when no exception was raised before.
  47240. try {
  47241. if ($hasMetRequirements) {
  47242. foreach ($hookMethods['after'] as $method) {
  47243. $this->$method();
  47244. }
  47245. if ($this->inIsolation) {
  47246. foreach ($hookMethods['afterClass'] as $method) {
  47247. $this->$method();
  47248. }
  47249. }
  47250. }
  47251. } catch (Throwable $_e) {
  47252. if (!isset($e)) {
  47253. $e = $_e;
  47254. }
  47255. } catch (Exception $_e) {
  47256. if (!isset($e)) {
  47257. $e = $_e;
  47258. }
  47259. }
  47260. try {
  47261. $this->stopOutputBuffering();
  47262. } catch (PHPUnit_Framework_RiskyTestError $_e) {
  47263. if (!isset($e)) {
  47264. $e = $_e;
  47265. }
  47266. }
  47267. clearstatcache();
  47268. if ($currentWorkingDirectory != getcwd()) {
  47269. chdir($currentWorkingDirectory);
  47270. }
  47271. $this->restoreGlobalState();
  47272. // Clean up INI settings.
  47273. foreach ($this->iniSettings as $varName => $oldValue) {
  47274. ini_set($varName, $oldValue);
  47275. }
  47276. $this->iniSettings = array();
  47277. // Clean up locale settings.
  47278. foreach ($this->locale as $category => $locale) {
  47279. setlocale($category, $locale);
  47280. }
  47281. // Perform assertion on output.
  47282. if (!isset($e)) {
  47283. try {
  47284. if ($this->outputExpectedRegex !== null) {
  47285. $this->assertRegExp($this->outputExpectedRegex, $this->output);
  47286. } elseif ($this->outputExpectedString !== null) {
  47287. $this->assertEquals($this->outputExpectedString, $this->output);
  47288. }
  47289. } catch (Throwable $_e) {
  47290. $e = $_e;
  47291. } catch (Exception $_e) {
  47292. $e = $_e;
  47293. }
  47294. }
  47295. // Workaround for missing "finally".
  47296. if (isset($e)) {
  47297. if ($e instanceof PredictionException) {
  47298. $e = new PHPUnit_Framework_AssertionFailedError($e->getMessage());
  47299. }
  47300. $this->onNotSuccessfulTest($e);
  47301. }
  47302. }
  47303. /**
  47304. * Override to run the test and assert its state.
  47305. *
  47306. * @return mixed
  47307. * @throws Exception|PHPUnit_Framework_Exception
  47308. * @throws PHPUnit_Framework_Exception
  47309. */
  47310. protected function runTest()
  47311. {
  47312. if ($this->name === null) {
  47313. throw new PHPUnit_Framework_Exception(
  47314. 'PHPUnit_Framework_TestCase::$name must not be null.'
  47315. );
  47316. }
  47317. try {
  47318. $class = new ReflectionClass($this);
  47319. $method = $class->getMethod($this->name);
  47320. } catch (ReflectionException $e) {
  47321. $this->fail($e->getMessage());
  47322. }
  47323. try {
  47324. $testResult = $method->invokeArgs(
  47325. $this,
  47326. array_merge($this->data, $this->dependencyInput)
  47327. );
  47328. } catch (Throwable $_e) {
  47329. $e = $_e;
  47330. } catch (Exception $_e) {
  47331. $e = $_e;
  47332. }
  47333. if (isset($e)) {
  47334. $checkException = false;
  47335. if (is_string($this->expectedException)) {
  47336. $checkException = true;
  47337. if ($e instanceof PHPUnit_Framework_Exception) {
  47338. $checkException = false;
  47339. }
  47340. $reflector = new ReflectionClass($this->expectedException);
  47341. if ($this->expectedException == 'PHPUnit_Framework_Exception' ||
  47342. $reflector->isSubclassOf('PHPUnit_Framework_Exception')) {
  47343. $checkException = true;
  47344. }
  47345. }
  47346. if ($checkException) {
  47347. $this->assertThat(
  47348. $e,
  47349. new PHPUnit_Framework_Constraint_Exception(
  47350. $this->expectedException
  47351. )
  47352. );
  47353. if (is_string($this->expectedExceptionMessage) &&
  47354. !empty($this->expectedExceptionMessage)) {
  47355. $this->assertThat(
  47356. $e,
  47357. new PHPUnit_Framework_Constraint_ExceptionMessage(
  47358. $this->expectedExceptionMessage
  47359. )
  47360. );
  47361. }
  47362. if (is_string($this->expectedExceptionMessageRegExp) &&
  47363. !empty($this->expectedExceptionMessageRegExp)) {
  47364. $this->assertThat(
  47365. $e,
  47366. new PHPUnit_Framework_Constraint_ExceptionMessageRegExp(
  47367. $this->expectedExceptionMessageRegExp
  47368. )
  47369. );
  47370. }
  47371. if ($this->expectedExceptionCode !== null) {
  47372. $this->assertThat(
  47373. $e,
  47374. new PHPUnit_Framework_Constraint_ExceptionCode(
  47375. $this->expectedExceptionCode
  47376. )
  47377. );
  47378. }
  47379. return;
  47380. } else {
  47381. throw $e;
  47382. }
  47383. }
  47384. if ($this->expectedException !== null) {
  47385. $this->assertThat(
  47386. null,
  47387. new PHPUnit_Framework_Constraint_Exception(
  47388. $this->expectedException
  47389. )
  47390. );
  47391. }
  47392. return $testResult;
  47393. }
  47394. /**
  47395. * Verifies the mock object expectations.
  47396. *
  47397. * @since Method available since Release 3.5.0
  47398. */
  47399. protected function verifyMockObjects()
  47400. {
  47401. foreach ($this->mockObjects as $mockObject) {
  47402. if ($mockObject->__phpunit_hasMatchers()) {
  47403. $this->numAssertions++;
  47404. }
  47405. $mockObject->__phpunit_verify();
  47406. }
  47407. if ($this->prophet !== null) {
  47408. try {
  47409. $this->prophet->checkPredictions();
  47410. } catch (Throwable $t) {
  47411. /* Intentionally left empty */
  47412. } catch (Exception $e) {
  47413. /* Intentionally left empty */
  47414. }
  47415. foreach ($this->prophet->getProphecies() as $objectProphecy) {
  47416. foreach ($objectProphecy->getMethodProphecies() as $methodProphecies) {
  47417. foreach ($methodProphecies as $methodProphecy) {
  47418. $this->numAssertions += count($methodProphecy->getCheckedPredictions());
  47419. }
  47420. }
  47421. }
  47422. if (isset($e)) {
  47423. throw $e;
  47424. }
  47425. }
  47426. }
  47427. /**
  47428. * Sets the name of a TestCase.
  47429. *
  47430. * @param string
  47431. */
  47432. public function setName($name)
  47433. {
  47434. $this->name = $name;
  47435. }
  47436. /**
  47437. * Sets the dependencies of a TestCase.
  47438. *
  47439. * @param array $dependencies
  47440. * @since Method available since Release 3.4.0
  47441. */
  47442. public function setDependencies(array $dependencies)
  47443. {
  47444. $this->dependencies = $dependencies;
  47445. }
  47446. /**
  47447. * Returns true if the tests has dependencies
  47448. *
  47449. * @return bool
  47450. * @since Method available since Release 4.0.0
  47451. */
  47452. public function hasDependencies()
  47453. {
  47454. return count($this->dependencies) > 0;
  47455. }
  47456. /**
  47457. * Sets
  47458. *
  47459. * @param array $dependencyInput
  47460. * @since Method available since Release 3.4.0
  47461. */
  47462. public function setDependencyInput(array $dependencyInput)
  47463. {
  47464. $this->dependencyInput = $dependencyInput;
  47465. }
  47466. /**
  47467. * @param bool $disallowChangesToGlobalState
  47468. * @since Method available since Release 4.6.0
  47469. */
  47470. public function setDisallowChangesToGlobalState($disallowChangesToGlobalState)
  47471. {
  47472. $this->disallowChangesToGlobalState = $disallowChangesToGlobalState;
  47473. }
  47474. /**
  47475. * Calling this method in setUp() has no effect!
  47476. *
  47477. * @param bool $backupGlobals
  47478. * @since Method available since Release 3.3.0
  47479. */
  47480. public function setBackupGlobals($backupGlobals)
  47481. {
  47482. if (is_null($this->backupGlobals) && is_bool($backupGlobals)) {
  47483. $this->backupGlobals = $backupGlobals;
  47484. }
  47485. }
  47486. /**
  47487. * Calling this method in setUp() has no effect!
  47488. *
  47489. * @param bool $backupStaticAttributes
  47490. * @since Method available since Release 3.4.0
  47491. */
  47492. public function setBackupStaticAttributes($backupStaticAttributes)
  47493. {
  47494. if (is_null($this->backupStaticAttributes) &&
  47495. is_bool($backupStaticAttributes)) {
  47496. $this->backupStaticAttributes = $backupStaticAttributes;
  47497. }
  47498. }
  47499. /**
  47500. * @param bool $runTestInSeparateProcess
  47501. * @throws PHPUnit_Framework_Exception
  47502. * @since Method available since Release 3.4.0
  47503. */
  47504. public function setRunTestInSeparateProcess($runTestInSeparateProcess)
  47505. {
  47506. if (is_bool($runTestInSeparateProcess)) {
  47507. if ($this->runTestInSeparateProcess === null) {
  47508. $this->runTestInSeparateProcess = $runTestInSeparateProcess;
  47509. }
  47510. } else {
  47511. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  47512. }
  47513. }
  47514. /**
  47515. * @param bool $preserveGlobalState
  47516. * @throws PHPUnit_Framework_Exception
  47517. * @since Method available since Release 3.4.0
  47518. */
  47519. public function setPreserveGlobalState($preserveGlobalState)
  47520. {
  47521. if (is_bool($preserveGlobalState)) {
  47522. $this->preserveGlobalState = $preserveGlobalState;
  47523. } else {
  47524. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  47525. }
  47526. }
  47527. /**
  47528. * @param bool $inIsolation
  47529. * @throws PHPUnit_Framework_Exception
  47530. * @since Method available since Release 3.4.0
  47531. */
  47532. public function setInIsolation($inIsolation)
  47533. {
  47534. if (is_bool($inIsolation)) {
  47535. $this->inIsolation = $inIsolation;
  47536. } else {
  47537. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  47538. }
  47539. }
  47540. /**
  47541. * @return bool
  47542. * @since Method available since Release 4.3.0
  47543. */
  47544. public function isInIsolation()
  47545. {
  47546. return $this->inIsolation;
  47547. }
  47548. /**
  47549. * @return mixed
  47550. * @since Method available since Release 3.4.0
  47551. */
  47552. public function getResult()
  47553. {
  47554. return $this->testResult;
  47555. }
  47556. /**
  47557. * @param mixed $result
  47558. * @since Method available since Release 3.4.0
  47559. */
  47560. public function setResult($result)
  47561. {
  47562. $this->testResult = $result;
  47563. }
  47564. /**
  47565. * @param callable $callback
  47566. * @throws PHPUnit_Framework_Exception
  47567. * @since Method available since Release 3.6.0
  47568. */
  47569. public function setOutputCallback($callback)
  47570. {
  47571. if (!is_callable($callback)) {
  47572. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'callback');
  47573. }
  47574. $this->outputCallback = $callback;
  47575. }
  47576. /**
  47577. * @return PHPUnit_Framework_TestResult
  47578. * @since Method available since Release 3.5.7
  47579. */
  47580. public function getTestResultObject()
  47581. {
  47582. return $this->result;
  47583. }
  47584. /**
  47585. * @param PHPUnit_Framework_TestResult $result
  47586. * @since Method available since Release 3.6.0
  47587. */
  47588. public function setTestResultObject(PHPUnit_Framework_TestResult $result)
  47589. {
  47590. $this->result = $result;
  47591. }
  47592. /**
  47593. * This method is a wrapper for the ini_set() function that automatically
  47594. * resets the modified php.ini setting to its original value after the
  47595. * test is run.
  47596. *
  47597. * @param string $varName
  47598. * @param string $newValue
  47599. * @throws PHPUnit_Framework_Exception
  47600. * @since Method available since Release 3.0.0
  47601. */
  47602. protected function iniSet($varName, $newValue)
  47603. {
  47604. if (!is_string($varName)) {
  47605. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  47606. }
  47607. $currentValue = ini_set($varName, $newValue);
  47608. if ($currentValue !== false) {
  47609. $this->iniSettings[$varName] = $currentValue;
  47610. } else {
  47611. throw new PHPUnit_Framework_Exception(
  47612. sprintf(
  47613. 'INI setting "%s" could not be set to "%s".',
  47614. $varName,
  47615. $newValue
  47616. )
  47617. );
  47618. }
  47619. }
  47620. /**
  47621. * This method is a wrapper for the setlocale() function that automatically
  47622. * resets the locale to its original value after the test is run.
  47623. *
  47624. * @param int $category
  47625. * @param string $locale
  47626. * @throws PHPUnit_Framework_Exception
  47627. * @since Method available since Release 3.1.0
  47628. */
  47629. protected function setLocale()
  47630. {
  47631. $args = func_get_args();
  47632. if (count($args) < 2) {
  47633. throw new PHPUnit_Framework_Exception;
  47634. }
  47635. $category = $args[0];
  47636. $locale = $args[1];
  47637. $categories = array(
  47638. LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME
  47639. );
  47640. if (defined('LC_MESSAGES')) {
  47641. $categories[] = LC_MESSAGES;
  47642. }
  47643. if (!in_array($category, $categories)) {
  47644. throw new PHPUnit_Framework_Exception;
  47645. }
  47646. if (!is_array($locale) && !is_string($locale)) {
  47647. throw new PHPUnit_Framework_Exception;
  47648. }
  47649. $this->locale[$category] = setlocale($category, null);
  47650. $result = call_user_func_array('setlocale', $args);
  47651. if ($result === false) {
  47652. throw new PHPUnit_Framework_Exception(
  47653. 'The locale functionality is not implemented on your platform, ' .
  47654. 'the specified locale does not exist or the category name is ' .
  47655. 'invalid.'
  47656. );
  47657. }
  47658. }
  47659. /**
  47660. * Returns a mock object for the specified class.
  47661. *
  47662. * @param string $originalClassName Name of the class to mock.
  47663. * @param array|null $methods When provided, only methods whose names are in the array
  47664. * are replaced with a configurable test double. The behavior
  47665. * of the other methods is not changed.
  47666. * Providing null means that no methods will be replaced.
  47667. * @param array $arguments Parameters to pass to the original class' constructor.
  47668. * @param string $mockClassName Class name for the generated test double class.
  47669. * @param bool $callOriginalConstructor Can be used to disable the call to the original class' constructor.
  47670. * @param bool $callOriginalClone Can be used to disable the call to the original class' clone constructor.
  47671. * @param bool $callAutoload Can be used to disable __autoload() during the generation of the test double class.
  47672. * @param bool $cloneArguments
  47673. * @param bool $callOriginalMethods
  47674. * @return PHPUnit_Framework_MockObject_MockObject
  47675. * @throws PHPUnit_Framework_Exception
  47676. * @since Method available since Release 3.0.0
  47677. */
  47678. public function getMock($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $cloneArguments = false, $callOriginalMethods = false)
  47679. {
  47680. $mockObject = $this->getMockObjectGenerator()->getMock(
  47681. $originalClassName,
  47682. $methods,
  47683. $arguments,
  47684. $mockClassName,
  47685. $callOriginalConstructor,
  47686. $callOriginalClone,
  47687. $callAutoload,
  47688. $cloneArguments,
  47689. $callOriginalMethods
  47690. );
  47691. $this->mockObjects[] = $mockObject;
  47692. return $mockObject;
  47693. }
  47694. /**
  47695. * Returns a builder object to create mock objects using a fluent interface.
  47696. *
  47697. * @param string $className
  47698. * @return PHPUnit_Framework_MockObject_MockBuilder
  47699. * @since Method available since Release 3.5.0
  47700. */
  47701. public function getMockBuilder($className)
  47702. {
  47703. return new PHPUnit_Framework_MockObject_MockBuilder($this, $className);
  47704. }
  47705. /**
  47706. * Mocks the specified class and returns the name of the mocked class.
  47707. *
  47708. * @param string $originalClassName
  47709. * @param array $methods
  47710. * @param array $arguments
  47711. * @param string $mockClassName
  47712. * @param bool $callOriginalConstructor
  47713. * @param bool $callOriginalClone
  47714. * @param bool $callAutoload
  47715. * @param bool $cloneArguments
  47716. * @return string
  47717. * @throws PHPUnit_Framework_Exception
  47718. * @since Method available since Release 3.5.0
  47719. */
  47720. protected function getMockClass($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = false, $callOriginalClone = true, $callAutoload = true, $cloneArguments = false)
  47721. {
  47722. $mock = $this->getMock(
  47723. $originalClassName,
  47724. $methods,
  47725. $arguments,
  47726. $mockClassName,
  47727. $callOriginalConstructor,
  47728. $callOriginalClone,
  47729. $callAutoload,
  47730. $cloneArguments
  47731. );
  47732. return get_class($mock);
  47733. }
  47734. /**
  47735. * Returns a mock object for the specified abstract class with all abstract
  47736. * methods of the class mocked. Concrete methods are not mocked by default.
  47737. * To mock concrete methods, use the 7th parameter ($mockedMethods).
  47738. *
  47739. * @param string $originalClassName
  47740. * @param array $arguments
  47741. * @param string $mockClassName
  47742. * @param bool $callOriginalConstructor
  47743. * @param bool $callOriginalClone
  47744. * @param bool $callAutoload
  47745. * @param array $mockedMethods
  47746. * @param bool $cloneArguments
  47747. * @return PHPUnit_Framework_MockObject_MockObject
  47748. * @since Method available since Release 3.4.0
  47749. * @throws PHPUnit_Framework_Exception
  47750. */
  47751. public function getMockForAbstractClass($originalClassName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = array(), $cloneArguments = false)
  47752. {
  47753. $mockObject = $this->getMockObjectGenerator()->getMockForAbstractClass(
  47754. $originalClassName,
  47755. $arguments,
  47756. $mockClassName,
  47757. $callOriginalConstructor,
  47758. $callOriginalClone,
  47759. $callAutoload,
  47760. $mockedMethods,
  47761. $cloneArguments
  47762. );
  47763. $this->mockObjects[] = $mockObject;
  47764. return $mockObject;
  47765. }
  47766. /**
  47767. * Returns a mock object based on the given WSDL file.
  47768. *
  47769. * @param string $wsdlFile
  47770. * @param string $originalClassName
  47771. * @param string $mockClassName
  47772. * @param array $methods
  47773. * @param bool $callOriginalConstructor
  47774. * @param array $options An array of options passed to SOAPClient::_construct
  47775. * @return PHPUnit_Framework_MockObject_MockObject
  47776. * @since Method available since Release 3.4.0
  47777. */
  47778. protected function getMockFromWsdl($wsdlFile, $originalClassName = '', $mockClassName = '', array $methods = array(), $callOriginalConstructor = true, array $options = array())
  47779. {
  47780. if ($originalClassName === '') {
  47781. $originalClassName = str_replace('.wsdl', '', basename($wsdlFile));
  47782. }
  47783. if (!class_exists($originalClassName)) {
  47784. eval(
  47785. $this->getMockObjectGenerator()->generateClassFromWsdl(
  47786. $wsdlFile,
  47787. $originalClassName,
  47788. $methods,
  47789. $options
  47790. )
  47791. );
  47792. }
  47793. return $this->getMock(
  47794. $originalClassName,
  47795. $methods,
  47796. array('', $options),
  47797. $mockClassName,
  47798. $callOriginalConstructor,
  47799. false,
  47800. false
  47801. );
  47802. }
  47803. /**
  47804. * Returns a mock object for the specified trait with all abstract methods
  47805. * of the trait mocked. Concrete methods to mock can be specified with the
  47806. * `$mockedMethods` parameter.
  47807. *
  47808. * @param string $traitName
  47809. * @param array $arguments
  47810. * @param string $mockClassName
  47811. * @param bool $callOriginalConstructor
  47812. * @param bool $callOriginalClone
  47813. * @param bool $callAutoload
  47814. * @param array $mockedMethods
  47815. * @param bool $cloneArguments
  47816. * @return PHPUnit_Framework_MockObject_MockObject
  47817. * @since Method available since Release 4.0.0
  47818. * @throws PHPUnit_Framework_Exception
  47819. */
  47820. public function getMockForTrait($traitName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = array(), $cloneArguments = false)
  47821. {
  47822. $mockObject = $this->getMockObjectGenerator()->getMockForTrait(
  47823. $traitName,
  47824. $arguments,
  47825. $mockClassName,
  47826. $callOriginalConstructor,
  47827. $callOriginalClone,
  47828. $callAutoload,
  47829. $mockedMethods,
  47830. $cloneArguments
  47831. );
  47832. $this->mockObjects[] = $mockObject;
  47833. return $mockObject;
  47834. }
  47835. /**
  47836. * Returns an object for the specified trait.
  47837. *
  47838. * @param string $traitName
  47839. * @param array $arguments
  47840. * @param string $traitClassName
  47841. * @param bool $callOriginalConstructor
  47842. * @param bool $callOriginalClone
  47843. * @param bool $callAutoload
  47844. * @param bool $cloneArguments
  47845. * @return object
  47846. * @since Method available since Release 3.6.0
  47847. * @throws PHPUnit_Framework_Exception
  47848. */
  47849. protected function getObjectForTrait($traitName, array $arguments = array(), $traitClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $cloneArguments = false)
  47850. {
  47851. return $this->getMockObjectGenerator()->getObjectForTrait(
  47852. $traitName,
  47853. $arguments,
  47854. $traitClassName,
  47855. $callOriginalConstructor,
  47856. $callOriginalClone,
  47857. $callAutoload,
  47858. $cloneArguments
  47859. );
  47860. }
  47861. /**
  47862. * @param string|null $classOrInterface
  47863. * @return \Prophecy\Prophecy\ObjectProphecy
  47864. * @throws \LogicException
  47865. * @since Method available since Release 4.5.0
  47866. */
  47867. protected function prophesize($classOrInterface = null)
  47868. {
  47869. return $this->getProphet()->prophesize($classOrInterface);
  47870. }
  47871. /**
  47872. * Adds a value to the assertion counter.
  47873. *
  47874. * @param int $count
  47875. * @since Method available since Release 3.3.3
  47876. */
  47877. public function addToAssertionCount($count)
  47878. {
  47879. $this->numAssertions += $count;
  47880. }
  47881. /**
  47882. * Returns the number of assertions performed by this test.
  47883. *
  47884. * @return int
  47885. * @since Method available since Release 3.3.0
  47886. */
  47887. public function getNumAssertions()
  47888. {
  47889. return $this->numAssertions;
  47890. }
  47891. /**
  47892. * Returns a matcher that matches when the method is executed
  47893. * zero or more times.
  47894. *
  47895. * @return PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount
  47896. * @since Method available since Release 3.0.0
  47897. */
  47898. public static function any()
  47899. {
  47900. return new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount;
  47901. }
  47902. /**
  47903. * Returns a matcher that matches when the method is never executed.
  47904. *
  47905. * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
  47906. * @since Method available since Release 3.0.0
  47907. */
  47908. public static function never()
  47909. {
  47910. return new PHPUnit_Framework_MockObject_Matcher_InvokedCount(0);
  47911. }
  47912. /**
  47913. * Returns a matcher that matches when the method is executed
  47914. * at least N times.
  47915. *
  47916. * @param int $requiredInvocations
  47917. * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount
  47918. * @since Method available since Release 4.2.0
  47919. */
  47920. public static function atLeast($requiredInvocations)
  47921. {
  47922. return new PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount(
  47923. $requiredInvocations
  47924. );
  47925. }
  47926. /**
  47927. * Returns a matcher that matches when the method is executed at least once.
  47928. *
  47929. * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce
  47930. * @since Method available since Release 3.0.0
  47931. */
  47932. public static function atLeastOnce()
  47933. {
  47934. return new PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce;
  47935. }
  47936. /**
  47937. * Returns a matcher that matches when the method is executed exactly once.
  47938. *
  47939. * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
  47940. * @since Method available since Release 3.0.0
  47941. */
  47942. public static function once()
  47943. {
  47944. return new PHPUnit_Framework_MockObject_Matcher_InvokedCount(1);
  47945. }
  47946. /**
  47947. * Returns a matcher that matches when the method is executed
  47948. * exactly $count times.
  47949. *
  47950. * @param int $count
  47951. * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount
  47952. * @since Method available since Release 3.0.0
  47953. */
  47954. public static function exactly($count)
  47955. {
  47956. return new PHPUnit_Framework_MockObject_Matcher_InvokedCount($count);
  47957. }
  47958. /**
  47959. * Returns a matcher that matches when the method is executed
  47960. * at most N times.
  47961. *
  47962. * @param int $allowedInvocations
  47963. * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount
  47964. * @since Method available since Release 4.2.0
  47965. */
  47966. public static function atMost($allowedInvocations)
  47967. {
  47968. return new PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount(
  47969. $allowedInvocations
  47970. );
  47971. }
  47972. /**
  47973. * Returns a matcher that matches when the method is executed
  47974. * at the given index.
  47975. *
  47976. * @param int $index
  47977. * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex
  47978. * @since Method available since Release 3.0.0
  47979. */
  47980. public static function at($index)
  47981. {
  47982. return new PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex($index);
  47983. }
  47984. /**
  47985. * @param mixed $value
  47986. * @return PHPUnit_Framework_MockObject_Stub_Return
  47987. * @since Method available since Release 3.0.0
  47988. */
  47989. public static function returnValue($value)
  47990. {
  47991. return new PHPUnit_Framework_MockObject_Stub_Return($value);
  47992. }
  47993. /**
  47994. * @param array $valueMap
  47995. * @return PHPUnit_Framework_MockObject_Stub_ReturnValueMap
  47996. * @since Method available since Release 3.6.0
  47997. */
  47998. public static function returnValueMap(array $valueMap)
  47999. {
  48000. return new PHPUnit_Framework_MockObject_Stub_ReturnValueMap($valueMap);
  48001. }
  48002. /**
  48003. * @param int $argumentIndex
  48004. * @return PHPUnit_Framework_MockObject_Stub_ReturnArgument
  48005. * @since Method available since Release 3.3.0
  48006. */
  48007. public static function returnArgument($argumentIndex)
  48008. {
  48009. return new PHPUnit_Framework_MockObject_Stub_ReturnArgument(
  48010. $argumentIndex
  48011. );
  48012. }
  48013. /**
  48014. * @param mixed $callback
  48015. * @return PHPUnit_Framework_MockObject_Stub_ReturnCallback
  48016. * @since Method available since Release 3.3.0
  48017. */
  48018. public static function returnCallback($callback)
  48019. {
  48020. return new PHPUnit_Framework_MockObject_Stub_ReturnCallback($callback);
  48021. }
  48022. /**
  48023. * Returns the current object.
  48024. *
  48025. * This method is useful when mocking a fluent interface.
  48026. *
  48027. * @return PHPUnit_Framework_MockObject_Stub_ReturnSelf
  48028. * @since Method available since Release 3.6.0
  48029. */
  48030. public static function returnSelf()
  48031. {
  48032. return new PHPUnit_Framework_MockObject_Stub_ReturnSelf();
  48033. }
  48034. /**
  48035. * @param Exception $exception
  48036. * @return PHPUnit_Framework_MockObject_Stub_Exception
  48037. * @since Method available since Release 3.1.0
  48038. */
  48039. public static function throwException(Exception $exception)
  48040. {
  48041. return new PHPUnit_Framework_MockObject_Stub_Exception($exception);
  48042. }
  48043. /**
  48044. * @param mixed $value, ...
  48045. * @return PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls
  48046. * @since Method available since Release 3.0.0
  48047. */
  48048. public static function onConsecutiveCalls()
  48049. {
  48050. $args = func_get_args();
  48051. return new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls($args);
  48052. }
  48053. /**
  48054. * Gets the data set description of a TestCase.
  48055. *
  48056. * @param bool $includeData
  48057. * @return string
  48058. * @since Method available since Release 3.3.0
  48059. */
  48060. protected function getDataSetAsString($includeData = true)
  48061. {
  48062. $buffer = '';
  48063. if (!empty($this->data)) {
  48064. if (is_int($this->dataName)) {
  48065. $buffer .= sprintf(' with data set #%d', $this->dataName);
  48066. } else {
  48067. $buffer .= sprintf(' with data set "%s"', $this->dataName);
  48068. }
  48069. $exporter = new Exporter;
  48070. if ($includeData) {
  48071. $buffer .= sprintf(' (%s)', $exporter->shortenedRecursiveExport($this->data));
  48072. }
  48073. }
  48074. return $buffer;
  48075. }
  48076. /**
  48077. * Creates a default TestResult object.
  48078. *
  48079. * @return PHPUnit_Framework_TestResult
  48080. */
  48081. protected function createResult()
  48082. {
  48083. return new PHPUnit_Framework_TestResult;
  48084. }
  48085. /**
  48086. * @since Method available since Release 3.5.4
  48087. */
  48088. protected function handleDependencies()
  48089. {
  48090. if (!empty($this->dependencies) && !$this->inIsolation) {
  48091. $className = get_class($this);
  48092. $passed = $this->result->passed();
  48093. $passedKeys = array_keys($passed);
  48094. $numKeys = count($passedKeys);
  48095. for ($i = 0; $i < $numKeys; $i++) {
  48096. $pos = strpos($passedKeys[$i], ' with data set');
  48097. if ($pos !== false) {
  48098. $passedKeys[$i] = substr($passedKeys[$i], 0, $pos);
  48099. }
  48100. }
  48101. $passedKeys = array_flip(array_unique($passedKeys));
  48102. foreach ($this->dependencies as $dependency) {
  48103. if (strpos($dependency, '::') === false) {
  48104. $dependency = $className . '::' . $dependency;
  48105. }
  48106. if (!isset($passedKeys[$dependency])) {
  48107. $this->result->addError(
  48108. $this,
  48109. new PHPUnit_Framework_SkippedTestError(
  48110. sprintf(
  48111. 'This test depends on "%s" to pass.',
  48112. $dependency
  48113. )
  48114. ),
  48115. 0
  48116. );
  48117. return false;
  48118. }
  48119. if (isset($passed[$dependency])) {
  48120. if ($passed[$dependency]['size'] != PHPUnit_Util_Test::UNKNOWN &&
  48121. $this->getSize() != PHPUnit_Util_Test::UNKNOWN &&
  48122. $passed[$dependency]['size'] > $this->getSize()) {
  48123. $this->result->addError(
  48124. $this,
  48125. new PHPUnit_Framework_SkippedTestError(
  48126. 'This test depends on a test that is larger than itself.'
  48127. ),
  48128. 0
  48129. );
  48130. return false;
  48131. }
  48132. $this->dependencyInput[$dependency] = $passed[$dependency]['result'];
  48133. } else {
  48134. $this->dependencyInput[$dependency] = null;
  48135. }
  48136. }
  48137. }
  48138. return true;
  48139. }
  48140. /**
  48141. * This method is called before the first test of this test class is run.
  48142. *
  48143. * @since Method available since Release 3.4.0
  48144. */
  48145. public static function setUpBeforeClass()
  48146. {
  48147. }
  48148. /**
  48149. * Sets up the fixture, for example, open a network connection.
  48150. * This method is called before a test is executed.
  48151. */
  48152. protected function setUp()
  48153. {
  48154. }
  48155. /**
  48156. * Performs assertions shared by all tests of a test case.
  48157. *
  48158. * This method is called before the execution of a test starts
  48159. * and after setUp() is called.
  48160. *
  48161. * @since Method available since Release 3.2.8
  48162. */
  48163. protected function assertPreConditions()
  48164. {
  48165. }
  48166. /**
  48167. * Performs assertions shared by all tests of a test case.
  48168. *
  48169. * This method is called before the execution of a test ends
  48170. * and before tearDown() is called.
  48171. *
  48172. * @since Method available since Release 3.2.8
  48173. */
  48174. protected function assertPostConditions()
  48175. {
  48176. }
  48177. /**
  48178. * Tears down the fixture, for example, close a network connection.
  48179. * This method is called after a test is executed.
  48180. */
  48181. protected function tearDown()
  48182. {
  48183. }
  48184. /**
  48185. * This method is called after the last test of this test class is run.
  48186. *
  48187. * @since Method available since Release 3.4.0
  48188. */
  48189. public static function tearDownAfterClass()
  48190. {
  48191. }
  48192. /**
  48193. * This method is called when a test method did not execute successfully.
  48194. *
  48195. * @param Exception $e
  48196. * @since Method available since Release 3.4.0
  48197. * @throws Exception
  48198. */
  48199. protected function onNotSuccessfulTest(Exception $e)
  48200. {
  48201. throw $e;
  48202. }
  48203. /**
  48204. * Performs custom preparations on the process isolation template.
  48205. *
  48206. * @param Text_Template $template
  48207. * @since Method available since Release 3.4.0
  48208. */
  48209. protected function prepareTemplate(Text_Template $template)
  48210. {
  48211. }
  48212. /**
  48213. * Get the mock object generator, creating it if it doesn't exist.
  48214. *
  48215. * @return PHPUnit_Framework_MockObject_Generator
  48216. */
  48217. protected function getMockObjectGenerator()
  48218. {
  48219. if (null === $this->mockObjectGenerator) {
  48220. $this->mockObjectGenerator = new PHPUnit_Framework_MockObject_Generator;
  48221. }
  48222. return $this->mockObjectGenerator;
  48223. }
  48224. /**
  48225. * @since Method available since Release 4.2.0
  48226. */
  48227. private function startOutputBuffering()
  48228. {
  48229. while (!defined('PHPUNIT_TESTSUITE') && ob_get_level() > 0) {
  48230. ob_end_clean();
  48231. }
  48232. ob_start();
  48233. $this->outputBufferingActive = true;
  48234. $this->outputBufferingLevel = ob_get_level();
  48235. }
  48236. /**
  48237. * @since Method available since Release 4.2.0
  48238. */
  48239. private function stopOutputBuffering()
  48240. {
  48241. if (ob_get_level() != $this->outputBufferingLevel) {
  48242. while (ob_get_level() > 0) {
  48243. ob_end_clean();
  48244. }
  48245. throw new PHPUnit_Framework_RiskyTestError(
  48246. 'Test code or tested code did not (only) close its own output buffers'
  48247. );
  48248. }
  48249. $output = ob_get_contents();
  48250. if ($this->outputCallback === false) {
  48251. $this->output = $output;
  48252. } else {
  48253. $this->output = call_user_func_array(
  48254. $this->outputCallback,
  48255. array($output)
  48256. );
  48257. }
  48258. ob_end_clean();
  48259. $this->outputBufferingActive = false;
  48260. $this->outputBufferingLevel = ob_get_level();
  48261. }
  48262. private function snapshotGlobalState()
  48263. {
  48264. $backupGlobals = $this->backupGlobals === null || $this->backupGlobals === true;
  48265. if ($this->runTestInSeparateProcess || $this->inIsolation ||
  48266. (!$backupGlobals && !$this->backupStaticAttributes)) {
  48267. return;
  48268. }
  48269. $this->snapshot = $this->createGlobalStateSnapshot($backupGlobals);
  48270. }
  48271. private function restoreGlobalState()
  48272. {
  48273. if (!$this->snapshot instanceof Snapshot) {
  48274. return;
  48275. }
  48276. $backupGlobals = $this->backupGlobals === null || $this->backupGlobals === true;
  48277. if ($this->disallowChangesToGlobalState) {
  48278. $this->compareGlobalStateSnapshots(
  48279. $this->snapshot,
  48280. $this->createGlobalStateSnapshot($backupGlobals)
  48281. );
  48282. }
  48283. $restorer = new Restorer;
  48284. if ($backupGlobals) {
  48285. $restorer->restoreGlobalVariables($this->snapshot);
  48286. }
  48287. if ($this->backupStaticAttributes) {
  48288. $restorer->restoreStaticAttributes($this->snapshot);
  48289. }
  48290. $this->snapshot = null;
  48291. }
  48292. /**
  48293. * @param bool $backupGlobals
  48294. * @return Snapshot
  48295. */
  48296. private function createGlobalStateSnapshot($backupGlobals)
  48297. {
  48298. $blacklist = new Blacklist;
  48299. foreach ($this->backupGlobalsBlacklist as $globalVariable) {
  48300. $blacklist->addGlobalVariable($globalVariable);
  48301. }
  48302. if (!defined('PHPUNIT_TESTSUITE')) {
  48303. $blacklist->addClassNamePrefix('PHPUnit');
  48304. $blacklist->addClassNamePrefix('File_Iterator');
  48305. $blacklist->addClassNamePrefix('PHP_CodeCoverage');
  48306. $blacklist->addClassNamePrefix('PHP_Invoker');
  48307. $blacklist->addClassNamePrefix('PHP_Timer');
  48308. $blacklist->addClassNamePrefix('PHP_Token');
  48309. $blacklist->addClassNamePrefix('Symfony');
  48310. $blacklist->addClassNamePrefix('Text_Template');
  48311. $blacklist->addClassNamePrefix('Doctrine\Instantiator');
  48312. foreach ($this->backupStaticAttributesBlacklist as $class => $attributes) {
  48313. foreach ($attributes as $attribute) {
  48314. $blacklist->addStaticAttribute($class, $attribute);
  48315. }
  48316. }
  48317. }
  48318. return new Snapshot(
  48319. $blacklist,
  48320. $backupGlobals,
  48321. $this->backupStaticAttributes,
  48322. false,
  48323. false,
  48324. false,
  48325. false,
  48326. false,
  48327. false,
  48328. false
  48329. );
  48330. }
  48331. /**
  48332. * @param Snapshot $before
  48333. * @param Snapshot $after
  48334. * @throws PHPUnit_Framework_RiskyTestError
  48335. */
  48336. private function compareGlobalStateSnapshots(Snapshot $before, Snapshot $after)
  48337. {
  48338. $backupGlobals = $this->backupGlobals === null || $this->backupGlobals === true;
  48339. if ($backupGlobals) {
  48340. $this->compareGlobalStateSnapshotPart(
  48341. $before->globalVariables(),
  48342. $after->globalVariables(),
  48343. "--- Global variables before the test\n+++ Global variables after the test\n"
  48344. );
  48345. $this->compareGlobalStateSnapshotPart(
  48346. $before->superGlobalVariables(),
  48347. $after->superGlobalVariables(),
  48348. "--- Super-global variables before the test\n+++ Super-global variables after the test\n"
  48349. );
  48350. }
  48351. if ($this->backupStaticAttributes) {
  48352. $this->compareGlobalStateSnapshotPart(
  48353. $before->staticAttributes(),
  48354. $after->staticAttributes(),
  48355. "--- Static attributes before the test\n+++ Static attributes after the test\n"
  48356. );
  48357. }
  48358. }
  48359. /**
  48360. * @param array $before
  48361. * @param array $after
  48362. * @param string $header
  48363. * @throws PHPUnit_Framework_RiskyTestError
  48364. */
  48365. private function compareGlobalStateSnapshotPart(array $before, array $after, $header)
  48366. {
  48367. if ($before != $after) {
  48368. $differ = new Differ($header);
  48369. $exporter = new Exporter;
  48370. $diff = $differ->diff(
  48371. $exporter->export($before),
  48372. $exporter->export($after)
  48373. );
  48374. throw new PHPUnit_Framework_RiskyTestError(
  48375. $diff
  48376. );
  48377. }
  48378. }
  48379. /**
  48380. * @return Prophecy\Prophet
  48381. * @since Method available since Release 4.5.0
  48382. */
  48383. private function getProphet()
  48384. {
  48385. if ($this->prophet === null) {
  48386. $this->prophet = new Prophet;
  48387. }
  48388. return $this->prophet;
  48389. }
  48390. }
  48391. <?php
  48392. /*
  48393. * This file is part of PHPUnit.
  48394. *
  48395. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  48396. *
  48397. * For the full copyright and license information, please view the LICENSE
  48398. * file that was distributed with this source code.
  48399. */
  48400. /**
  48401. * Exception for expectations which failed their check.
  48402. *
  48403. * The exception contains the error message and optionally a
  48404. * SebastianBergmann\Comparator\ComparisonFailure which is used to
  48405. * generate diff output of the failed expectations.
  48406. *
  48407. * @since Class available since Release 3.0.0
  48408. */
  48409. class PHPUnit_Framework_ExpectationFailedException extends PHPUnit_Framework_AssertionFailedError
  48410. {
  48411. /**
  48412. * @var SebastianBergmann\Comparator\ComparisonFailure
  48413. */
  48414. protected $comparisonFailure;
  48415. public function __construct($message, SebastianBergmann\Comparator\ComparisonFailure $comparisonFailure = null, Exception $previous = null)
  48416. {
  48417. $this->comparisonFailure = $comparisonFailure;
  48418. parent::__construct($message, 0, $previous);
  48419. }
  48420. /**
  48421. * @return SebastianBergmann\Comparator\ComparisonFailure
  48422. */
  48423. public function getComparisonFailure()
  48424. {
  48425. return $this->comparisonFailure;
  48426. }
  48427. }
  48428. <?php
  48429. /*
  48430. * This file is part of PHPUnit.
  48431. *
  48432. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  48433. *
  48434. * For the full copyright and license information, please view the LICENSE
  48435. * file that was distributed with this source code.
  48436. */
  48437. /**
  48438. * Wrapper for PHP errors.
  48439. *
  48440. * @since Class available since Release 2.2.0
  48441. */
  48442. class PHPUnit_Framework_Error extends PHPUnit_Framework_Exception
  48443. {
  48444. /**
  48445. * Constructor.
  48446. *
  48447. * @param string $message
  48448. * @param int $code
  48449. * @param string $file
  48450. * @param int $line
  48451. * @param Exception $previous
  48452. */
  48453. public function __construct($message, $code, $file, $line, Exception $previous = null)
  48454. {
  48455. parent::__construct($message, $code, $previous);
  48456. $this->file = $file;
  48457. $this->line = $line;
  48458. }
  48459. }
  48460. <?php
  48461. /*
  48462. * This file is part of PHPUnit.
  48463. *
  48464. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  48465. *
  48466. * For the full copyright and license information, please view the LICENSE
  48467. * file that was distributed with this source code.
  48468. */
  48469. use SebastianBergmann\Exporter\Exporter;
  48470. /**
  48471. * Abstract base class for constraints. which are placed upon any value.
  48472. *
  48473. * @since Interface available since Release 3.0.0
  48474. */
  48475. abstract class PHPUnit_Framework_Constraint implements Countable, PHPUnit_Framework_SelfDescribing
  48476. {
  48477. protected $exporter;
  48478. public function __construct()
  48479. {
  48480. $this->exporter = new Exporter;
  48481. }
  48482. /**
  48483. * Evaluates the constraint for parameter $other
  48484. *
  48485. * If $returnResult is set to false (the default), an exception is thrown
  48486. * in case of a failure. null is returned otherwise.
  48487. *
  48488. * If $returnResult is true, the result of the evaluation is returned as
  48489. * a boolean value instead: true in case of success, false in case of a
  48490. * failure.
  48491. *
  48492. * @param mixed $other Value or object to evaluate.
  48493. * @param string $description Additional information about the test
  48494. * @param bool $returnResult Whether to return a result or throw an exception
  48495. * @return mixed
  48496. * @throws PHPUnit_Framework_ExpectationFailedException
  48497. */
  48498. public function evaluate($other, $description = '', $returnResult = false)
  48499. {
  48500. $success = false;
  48501. if ($this->matches($other)) {
  48502. $success = true;
  48503. }
  48504. if ($returnResult) {
  48505. return $success;
  48506. }
  48507. if (!$success) {
  48508. $this->fail($other, $description);
  48509. }
  48510. }
  48511. /**
  48512. * Evaluates the constraint for parameter $other. Returns true if the
  48513. * constraint is met, false otherwise.
  48514. *
  48515. * This method can be overridden to implement the evaluation algorithm.
  48516. *
  48517. * @param mixed $other Value or object to evaluate.
  48518. * @return bool
  48519. */
  48520. protected function matches($other)
  48521. {
  48522. return false;
  48523. }
  48524. /**
  48525. * Counts the number of constraint elements.
  48526. *
  48527. * @return int
  48528. * @since Method available since Release 3.4.0
  48529. */
  48530. public function count()
  48531. {
  48532. return 1;
  48533. }
  48534. /**
  48535. * Throws an exception for the given compared value and test description
  48536. *
  48537. * @param mixed $other Evaluated value or object.
  48538. * @param string $description Additional information about the test
  48539. * @param SebastianBergmann\Comparator\ComparisonFailure $comparisonFailure
  48540. * @throws PHPUnit_Framework_ExpectationFailedException
  48541. */
  48542. protected function fail($other, $description, SebastianBergmann\Comparator\ComparisonFailure $comparisonFailure = null)
  48543. {
  48544. $failureDescription = sprintf(
  48545. 'Failed asserting that %s.',
  48546. $this->failureDescription($other)
  48547. );
  48548. $additionalFailureDescription = $this->additionalFailureDescription($other);
  48549. if ($additionalFailureDescription) {
  48550. $failureDescription .= "\n" . $additionalFailureDescription;
  48551. }
  48552. if (!empty($description)) {
  48553. $failureDescription = $description . "\n" . $failureDescription;
  48554. }
  48555. throw new PHPUnit_Framework_ExpectationFailedException(
  48556. $failureDescription,
  48557. $comparisonFailure
  48558. );
  48559. }
  48560. /**
  48561. * Return additional failure description where needed
  48562. *
  48563. * The function can be overridden to provide additional failure
  48564. * information like a diff
  48565. *
  48566. * @param mixed $other Evaluated value or object.
  48567. * @return string
  48568. */
  48569. protected function additionalFailureDescription($other)
  48570. {
  48571. return '';
  48572. }
  48573. /**
  48574. * Returns the description of the failure
  48575. *
  48576. * The beginning of failure messages is "Failed asserting that" in most
  48577. * cases. This method should return the second part of that sentence.
  48578. *
  48579. * To provide additional failure information additionalFailureDescription
  48580. * can be used.
  48581. *
  48582. * @param mixed $other Evaluated value or object.
  48583. * @return string
  48584. */
  48585. protected function failureDescription($other)
  48586. {
  48587. return $this->exporter->export($other) . ' ' . $this->toString();
  48588. }
  48589. }
  48590. <?php
  48591. /*
  48592. * This file is part of PHPUnit.
  48593. *
  48594. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  48595. *
  48596. * For the full copyright and license information, please view the LICENSE
  48597. * file that was distributed with this source code.
  48598. */
  48599. /**
  48600. * Thrown when an assertion failed.
  48601. *
  48602. * @since Class available since Release 2.0.0
  48603. */
  48604. class PHPUnit_Framework_AssertionFailedError extends PHPUnit_Framework_Exception implements PHPUnit_Framework_SelfDescribing
  48605. {
  48606. /**
  48607. * Wrapper for getMessage() which is declared as final.
  48608. *
  48609. * @return string
  48610. */
  48611. public function toString()
  48612. {
  48613. return $this->getMessage();
  48614. }
  48615. }
  48616. <?php
  48617. /*
  48618. * This file is part of PHPUnit.
  48619. *
  48620. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  48621. *
  48622. * For the full copyright and license information, please view the LICENSE
  48623. * file that was distributed with this source code.
  48624. */
  48625. /**
  48626. * An incomplete test case
  48627. *
  48628. * @since Class available since Release 4.3.0
  48629. */
  48630. class PHPUnit_Framework_IncompleteTestCase extends PHPUnit_Framework_TestCase
  48631. {
  48632. /**
  48633. * @var string
  48634. */
  48635. protected $message = '';
  48636. /**
  48637. * @var bool
  48638. */
  48639. protected $backupGlobals = false;
  48640. /**
  48641. * @var bool
  48642. */
  48643. protected $backupStaticAttributes = false;
  48644. /**
  48645. * @var bool
  48646. */
  48647. protected $runTestInSeparateProcess = false;
  48648. /**
  48649. * @var bool
  48650. */
  48651. protected $useErrorHandler = false;
  48652. /**
  48653. * @var bool
  48654. */
  48655. protected $useOutputBuffering = false;
  48656. /**
  48657. * @param string $className
  48658. * @param string $methodName
  48659. * @param string $message
  48660. */
  48661. public function __construct($className, $methodName, $message = '')
  48662. {
  48663. $this->message = $message;
  48664. parent::__construct($className . '::' . $methodName);
  48665. }
  48666. /**
  48667. * @throws PHPUnit_Framework_Exception
  48668. */
  48669. protected function runTest()
  48670. {
  48671. $this->markTestIncomplete($this->message);
  48672. }
  48673. /**
  48674. * @return string
  48675. */
  48676. public function getMessage()
  48677. {
  48678. return $this->message;
  48679. }
  48680. /**
  48681. * Returns a string representation of the test case.
  48682. *
  48683. * @return string
  48684. */
  48685. public function toString()
  48686. {
  48687. return $this->getName();
  48688. }
  48689. }
  48690. <?php
  48691. /*
  48692. * This file is part of PHPUnit.
  48693. *
  48694. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  48695. *
  48696. * For the full copyright and license information, please view the LICENSE
  48697. * file that was distributed with this source code.
  48698. */
  48699. /**
  48700. * @since Class available since Release 3.4.0
  48701. */
  48702. class PHPUnit_Framework_TestSuite_DataProvider extends PHPUnit_Framework_TestSuite
  48703. {
  48704. /**
  48705. * Sets the dependencies of a TestCase.
  48706. *
  48707. * @param array $dependencies
  48708. */
  48709. public function setDependencies(array $dependencies)
  48710. {
  48711. foreach ($this->tests as $test) {
  48712. $test->setDependencies($dependencies);
  48713. }
  48714. }
  48715. }
  48716. <?php
  48717. /*
  48718. * This file is part of PHPUnit.
  48719. *
  48720. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  48721. *
  48722. * For the full copyright and license information, please view the LICENSE
  48723. * file that was distributed with this source code.
  48724. */
  48725. /**
  48726. * Wrapper for PHP deprecated errors.
  48727. * You can disable deprecated-to-exception conversion by setting
  48728. *
  48729. * <code>
  48730. * PHPUnit_Framework_Error_Deprecated::$enabled = false;
  48731. * </code>
  48732. *
  48733. * @since Class available since Release 3.3.0
  48734. */
  48735. class PHPUnit_Framework_Error_Deprecated extends PHPUnit_Framework_Error
  48736. {
  48737. public static $enabled = true;
  48738. }
  48739. <?php
  48740. /*
  48741. * This file is part of PHPUnit.
  48742. *
  48743. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  48744. *
  48745. * For the full copyright and license information, please view the LICENSE
  48746. * file that was distributed with this source code.
  48747. */
  48748. /**
  48749. * Wrapper for PHP notices.
  48750. * You can disable notice-to-exception conversion by setting
  48751. *
  48752. * <code>
  48753. * PHPUnit_Framework_Error_Notice::$enabled = false;
  48754. * </code>
  48755. *
  48756. * @since Class available since Release 3.3.0
  48757. */
  48758. class PHPUnit_Framework_Error_Notice extends PHPUnit_Framework_Error
  48759. {
  48760. public static $enabled = true;
  48761. }
  48762. <?php
  48763. /*
  48764. * This file is part of PHPUnit.
  48765. *
  48766. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  48767. *
  48768. * For the full copyright and license information, please view the LICENSE
  48769. * file that was distributed with this source code.
  48770. */
  48771. /**
  48772. * Wrapper for PHP warnings.
  48773. * You can disable notice-to-exception conversion by setting
  48774. *
  48775. * <code>
  48776. * PHPUnit_Framework_Error_Warning::$enabled = false;
  48777. * </code>
  48778. *
  48779. * @since Class available since Release 3.3.0
  48780. */
  48781. class PHPUnit_Framework_Error_Warning extends PHPUnit_Framework_Error
  48782. {
  48783. public static $enabled = true;
  48784. }
  48785. <?php
  48786. /*
  48787. * This file is part of PHPUnit.
  48788. *
  48789. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  48790. *
  48791. * For the full copyright and license information, please view the LICENSE
  48792. * file that was distributed with this source code.
  48793. */
  48794. /**
  48795. * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
  48796. * case of an incomplete test.
  48797. *
  48798. * @since Class available since Release 2.0.0
  48799. */
  48800. class PHPUnit_Framework_IncompleteTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_IncompleteTest
  48801. {
  48802. }
  48803. <?php
  48804. /*
  48805. * This file is part of PHPUnit.
  48806. *
  48807. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  48808. *
  48809. * For the full copyright and license information, please view the LICENSE
  48810. * file that was distributed with this source code.
  48811. */
  48812. /**
  48813. * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
  48814. * case of a test that is skipped because of an invalid @covers annotation.
  48815. *
  48816. * @since Class available since Release 4.0.0
  48817. */
  48818. class PHPUnit_Framework_InvalidCoversTargetError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest
  48819. {
  48820. }
  48821. <?php
  48822. /*
  48823. * This file is part of PHPUnit.
  48824. *
  48825. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  48826. *
  48827. * For the full copyright and license information, please view the LICENSE
  48828. * file that was distributed with this source code.
  48829. */
  48830. /**
  48831. * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
  48832. * case of a skipped test suite.
  48833. *
  48834. * @since Class available since Release 3.1.0
  48835. */
  48836. class PHPUnit_Framework_SkippedTestSuiteError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest
  48837. {
  48838. }
  48839. <?php
  48840. /*
  48841. * This file is part of PHPUnit.
  48842. *
  48843. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  48844. *
  48845. * For the full copyright and license information, please view the LICENSE
  48846. * file that was distributed with this source code.
  48847. */
  48848. /**
  48849. * A TestResult collects the results of executing a test case.
  48850. *
  48851. * @since Class available since Release 2.0.0
  48852. */
  48853. class PHPUnit_Framework_TestResult implements Countable
  48854. {
  48855. /**
  48856. * @var array
  48857. */
  48858. protected $passed = array();
  48859. /**
  48860. * @var array
  48861. */
  48862. protected $errors = array();
  48863. /**
  48864. * @var array
  48865. */
  48866. protected $failures = array();
  48867. /**
  48868. * @var array
  48869. */
  48870. protected $notImplemented = array();
  48871. /**
  48872. * @var array
  48873. */
  48874. protected $risky = array();
  48875. /**
  48876. * @var array
  48877. */
  48878. protected $skipped = array();
  48879. /**
  48880. * @var array
  48881. */
  48882. protected $listeners = array();
  48883. /**
  48884. * @var int
  48885. */
  48886. protected $runTests = 0;
  48887. /**
  48888. * @var float
  48889. */
  48890. protected $time = 0;
  48891. /**
  48892. * @var PHPUnit_Framework_TestSuite
  48893. */
  48894. protected $topTestSuite = null;
  48895. /**
  48896. * Code Coverage information.
  48897. *
  48898. * @var PHP_CodeCoverage
  48899. */
  48900. protected $codeCoverage;
  48901. /**
  48902. * @var bool
  48903. */
  48904. protected $convertErrorsToExceptions = true;
  48905. /**
  48906. * @var bool
  48907. */
  48908. protected $stop = false;
  48909. /**
  48910. * @var bool
  48911. */
  48912. protected $stopOnError = false;
  48913. /**
  48914. * @var bool
  48915. */
  48916. protected $stopOnFailure = false;
  48917. /**
  48918. * @var bool
  48919. */
  48920. protected $beStrictAboutTestsThatDoNotTestAnything = false;
  48921. /**
  48922. * @var bool
  48923. */
  48924. protected $beStrictAboutOutputDuringTests = false;
  48925. /**
  48926. * @var bool
  48927. */
  48928. protected $beStrictAboutTestSize = false;
  48929. /**
  48930. * @var bool
  48931. */
  48932. protected $beStrictAboutTodoAnnotatedTests = false;
  48933. /**
  48934. * @var bool
  48935. */
  48936. protected $stopOnRisky = false;
  48937. /**
  48938. * @var bool
  48939. */
  48940. protected $stopOnIncomplete = false;
  48941. /**
  48942. * @var bool
  48943. */
  48944. protected $stopOnSkipped = false;
  48945. /**
  48946. * @var bool
  48947. */
  48948. protected $lastTestFailed = false;
  48949. /**
  48950. * @var int
  48951. */
  48952. protected $timeoutForSmallTests = 1;
  48953. /**
  48954. * @var int
  48955. */
  48956. protected $timeoutForMediumTests = 10;
  48957. /**
  48958. * @var int
  48959. */
  48960. protected $timeoutForLargeTests = 60;
  48961. /**
  48962. * Registers a TestListener.
  48963. *
  48964. * @param PHPUnit_Framework_TestListener
  48965. */
  48966. public function addListener(PHPUnit_Framework_TestListener $listener)
  48967. {
  48968. $this->listeners[] = $listener;
  48969. }
  48970. /**
  48971. * Unregisters a TestListener.
  48972. *
  48973. * @param PHPUnit_Framework_TestListener $listener
  48974. */
  48975. public function removeListener(PHPUnit_Framework_TestListener $listener)
  48976. {
  48977. foreach ($this->listeners as $key => $_listener) {
  48978. if ($listener === $_listener) {
  48979. unset($this->listeners[$key]);
  48980. }
  48981. }
  48982. }
  48983. /**
  48984. * Flushes all flushable TestListeners.
  48985. *
  48986. * @since Method available since Release 3.0.0
  48987. */
  48988. public function flushListeners()
  48989. {
  48990. foreach ($this->listeners as $listener) {
  48991. if ($listener instanceof PHPUnit_Util_Printer) {
  48992. $listener->flush();
  48993. }
  48994. }
  48995. }
  48996. /**
  48997. * Adds an error to the list of errors.
  48998. *
  48999. * @param PHPUnit_Framework_Test $test
  49000. * @param Exception $e
  49001. * @param float $time
  49002. */
  49003. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  49004. {
  49005. if ($e instanceof PHPUnit_Framework_RiskyTest) {
  49006. $this->risky[] = new PHPUnit_Framework_TestFailure($test, $e);
  49007. $notifyMethod = 'addRiskyTest';
  49008. if ($this->stopOnRisky) {
  49009. $this->stop();
  49010. }
  49011. } elseif ($e instanceof PHPUnit_Framework_IncompleteTest) {
  49012. $this->notImplemented[] = new PHPUnit_Framework_TestFailure($test, $e);
  49013. $notifyMethod = 'addIncompleteTest';
  49014. if ($this->stopOnIncomplete) {
  49015. $this->stop();
  49016. }
  49017. } elseif ($e instanceof PHPUnit_Framework_SkippedTest) {
  49018. $this->skipped[] = new PHPUnit_Framework_TestFailure($test, $e);
  49019. $notifyMethod = 'addSkippedTest';
  49020. if ($this->stopOnSkipped) {
  49021. $this->stop();
  49022. }
  49023. } else {
  49024. $this->errors[] = new PHPUnit_Framework_TestFailure($test, $e);
  49025. $notifyMethod = 'addError';
  49026. if ($this->stopOnError || $this->stopOnFailure) {
  49027. $this->stop();
  49028. }
  49029. }
  49030. foreach ($this->listeners as $listener) {
  49031. $listener->$notifyMethod($test, $e, $time);
  49032. }
  49033. $this->lastTestFailed = true;
  49034. $this->time += $time;
  49035. }
  49036. /**
  49037. * Adds a failure to the list of failures.
  49038. * The passed in exception caused the failure.
  49039. *
  49040. * @param PHPUnit_Framework_Test $test
  49041. * @param PHPUnit_Framework_AssertionFailedError $e
  49042. * @param float $time
  49043. */
  49044. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  49045. {
  49046. if ($e instanceof PHPUnit_Framework_RiskyTest ||
  49047. $e instanceof PHPUnit_Framework_OutputError) {
  49048. $this->risky[] = new PHPUnit_Framework_TestFailure($test, $e);
  49049. $notifyMethod = 'addRiskyTest';
  49050. if ($this->stopOnRisky) {
  49051. $this->stop();
  49052. }
  49053. } elseif ($e instanceof PHPUnit_Framework_IncompleteTest) {
  49054. $this->notImplemented[] = new PHPUnit_Framework_TestFailure($test, $e);
  49055. $notifyMethod = 'addIncompleteTest';
  49056. if ($this->stopOnIncomplete) {
  49057. $this->stop();
  49058. }
  49059. } elseif ($e instanceof PHPUnit_Framework_SkippedTest) {
  49060. $this->skipped[] = new PHPUnit_Framework_TestFailure($test, $e);
  49061. $notifyMethod = 'addSkippedTest';
  49062. if ($this->stopOnSkipped) {
  49063. $this->stop();
  49064. }
  49065. } else {
  49066. $this->failures[] = new PHPUnit_Framework_TestFailure($test, $e);
  49067. $notifyMethod = 'addFailure';
  49068. if ($this->stopOnFailure) {
  49069. $this->stop();
  49070. }
  49071. }
  49072. foreach ($this->listeners as $listener) {
  49073. $listener->$notifyMethod($test, $e, $time);
  49074. }
  49075. $this->lastTestFailed = true;
  49076. $this->time += $time;
  49077. }
  49078. /**
  49079. * Informs the result that a testsuite will be started.
  49080. *
  49081. * @param PHPUnit_Framework_TestSuite $suite
  49082. * @since Method available since Release 2.2.0
  49083. */
  49084. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  49085. {
  49086. if ($this->topTestSuite === null) {
  49087. $this->topTestSuite = $suite;
  49088. }
  49089. foreach ($this->listeners as $listener) {
  49090. $listener->startTestSuite($suite);
  49091. }
  49092. }
  49093. /**
  49094. * Informs the result that a testsuite was completed.
  49095. *
  49096. * @param PHPUnit_Framework_TestSuite $suite
  49097. * @since Method available since Release 2.2.0
  49098. */
  49099. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  49100. {
  49101. foreach ($this->listeners as $listener) {
  49102. $listener->endTestSuite($suite);
  49103. }
  49104. }
  49105. /**
  49106. * Informs the result that a test will be started.
  49107. *
  49108. * @param PHPUnit_Framework_Test $test
  49109. */
  49110. public function startTest(PHPUnit_Framework_Test $test)
  49111. {
  49112. $this->lastTestFailed = false;
  49113. $this->runTests += count($test);
  49114. foreach ($this->listeners as $listener) {
  49115. $listener->startTest($test);
  49116. }
  49117. }
  49118. /**
  49119. * Informs the result that a test was completed.
  49120. *
  49121. * @param PHPUnit_Framework_Test $test
  49122. * @param float $time
  49123. */
  49124. public function endTest(PHPUnit_Framework_Test $test, $time)
  49125. {
  49126. foreach ($this->listeners as $listener) {
  49127. $listener->endTest($test, $time);
  49128. }
  49129. if (!$this->lastTestFailed && $test instanceof PHPUnit_Framework_TestCase) {
  49130. $class = get_class($test);
  49131. $key = $class . '::' . $test->getName();
  49132. $this->passed[$key] = array(
  49133. 'result' => $test->getResult(),
  49134. 'size' => PHPUnit_Util_Test::getSize(
  49135. $class,
  49136. $test->getName(false)
  49137. )
  49138. );
  49139. $this->time += $time;
  49140. }
  49141. }
  49142. /**
  49143. * Returns true if no risky test occurred.
  49144. *
  49145. * @return bool
  49146. * @since Method available since Release 4.0.0
  49147. */
  49148. public function allHarmless()
  49149. {
  49150. return $this->riskyCount() == 0;
  49151. }
  49152. /**
  49153. * Gets the number of risky tests.
  49154. *
  49155. * @return int
  49156. * @since Method available since Release 4.0.0
  49157. */
  49158. public function riskyCount()
  49159. {
  49160. return count($this->risky);
  49161. }
  49162. /**
  49163. * Returns true if no incomplete test occurred.
  49164. *
  49165. * @return bool
  49166. */
  49167. public function allCompletelyImplemented()
  49168. {
  49169. return $this->notImplementedCount() == 0;
  49170. }
  49171. /**
  49172. * Gets the number of incomplete tests.
  49173. *
  49174. * @return int
  49175. */
  49176. public function notImplementedCount()
  49177. {
  49178. return count($this->notImplemented);
  49179. }
  49180. /**
  49181. * Returns an Enumeration for the risky tests.
  49182. *
  49183. * @return array
  49184. * @since Method available since Release 4.0.0
  49185. */
  49186. public function risky()
  49187. {
  49188. return $this->risky;
  49189. }
  49190. /**
  49191. * Returns an Enumeration for the incomplete tests.
  49192. *
  49193. * @return array
  49194. */
  49195. public function notImplemented()
  49196. {
  49197. return $this->notImplemented;
  49198. }
  49199. /**
  49200. * Returns true if no test has been skipped.
  49201. *
  49202. * @return bool
  49203. * @since Method available since Release 3.0.0
  49204. */
  49205. public function noneSkipped()
  49206. {
  49207. return $this->skippedCount() == 0;
  49208. }
  49209. /**
  49210. * Gets the number of skipped tests.
  49211. *
  49212. * @return int
  49213. * @since Method available since Release 3.0.0
  49214. */
  49215. public function skippedCount()
  49216. {
  49217. return count($this->skipped);
  49218. }
  49219. /**
  49220. * Returns an Enumeration for the skipped tests.
  49221. *
  49222. * @return array
  49223. * @since Method available since Release 3.0.0
  49224. */
  49225. public function skipped()
  49226. {
  49227. return $this->skipped;
  49228. }
  49229. /**
  49230. * Gets the number of detected errors.
  49231. *
  49232. * @return int
  49233. */
  49234. public function errorCount()
  49235. {
  49236. return count($this->errors);
  49237. }
  49238. /**
  49239. * Returns an Enumeration for the errors.
  49240. *
  49241. * @return array
  49242. */
  49243. public function errors()
  49244. {
  49245. return $this->errors;
  49246. }
  49247. /**
  49248. * Gets the number of detected failures.
  49249. *
  49250. * @return int
  49251. */
  49252. public function failureCount()
  49253. {
  49254. return count($this->failures);
  49255. }
  49256. /**
  49257. * Returns an Enumeration for the failures.
  49258. *
  49259. * @return array
  49260. */
  49261. public function failures()
  49262. {
  49263. return $this->failures;
  49264. }
  49265. /**
  49266. * Returns the names of the tests that have passed.
  49267. *
  49268. * @return array
  49269. * @since Method available since Release 3.4.0
  49270. */
  49271. public function passed()
  49272. {
  49273. return $this->passed;
  49274. }
  49275. /**
  49276. * Returns the (top) test suite.
  49277. *
  49278. * @return PHPUnit_Framework_TestSuite
  49279. * @since Method available since Release 3.0.0
  49280. */
  49281. public function topTestSuite()
  49282. {
  49283. return $this->topTestSuite;
  49284. }
  49285. /**
  49286. * Returns whether code coverage information should be collected.
  49287. *
  49288. * @return bool If code coverage should be collected
  49289. * @since Method available since Release 3.2.0
  49290. */
  49291. public function getCollectCodeCoverageInformation()
  49292. {
  49293. return $this->codeCoverage !== null;
  49294. }
  49295. /**
  49296. * Runs a TestCase.
  49297. *
  49298. * @param PHPUnit_Framework_Test $test
  49299. */
  49300. public function run(PHPUnit_Framework_Test $test)
  49301. {
  49302. PHPUnit_Framework_Assert::resetCount();
  49303. $error = false;
  49304. $failure = false;
  49305. $incomplete = false;
  49306. $risky = false;
  49307. $skipped = false;
  49308. $this->startTest($test);
  49309. $errorHandlerSet = false;
  49310. if ($this->convertErrorsToExceptions) {
  49311. $oldErrorHandler = set_error_handler(
  49312. array('PHPUnit_Util_ErrorHandler', 'handleError'),
  49313. E_ALL | E_STRICT
  49314. );
  49315. if ($oldErrorHandler === null) {
  49316. $errorHandlerSet = true;
  49317. } else {
  49318. restore_error_handler();
  49319. }
  49320. }
  49321. $collectCodeCoverage = $this->codeCoverage !== null &&
  49322. !$test instanceof PHPUnit_Extensions_SeleniumTestCase &&
  49323. !$test instanceof PHPUnit_Framework_Warning;
  49324. if ($collectCodeCoverage) {
  49325. // We need to blacklist test source files when no whitelist is used.
  49326. if (!$this->codeCoverage->filter()->hasWhitelist()) {
  49327. $classes = $this->getHierarchy(get_class($test), true);
  49328. foreach ($classes as $class) {
  49329. $this->codeCoverage->filter()->addFileToBlacklist(
  49330. $class->getFileName()
  49331. );
  49332. }
  49333. }
  49334. $this->codeCoverage->start($test);
  49335. }
  49336. PHP_Timer::start();
  49337. try {
  49338. if (!$test instanceof PHPUnit_Framework_Warning &&
  49339. $test->getSize() != PHPUnit_Util_Test::UNKNOWN &&
  49340. $this->beStrictAboutTestSize &&
  49341. extension_loaded('pcntl') && class_exists('PHP_Invoker')) {
  49342. switch ($test->getSize()) {
  49343. case PHPUnit_Util_Test::SMALL:
  49344. $_timeout = $this->timeoutForSmallTests;
  49345. break;
  49346. case PHPUnit_Util_Test::MEDIUM:
  49347. $_timeout = $this->timeoutForMediumTests;
  49348. break;
  49349. case PHPUnit_Util_Test::LARGE:
  49350. $_timeout = $this->timeoutForLargeTests;
  49351. break;
  49352. }
  49353. $invoker = new PHP_Invoker;
  49354. $invoker->invoke(array($test, 'runBare'), array(), $_timeout);
  49355. } else {
  49356. $test->runBare();
  49357. }
  49358. } catch (PHPUnit_Framework_AssertionFailedError $e) {
  49359. $failure = true;
  49360. if ($e instanceof PHPUnit_Framework_RiskyTestError) {
  49361. $risky = true;
  49362. } elseif ($e instanceof PHPUnit_Framework_IncompleteTestError) {
  49363. $incomplete = true;
  49364. } elseif ($e instanceof PHPUnit_Framework_SkippedTestError) {
  49365. $skipped = true;
  49366. }
  49367. } catch (PHPUnit_Framework_Exception $e) {
  49368. $error = true;
  49369. } catch (Throwable $e) {
  49370. $e = new PHPUnit_Framework_ExceptionWrapper($e);
  49371. $error = true;
  49372. } catch (Exception $e) {
  49373. $e = new PHPUnit_Framework_ExceptionWrapper($e);
  49374. $error = true;
  49375. }
  49376. $time = PHP_Timer::stop();
  49377. $test->addToAssertionCount(PHPUnit_Framework_Assert::getCount());
  49378. if ($this->beStrictAboutTestsThatDoNotTestAnything &&
  49379. $test->getNumAssertions() == 0) {
  49380. $risky = true;
  49381. }
  49382. if ($collectCodeCoverage) {
  49383. $append = !$risky && !$incomplete && !$skipped;
  49384. $linesToBeCovered = array();
  49385. $linesToBeUsed = array();
  49386. if ($append && $test instanceof PHPUnit_Framework_TestCase) {
  49387. $linesToBeCovered = PHPUnit_Util_Test::getLinesToBeCovered(
  49388. get_class($test),
  49389. $test->getName(false)
  49390. );
  49391. $linesToBeUsed = PHPUnit_Util_Test::getLinesToBeUsed(
  49392. get_class($test),
  49393. $test->getName(false)
  49394. );
  49395. }
  49396. try {
  49397. $this->codeCoverage->stop(
  49398. $append,
  49399. $linesToBeCovered,
  49400. $linesToBeUsed
  49401. );
  49402. } catch (PHP_CodeCoverage_Exception_UnintentionallyCoveredCode $cce) {
  49403. $this->addFailure(
  49404. $test,
  49405. new PHPUnit_Framework_UnintentionallyCoveredCodeError(
  49406. 'This test executed code that is not listed as code to be covered or used:' .
  49407. PHP_EOL . $cce->getMessage()
  49408. ),
  49409. $time
  49410. );
  49411. } catch (PHPUnit_Framework_InvalidCoversTargetException $cce) {
  49412. $this->addFailure(
  49413. $test,
  49414. new PHPUnit_Framework_InvalidCoversTargetError(
  49415. $cce->getMessage()
  49416. ),
  49417. $time
  49418. );
  49419. } catch (PHP_CodeCoverage_Exception $cce) {
  49420. $error = true;
  49421. if (!isset($e)) {
  49422. $e = $cce;
  49423. }
  49424. }
  49425. }
  49426. if ($errorHandlerSet === true) {
  49427. restore_error_handler();
  49428. }
  49429. if ($error === true) {
  49430. $this->addError($test, $e, $time);
  49431. } elseif ($failure === true) {
  49432. $this->addFailure($test, $e, $time);
  49433. } elseif ($this->beStrictAboutTestsThatDoNotTestAnything &&
  49434. $test->getNumAssertions() == 0) {
  49435. $this->addFailure(
  49436. $test,
  49437. new PHPUnit_Framework_RiskyTestError(
  49438. 'This test did not perform any assertions'
  49439. ),
  49440. $time
  49441. );
  49442. } elseif ($this->beStrictAboutOutputDuringTests && $test->hasOutput()) {
  49443. $this->addFailure(
  49444. $test,
  49445. new PHPUnit_Framework_OutputError(
  49446. sprintf(
  49447. 'This test printed output: %s',
  49448. $test->getActualOutput()
  49449. )
  49450. ),
  49451. $time
  49452. );
  49453. } elseif ($this->beStrictAboutTodoAnnotatedTests && $test instanceof PHPUnit_Framework_TestCase) {
  49454. $annotations = $test->getAnnotations();
  49455. if (isset($annotations['method']['todo'])) {
  49456. $this->addFailure(
  49457. $test,
  49458. new PHPUnit_Framework_RiskyTestError(
  49459. 'Test method is annotated with @todo'
  49460. ),
  49461. $time
  49462. );
  49463. }
  49464. }
  49465. $this->endTest($test, $time);
  49466. }
  49467. /**
  49468. * Gets the number of run tests.
  49469. *
  49470. * @return int
  49471. */
  49472. public function count()
  49473. {
  49474. return $this->runTests;
  49475. }
  49476. /**
  49477. * Checks whether the test run should stop.
  49478. *
  49479. * @return bool
  49480. */
  49481. public function shouldStop()
  49482. {
  49483. return $this->stop;
  49484. }
  49485. /**
  49486. * Marks that the test run should stop.
  49487. */
  49488. public function stop()
  49489. {
  49490. $this->stop = true;
  49491. }
  49492. /**
  49493. * Returns the PHP_CodeCoverage object.
  49494. *
  49495. * @return PHP_CodeCoverage
  49496. * @since Method available since Release 3.5.0
  49497. */
  49498. public function getCodeCoverage()
  49499. {
  49500. return $this->codeCoverage;
  49501. }
  49502. /**
  49503. * Sets the PHP_CodeCoverage object.
  49504. *
  49505. * @param PHP_CodeCoverage $codeCoverage
  49506. * @since Method available since Release 3.6.0
  49507. */
  49508. public function setCodeCoverage(PHP_CodeCoverage $codeCoverage)
  49509. {
  49510. $this->codeCoverage = $codeCoverage;
  49511. }
  49512. /**
  49513. * Enables or disables the error-to-exception conversion.
  49514. *
  49515. * @param bool $flag
  49516. * @throws PHPUnit_Framework_Exception
  49517. * @since Method available since Release 3.2.14
  49518. */
  49519. public function convertErrorsToExceptions($flag)
  49520. {
  49521. if (!is_bool($flag)) {
  49522. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  49523. }
  49524. $this->convertErrorsToExceptions = $flag;
  49525. }
  49526. /**
  49527. * Returns the error-to-exception conversion setting.
  49528. *
  49529. * @return bool
  49530. * @since Method available since Release 3.4.0
  49531. */
  49532. public function getConvertErrorsToExceptions()
  49533. {
  49534. return $this->convertErrorsToExceptions;
  49535. }
  49536. /**
  49537. * Enables or disables the stopping when an error occurs.
  49538. *
  49539. * @param bool $flag
  49540. * @throws PHPUnit_Framework_Exception
  49541. * @since Method available since Release 3.5.0
  49542. */
  49543. public function stopOnError($flag)
  49544. {
  49545. if (!is_bool($flag)) {
  49546. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  49547. }
  49548. $this->stopOnError = $flag;
  49549. }
  49550. /**
  49551. * Enables or disables the stopping when a failure occurs.
  49552. *
  49553. * @param bool $flag
  49554. * @throws PHPUnit_Framework_Exception
  49555. * @since Method available since Release 3.1.0
  49556. */
  49557. public function stopOnFailure($flag)
  49558. {
  49559. if (!is_bool($flag)) {
  49560. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  49561. }
  49562. $this->stopOnFailure = $flag;
  49563. }
  49564. /**
  49565. * @param bool $flag
  49566. * @throws PHPUnit_Framework_Exception
  49567. * @since Method available since Release 4.0.0
  49568. */
  49569. public function beStrictAboutTestsThatDoNotTestAnything($flag)
  49570. {
  49571. if (!is_bool($flag)) {
  49572. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  49573. }
  49574. $this->beStrictAboutTestsThatDoNotTestAnything = $flag;
  49575. }
  49576. /**
  49577. * @return bool
  49578. * @since Method available since Release 4.0.0
  49579. */
  49580. public function isStrictAboutTestsThatDoNotTestAnything()
  49581. {
  49582. return $this->beStrictAboutTestsThatDoNotTestAnything;
  49583. }
  49584. /**
  49585. * @param bool $flag
  49586. * @throws PHPUnit_Framework_Exception
  49587. * @since Method available since Release 4.0.0
  49588. */
  49589. public function beStrictAboutOutputDuringTests($flag)
  49590. {
  49591. if (!is_bool($flag)) {
  49592. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  49593. }
  49594. $this->beStrictAboutOutputDuringTests = $flag;
  49595. }
  49596. /**
  49597. * @return bool
  49598. * @since Method available since Release 4.0.0
  49599. */
  49600. public function isStrictAboutOutputDuringTests()
  49601. {
  49602. return $this->beStrictAboutOutputDuringTests;
  49603. }
  49604. /**
  49605. * @param bool $flag
  49606. * @throws PHPUnit_Framework_Exception
  49607. * @since Method available since Release 4.0.0
  49608. */
  49609. public function beStrictAboutTestSize($flag)
  49610. {
  49611. if (!is_bool($flag)) {
  49612. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  49613. }
  49614. $this->beStrictAboutTestSize = $flag;
  49615. }
  49616. /**
  49617. * @return bool
  49618. * @since Method available since Release 4.0.0
  49619. */
  49620. public function isStrictAboutTestSize()
  49621. {
  49622. return $this->beStrictAboutTestSize;
  49623. }
  49624. /**
  49625. * @param bool $flag
  49626. * @throws PHPUnit_Framework_Exception
  49627. * @since Method available since Release 4.2.0
  49628. */
  49629. public function beStrictAboutTodoAnnotatedTests($flag)
  49630. {
  49631. if (!is_bool($flag)) {
  49632. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  49633. }
  49634. $this->beStrictAboutTodoAnnotatedTests = $flag;
  49635. }
  49636. /**
  49637. * @return bool
  49638. * @since Method available since Release 4.2.0
  49639. */
  49640. public function isStrictAboutTodoAnnotatedTests()
  49641. {
  49642. return $this->beStrictAboutTodoAnnotatedTests;
  49643. }
  49644. /**
  49645. * Enables or disables the stopping for risky tests.
  49646. *
  49647. * @param bool $flag
  49648. * @throws PHPUnit_Framework_Exception
  49649. * @since Method available since Release 4.0.0
  49650. */
  49651. public function stopOnRisky($flag)
  49652. {
  49653. if (!is_bool($flag)) {
  49654. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  49655. }
  49656. $this->stopOnRisky = $flag;
  49657. }
  49658. /**
  49659. * Enables or disables the stopping for incomplete tests.
  49660. *
  49661. * @param bool $flag
  49662. * @throws PHPUnit_Framework_Exception
  49663. * @since Method available since Release 3.5.0
  49664. */
  49665. public function stopOnIncomplete($flag)
  49666. {
  49667. if (!is_bool($flag)) {
  49668. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  49669. }
  49670. $this->stopOnIncomplete = $flag;
  49671. }
  49672. /**
  49673. * Enables or disables the stopping for skipped tests.
  49674. *
  49675. * @param bool $flag
  49676. * @throws PHPUnit_Framework_Exception
  49677. * @since Method available since Release 3.1.0
  49678. */
  49679. public function stopOnSkipped($flag)
  49680. {
  49681. if (!is_bool($flag)) {
  49682. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  49683. }
  49684. $this->stopOnSkipped = $flag;
  49685. }
  49686. /**
  49687. * Returns the time spent running the tests.
  49688. *
  49689. * @return float
  49690. */
  49691. public function time()
  49692. {
  49693. return $this->time;
  49694. }
  49695. /**
  49696. * Returns whether the entire test was successful or not.
  49697. *
  49698. * @return bool
  49699. */
  49700. public function wasSuccessful()
  49701. {
  49702. return empty($this->errors) && empty($this->failures);
  49703. }
  49704. /**
  49705. * Sets the timeout for small tests.
  49706. *
  49707. * @param int $timeout
  49708. * @throws PHPUnit_Framework_Exception
  49709. * @since Method available since Release 3.6.0
  49710. */
  49711. public function setTimeoutForSmallTests($timeout)
  49712. {
  49713. if (!is_integer($timeout)) {
  49714. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  49715. }
  49716. $this->timeoutForSmallTests = $timeout;
  49717. }
  49718. /**
  49719. * Sets the timeout for medium tests.
  49720. *
  49721. * @param int $timeout
  49722. * @throws PHPUnit_Framework_Exception
  49723. * @since Method available since Release 3.6.0
  49724. */
  49725. public function setTimeoutForMediumTests($timeout)
  49726. {
  49727. if (!is_integer($timeout)) {
  49728. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  49729. }
  49730. $this->timeoutForMediumTests = $timeout;
  49731. }
  49732. /**
  49733. * Sets the timeout for large tests.
  49734. *
  49735. * @param int $timeout
  49736. * @throws PHPUnit_Framework_Exception
  49737. * @since Method available since Release 3.6.0
  49738. */
  49739. public function setTimeoutForLargeTests($timeout)
  49740. {
  49741. if (!is_integer($timeout)) {
  49742. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
  49743. }
  49744. $this->timeoutForLargeTests = $timeout;
  49745. }
  49746. /**
  49747. * Returns the class hierarchy for a given class.
  49748. *
  49749. * @param string $className
  49750. * @param bool $asReflectionObjects
  49751. * @return array
  49752. */
  49753. protected function getHierarchy($className, $asReflectionObjects = false)
  49754. {
  49755. if ($asReflectionObjects) {
  49756. $classes = array(new ReflectionClass($className));
  49757. } else {
  49758. $classes = array($className);
  49759. }
  49760. $done = false;
  49761. while (!$done) {
  49762. if ($asReflectionObjects) {
  49763. $class = new ReflectionClass(
  49764. $classes[count($classes)-1]->getName()
  49765. );
  49766. } else {
  49767. $class = new ReflectionClass($classes[count($classes)-1]);
  49768. }
  49769. $parent = $class->getParentClass();
  49770. if ($parent !== false) {
  49771. if ($asReflectionObjects) {
  49772. $classes[] = $parent;
  49773. } else {
  49774. $classes[] = $parent->getName();
  49775. }
  49776. } else {
  49777. $done = true;
  49778. }
  49779. }
  49780. return $classes;
  49781. }
  49782. }
  49783. <?php
  49784. /*
  49785. * This file is part of PHPUnit.
  49786. *
  49787. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  49788. *
  49789. * For the full copyright and license information, please view the LICENSE
  49790. * file that was distributed with this source code.
  49791. */
  49792. /**
  49793. * A TestFailure collects a failed test together with the caught exception.
  49794. *
  49795. * @since Class available since Release 2.0.0
  49796. */
  49797. class PHPUnit_Framework_TestFailure
  49798. {
  49799. /**
  49800. * @var string
  49801. */
  49802. private $testName;
  49803. /**
  49804. * @var PHPUnit_Framework_Test|null
  49805. */
  49806. protected $failedTest;
  49807. /**
  49808. * @var Exception
  49809. */
  49810. protected $thrownException;
  49811. /**
  49812. * Constructs a TestFailure with the given test and exception.
  49813. *
  49814. * @param PHPUnit_Framework_Test $failedTest
  49815. * @param Exception $thrownException
  49816. */
  49817. public function __construct(PHPUnit_Framework_Test $failedTest, Exception $thrownException)
  49818. {
  49819. if ($failedTest instanceof PHPUnit_Framework_SelfDescribing) {
  49820. $this->testName = $failedTest->toString();
  49821. } else {
  49822. $this->testName = get_class($failedTest);
  49823. }
  49824. if (!$failedTest instanceof PHPUnit_Framework_TestCase || !$failedTest->isInIsolation()) {
  49825. $this->failedTest = $failedTest;
  49826. }
  49827. $this->thrownException = $thrownException;
  49828. }
  49829. /**
  49830. * Returns a short description of the failure.
  49831. *
  49832. * @return string
  49833. */
  49834. public function toString()
  49835. {
  49836. return sprintf(
  49837. '%s: %s',
  49838. $this->testName,
  49839. $this->thrownException->getMessage()
  49840. );
  49841. }
  49842. /**
  49843. * Returns a description for the thrown exception.
  49844. *
  49845. * @return string
  49846. * @since Method available since Release 3.4.0
  49847. */
  49848. public function getExceptionAsString()
  49849. {
  49850. return self::exceptionToString($this->thrownException);
  49851. }
  49852. /**
  49853. * Returns a description for an exception.
  49854. *
  49855. * @param Exception $e
  49856. * @return string
  49857. * @since Method available since Release 3.2.0
  49858. */
  49859. public static function exceptionToString(Exception $e)
  49860. {
  49861. if ($e instanceof PHPUnit_Framework_SelfDescribing) {
  49862. $buffer = $e->toString();
  49863. if ($e instanceof PHPUnit_Framework_ExpectationFailedException && $e->getComparisonFailure()) {
  49864. $buffer = $buffer . $e->getComparisonFailure()->getDiff();
  49865. }
  49866. if (!empty($buffer)) {
  49867. $buffer = trim($buffer) . "\n";
  49868. }
  49869. } elseif ($e instanceof PHPUnit_Framework_Error) {
  49870. $buffer = $e->getMessage() . "\n";
  49871. } elseif ($e instanceof PHPUnit_Framework_ExceptionWrapper) {
  49872. $buffer = $e->getClassname() . ': ' . $e->getMessage() . "\n";
  49873. } else {
  49874. $buffer = get_class($e) . ': ' . $e->getMessage() . "\n";
  49875. }
  49876. return $buffer;
  49877. }
  49878. /**
  49879. * Returns the name of the failing test (including data set, if any).
  49880. *
  49881. * @return string
  49882. * @since Method available since Release 4.3.0
  49883. */
  49884. public function getTestName()
  49885. {
  49886. return $this->testName;
  49887. }
  49888. /**
  49889. * Returns the failing test.
  49890. *
  49891. * Note: The test object is not set when the test is executed in process
  49892. * isolation.
  49893. *
  49894. * @see PHPUnit_Framework_Exception
  49895. *
  49896. * @return PHPUnit_Framework_Test|null
  49897. */
  49898. public function failedTest()
  49899. {
  49900. return $this->failedTest;
  49901. }
  49902. /**
  49903. * Gets the thrown exception.
  49904. *
  49905. * @return Exception
  49906. */
  49907. public function thrownException()
  49908. {
  49909. return $this->thrownException;
  49910. }
  49911. /**
  49912. * Returns the exception's message.
  49913. *
  49914. * @return string
  49915. */
  49916. public function exceptionMessage()
  49917. {
  49918. return $this->thrownException()->getMessage();
  49919. }
  49920. /**
  49921. * Returns true if the thrown exception
  49922. * is of type AssertionFailedError.
  49923. *
  49924. * @return bool
  49925. */
  49926. public function isFailure()
  49927. {
  49928. return ($this->thrownException() instanceof PHPUnit_Framework_AssertionFailedError);
  49929. }
  49930. }
  49931. <?php
  49932. /*
  49933. * This file is part of PHPUnit.
  49934. *
  49935. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  49936. *
  49937. * For the full copyright and license information, please view the LICENSE
  49938. * file that was distributed with this source code.
  49939. */
  49940. /**
  49941. * A marker interface for marking any exception/error as result of an unit
  49942. * test as incomplete implementation or currently not implemented.
  49943. *
  49944. * @since Interface available since Release 2.0.0
  49945. */
  49946. interface PHPUnit_Framework_IncompleteTest
  49947. {
  49948. }
  49949. <?php
  49950. /*
  49951. * This file is part of PHPUnit.
  49952. *
  49953. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  49954. *
  49955. * For the full copyright and license information, please view the LICENSE
  49956. * file that was distributed with this source code.
  49957. */
  49958. /**
  49959. * A skipped test case
  49960. *
  49961. * @since Class available since Release 4.3.0
  49962. */
  49963. class PHPUnit_Framework_SkippedTestCase extends PHPUnit_Framework_TestCase
  49964. {
  49965. /**
  49966. * @var string
  49967. */
  49968. protected $message = '';
  49969. /**
  49970. * @var bool
  49971. */
  49972. protected $backupGlobals = false;
  49973. /**
  49974. * @var bool
  49975. */
  49976. protected $backupStaticAttributes = false;
  49977. /**
  49978. * @var bool
  49979. */
  49980. protected $runTestInSeparateProcess = false;
  49981. /**
  49982. * @var bool
  49983. */
  49984. protected $useErrorHandler = false;
  49985. /**
  49986. * @var bool
  49987. */
  49988. protected $useOutputBuffering = false;
  49989. /**
  49990. * @param string $message
  49991. */
  49992. public function __construct($className, $methodName, $message = '')
  49993. {
  49994. $this->message = $message;
  49995. parent::__construct($className . '::' . $methodName);
  49996. }
  49997. /**
  49998. * @throws PHPUnit_Framework_Exception
  49999. */
  50000. protected function runTest()
  50001. {
  50002. $this->markTestSkipped($this->message);
  50003. }
  50004. /**
  50005. * @return string
  50006. */
  50007. public function getMessage()
  50008. {
  50009. return $this->message;
  50010. }
  50011. /**
  50012. * Returns a string representation of the test case.
  50013. *
  50014. * @return string
  50015. */
  50016. public function toString()
  50017. {
  50018. return $this->getName();
  50019. }
  50020. }
  50021. <?php
  50022. /*
  50023. * This file is part of PHPUnit.
  50024. *
  50025. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50026. *
  50027. * For the full copyright and license information, please view the LICENSE
  50028. * file that was distributed with this source code.
  50029. */
  50030. /**
  50031. * Constraint that asserts that the class it is evaluated for has a given
  50032. * attribute.
  50033. *
  50034. * The attribute name is passed in the constructor.
  50035. *
  50036. * @since Class available since Release 3.1.0
  50037. */
  50038. class PHPUnit_Framework_Constraint_ClassHasAttribute extends PHPUnit_Framework_Constraint
  50039. {
  50040. /**
  50041. * @var string
  50042. */
  50043. protected $attributeName;
  50044. /**
  50045. * @param string $attributeName
  50046. */
  50047. public function __construct($attributeName)
  50048. {
  50049. parent::__construct();
  50050. $this->attributeName = $attributeName;
  50051. }
  50052. /**
  50053. * Evaluates the constraint for parameter $other. Returns true if the
  50054. * constraint is met, false otherwise.
  50055. *
  50056. * @param mixed $other Value or object to evaluate.
  50057. * @return bool
  50058. */
  50059. protected function matches($other)
  50060. {
  50061. $class = new ReflectionClass($other);
  50062. return $class->hasProperty($this->attributeName);
  50063. }
  50064. /**
  50065. * Returns a string representation of the constraint.
  50066. *
  50067. * @return string
  50068. */
  50069. public function toString()
  50070. {
  50071. return sprintf(
  50072. 'has attribute "%s"',
  50073. $this->attributeName
  50074. );
  50075. }
  50076. /**
  50077. * Returns the description of the failure
  50078. *
  50079. * The beginning of failure messages is "Failed asserting that" in most
  50080. * cases. This method should return the second part of that sentence.
  50081. *
  50082. * @param mixed $other Evaluated value or object.
  50083. * @return string
  50084. */
  50085. protected function failureDescription($other)
  50086. {
  50087. return sprintf(
  50088. '%sclass "%s" %s',
  50089. is_object($other) ? 'object of ' : '',
  50090. is_object($other) ? get_class($other) : $other,
  50091. $this->toString()
  50092. );
  50093. }
  50094. }
  50095. <?php
  50096. /*
  50097. * This file is part of PHPUnit.
  50098. *
  50099. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50100. *
  50101. * For the full copyright and license information, please view the LICENSE
  50102. * file that was distributed with this source code.
  50103. */
  50104. /**
  50105. * Constraint that asserts that the Traversable it is applied to contains
  50106. * a given value.
  50107. *
  50108. * @since Class available since Release 3.0.0
  50109. */
  50110. class PHPUnit_Framework_Constraint_TraversableContains extends PHPUnit_Framework_Constraint
  50111. {
  50112. /**
  50113. * @var bool
  50114. */
  50115. protected $checkForObjectIdentity;
  50116. /**
  50117. * @var bool
  50118. */
  50119. protected $checkForNonObjectIdentity;
  50120. /**
  50121. * @var mixed
  50122. */
  50123. protected $value;
  50124. /**
  50125. * @param mixed $value
  50126. * @param bool $checkForObjectIdentity
  50127. * @param bool $checkForNonObjectIdentity
  50128. * @throws PHPUnit_Framework_Exception
  50129. */
  50130. public function __construct($value, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false)
  50131. {
  50132. parent::__construct();
  50133. if (!is_bool($checkForObjectIdentity)) {
  50134. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'boolean');
  50135. }
  50136. if (!is_bool($checkForNonObjectIdentity)) {
  50137. throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'boolean');
  50138. }
  50139. $this->checkForObjectIdentity = $checkForObjectIdentity;
  50140. $this->checkForNonObjectIdentity = $checkForNonObjectIdentity;
  50141. $this->value = $value;
  50142. }
  50143. /**
  50144. * Evaluates the constraint for parameter $other. Returns true if the
  50145. * constraint is met, false otherwise.
  50146. *
  50147. * @param mixed $other Value or object to evaluate.
  50148. * @return bool
  50149. */
  50150. protected function matches($other)
  50151. {
  50152. if ($other instanceof SplObjectStorage) {
  50153. return $other->contains($this->value);
  50154. }
  50155. if (is_object($this->value)) {
  50156. foreach ($other as $element) {
  50157. if (($this->checkForObjectIdentity &&
  50158. $element === $this->value) ||
  50159. (!$this->checkForObjectIdentity &&
  50160. $element == $this->value)) {
  50161. return true;
  50162. }
  50163. }
  50164. } else {
  50165. foreach ($other as $element) {
  50166. if (($this->checkForNonObjectIdentity &&
  50167. $element === $this->value) ||
  50168. (!$this->checkForNonObjectIdentity &&
  50169. $element == $this->value)) {
  50170. return true;
  50171. }
  50172. }
  50173. }
  50174. return false;
  50175. }
  50176. /**
  50177. * Returns a string representation of the constraint.
  50178. *
  50179. * @return string
  50180. */
  50181. public function toString()
  50182. {
  50183. if (is_string($this->value) && strpos($this->value, "\n") !== false) {
  50184. return 'contains "' . $this->value . '"';
  50185. } else {
  50186. return 'contains ' . $this->exporter->export($this->value);
  50187. }
  50188. }
  50189. /**
  50190. * Returns the description of the failure
  50191. *
  50192. * The beginning of failure messages is "Failed asserting that" in most
  50193. * cases. This method should return the second part of that sentence.
  50194. *
  50195. * @param mixed $other Evaluated value or object.
  50196. * @return string
  50197. */
  50198. protected function failureDescription($other)
  50199. {
  50200. return sprintf(
  50201. '%s %s',
  50202. is_array($other) ? 'an array' : 'a traversable',
  50203. $this->toString()
  50204. );
  50205. }
  50206. }
  50207. <?php
  50208. /*
  50209. * This file is part of PHPUnit.
  50210. *
  50211. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50212. *
  50213. * For the full copyright and license information, please view the LICENSE
  50214. * file that was distributed with this source code.
  50215. */
  50216. /**
  50217. * @since Class available since Release 3.6.6
  50218. */
  50219. class PHPUnit_Framework_Constraint_ExceptionCode extends PHPUnit_Framework_Constraint
  50220. {
  50221. /**
  50222. * @var int
  50223. */
  50224. protected $expectedCode;
  50225. /**
  50226. * @param int $expected
  50227. */
  50228. public function __construct($expected)
  50229. {
  50230. parent::__construct();
  50231. $this->expectedCode = $expected;
  50232. }
  50233. /**
  50234. * Evaluates the constraint for parameter $other. Returns true if the
  50235. * constraint is met, false otherwise.
  50236. *
  50237. * @param Exception $other
  50238. * @return bool
  50239. */
  50240. protected function matches($other)
  50241. {
  50242. return (string) $other->getCode() == (string) $this->expectedCode;
  50243. }
  50244. /**
  50245. * Returns the description of the failure
  50246. *
  50247. * The beginning of failure messages is "Failed asserting that" in most
  50248. * cases. This method should return the second part of that sentence.
  50249. *
  50250. * @param mixed $other Evaluated value or object.
  50251. * @return string
  50252. */
  50253. protected function failureDescription($other)
  50254. {
  50255. return sprintf(
  50256. '%s is equal to expected exception code %s',
  50257. $this->exporter->export($other->getCode()),
  50258. $this->exporter->export($this->expectedCode)
  50259. );
  50260. }
  50261. /**
  50262. * @return string
  50263. */
  50264. public function toString()
  50265. {
  50266. return 'exception code is ';
  50267. }
  50268. }
  50269. <?php
  50270. /*
  50271. * This file is part of PHPUnit.
  50272. *
  50273. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50274. *
  50275. * For the full copyright and license information, please view the LICENSE
  50276. * file that was distributed with this source code.
  50277. */
  50278. /**
  50279. * @since Class available since Release 3.6.6
  50280. */
  50281. class PHPUnit_Framework_Constraint_Exception extends PHPUnit_Framework_Constraint
  50282. {
  50283. /**
  50284. * @var string
  50285. */
  50286. protected $className;
  50287. /**
  50288. * @param string $className
  50289. */
  50290. public function __construct($className)
  50291. {
  50292. parent::__construct();
  50293. $this->className = $className;
  50294. }
  50295. /**
  50296. * Evaluates the constraint for parameter $other. Returns true if the
  50297. * constraint is met, false otherwise.
  50298. *
  50299. * @param mixed $other Value or object to evaluate.
  50300. * @return bool
  50301. */
  50302. protected function matches($other)
  50303. {
  50304. return $other instanceof $this->className;
  50305. }
  50306. /**
  50307. * Returns the description of the failure
  50308. *
  50309. * The beginning of failure messages is "Failed asserting that" in most
  50310. * cases. This method should return the second part of that sentence.
  50311. *
  50312. * @param mixed $other Evaluated value or object.
  50313. * @return string
  50314. */
  50315. protected function failureDescription($other)
  50316. {
  50317. if ($other !== null) {
  50318. $message = '';
  50319. if ($other instanceof Exception) {
  50320. $message = '. Message was: "' . $other->getMessage() . '" at'
  50321. . "\n" . $other->getTraceAsString();
  50322. }
  50323. return sprintf(
  50324. 'exception of type "%s" matches expected exception "%s"%s',
  50325. get_class($other),
  50326. $this->className,
  50327. $message
  50328. );
  50329. }
  50330. return sprintf(
  50331. 'exception of type "%s" is thrown',
  50332. $this->className
  50333. );
  50334. }
  50335. /**
  50336. * Returns a string representation of the constraint.
  50337. *
  50338. * @return string
  50339. */
  50340. public function toString()
  50341. {
  50342. return sprintf(
  50343. 'exception of type "%s"',
  50344. $this->className
  50345. );
  50346. }
  50347. }
  50348. <?php
  50349. /*
  50350. * This file is part of PHPUnit.
  50351. *
  50352. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50353. *
  50354. * For the full copyright and license information, please view the LICENSE
  50355. * file that was distributed with this source code.
  50356. */
  50357. /**
  50358. * @since Class available since Release 3.6.0
  50359. */
  50360. class PHPUnit_Framework_Constraint_SameSize extends PHPUnit_Framework_Constraint_Count
  50361. {
  50362. /**
  50363. * @var int
  50364. */
  50365. protected $expectedCount;
  50366. /**
  50367. * @param int $expected
  50368. */
  50369. public function __construct($expected)
  50370. {
  50371. parent::__construct($this->getCountOf($expected));
  50372. }
  50373. }
  50374. <?php
  50375. /*
  50376. * This file is part of PHPUnit.
  50377. *
  50378. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50379. *
  50380. * For the full copyright and license information, please view the LICENSE
  50381. * file that was distributed with this source code.
  50382. */
  50383. /**
  50384. * Asserts whether or not two JSON objects are equal.
  50385. *
  50386. * @since Class available since Release 3.7.0
  50387. */
  50388. class PHPUnit_Framework_Constraint_JsonMatches extends PHPUnit_Framework_Constraint
  50389. {
  50390. /**
  50391. * @var string
  50392. */
  50393. protected $value;
  50394. /**
  50395. * Creates a new constraint.
  50396. *
  50397. * @param string $value
  50398. */
  50399. public function __construct($value)
  50400. {
  50401. parent::__construct();
  50402. $this->value = $value;
  50403. }
  50404. /**
  50405. * Evaluates the constraint for parameter $other. Returns true if the
  50406. * constraint is met, false otherwise.
  50407. *
  50408. * This method can be overridden to implement the evaluation algorithm.
  50409. *
  50410. * @param mixed $other Value or object to evaluate.
  50411. * @return bool
  50412. */
  50413. protected function matches($other)
  50414. {
  50415. $decodedOther = json_decode($other);
  50416. if (json_last_error()) {
  50417. return false;
  50418. }
  50419. $decodedValue = json_decode($this->value);
  50420. if (json_last_error()) {
  50421. return false;
  50422. }
  50423. return $decodedOther == $decodedValue;
  50424. }
  50425. /**
  50426. * Returns a string representation of the object.
  50427. *
  50428. * @return string
  50429. */
  50430. public function toString()
  50431. {
  50432. return sprintf(
  50433. 'matches JSON string "%s"',
  50434. $this->value
  50435. );
  50436. }
  50437. }
  50438. <?php
  50439. /*
  50440. * This file is part of PHPUnit.
  50441. *
  50442. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50443. *
  50444. * For the full copyright and license information, please view the LICENSE
  50445. * file that was distributed with this source code.
  50446. */
  50447. /**
  50448. * Constraint that asserts that the object it is evaluated for is an instance
  50449. * of a given class.
  50450. *
  50451. * The expected class name is passed in the constructor.
  50452. *
  50453. * @since Class available since Release 3.0.0
  50454. */
  50455. class PHPUnit_Framework_Constraint_IsInstanceOf extends PHPUnit_Framework_Constraint
  50456. {
  50457. /**
  50458. * @var string
  50459. */
  50460. protected $className;
  50461. /**
  50462. * @param string $className
  50463. */
  50464. public function __construct($className)
  50465. {
  50466. parent::__construct();
  50467. $this->className = $className;
  50468. }
  50469. /**
  50470. * Evaluates the constraint for parameter $other. Returns true if the
  50471. * constraint is met, false otherwise.
  50472. *
  50473. * @param mixed $other Value or object to evaluate.
  50474. * @return bool
  50475. */
  50476. protected function matches($other)
  50477. {
  50478. return ($other instanceof $this->className);
  50479. }
  50480. /**
  50481. * Returns the description of the failure
  50482. *
  50483. * The beginning of failure messages is "Failed asserting that" in most
  50484. * cases. This method should return the second part of that sentence.
  50485. *
  50486. * @param mixed $other Evaluated value or object.
  50487. * @return string
  50488. */
  50489. protected function failureDescription($other)
  50490. {
  50491. return sprintf(
  50492. '%s is an instance of %s "%s"',
  50493. $this->exporter->shortenedExport($other),
  50494. $this->getType(),
  50495. $this->className
  50496. );
  50497. }
  50498. /**
  50499. * Returns a string representation of the constraint.
  50500. *
  50501. * @return string
  50502. */
  50503. public function toString()
  50504. {
  50505. return sprintf(
  50506. 'is instance of %s "%s"',
  50507. $this->getType(),
  50508. $this->className
  50509. );
  50510. }
  50511. private function getType()
  50512. {
  50513. try {
  50514. $reflection = new ReflectionClass($this->className);
  50515. if ($reflection->isInterface()) {
  50516. return 'interface';
  50517. }
  50518. } catch (ReflectionException $e) {
  50519. }
  50520. return 'class';
  50521. }
  50522. }
  50523. <?php
  50524. /*
  50525. * This file is part of PHPUnit.
  50526. *
  50527. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50528. *
  50529. * For the full copyright and license information, please view the LICENSE
  50530. * file that was distributed with this source code.
  50531. */
  50532. /**
  50533. * Constraint that asserts that the object it is evaluated for has a given
  50534. * attribute.
  50535. *
  50536. * The attribute name is passed in the constructor.
  50537. *
  50538. * @since Class available since Release 3.0.0
  50539. */
  50540. class PHPUnit_Framework_Constraint_ObjectHasAttribute extends PHPUnit_Framework_Constraint_ClassHasAttribute
  50541. {
  50542. /**
  50543. * Evaluates the constraint for parameter $other. Returns true if the
  50544. * constraint is met, false otherwise.
  50545. *
  50546. * @param mixed $other Value or object to evaluate.
  50547. * @return bool
  50548. */
  50549. protected function matches($other)
  50550. {
  50551. $object = new ReflectionObject($other);
  50552. return $object->hasProperty($this->attributeName);
  50553. }
  50554. }
  50555. <?php
  50556. /*
  50557. * This file is part of PHPUnit.
  50558. *
  50559. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50560. *
  50561. * For the full copyright and license information, please view the LICENSE
  50562. * file that was distributed with this source code.
  50563. */
  50564. /**
  50565. * Constraint that asserts that the value it is evaluated for is of a
  50566. * specified type.
  50567. *
  50568. * The expected value is passed in the constructor.
  50569. *
  50570. * @since Class available since Release 3.0.0
  50571. */
  50572. class PHPUnit_Framework_Constraint_IsType extends PHPUnit_Framework_Constraint
  50573. {
  50574. const TYPE_ARRAY = 'array';
  50575. const TYPE_BOOL = 'bool';
  50576. const TYPE_FLOAT = 'float';
  50577. const TYPE_INT = 'int';
  50578. const TYPE_NULL = 'null';
  50579. const TYPE_NUMERIC = 'numeric';
  50580. const TYPE_OBJECT = 'object';
  50581. const TYPE_RESOURCE = 'resource';
  50582. const TYPE_STRING = 'string';
  50583. const TYPE_SCALAR = 'scalar';
  50584. const TYPE_CALLABLE = 'callable';
  50585. /**
  50586. * @var array
  50587. */
  50588. protected $types = array(
  50589. 'array' => true,
  50590. 'boolean' => true,
  50591. 'bool' => true,
  50592. 'double' => true,
  50593. 'float' => true,
  50594. 'integer' => true,
  50595. 'int' => true,
  50596. 'null' => true,
  50597. 'numeric' => true,
  50598. 'object' => true,
  50599. 'real' => true,
  50600. 'resource' => true,
  50601. 'string' => true,
  50602. 'scalar' => true,
  50603. 'callable' => true
  50604. );
  50605. /**
  50606. * @var string
  50607. */
  50608. protected $type;
  50609. /**
  50610. * @param string $type
  50611. * @throws PHPUnit_Framework_Exception
  50612. */
  50613. public function __construct($type)
  50614. {
  50615. parent::__construct();
  50616. if (!isset($this->types[$type])) {
  50617. throw new PHPUnit_Framework_Exception(
  50618. sprintf(
  50619. 'Type specified for PHPUnit_Framework_Constraint_IsType <%s> ' .
  50620. 'is not a valid type.',
  50621. $type
  50622. )
  50623. );
  50624. }
  50625. $this->type = $type;
  50626. }
  50627. /**
  50628. * Evaluates the constraint for parameter $other. Returns true if the
  50629. * constraint is met, false otherwise.
  50630. *
  50631. * @param mixed $other Value or object to evaluate.
  50632. * @return bool
  50633. */
  50634. protected function matches($other)
  50635. {
  50636. switch ($this->type) {
  50637. case 'numeric':
  50638. return is_numeric($other);
  50639. case 'integer':
  50640. case 'int':
  50641. return is_integer($other);
  50642. case 'double':
  50643. case 'float':
  50644. case 'real':
  50645. return is_float($other);
  50646. case 'string':
  50647. return is_string($other);
  50648. case 'boolean':
  50649. case 'bool':
  50650. return is_bool($other);
  50651. case 'null':
  50652. return is_null($other);
  50653. case 'array':
  50654. return is_array($other);
  50655. case 'object':
  50656. return is_object($other);
  50657. case 'resource':
  50658. return is_resource($other) || is_string(@get_resource_type($other));
  50659. case 'scalar':
  50660. return is_scalar($other);
  50661. case 'callable':
  50662. return is_callable($other);
  50663. }
  50664. }
  50665. /**
  50666. * Returns a string representation of the constraint.
  50667. *
  50668. * @return string
  50669. */
  50670. public function toString()
  50671. {
  50672. return sprintf(
  50673. 'is of type "%s"',
  50674. $this->type
  50675. );
  50676. }
  50677. }
  50678. <?php
  50679. /*
  50680. * This file is part of PHPUnit.
  50681. *
  50682. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50683. *
  50684. * For the full copyright and license information, please view the LICENSE
  50685. * file that was distributed with this source code.
  50686. */
  50687. /**
  50688. * Constraint that asserts that the value it is evaluated for is less than
  50689. * a given value.
  50690. *
  50691. * @since Class available since Release 3.0.0
  50692. */
  50693. class PHPUnit_Framework_Constraint_LessThan extends PHPUnit_Framework_Constraint
  50694. {
  50695. /**
  50696. * @var numeric
  50697. */
  50698. protected $value;
  50699. /**
  50700. * @param numeric $value
  50701. */
  50702. public function __construct($value)
  50703. {
  50704. parent::__construct();
  50705. $this->value = $value;
  50706. }
  50707. /**
  50708. * Evaluates the constraint for parameter $other. Returns true if the
  50709. * constraint is met, false otherwise.
  50710. *
  50711. * @param mixed $other Value or object to evaluate.
  50712. * @return bool
  50713. */
  50714. protected function matches($other)
  50715. {
  50716. return $this->value > $other;
  50717. }
  50718. /**
  50719. * Returns a string representation of the constraint.
  50720. *
  50721. * @return string
  50722. */
  50723. public function toString()
  50724. {
  50725. return 'is less than ' . $this->exporter->export($this->value);
  50726. }
  50727. }
  50728. <?php
  50729. /*
  50730. * This file is part of PHPUnit.
  50731. *
  50732. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50733. *
  50734. * For the full copyright and license information, please view the LICENSE
  50735. * file that was distributed with this source code.
  50736. */
  50737. /**
  50738. * Constraint that asserts that the array it is evaluated for has a specified subset.
  50739. *
  50740. * Uses array_replace_recursive() to check if a key value subset is part of the
  50741. * subject array.
  50742. *
  50743. * @since Class available since Release 4.4.0
  50744. */
  50745. class PHPUnit_Framework_Constraint_ArraySubset extends PHPUnit_Framework_Constraint
  50746. {
  50747. /**
  50748. * @var array|ArrayAccess
  50749. */
  50750. protected $subset;
  50751. /**
  50752. * @var bool
  50753. */
  50754. protected $strict;
  50755. /**
  50756. * @param array|ArrayAccess $subset
  50757. * @param bool $strict Check for object identity
  50758. */
  50759. public function __construct($subset, $strict = false)
  50760. {
  50761. parent::__construct();
  50762. $this->strict = $strict;
  50763. $this->subset = $subset;
  50764. }
  50765. /**
  50766. * Evaluates the constraint for parameter $other. Returns true if the
  50767. * constraint is met, false otherwise.
  50768. *
  50769. * @param array|ArrayAccess $other Array or ArrayAccess object to evaluate.
  50770. * @return bool
  50771. */
  50772. protected function matches($other)
  50773. {
  50774. $patched = array_replace_recursive($other, $this->subset);
  50775. if ($this->strict) {
  50776. return $other === $patched;
  50777. } else {
  50778. return $other == $patched;
  50779. }
  50780. }
  50781. /**
  50782. * Returns a string representation of the constraint.
  50783. *
  50784. * @return string
  50785. */
  50786. public function toString()
  50787. {
  50788. return 'has the subset ' . $this->exporter->export($this->subset);
  50789. }
  50790. /**
  50791. * Returns the description of the failure
  50792. *
  50793. * The beginning of failure messages is "Failed asserting that" in most
  50794. * cases. This method should return the second part of that sentence.
  50795. *
  50796. * @param mixed $other Evaluated value or object.
  50797. * @return string
  50798. */
  50799. protected function failureDescription($other)
  50800. {
  50801. return 'an array ' . $this->toString();
  50802. }
  50803. }
  50804. <?php
  50805. /*
  50806. * This file is part of PHPUnit.
  50807. *
  50808. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50809. *
  50810. * For the full copyright and license information, please view the LICENSE
  50811. * file that was distributed with this source code.
  50812. */
  50813. /**
  50814. * Constraint that accepts true.
  50815. *
  50816. * @since Class available since Release 3.3.0
  50817. */
  50818. class PHPUnit_Framework_Constraint_IsTrue extends PHPUnit_Framework_Constraint
  50819. {
  50820. /**
  50821. * Evaluates the constraint for parameter $other. Returns true if the
  50822. * constraint is met, false otherwise.
  50823. *
  50824. * @param mixed $other Value or object to evaluate.
  50825. * @return bool
  50826. */
  50827. protected function matches($other)
  50828. {
  50829. return $other === true;
  50830. }
  50831. /**
  50832. * Returns a string representation of the constraint.
  50833. *
  50834. * @return string
  50835. */
  50836. public function toString()
  50837. {
  50838. return 'is true';
  50839. }
  50840. }
  50841. <?php
  50842. /*
  50843. * This file is part of PHPUnit.
  50844. *
  50845. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50846. *
  50847. * For the full copyright and license information, please view the LICENSE
  50848. * file that was distributed with this source code.
  50849. */
  50850. /**
  50851. * Constraint that asserts that a string is valid JSON.
  50852. *
  50853. * @since Class available since Release 3.7.20
  50854. */
  50855. class PHPUnit_Framework_Constraint_IsJson extends PHPUnit_Framework_Constraint
  50856. {
  50857. /**
  50858. * Evaluates the constraint for parameter $other. Returns true if the
  50859. * constraint is met, false otherwise.
  50860. *
  50861. * @param mixed $other Value or object to evaluate.
  50862. * @return bool
  50863. */
  50864. protected function matches($other)
  50865. {
  50866. json_decode($other);
  50867. if (json_last_error()) {
  50868. return false;
  50869. }
  50870. return true;
  50871. }
  50872. /**
  50873. * Returns the description of the failure
  50874. *
  50875. * The beginning of failure messages is "Failed asserting that" in most
  50876. * cases. This method should return the second part of that sentence.
  50877. *
  50878. * @param mixed $other Evaluated value or object.
  50879. * @return string
  50880. */
  50881. protected function failureDescription($other)
  50882. {
  50883. json_decode($other);
  50884. $error = PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider::determineJsonError(
  50885. json_last_error()
  50886. );
  50887. return sprintf(
  50888. '%s is valid JSON (%s)',
  50889. $this->exporter->shortenedExport($other),
  50890. $error
  50891. );
  50892. }
  50893. /**
  50894. * Returns a string representation of the constraint.
  50895. *
  50896. * @return string
  50897. */
  50898. public function toString()
  50899. {
  50900. return 'is valid JSON';
  50901. }
  50902. }
  50903. <?php
  50904. /*
  50905. * This file is part of PHPUnit.
  50906. *
  50907. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  50908. *
  50909. * For the full copyright and license information, please view the LICENSE
  50910. * file that was distributed with this source code.
  50911. */
  50912. /**
  50913. * Constraint that checks if one value is equal to another.
  50914. *
  50915. * Equality is checked with PHP's == operator, the operator is explained in
  50916. * detail at {@url http://www.php.net/manual/en/types.comparisons.php}.
  50917. * Two values are equal if they have the same value disregarding type.
  50918. *
  50919. * The expected value is passed in the constructor.
  50920. *
  50921. * @since Class available since Release 3.0.0
  50922. */
  50923. class PHPUnit_Framework_Constraint_IsEqual extends PHPUnit_Framework_Constraint
  50924. {
  50925. /**
  50926. * @var mixed
  50927. */
  50928. protected $value;
  50929. /**
  50930. * @var float
  50931. */
  50932. protected $delta = 0.0;
  50933. /**
  50934. * @var int
  50935. */
  50936. protected $maxDepth = 10;
  50937. /**
  50938. * @var bool
  50939. */
  50940. protected $canonicalize = false;
  50941. /**
  50942. * @var bool
  50943. */
  50944. protected $ignoreCase = false;
  50945. /**
  50946. * @var SebastianBergmann\Comparator\ComparisonFailure
  50947. */
  50948. protected $lastFailure;
  50949. /**
  50950. * @param mixed $value
  50951. * @param float $delta
  50952. * @param int $maxDepth
  50953. * @param bool $canonicalize
  50954. * @param bool $ignoreCase
  50955. * @throws PHPUnit_Framework_Exception
  50956. */
  50957. public function __construct($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
  50958. {
  50959. parent::__construct();
  50960. if (!is_numeric($delta)) {
  50961. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'numeric');
  50962. }
  50963. if (!is_int($maxDepth)) {
  50964. throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'integer');
  50965. }
  50966. if (!is_bool($canonicalize)) {
  50967. throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'boolean');
  50968. }
  50969. if (!is_bool($ignoreCase)) {
  50970. throw PHPUnit_Util_InvalidArgumentHelper::factory(5, 'boolean');
  50971. }
  50972. $this->value = $value;
  50973. $this->delta = $delta;
  50974. $this->maxDepth = $maxDepth;
  50975. $this->canonicalize = $canonicalize;
  50976. $this->ignoreCase = $ignoreCase;
  50977. }
  50978. /**
  50979. * Evaluates the constraint for parameter $other
  50980. *
  50981. * If $returnResult is set to false (the default), an exception is thrown
  50982. * in case of a failure. null is returned otherwise.
  50983. *
  50984. * If $returnResult is true, the result of the evaluation is returned as
  50985. * a boolean value instead: true in case of success, false in case of a
  50986. * failure.
  50987. *
  50988. * @param mixed $other Value or object to evaluate.
  50989. * @param string $description Additional information about the test
  50990. * @param bool $returnResult Whether to return a result or throw an exception
  50991. * @return mixed
  50992. * @throws PHPUnit_Framework_ExpectationFailedException
  50993. */
  50994. public function evaluate($other, $description = '', $returnResult = false)
  50995. {
  50996. // If $this->value and $other are identical, they are also equal.
  50997. // This is the most common path and will allow us to skip
  50998. // initialization of all the comparators.
  50999. if ($this->value === $other) {
  51000. return true;
  51001. }
  51002. $comparatorFactory = SebastianBergmann\Comparator\Factory::getInstance();
  51003. try {
  51004. $comparator = $comparatorFactory->getComparatorFor(
  51005. $this->value,
  51006. $other
  51007. );
  51008. $comparator->assertEquals(
  51009. $this->value,
  51010. $other,
  51011. $this->delta,
  51012. $this->canonicalize,
  51013. $this->ignoreCase
  51014. );
  51015. } catch (SebastianBergmann\Comparator\ComparisonFailure $f) {
  51016. if ($returnResult) {
  51017. return false;
  51018. }
  51019. throw new PHPUnit_Framework_ExpectationFailedException(
  51020. trim($description . "\n" . $f->getMessage()),
  51021. $f
  51022. );
  51023. }
  51024. return true;
  51025. }
  51026. /**
  51027. * Returns a string representation of the constraint.
  51028. *
  51029. * @return string
  51030. */
  51031. public function toString()
  51032. {
  51033. $delta = '';
  51034. if (is_string($this->value)) {
  51035. if (strpos($this->value, "\n") !== false) {
  51036. return 'is equal to <text>';
  51037. } else {
  51038. return sprintf(
  51039. 'is equal to <string:%s>',
  51040. $this->value
  51041. );
  51042. }
  51043. } else {
  51044. if ($this->delta != 0) {
  51045. $delta = sprintf(
  51046. ' with delta <%F>',
  51047. $this->delta
  51048. );
  51049. }
  51050. return sprintf(
  51051. 'is equal to %s%s',
  51052. $this->exporter->export($this->value),
  51053. $delta
  51054. );
  51055. }
  51056. }
  51057. }
  51058. <?php
  51059. /*
  51060. * This file is part of PHPUnit.
  51061. *
  51062. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51063. *
  51064. * For the full copyright and license information, please view the LICENSE
  51065. * file that was distributed with this source code.
  51066. */
  51067. /**
  51068. * Logical XOR.
  51069. *
  51070. * @since Class available since Release 3.0.0
  51071. */
  51072. class PHPUnit_Framework_Constraint_Xor extends PHPUnit_Framework_Constraint
  51073. {
  51074. /**
  51075. * @var PHPUnit_Framework_Constraint[]
  51076. */
  51077. protected $constraints = array();
  51078. /**
  51079. * @param PHPUnit_Framework_Constraint[] $constraints
  51080. */
  51081. public function setConstraints(array $constraints)
  51082. {
  51083. $this->constraints = array();
  51084. foreach ($constraints as $constraint) {
  51085. if (!($constraint instanceof PHPUnit_Framework_Constraint)) {
  51086. $constraint = new PHPUnit_Framework_Constraint_IsEqual(
  51087. $constraint
  51088. );
  51089. }
  51090. $this->constraints[] = $constraint;
  51091. }
  51092. }
  51093. /**
  51094. * Evaluates the constraint for parameter $other
  51095. *
  51096. * If $returnResult is set to false (the default), an exception is thrown
  51097. * in case of a failure. null is returned otherwise.
  51098. *
  51099. * If $returnResult is true, the result of the evaluation is returned as
  51100. * a boolean value instead: true in case of success, false in case of a
  51101. * failure.
  51102. *
  51103. * @param mixed $other Value or object to evaluate.
  51104. * @param string $description Additional information about the test
  51105. * @param bool $returnResult Whether to return a result or throw an exception
  51106. * @return mixed
  51107. * @throws PHPUnit_Framework_ExpectationFailedException
  51108. */
  51109. public function evaluate($other, $description = '', $returnResult = false)
  51110. {
  51111. $success = true;
  51112. $lastResult = null;
  51113. $constraint = null;
  51114. foreach ($this->constraints as $constraint) {
  51115. $result = $constraint->evaluate($other, $description, true);
  51116. if ($result === $lastResult) {
  51117. $success = false;
  51118. break;
  51119. }
  51120. $lastResult = $result;
  51121. }
  51122. if ($returnResult) {
  51123. return $success;
  51124. }
  51125. if (!$success) {
  51126. $this->fail($other, $description);
  51127. }
  51128. }
  51129. /**
  51130. * Returns a string representation of the constraint.
  51131. *
  51132. * @return string
  51133. */
  51134. public function toString()
  51135. {
  51136. $text = '';
  51137. foreach ($this->constraints as $key => $constraint) {
  51138. if ($key > 0) {
  51139. $text .= ' xor ';
  51140. }
  51141. $text .= $constraint->toString();
  51142. }
  51143. return $text;
  51144. }
  51145. /**
  51146. * Counts the number of constraint elements.
  51147. *
  51148. * @return int
  51149. * @since Method available since Release 3.4.0
  51150. */
  51151. public function count()
  51152. {
  51153. $count = 0;
  51154. foreach ($this->constraints as $constraint) {
  51155. $count += count($constraint);
  51156. }
  51157. return $count;
  51158. }
  51159. }
  51160. <?php
  51161. /*
  51162. * This file is part of PHPUnit.
  51163. *
  51164. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51165. *
  51166. * For the full copyright and license information, please view the LICENSE
  51167. * file that was distributed with this source code.
  51168. */
  51169. /**
  51170. * Provides human readable messages for each JSON error.
  51171. *
  51172. * @since Class available since Release 3.7.0
  51173. */
  51174. class PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider
  51175. {
  51176. /**
  51177. * Translates JSON error to a human readable string.
  51178. *
  51179. * @param string $error
  51180. * @param string $prefix
  51181. * @return string
  51182. */
  51183. public static function determineJsonError($error, $prefix = '')
  51184. {
  51185. switch ($error) {
  51186. case JSON_ERROR_NONE:
  51187. return;
  51188. case JSON_ERROR_DEPTH:
  51189. return $prefix . 'Maximum stack depth exceeded';
  51190. case JSON_ERROR_STATE_MISMATCH:
  51191. return $prefix . 'Underflow or the modes mismatch';
  51192. case JSON_ERROR_CTRL_CHAR:
  51193. return $prefix . 'Unexpected control character found';
  51194. case JSON_ERROR_SYNTAX:
  51195. return $prefix . 'Syntax error, malformed JSON';
  51196. case JSON_ERROR_UTF8:
  51197. return $prefix . 'Malformed UTF-8 characters, possibly incorrectly encoded';
  51198. default:
  51199. return $prefix . 'Unknown error';
  51200. }
  51201. }
  51202. /**
  51203. * Translates a given type to a human readable message prefix.
  51204. *
  51205. * @param string $type
  51206. * @return string
  51207. */
  51208. public static function translateTypeToPrefix($type)
  51209. {
  51210. switch (strtolower($type)) {
  51211. case 'expected':
  51212. $prefix = 'Expected value JSON decode error - ';
  51213. break;
  51214. case 'actual':
  51215. $prefix = 'Actual value JSON decode error - ';
  51216. break;
  51217. default:
  51218. $prefix = '';
  51219. break;
  51220. }
  51221. return $prefix;
  51222. }
  51223. }
  51224. <?php
  51225. /*
  51226. * This file is part of PHPUnit.
  51227. *
  51228. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51229. *
  51230. * For the full copyright and license information, please view the LICENSE
  51231. * file that was distributed with this source code.
  51232. */
  51233. use SebastianBergmann\Diff\Differ;
  51234. /**
  51235. * ...
  51236. *
  51237. * @since Class available since Release 3.5.0
  51238. */
  51239. class PHPUnit_Framework_Constraint_StringMatches extends PHPUnit_Framework_Constraint_PCREMatch
  51240. {
  51241. /**
  51242. * @var string
  51243. */
  51244. protected $string;
  51245. /**
  51246. * @param string $string
  51247. */
  51248. public function __construct($string)
  51249. {
  51250. parent::__construct($string);
  51251. $this->pattern = $this->createPatternFromFormat(
  51252. preg_replace('/\r\n/', "\n", $string)
  51253. );
  51254. $this->string = $string;
  51255. }
  51256. protected function failureDescription($other)
  51257. {
  51258. return 'format description matches text';
  51259. }
  51260. protected function additionalFailureDescription($other)
  51261. {
  51262. $from = preg_split('(\r\n|\r|\n)', $this->string);
  51263. $to = preg_split('(\r\n|\r|\n)', $other);
  51264. foreach ($from as $index => $line) {
  51265. if (isset($to[$index]) && $line !== $to[$index]) {
  51266. $line = $this->createPatternFromFormat($line);
  51267. if (preg_match($line, $to[$index]) > 0) {
  51268. $from[$index] = $to[$index];
  51269. }
  51270. }
  51271. }
  51272. $this->string = implode("\n", $from);
  51273. $other = implode("\n", $to);
  51274. $differ = new Differ("--- Expected\n+++ Actual\n");
  51275. return $differ->diff($this->string, $other);
  51276. }
  51277. protected function createPatternFromFormat($string)
  51278. {
  51279. $string = str_replace(
  51280. array(
  51281. '%e',
  51282. '%s',
  51283. '%S',
  51284. '%a',
  51285. '%A',
  51286. '%w',
  51287. '%i',
  51288. '%d',
  51289. '%x',
  51290. '%f',
  51291. '%c'
  51292. ),
  51293. array(
  51294. '\\' . DIRECTORY_SEPARATOR,
  51295. '[^\r\n]+',
  51296. '[^\r\n]*',
  51297. '.+',
  51298. '.*',
  51299. '\s*',
  51300. '[+-]?\d+',
  51301. '\d+',
  51302. '[0-9a-fA-F]+',
  51303. '[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?',
  51304. '.'
  51305. ),
  51306. preg_quote($string, '/')
  51307. );
  51308. return '/^' . $string . '$/s';
  51309. }
  51310. }
  51311. <?php
  51312. /*
  51313. * This file is part of PHPUnit.
  51314. *
  51315. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51316. *
  51317. * For the full copyright and license information, please view the LICENSE
  51318. * file that was distributed with this source code.
  51319. */
  51320. /**
  51321. * Logical NOT.
  51322. *
  51323. * @since Class available since Release 3.0.0
  51324. */
  51325. class PHPUnit_Framework_Constraint_Not extends PHPUnit_Framework_Constraint
  51326. {
  51327. /**
  51328. * @var PHPUnit_Framework_Constraint
  51329. */
  51330. protected $constraint;
  51331. /**
  51332. * @param PHPUnit_Framework_Constraint $constraint
  51333. */
  51334. public function __construct($constraint)
  51335. {
  51336. parent::__construct();
  51337. if (!($constraint instanceof PHPUnit_Framework_Constraint)) {
  51338. $constraint = new PHPUnit_Framework_Constraint_IsEqual($constraint);
  51339. }
  51340. $this->constraint = $constraint;
  51341. }
  51342. /**
  51343. * @param string $string
  51344. * @return string
  51345. */
  51346. public static function negate($string)
  51347. {
  51348. return str_replace(
  51349. array(
  51350. 'contains ',
  51351. 'exists',
  51352. 'has ',
  51353. 'is ',
  51354. 'are ',
  51355. 'matches ',
  51356. 'starts with ',
  51357. 'ends with ',
  51358. 'reference ',
  51359. 'not not '
  51360. ),
  51361. array(
  51362. 'does not contain ',
  51363. 'does not exist',
  51364. 'does not have ',
  51365. 'is not ',
  51366. 'are not ',
  51367. 'does not match ',
  51368. 'starts not with ',
  51369. 'ends not with ',
  51370. 'don\'t reference ',
  51371. 'not '
  51372. ),
  51373. $string
  51374. );
  51375. }
  51376. /**
  51377. * Evaluates the constraint for parameter $other
  51378. *
  51379. * If $returnResult is set to false (the default), an exception is thrown
  51380. * in case of a failure. null is returned otherwise.
  51381. *
  51382. * If $returnResult is true, the result of the evaluation is returned as
  51383. * a boolean value instead: true in case of success, false in case of a
  51384. * failure.
  51385. *
  51386. * @param mixed $other Value or object to evaluate.
  51387. * @param string $description Additional information about the test
  51388. * @param bool $returnResult Whether to return a result or throw an exception
  51389. * @return mixed
  51390. * @throws PHPUnit_Framework_ExpectationFailedException
  51391. */
  51392. public function evaluate($other, $description = '', $returnResult = false)
  51393. {
  51394. $success = !$this->constraint->evaluate($other, $description, true);
  51395. if ($returnResult) {
  51396. return $success;
  51397. }
  51398. if (!$success) {
  51399. $this->fail($other, $description);
  51400. }
  51401. }
  51402. /**
  51403. * Returns the description of the failure
  51404. *
  51405. * The beginning of failure messages is "Failed asserting that" in most
  51406. * cases. This method should return the second part of that sentence.
  51407. *
  51408. * @param mixed $other Evaluated value or object.
  51409. * @return string
  51410. */
  51411. protected function failureDescription($other)
  51412. {
  51413. switch (get_class($this->constraint)) {
  51414. case 'PHPUnit_Framework_Constraint_And':
  51415. case 'PHPUnit_Framework_Constraint_Not':
  51416. case 'PHPUnit_Framework_Constraint_Or':
  51417. return 'not( ' . $this->constraint->failureDescription($other) . ' )';
  51418. default:
  51419. return self::negate(
  51420. $this->constraint->failureDescription($other)
  51421. );
  51422. }
  51423. }
  51424. /**
  51425. * Returns a string representation of the constraint.
  51426. *
  51427. * @return string
  51428. */
  51429. public function toString()
  51430. {
  51431. switch (get_class($this->constraint)) {
  51432. case 'PHPUnit_Framework_Constraint_And':
  51433. case 'PHPUnit_Framework_Constraint_Not':
  51434. case 'PHPUnit_Framework_Constraint_Or':
  51435. return 'not( ' . $this->constraint->toString() . ' )';
  51436. default:
  51437. return self::negate(
  51438. $this->constraint->toString()
  51439. );
  51440. }
  51441. }
  51442. /**
  51443. * Counts the number of constraint elements.
  51444. *
  51445. * @return int
  51446. * @since Method available since Release 3.4.0
  51447. */
  51448. public function count()
  51449. {
  51450. return count($this->constraint);
  51451. }
  51452. }
  51453. <?php
  51454. /*
  51455. * This file is part of PHPUnit.
  51456. *
  51457. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51458. *
  51459. * For the full copyright and license information, please view the LICENSE
  51460. * file that was distributed with this source code.
  51461. */
  51462. /**
  51463. * @since Class available since Release 4.3.0
  51464. */
  51465. class PHPUnit_Framework_Constraint_ExceptionMessageRegExp extends PHPUnit_Framework_Constraint
  51466. {
  51467. /**
  51468. * @var int
  51469. */
  51470. protected $expectedMessageRegExp;
  51471. /**
  51472. * @param string $expected
  51473. */
  51474. public function __construct($expected)
  51475. {
  51476. parent::__construct();
  51477. $this->expectedMessageRegExp = $expected;
  51478. }
  51479. /**
  51480. * Evaluates the constraint for parameter $other. Returns true if the
  51481. * constraint is met, false otherwise.
  51482. *
  51483. * @param Exception $other
  51484. * @return bool
  51485. */
  51486. protected function matches($other)
  51487. {
  51488. $match = PHPUnit_Util_Regex::pregMatchSafe($this->expectedMessageRegExp, $other->getMessage());
  51489. if (false === $match) {
  51490. throw new PHPUnit_Framework_Exception(
  51491. "Invalid expected exception message regex given: '{$this->expectedMessageRegExp}'"
  51492. );
  51493. }
  51494. return 1 === $match;
  51495. }
  51496. /**
  51497. * Returns the description of the failure
  51498. *
  51499. * The beginning of failure messages is "Failed asserting that" in most
  51500. * cases. This method should return the second part of that sentence.
  51501. *
  51502. * @param mixed $other Evaluated value or object.
  51503. * @return string
  51504. */
  51505. protected function failureDescription($other)
  51506. {
  51507. return sprintf(
  51508. "exception message '%s' matches '%s'",
  51509. $other->getMessage(),
  51510. $this->expectedMessageRegExp
  51511. );
  51512. }
  51513. /**
  51514. * @return string
  51515. */
  51516. public function toString()
  51517. {
  51518. return 'exception message matches ';
  51519. }
  51520. }
  51521. <?php
  51522. /*
  51523. * This file is part of PHPUnit.
  51524. *
  51525. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51526. *
  51527. * For the full copyright and license information, please view the LICENSE
  51528. * file that was distributed with this source code.
  51529. */
  51530. /**
  51531. * Constraint that asserts that the value it is evaluated for is greater
  51532. * than a given value.
  51533. *
  51534. * @since Class available since Release 3.0.0
  51535. */
  51536. class PHPUnit_Framework_Constraint_GreaterThan extends PHPUnit_Framework_Constraint
  51537. {
  51538. /**
  51539. * @var numeric
  51540. */
  51541. protected $value;
  51542. /**
  51543. * @param numeric $value
  51544. */
  51545. public function __construct($value)
  51546. {
  51547. parent::__construct();
  51548. $this->value = $value;
  51549. }
  51550. /**
  51551. * Evaluates the constraint for parameter $other. Returns true if the
  51552. * constraint is met, false otherwise.
  51553. *
  51554. * @param mixed $other Value or object to evaluate.
  51555. * @return bool
  51556. */
  51557. protected function matches($other)
  51558. {
  51559. return $this->value < $other;
  51560. }
  51561. /**
  51562. * Returns a string representation of the constraint.
  51563. *
  51564. * @return string
  51565. */
  51566. public function toString()
  51567. {
  51568. return 'is greater than ' . $this->exporter->export($this->value);
  51569. }
  51570. }
  51571. <?php
  51572. /*
  51573. * This file is part of PHPUnit.
  51574. *
  51575. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51576. *
  51577. * For the full copyright and license information, please view the LICENSE
  51578. * file that was distributed with this source code.
  51579. */
  51580. /**
  51581. * @since Class available since Release 3.6.6
  51582. */
  51583. class PHPUnit_Framework_Constraint_ExceptionMessage extends PHPUnit_Framework_Constraint
  51584. {
  51585. /**
  51586. * @var int
  51587. */
  51588. protected $expectedMessage;
  51589. /**
  51590. * @param string $expected
  51591. */
  51592. public function __construct($expected)
  51593. {
  51594. parent::__construct();
  51595. $this->expectedMessage = $expected;
  51596. }
  51597. /**
  51598. * Evaluates the constraint for parameter $other. Returns true if the
  51599. * constraint is met, false otherwise.
  51600. *
  51601. * @param Exception $other
  51602. * @return bool
  51603. */
  51604. protected function matches($other)
  51605. {
  51606. return strpos($other->getMessage(), $this->expectedMessage) !== false;
  51607. }
  51608. /**
  51609. * Returns the description of the failure
  51610. *
  51611. * The beginning of failure messages is "Failed asserting that" in most
  51612. * cases. This method should return the second part of that sentence.
  51613. *
  51614. * @param mixed $other Evaluated value or object.
  51615. * @return string
  51616. */
  51617. protected function failureDescription($other)
  51618. {
  51619. return sprintf(
  51620. "exception message '%s' contains '%s'",
  51621. $other->getMessage(),
  51622. $this->expectedMessage
  51623. );
  51624. }
  51625. /**
  51626. * @return string
  51627. */
  51628. public function toString()
  51629. {
  51630. return 'exception message contains ';
  51631. }
  51632. }
  51633. <?php
  51634. /*
  51635. * This file is part of PHPUnit.
  51636. *
  51637. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51638. *
  51639. * For the full copyright and license information, please view the LICENSE
  51640. * file that was distributed with this source code.
  51641. */
  51642. /**
  51643. * Constraint that evaluates against a specified closure.
  51644. */
  51645. class PHPUnit_Framework_Constraint_Callback extends PHPUnit_Framework_Constraint
  51646. {
  51647. private $callback;
  51648. /**
  51649. * @param callable $callback
  51650. * @throws PHPUnit_Framework_Exception
  51651. */
  51652. public function __construct($callback)
  51653. {
  51654. if (!is_callable($callback)) {
  51655. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  51656. 1,
  51657. 'callable'
  51658. );
  51659. }
  51660. parent::__construct();
  51661. $this->callback = $callback;
  51662. }
  51663. /**
  51664. * Evaluates the constraint for parameter $value. Returns true if the
  51665. * constraint is met, false otherwise.
  51666. *
  51667. * @param mixed $other Value or object to evaluate.
  51668. * @return bool
  51669. */
  51670. protected function matches($other)
  51671. {
  51672. return call_user_func($this->callback, $other);
  51673. }
  51674. /**
  51675. * Returns a string representation of the constraint.
  51676. *
  51677. * @return string
  51678. */
  51679. public function toString()
  51680. {
  51681. return 'is accepted by specified callback';
  51682. }
  51683. }
  51684. <?php
  51685. /*
  51686. * This file is part of PHPUnit.
  51687. *
  51688. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51689. *
  51690. * For the full copyright and license information, please view the LICENSE
  51691. * file that was distributed with this source code.
  51692. */
  51693. /**
  51694. * Constraint that asserts that the array it is evaluated for has a given key.
  51695. *
  51696. * Uses array_key_exists() to check if the key is found in the input array, if
  51697. * not found the evaluation fails.
  51698. *
  51699. * The array key is passed in the constructor.
  51700. *
  51701. * @since Class available since Release 3.0.0
  51702. */
  51703. class PHPUnit_Framework_Constraint_ArrayHasKey extends PHPUnit_Framework_Constraint
  51704. {
  51705. /**
  51706. * @var int|string
  51707. */
  51708. protected $key;
  51709. /**
  51710. * @param int|string $key
  51711. */
  51712. public function __construct($key)
  51713. {
  51714. parent::__construct();
  51715. $this->key = $key;
  51716. }
  51717. /**
  51718. * Evaluates the constraint for parameter $other. Returns true if the
  51719. * constraint is met, false otherwise.
  51720. *
  51721. * @param mixed $other Value or object to evaluate.
  51722. * @return bool
  51723. */
  51724. protected function matches($other)
  51725. {
  51726. if (is_array($other)) {
  51727. return array_key_exists($this->key, $other);
  51728. }
  51729. if ($other instanceof ArrayAccess) {
  51730. return $other->offsetExists($this->key);
  51731. }
  51732. return false;
  51733. }
  51734. /**
  51735. * Returns a string representation of the constraint.
  51736. *
  51737. * @return string
  51738. */
  51739. public function toString()
  51740. {
  51741. return 'has the key ' . $this->exporter->export($this->key);
  51742. }
  51743. /**
  51744. * Returns the description of the failure
  51745. *
  51746. * The beginning of failure messages is "Failed asserting that" in most
  51747. * cases. This method should return the second part of that sentence.
  51748. *
  51749. * @param mixed $other Evaluated value or object.
  51750. * @return string
  51751. */
  51752. protected function failureDescription($other)
  51753. {
  51754. return 'an array ' . $this->toString();
  51755. }
  51756. }
  51757. <?php
  51758. /*
  51759. * This file is part of PHPUnit.
  51760. *
  51761. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51762. *
  51763. * For the full copyright and license information, please view the LICENSE
  51764. * file that was distributed with this source code.
  51765. */
  51766. /**
  51767. * Constraint that asserts that the string it is evaluated for contains
  51768. * a given string.
  51769. *
  51770. * Uses strpos() to find the position of the string in the input, if not found
  51771. * the evaluation fails.
  51772. *
  51773. * The sub-string is passed in the constructor.
  51774. *
  51775. * @since Class available since Release 3.0.0
  51776. */
  51777. class PHPUnit_Framework_Constraint_StringContains extends PHPUnit_Framework_Constraint
  51778. {
  51779. /**
  51780. * @var string
  51781. */
  51782. protected $string;
  51783. /**
  51784. * @var bool
  51785. */
  51786. protected $ignoreCase;
  51787. /**
  51788. * @param string $string
  51789. * @param bool $ignoreCase
  51790. */
  51791. public function __construct($string, $ignoreCase = false)
  51792. {
  51793. parent::__construct();
  51794. $this->string = $string;
  51795. $this->ignoreCase = $ignoreCase;
  51796. }
  51797. /**
  51798. * Evaluates the constraint for parameter $other. Returns true if the
  51799. * constraint is met, false otherwise.
  51800. *
  51801. * @param mixed $other Value or object to evaluate.
  51802. * @return bool
  51803. */
  51804. protected function matches($other)
  51805. {
  51806. if ($this->ignoreCase) {
  51807. return stripos($other, $this->string) !== false;
  51808. } else {
  51809. return strpos($other, $this->string) !== false;
  51810. }
  51811. }
  51812. /**
  51813. * Returns a string representation of the constraint.
  51814. *
  51815. * @return string
  51816. */
  51817. public function toString()
  51818. {
  51819. if ($this->ignoreCase) {
  51820. $string = strtolower($this->string);
  51821. } else {
  51822. $string = $this->string;
  51823. }
  51824. return sprintf(
  51825. 'contains "%s"',
  51826. $string
  51827. );
  51828. }
  51829. }
  51830. <?php
  51831. /*
  51832. * This file is part of PHPUnit.
  51833. *
  51834. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51835. *
  51836. * For the full copyright and license information, please view the LICENSE
  51837. * file that was distributed with this source code.
  51838. */
  51839. /**
  51840. * Constraint that asserts that the Traversable it is applied to contains
  51841. * only values of a given type.
  51842. *
  51843. * @since Class available since Release 3.1.4
  51844. */
  51845. class PHPUnit_Framework_Constraint_TraversableContainsOnly extends PHPUnit_Framework_Constraint
  51846. {
  51847. /**
  51848. * @var PHPUnit_Framework_Constraint
  51849. */
  51850. protected $constraint;
  51851. /**
  51852. * @var string
  51853. */
  51854. protected $type;
  51855. /**
  51856. * @param string $type
  51857. * @param bool $isNativeType
  51858. */
  51859. public function __construct($type, $isNativeType = true)
  51860. {
  51861. parent::__construct();
  51862. if ($isNativeType) {
  51863. $this->constraint = new PHPUnit_Framework_Constraint_IsType($type);
  51864. } else {
  51865. $this->constraint = new PHPUnit_Framework_Constraint_IsInstanceOf(
  51866. $type
  51867. );
  51868. }
  51869. $this->type = $type;
  51870. }
  51871. /**
  51872. * Evaluates the constraint for parameter $other
  51873. *
  51874. * If $returnResult is set to false (the default), an exception is thrown
  51875. * in case of a failure. null is returned otherwise.
  51876. *
  51877. * If $returnResult is true, the result of the evaluation is returned as
  51878. * a boolean value instead: true in case of success, false in case of a
  51879. * failure.
  51880. *
  51881. * @param mixed $other Value or object to evaluate.
  51882. * @param string $description Additional information about the test
  51883. * @param bool $returnResult Whether to return a result or throw an exception
  51884. * @return mixed
  51885. * @throws PHPUnit_Framework_ExpectationFailedException
  51886. */
  51887. public function evaluate($other, $description = '', $returnResult = false)
  51888. {
  51889. $success = true;
  51890. foreach ($other as $item) {
  51891. if (!$this->constraint->evaluate($item, '', true)) {
  51892. $success = false;
  51893. break;
  51894. }
  51895. }
  51896. if ($returnResult) {
  51897. return $success;
  51898. }
  51899. if (!$success) {
  51900. $this->fail($other, $description);
  51901. }
  51902. }
  51903. /**
  51904. * Returns a string representation of the constraint.
  51905. *
  51906. * @return string
  51907. */
  51908. public function toString()
  51909. {
  51910. return 'contains only values of type "' . $this->type . '"';
  51911. }
  51912. }
  51913. <?php
  51914. /*
  51915. * This file is part of PHPUnit.
  51916. *
  51917. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51918. *
  51919. * For the full copyright and license information, please view the LICENSE
  51920. * file that was distributed with this source code.
  51921. */
  51922. /**
  51923. * Constraint that checks whether a variable is empty().
  51924. *
  51925. * @since Class available since Release 3.5.0
  51926. */
  51927. class PHPUnit_Framework_Constraint_IsEmpty extends PHPUnit_Framework_Constraint
  51928. {
  51929. /**
  51930. * Evaluates the constraint for parameter $other. Returns true if the
  51931. * constraint is met, false otherwise.
  51932. *
  51933. * @param mixed $other Value or object to evaluate.
  51934. * @return bool
  51935. */
  51936. protected function matches($other)
  51937. {
  51938. if ($other instanceof Countable) {
  51939. return count($other) === 0;
  51940. }
  51941. return empty($other);
  51942. }
  51943. /**
  51944. * Returns a string representation of the constraint.
  51945. *
  51946. * @return string
  51947. */
  51948. public function toString()
  51949. {
  51950. return 'is empty';
  51951. }
  51952. /**
  51953. * Returns the description of the failure
  51954. *
  51955. * The beginning of failure messages is "Failed asserting that" in most
  51956. * cases. This method should return the second part of that sentence.
  51957. *
  51958. * @param mixed $other Evaluated value or object.
  51959. * @return string
  51960. */
  51961. protected function failureDescription($other)
  51962. {
  51963. $type = gettype($other);
  51964. return sprintf(
  51965. '%s %s %s',
  51966. $type[0] == 'a' || $type[0] == 'o' ? 'an' : 'a',
  51967. $type,
  51968. $this->toString()
  51969. );
  51970. }
  51971. }
  51972. <?php
  51973. /*
  51974. * This file is part of PHPUnit.
  51975. *
  51976. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  51977. *
  51978. * For the full copyright and license information, please view the LICENSE
  51979. * file that was distributed with this source code.
  51980. */
  51981. /**
  51982. * Constraint that asserts that the string it is evaluated for matches
  51983. * a regular expression.
  51984. *
  51985. * Checks a given value using the Perl Compatible Regular Expression extension
  51986. * in PHP. The pattern is matched by executing preg_match().
  51987. *
  51988. * The pattern string passed in the constructor.
  51989. *
  51990. * @since Class available since Release 3.0.0
  51991. */
  51992. class PHPUnit_Framework_Constraint_PCREMatch extends PHPUnit_Framework_Constraint
  51993. {
  51994. /**
  51995. * @var string
  51996. */
  51997. protected $pattern;
  51998. /**
  51999. * @param string $pattern
  52000. */
  52001. public function __construct($pattern)
  52002. {
  52003. parent::__construct();
  52004. $this->pattern = $pattern;
  52005. }
  52006. /**
  52007. * Evaluates the constraint for parameter $other. Returns true if the
  52008. * constraint is met, false otherwise.
  52009. *
  52010. * @param mixed $other Value or object to evaluate.
  52011. * @return bool
  52012. */
  52013. protected function matches($other)
  52014. {
  52015. return preg_match($this->pattern, $other) > 0;
  52016. }
  52017. /**
  52018. * Returns a string representation of the constraint.
  52019. *
  52020. * @return string
  52021. */
  52022. public function toString()
  52023. {
  52024. return sprintf(
  52025. 'matches PCRE pattern "%s"',
  52026. $this->pattern
  52027. );
  52028. }
  52029. }
  52030. <?php
  52031. /*
  52032. * This file is part of PHPUnit.
  52033. *
  52034. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52035. *
  52036. * For the full copyright and license information, please view the LICENSE
  52037. * file that was distributed with this source code.
  52038. */
  52039. /**
  52040. * Constraint that accepts null.
  52041. *
  52042. * @since Class available since Release 3.3.0
  52043. */
  52044. class PHPUnit_Framework_Constraint_IsNull extends PHPUnit_Framework_Constraint
  52045. {
  52046. /**
  52047. * Evaluates the constraint for parameter $other. Returns true if the
  52048. * constraint is met, false otherwise.
  52049. *
  52050. * @param mixed $other Value or object to evaluate.
  52051. * @return bool
  52052. */
  52053. protected function matches($other)
  52054. {
  52055. return $other === null;
  52056. }
  52057. /**
  52058. * Returns a string representation of the constraint.
  52059. *
  52060. * @return string
  52061. */
  52062. public function toString()
  52063. {
  52064. return 'is null';
  52065. }
  52066. }
  52067. <?php
  52068. /*
  52069. * This file is part of PHPUnit.
  52070. *
  52071. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52072. *
  52073. * For the full copyright and license information, please view the LICENSE
  52074. * file that was distributed with this source code.
  52075. */
  52076. /**
  52077. * @since Class available since Release 3.1.0
  52078. */
  52079. class PHPUnit_Framework_Constraint_Attribute extends PHPUnit_Framework_Constraint_Composite
  52080. {
  52081. /**
  52082. * @var string
  52083. */
  52084. protected $attributeName;
  52085. /**
  52086. * @param PHPUnit_Framework_Constraint $constraint
  52087. * @param string $attributeName
  52088. */
  52089. public function __construct(PHPUnit_Framework_Constraint $constraint, $attributeName)
  52090. {
  52091. parent::__construct($constraint);
  52092. $this->attributeName = $attributeName;
  52093. }
  52094. /**
  52095. * Evaluates the constraint for parameter $other
  52096. *
  52097. * If $returnResult is set to false (the default), an exception is thrown
  52098. * in case of a failure. null is returned otherwise.
  52099. *
  52100. * If $returnResult is true, the result of the evaluation is returned as
  52101. * a boolean value instead: true in case of success, false in case of a
  52102. * failure.
  52103. *
  52104. * @param mixed $other Value or object to evaluate.
  52105. * @param string $description Additional information about the test
  52106. * @param bool $returnResult Whether to return a result or throw an exception
  52107. * @return mixed
  52108. * @throws PHPUnit_Framework_ExpectationFailedException
  52109. */
  52110. public function evaluate($other, $description = '', $returnResult = false)
  52111. {
  52112. return parent::evaluate(
  52113. PHPUnit_Framework_Assert::readAttribute(
  52114. $other,
  52115. $this->attributeName
  52116. ),
  52117. $description,
  52118. $returnResult
  52119. );
  52120. }
  52121. /**
  52122. * Returns a string representation of the constraint.
  52123. *
  52124. * @return string
  52125. */
  52126. public function toString()
  52127. {
  52128. return 'attribute "' . $this->attributeName . '" ' .
  52129. $this->innerConstraint->toString();
  52130. }
  52131. /**
  52132. * Returns the description of the failure
  52133. *
  52134. * The beginning of failure messages is "Failed asserting that" in most
  52135. * cases. This method should return the second part of that sentence.
  52136. *
  52137. * @param mixed $other Evaluated value or object.
  52138. * @return string
  52139. */
  52140. protected function failureDescription($other)
  52141. {
  52142. return $this->toString();
  52143. }
  52144. }
  52145. <?php
  52146. /*
  52147. * This file is part of PHPUnit.
  52148. *
  52149. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52150. *
  52151. * For the full copyright and license information, please view the LICENSE
  52152. * file that was distributed with this source code.
  52153. */
  52154. /**
  52155. * Constraint that accepts false.
  52156. *
  52157. * @since Class available since Release 3.3.0
  52158. */
  52159. class PHPUnit_Framework_Constraint_IsFalse extends PHPUnit_Framework_Constraint
  52160. {
  52161. /**
  52162. * Evaluates the constraint for parameter $other. Returns true if the
  52163. * constraint is met, false otherwise.
  52164. *
  52165. * @param mixed $other Value or object to evaluate.
  52166. * @return bool
  52167. */
  52168. protected function matches($other)
  52169. {
  52170. return $other === false;
  52171. }
  52172. /**
  52173. * Returns a string representation of the constraint.
  52174. *
  52175. * @return string
  52176. */
  52177. public function toString()
  52178. {
  52179. return 'is false';
  52180. }
  52181. }
  52182. <?php
  52183. /*
  52184. * This file is part of PHPUnit.
  52185. *
  52186. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52187. *
  52188. * For the full copyright and license information, please view the LICENSE
  52189. * file that was distributed with this source code.
  52190. */
  52191. /**
  52192. * Constraint that asserts that the class it is evaluated for has a given
  52193. * static attribute.
  52194. *
  52195. * The attribute name is passed in the constructor.
  52196. *
  52197. * @since Class available since Release 3.1.0
  52198. */
  52199. class PHPUnit_Framework_Constraint_ClassHasStaticAttribute extends PHPUnit_Framework_Constraint_ClassHasAttribute
  52200. {
  52201. /**
  52202. * Evaluates the constraint for parameter $other. Returns true if the
  52203. * constraint is met, false otherwise.
  52204. *
  52205. * @param mixed $other Value or object to evaluate.
  52206. * @return bool
  52207. */
  52208. protected function matches($other)
  52209. {
  52210. $class = new ReflectionClass($other);
  52211. if ($class->hasProperty($this->attributeName)) {
  52212. $attribute = $class->getProperty($this->attributeName);
  52213. return $attribute->isStatic();
  52214. } else {
  52215. return false;
  52216. }
  52217. }
  52218. /**
  52219. * Returns a string representation of the constraint.
  52220. *
  52221. * @return string
  52222. * @since Method available since Release 3.3.0
  52223. */
  52224. public function toString()
  52225. {
  52226. return sprintf(
  52227. 'has static attribute "%s"',
  52228. $this->attributeName
  52229. );
  52230. }
  52231. }
  52232. <?php
  52233. /*
  52234. * This file is part of PHPUnit.
  52235. *
  52236. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52237. *
  52238. * For the full copyright and license information, please view the LICENSE
  52239. * file that was distributed with this source code.
  52240. */
  52241. /**
  52242. * Logical OR.
  52243. *
  52244. * @since Class available since Release 3.0.0
  52245. */
  52246. class PHPUnit_Framework_Constraint_Or extends PHPUnit_Framework_Constraint
  52247. {
  52248. /**
  52249. * @var PHPUnit_Framework_Constraint[]
  52250. */
  52251. protected $constraints = array();
  52252. /**
  52253. * @param PHPUnit_Framework_Constraint[] $constraints
  52254. */
  52255. public function setConstraints(array $constraints)
  52256. {
  52257. $this->constraints = array();
  52258. foreach ($constraints as $constraint) {
  52259. if (!($constraint instanceof PHPUnit_Framework_Constraint)) {
  52260. $constraint = new PHPUnit_Framework_Constraint_IsEqual(
  52261. $constraint
  52262. );
  52263. }
  52264. $this->constraints[] = $constraint;
  52265. }
  52266. }
  52267. /**
  52268. * Evaluates the constraint for parameter $other
  52269. *
  52270. * If $returnResult is set to false (the default), an exception is thrown
  52271. * in case of a failure. null is returned otherwise.
  52272. *
  52273. * If $returnResult is true, the result of the evaluation is returned as
  52274. * a boolean value instead: true in case of success, false in case of a
  52275. * failure.
  52276. *
  52277. * @param mixed $other Value or object to evaluate.
  52278. * @param string $description Additional information about the test
  52279. * @param bool $returnResult Whether to return a result or throw an exception
  52280. * @return mixed
  52281. * @throws PHPUnit_Framework_ExpectationFailedException
  52282. */
  52283. public function evaluate($other, $description = '', $returnResult = false)
  52284. {
  52285. $success = false;
  52286. $constraint = null;
  52287. foreach ($this->constraints as $constraint) {
  52288. if ($constraint->evaluate($other, $description, true)) {
  52289. $success = true;
  52290. break;
  52291. }
  52292. }
  52293. if ($returnResult) {
  52294. return $success;
  52295. }
  52296. if (!$success) {
  52297. $this->fail($other, $description);
  52298. }
  52299. }
  52300. /**
  52301. * Returns a string representation of the constraint.
  52302. *
  52303. * @return string
  52304. */
  52305. public function toString()
  52306. {
  52307. $text = '';
  52308. foreach ($this->constraints as $key => $constraint) {
  52309. if ($key > 0) {
  52310. $text .= ' or ';
  52311. }
  52312. $text .= $constraint->toString();
  52313. }
  52314. return $text;
  52315. }
  52316. /**
  52317. * Counts the number of constraint elements.
  52318. *
  52319. * @return int
  52320. * @since Method available since Release 3.4.0
  52321. */
  52322. public function count()
  52323. {
  52324. $count = 0;
  52325. foreach ($this->constraints as $constraint) {
  52326. $count += count($constraint);
  52327. }
  52328. return $count;
  52329. }
  52330. }
  52331. <?php
  52332. /*
  52333. * This file is part of PHPUnit.
  52334. *
  52335. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52336. *
  52337. * For the full copyright and license information, please view the LICENSE
  52338. * file that was distributed with this source code.
  52339. */
  52340. /**
  52341. * Constraint that asserts that one value is identical to another.
  52342. *
  52343. * Identical check is performed with PHP's === operator, the operator is
  52344. * explained in detail at
  52345. * {@url http://www.php.net/manual/en/types.comparisons.php}.
  52346. * Two values are identical if they have the same value and are of the same
  52347. * type.
  52348. *
  52349. * The expected value is passed in the constructor.
  52350. *
  52351. * @since Class available since Release 3.0.0
  52352. */
  52353. class PHPUnit_Framework_Constraint_IsIdentical extends PHPUnit_Framework_Constraint
  52354. {
  52355. /**
  52356. * @var float
  52357. */
  52358. const EPSILON = 0.0000000001;
  52359. /**
  52360. * @var mixed
  52361. */
  52362. protected $value;
  52363. /**
  52364. * @param mixed $value
  52365. */
  52366. public function __construct($value)
  52367. {
  52368. parent::__construct();
  52369. $this->value = $value;
  52370. }
  52371. /**
  52372. * Evaluates the constraint for parameter $other
  52373. *
  52374. * If $returnResult is set to false (the default), an exception is thrown
  52375. * in case of a failure. null is returned otherwise.
  52376. *
  52377. * If $returnResult is true, the result of the evaluation is returned as
  52378. * a boolean value instead: true in case of success, false in case of a
  52379. * failure.
  52380. *
  52381. * @param mixed $other Value or object to evaluate.
  52382. * @param string $description Additional information about the test
  52383. * @param bool $returnResult Whether to return a result or throw an exception
  52384. * @return mixed
  52385. * @throws PHPUnit_Framework_ExpectationFailedException
  52386. */
  52387. public function evaluate($other, $description = '', $returnResult = false)
  52388. {
  52389. if (is_double($this->value) && is_double($other) &&
  52390. !is_infinite($this->value) && !is_infinite($other) &&
  52391. !is_nan($this->value) && !is_nan($other)) {
  52392. $success = abs($this->value - $other) < self::EPSILON;
  52393. } else {
  52394. $success = $this->value === $other;
  52395. }
  52396. if ($returnResult) {
  52397. return $success;
  52398. }
  52399. if (!$success) {
  52400. $f = null;
  52401. // if both values are strings, make sure a diff is generated
  52402. if (is_string($this->value) && is_string($other)) {
  52403. $f = new SebastianBergmann\Comparator\ComparisonFailure(
  52404. $this->value,
  52405. $other,
  52406. $this->value,
  52407. $other
  52408. );
  52409. }
  52410. $this->fail($other, $description, $f);
  52411. }
  52412. }
  52413. /**
  52414. * Returns the description of the failure
  52415. *
  52416. * The beginning of failure messages is "Failed asserting that" in most
  52417. * cases. This method should return the second part of that sentence.
  52418. *
  52419. * @param mixed $other Evaluated value or object.
  52420. * @return string
  52421. */
  52422. protected function failureDescription($other)
  52423. {
  52424. if (is_object($this->value) && is_object($other)) {
  52425. return 'two variables reference the same object';
  52426. }
  52427. if (is_string($this->value) && is_string($other)) {
  52428. return 'two strings are identical';
  52429. }
  52430. return parent::failureDescription($other);
  52431. }
  52432. /**
  52433. * Returns a string representation of the constraint.
  52434. *
  52435. * @return string
  52436. */
  52437. public function toString()
  52438. {
  52439. if (is_object($this->value)) {
  52440. return 'is identical to an object of class "' .
  52441. get_class($this->value) . '"';
  52442. } else {
  52443. return 'is identical to ' .
  52444. $this->exporter->export($this->value);
  52445. }
  52446. }
  52447. }
  52448. <?php
  52449. /*
  52450. * This file is part of PHPUnit.
  52451. *
  52452. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52453. *
  52454. * For the full copyright and license information, please view the LICENSE
  52455. * file that was distributed with this source code.
  52456. */
  52457. /**
  52458. * Constraint that checks if the file(name) that it is evaluated for exists.
  52459. *
  52460. * The file path to check is passed as $other in evaluate().
  52461. *
  52462. * @since Class available since Release 3.0.0
  52463. */
  52464. class PHPUnit_Framework_Constraint_FileExists extends PHPUnit_Framework_Constraint
  52465. {
  52466. /**
  52467. * Evaluates the constraint for parameter $other. Returns true if the
  52468. * constraint is met, false otherwise.
  52469. *
  52470. * @param mixed $other Value or object to evaluate.
  52471. * @return bool
  52472. */
  52473. protected function matches($other)
  52474. {
  52475. return file_exists($other);
  52476. }
  52477. /**
  52478. * Returns the description of the failure
  52479. *
  52480. * The beginning of failure messages is "Failed asserting that" in most
  52481. * cases. This method should return the second part of that sentence.
  52482. *
  52483. * @param mixed $other Evaluated value or object.
  52484. * @return string
  52485. */
  52486. protected function failureDescription($other)
  52487. {
  52488. return sprintf(
  52489. 'file "%s" exists',
  52490. $other
  52491. );
  52492. }
  52493. /**
  52494. * Returns a string representation of the constraint.
  52495. *
  52496. * @return string
  52497. */
  52498. public function toString()
  52499. {
  52500. return 'file exists';
  52501. }
  52502. }
  52503. <?php
  52504. /*
  52505. * This file is part of PHPUnit.
  52506. *
  52507. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52508. *
  52509. * For the full copyright and license information, please view the LICENSE
  52510. * file that was distributed with this source code.
  52511. */
  52512. /**
  52513. * @since Class available since Release 3.1.0
  52514. */
  52515. abstract class PHPUnit_Framework_Constraint_Composite extends PHPUnit_Framework_Constraint
  52516. {
  52517. /**
  52518. * @var PHPUnit_Framework_Constraint
  52519. */
  52520. protected $innerConstraint;
  52521. /**
  52522. * @param PHPUnit_Framework_Constraint $innerConstraint
  52523. */
  52524. public function __construct(PHPUnit_Framework_Constraint $innerConstraint)
  52525. {
  52526. parent::__construct();
  52527. $this->innerConstraint = $innerConstraint;
  52528. }
  52529. /**
  52530. * Evaluates the constraint for parameter $other
  52531. *
  52532. * If $returnResult is set to false (the default), an exception is thrown
  52533. * in case of a failure. null is returned otherwise.
  52534. *
  52535. * If $returnResult is true, the result of the evaluation is returned as
  52536. * a boolean value instead: true in case of success, false in case of a
  52537. * failure.
  52538. *
  52539. * @param mixed $other Value or object to evaluate.
  52540. * @param string $description Additional information about the test
  52541. * @param bool $returnResult Whether to return a result or throw an exception
  52542. * @return mixed
  52543. * @throws PHPUnit_Framework_ExpectationFailedException
  52544. */
  52545. public function evaluate($other, $description = '', $returnResult = false)
  52546. {
  52547. try {
  52548. return $this->innerConstraint->evaluate(
  52549. $other,
  52550. $description,
  52551. $returnResult
  52552. );
  52553. } catch (PHPUnit_Framework_ExpectationFailedException $e) {
  52554. $this->fail($other, $description);
  52555. }
  52556. }
  52557. /**
  52558. * Counts the number of constraint elements.
  52559. *
  52560. * @return int
  52561. */
  52562. public function count()
  52563. {
  52564. return count($this->innerConstraint);
  52565. }
  52566. }
  52567. <?php
  52568. /*
  52569. * This file is part of PHPUnit.
  52570. *
  52571. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52572. *
  52573. * For the full copyright and license information, please view the LICENSE
  52574. * file that was distributed with this source code.
  52575. */
  52576. /**
  52577. * Constraint that asserts that the string it is evaluated for begins with a
  52578. * given prefix.
  52579. *
  52580. * @since Class available since Release 3.4.0
  52581. */
  52582. class PHPUnit_Framework_Constraint_StringStartsWith extends PHPUnit_Framework_Constraint
  52583. {
  52584. /**
  52585. * @var string
  52586. */
  52587. protected $prefix;
  52588. /**
  52589. * @param string $prefix
  52590. */
  52591. public function __construct($prefix)
  52592. {
  52593. parent::__construct();
  52594. $this->prefix = $prefix;
  52595. }
  52596. /**
  52597. * Evaluates the constraint for parameter $other. Returns true if the
  52598. * constraint is met, false otherwise.
  52599. *
  52600. * @param mixed $other Value or object to evaluate.
  52601. * @return bool
  52602. */
  52603. protected function matches($other)
  52604. {
  52605. return strpos($other, $this->prefix) === 0;
  52606. }
  52607. /**
  52608. * Returns a string representation of the constraint.
  52609. *
  52610. * @return string
  52611. */
  52612. public function toString()
  52613. {
  52614. return 'starts with "' . $this->prefix . '"';
  52615. }
  52616. }
  52617. <?php
  52618. /*
  52619. * This file is part of PHPUnit.
  52620. *
  52621. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52622. *
  52623. * For the full copyright and license information, please view the LICENSE
  52624. * file that was distributed with this source code.
  52625. */
  52626. /**
  52627. * Constraint that asserts that the string it is evaluated for ends with a given
  52628. * suffix.
  52629. *
  52630. * @since Class available since Release 3.4.0
  52631. */
  52632. class PHPUnit_Framework_Constraint_StringEndsWith extends PHPUnit_Framework_Constraint
  52633. {
  52634. /**
  52635. * @var string
  52636. */
  52637. protected $suffix;
  52638. /**
  52639. * @param string $suffix
  52640. */
  52641. public function __construct($suffix)
  52642. {
  52643. parent::__construct();
  52644. $this->suffix = $suffix;
  52645. }
  52646. /**
  52647. * Evaluates the constraint for parameter $other. Returns true if the
  52648. * constraint is met, false otherwise.
  52649. *
  52650. * @param mixed $other Value or object to evaluate.
  52651. * @return bool
  52652. */
  52653. protected function matches($other)
  52654. {
  52655. return substr($other, 0 - strlen($this->suffix)) == $this->suffix;
  52656. }
  52657. /**
  52658. * Returns a string representation of the constraint.
  52659. *
  52660. * @return string
  52661. */
  52662. public function toString()
  52663. {
  52664. return 'ends with "' . $this->suffix . '"';
  52665. }
  52666. }
  52667. <?php
  52668. /*
  52669. * This file is part of PHPUnit.
  52670. *
  52671. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52672. *
  52673. * For the full copyright and license information, please view the LICENSE
  52674. * file that was distributed with this source code.
  52675. */
  52676. /**
  52677. * Constraint that accepts any input value.
  52678. *
  52679. * @since Class available since Release 3.0.0
  52680. */
  52681. class PHPUnit_Framework_Constraint_IsAnything extends PHPUnit_Framework_Constraint
  52682. {
  52683. /**
  52684. * Evaluates the constraint for parameter $other
  52685. *
  52686. * If $returnResult is set to false (the default), an exception is thrown
  52687. * in case of a failure. null is returned otherwise.
  52688. *
  52689. * If $returnResult is true, the result of the evaluation is returned as
  52690. * a boolean value instead: true in case of success, false in case of a
  52691. * failure.
  52692. *
  52693. * @param mixed $other Value or object to evaluate.
  52694. * @param string $description Additional information about the test
  52695. * @param bool $returnResult Whether to return a result or throw an exception
  52696. * @return mixed
  52697. * @throws PHPUnit_Framework_ExpectationFailedException
  52698. */
  52699. public function evaluate($other, $description = '', $returnResult = false)
  52700. {
  52701. return $returnResult ? true : null;
  52702. }
  52703. /**
  52704. * Returns a string representation of the constraint.
  52705. *
  52706. * @return string
  52707. */
  52708. public function toString()
  52709. {
  52710. return 'is anything';
  52711. }
  52712. /**
  52713. * Counts the number of constraint elements.
  52714. *
  52715. * @return int
  52716. * @since Method available since Release 3.5.0
  52717. */
  52718. public function count()
  52719. {
  52720. return 0;
  52721. }
  52722. }
  52723. <?php
  52724. /*
  52725. * This file is part of PHPUnit.
  52726. *
  52727. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52728. *
  52729. * For the full copyright and license information, please view the LICENSE
  52730. * file that was distributed with this source code.
  52731. */
  52732. /**
  52733. * @since Class available since Release 3.6.0
  52734. */
  52735. class PHPUnit_Framework_Constraint_Count extends PHPUnit_Framework_Constraint
  52736. {
  52737. /**
  52738. * @var int
  52739. */
  52740. protected $expectedCount = 0;
  52741. /**
  52742. * @param int $expected
  52743. */
  52744. public function __construct($expected)
  52745. {
  52746. parent::__construct();
  52747. $this->expectedCount = $expected;
  52748. }
  52749. /**
  52750. * Evaluates the constraint for parameter $other. Returns true if the
  52751. * constraint is met, false otherwise.
  52752. *
  52753. * @param mixed $other
  52754. * @return bool
  52755. */
  52756. protected function matches($other)
  52757. {
  52758. return $this->expectedCount === $this->getCountOf($other);
  52759. }
  52760. /**
  52761. * @param mixed $other
  52762. * @return bool
  52763. */
  52764. protected function getCountOf($other)
  52765. {
  52766. if ($other instanceof Countable || is_array($other)) {
  52767. return count($other);
  52768. } elseif ($other instanceof Traversable) {
  52769. if ($other instanceof IteratorAggregate) {
  52770. $iterator = $other->getIterator();
  52771. } else {
  52772. $iterator = $other;
  52773. }
  52774. $key = $iterator->key();
  52775. $count = iterator_count($iterator);
  52776. // manually rewind $iterator to previous key, since iterator_count
  52777. // moves pointer
  52778. if ($key !== null) {
  52779. $iterator->rewind();
  52780. while ($iterator->valid() && $key !== $iterator->key()) {
  52781. $iterator->next();
  52782. }
  52783. }
  52784. return $count;
  52785. }
  52786. }
  52787. /**
  52788. * Returns the description of the failure
  52789. *
  52790. * The beginning of failure messages is "Failed asserting that" in most
  52791. * cases. This method should return the second part of that sentence.
  52792. *
  52793. * @param mixed $other Evaluated value or object.
  52794. * @return string
  52795. */
  52796. protected function failureDescription($other)
  52797. {
  52798. return sprintf(
  52799. 'actual size %d matches expected size %d',
  52800. $this->getCountOf($other),
  52801. $this->expectedCount
  52802. );
  52803. }
  52804. /**
  52805. * @return string
  52806. */
  52807. public function toString()
  52808. {
  52809. return sprintf(
  52810. 'count matches %d',
  52811. $this->expectedCount
  52812. );
  52813. }
  52814. }
  52815. <?php
  52816. /*
  52817. * This file is part of PHPUnit.
  52818. *
  52819. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52820. *
  52821. * For the full copyright and license information, please view the LICENSE
  52822. * file that was distributed with this source code.
  52823. */
  52824. /**
  52825. * Logical AND.
  52826. *
  52827. * @since Class available since Release 3.0.0
  52828. */
  52829. class PHPUnit_Framework_Constraint_And extends PHPUnit_Framework_Constraint
  52830. {
  52831. /**
  52832. * @var PHPUnit_Framework_Constraint[]
  52833. */
  52834. protected $constraints = array();
  52835. /**
  52836. * @var PHPUnit_Framework_Constraint
  52837. */
  52838. protected $lastConstraint = null;
  52839. /**
  52840. * @param PHPUnit_Framework_Constraint[] $constraints
  52841. * @throws PHPUnit_Framework_Exception
  52842. */
  52843. public function setConstraints(array $constraints)
  52844. {
  52845. $this->constraints = array();
  52846. foreach ($constraints as $constraint) {
  52847. if (!($constraint instanceof PHPUnit_Framework_Constraint)) {
  52848. throw new PHPUnit_Framework_Exception(
  52849. 'All parameters to ' . __CLASS__ .
  52850. ' must be a constraint object.'
  52851. );
  52852. }
  52853. $this->constraints[] = $constraint;
  52854. }
  52855. }
  52856. /**
  52857. * Evaluates the constraint for parameter $other
  52858. *
  52859. * If $returnResult is set to false (the default), an exception is thrown
  52860. * in case of a failure. null is returned otherwise.
  52861. *
  52862. * If $returnResult is true, the result of the evaluation is returned as
  52863. * a boolean value instead: true in case of success, false in case of a
  52864. * failure.
  52865. *
  52866. * @param mixed $other Value or object to evaluate.
  52867. * @param string $description Additional information about the test
  52868. * @param bool $returnResult Whether to return a result or throw an exception
  52869. * @return mixed
  52870. * @throws PHPUnit_Framework_ExpectationFailedException
  52871. */
  52872. public function evaluate($other, $description = '', $returnResult = false)
  52873. {
  52874. $success = true;
  52875. $constraint = null;
  52876. foreach ($this->constraints as $constraint) {
  52877. if (!$constraint->evaluate($other, $description, true)) {
  52878. $success = false;
  52879. break;
  52880. }
  52881. }
  52882. if ($returnResult) {
  52883. return $success;
  52884. }
  52885. if (!$success) {
  52886. $this->fail($other, $description);
  52887. }
  52888. }
  52889. /**
  52890. * Returns a string representation of the constraint.
  52891. *
  52892. * @return string
  52893. */
  52894. public function toString()
  52895. {
  52896. $text = '';
  52897. foreach ($this->constraints as $key => $constraint) {
  52898. if ($key > 0) {
  52899. $text .= ' and ';
  52900. }
  52901. $text .= $constraint->toString();
  52902. }
  52903. return $text;
  52904. }
  52905. /**
  52906. * Counts the number of constraint elements.
  52907. *
  52908. * @return int
  52909. * @since Method available since Release 3.4.0
  52910. */
  52911. public function count()
  52912. {
  52913. $count = 0;
  52914. foreach ($this->constraints as $constraint) {
  52915. $count += count($constraint);
  52916. }
  52917. return $count;
  52918. }
  52919. }
  52920. <?php
  52921. /*
  52922. * This file is part of PHPUnit.
  52923. *
  52924. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52925. *
  52926. * For the full copyright and license information, please view the LICENSE
  52927. * file that was distributed with this source code.
  52928. */
  52929. /**
  52930. * An empty Listener that can be extended to implement TestListener
  52931. * with just a few lines of code.
  52932. * @see PHPUnit_Framework_TestListener for documentation on the API methods.
  52933. *
  52934. * @since Class available since Release 4.0.0
  52935. */
  52936. abstract class PHPUnit_Framework_BaseTestListener implements PHPUnit_Framework_TestListener
  52937. {
  52938. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  52939. {
  52940. }
  52941. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  52942. {
  52943. }
  52944. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  52945. {
  52946. }
  52947. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  52948. {
  52949. }
  52950. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  52951. {
  52952. }
  52953. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  52954. {
  52955. }
  52956. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  52957. {
  52958. }
  52959. public function startTest(PHPUnit_Framework_Test $test)
  52960. {
  52961. }
  52962. public function endTest(PHPUnit_Framework_Test $test, $time)
  52963. {
  52964. }
  52965. }
  52966. <?php
  52967. /*
  52968. * This file is part of PHPUnit.
  52969. *
  52970. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52971. *
  52972. * For the full copyright and license information, please view the LICENSE
  52973. * file that was distributed with this source code.
  52974. */
  52975. /**
  52976. * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
  52977. * case of a skipped test.
  52978. *
  52979. * @since Class available since Release 3.0.0
  52980. */
  52981. class PHPUnit_Framework_SkippedTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest
  52982. {
  52983. }
  52984. <?php
  52985. /*
  52986. * This file is part of PHPUnit.
  52987. *
  52988. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  52989. *
  52990. * For the full copyright and license information, please view the LICENSE
  52991. * file that was distributed with this source code.
  52992. */
  52993. /**
  52994. * Extension to PHPUnit_Framework_AssertionFailedError to mark the special
  52995. * case of a test test that unintentionally covers code.
  52996. *
  52997. * @since Class available since Release 4.0.0
  52998. */
  52999. class PHPUnit_Framework_UnintentionallyCoveredCodeError extends PHPUnit_Framework_RiskyTestError
  53000. {
  53001. }
  53002. <?php
  53003. /*
  53004. * This file is part of PHPUnit.
  53005. *
  53006. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53007. *
  53008. * For the full copyright and license information, please view the LICENSE
  53009. * file that was distributed with this source code.
  53010. */
  53011. /**
  53012. * A warning.
  53013. *
  53014. * @since Class available since Release 2.0.0
  53015. */
  53016. class PHPUnit_Framework_Warning extends PHPUnit_Framework_TestCase
  53017. {
  53018. /**
  53019. * @var string
  53020. */
  53021. protected $message = '';
  53022. /**
  53023. * @var bool
  53024. */
  53025. protected $backupGlobals = false;
  53026. /**
  53027. * @var bool
  53028. */
  53029. protected $backupStaticAttributes = false;
  53030. /**
  53031. * @var bool
  53032. */
  53033. protected $runTestInSeparateProcess = false;
  53034. /**
  53035. * @var bool
  53036. */
  53037. protected $useErrorHandler = false;
  53038. /**
  53039. * @param string $message
  53040. */
  53041. public function __construct($message = '')
  53042. {
  53043. $this->message = $message;
  53044. parent::__construct('Warning');
  53045. }
  53046. /**
  53047. * @throws PHPUnit_Framework_Exception
  53048. */
  53049. protected function runTest()
  53050. {
  53051. $this->fail($this->message);
  53052. }
  53053. /**
  53054. * @return string
  53055. * @since Method available since Release 3.0.0
  53056. */
  53057. public function getMessage()
  53058. {
  53059. return $this->message;
  53060. }
  53061. /**
  53062. * Returns a string representation of the test case.
  53063. *
  53064. * @return string
  53065. * @since Method available since Release 3.4.0
  53066. */
  53067. public function toString()
  53068. {
  53069. return 'Warning';
  53070. }
  53071. }
  53072. <?php
  53073. /*
  53074. * This file is part of PHPUnit.
  53075. *
  53076. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53077. *
  53078. * For the full copyright and license information, please view the LICENSE
  53079. * file that was distributed with this source code.
  53080. */
  53081. /**
  53082. * We have a TestSuite object A.
  53083. * In TestSuite object A we have Tests tagged with @group.
  53084. * We want a TestSuite object B that contains TestSuite objects C, D, ...
  53085. * for the Tests tagged with @group C, @group D, ...
  53086. * Running the Tests from TestSuite object B results in Tests tagged with both
  53087. * @group C and @group D in TestSuite object A to be run twice .
  53088. *
  53089. * <code>
  53090. * $suite = new PHPUnit_Extensions_GroupTestSuite($A, array('C', 'D'));
  53091. * </code>
  53092. *
  53093. * @since Class available since Release 3.3.0
  53094. */
  53095. class PHPUnit_Extensions_GroupTestSuite extends PHPUnit_Framework_TestSuite
  53096. {
  53097. public function __construct(PHPUnit_Framework_TestSuite $suite, array $groups)
  53098. {
  53099. $groupSuites = array();
  53100. $name = $suite->getName();
  53101. foreach ($groups as $group) {
  53102. $groupSuites[$group] = new PHPUnit_Framework_TestSuite($name . ' - ' . $group);
  53103. $this->addTest($groupSuites[$group]);
  53104. }
  53105. $tests = new RecursiveIteratorIterator(
  53106. new PHPUnit_Util_TestSuiteIterator($suite),
  53107. RecursiveIteratorIterator::LEAVES_ONLY
  53108. );
  53109. foreach ($tests as $test) {
  53110. if ($test instanceof PHPUnit_Framework_TestCase) {
  53111. $testGroups = PHPUnit_Util_Test::getGroups(
  53112. get_class($test),
  53113. $test->getName(false)
  53114. );
  53115. foreach ($groups as $group) {
  53116. foreach ($testGroups as $testGroup) {
  53117. if ($group == $testGroup) {
  53118. $groupSuites[$group]->addTest($test);
  53119. }
  53120. }
  53121. }
  53122. }
  53123. }
  53124. }
  53125. }
  53126. <?php
  53127. /*
  53128. * This file is part of PHPUnit.
  53129. *
  53130. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53131. *
  53132. * For the full copyright and license information, please view the LICENSE
  53133. * file that was distributed with this source code.
  53134. */
  53135. /**
  53136. * Suite for .phpt test cases.
  53137. *
  53138. * @since Class available since Release 3.1.4
  53139. */
  53140. class PHPUnit_Extensions_PhptTestSuite extends PHPUnit_Framework_TestSuite
  53141. {
  53142. /**
  53143. * Constructs a new TestSuite for .phpt test cases.
  53144. *
  53145. * @param string $directory
  53146. * @param array $options Array with ini settings for the php instance run,
  53147. * key being the name if the setting, value the ini value.
  53148. * @throws PHPUnit_Framework_Exception
  53149. */
  53150. public function __construct($directory, array $options = array())
  53151. {
  53152. if (is_string($directory) && is_dir($directory)) {
  53153. $this->setName($directory);
  53154. $facade = new File_Iterator_Facade;
  53155. $files = $facade->getFilesAsArray($directory, '.phpt');
  53156. foreach ($files as $file) {
  53157. $this->addTestFile($file, $options);
  53158. }
  53159. } else {
  53160. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'directory name');
  53161. }
  53162. }
  53163. }
  53164. <?php
  53165. /*
  53166. * This file is part of PHPUnit.
  53167. *
  53168. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53169. *
  53170. * For the full copyright and license information, please view the LICENSE
  53171. * file that was distributed with this source code.
  53172. */
  53173. /**
  53174. * A Decorator that runs a test repeatedly.
  53175. *
  53176. * @since Class available since Release 2.0.0
  53177. */
  53178. class PHPUnit_Extensions_RepeatedTest extends PHPUnit_Extensions_TestDecorator
  53179. {
  53180. /**
  53181. * @var bool
  53182. */
  53183. protected $processIsolation = false;
  53184. /**
  53185. * @var int
  53186. */
  53187. protected $timesRepeat = 1;
  53188. /**
  53189. * @param PHPUnit_Framework_Test $test
  53190. * @param int $timesRepeat
  53191. * @param bool $processIsolation
  53192. * @throws PHPUnit_Framework_Exception
  53193. */
  53194. public function __construct(PHPUnit_Framework_Test $test, $timesRepeat = 1, $processIsolation = false)
  53195. {
  53196. parent::__construct($test);
  53197. if (is_integer($timesRepeat) &&
  53198. $timesRepeat >= 0) {
  53199. $this->timesRepeat = $timesRepeat;
  53200. } else {
  53201. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  53202. 2,
  53203. 'positive integer'
  53204. );
  53205. }
  53206. $this->processIsolation = $processIsolation;
  53207. }
  53208. /**
  53209. * Counts the number of test cases that
  53210. * will be run by this test.
  53211. *
  53212. * @return int
  53213. */
  53214. public function count()
  53215. {
  53216. return $this->timesRepeat * count($this->test);
  53217. }
  53218. /**
  53219. * Runs the decorated test and collects the
  53220. * result in a TestResult.
  53221. *
  53222. * @param PHPUnit_Framework_TestResult $result
  53223. * @return PHPUnit_Framework_TestResult
  53224. * @throws PHPUnit_Framework_Exception
  53225. */
  53226. public function run(PHPUnit_Framework_TestResult $result = null)
  53227. {
  53228. if ($result === null) {
  53229. $result = $this->createResult();
  53230. }
  53231. //@codingStandardsIgnoreStart
  53232. for ($i = 0; $i < $this->timesRepeat && !$result->shouldStop(); $i++) {
  53233. //@codingStandardsIgnoreEnd
  53234. if ($this->test instanceof PHPUnit_Framework_TestSuite) {
  53235. $this->test->setRunTestInSeparateProcess($this->processIsolation);
  53236. }
  53237. $this->test->run($result);
  53238. }
  53239. return $result;
  53240. }
  53241. }
  53242. <?php
  53243. /*
  53244. * This file is part of PHPUnit.
  53245. *
  53246. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53247. *
  53248. * For the full copyright and license information, please view the LICENSE
  53249. * file that was distributed with this source code.
  53250. */
  53251. /**
  53252. * Base class for test listeners that interact with an issue tracker.
  53253. *
  53254. * @since Class available since Release 3.4.0
  53255. */
  53256. abstract class PHPUnit_Extensions_TicketListener implements PHPUnit_Framework_TestListener
  53257. {
  53258. /**
  53259. * @var array
  53260. */
  53261. protected $ticketCounts = array();
  53262. /**
  53263. * @var bool
  53264. */
  53265. protected $ran = false;
  53266. /**
  53267. * An error occurred.
  53268. *
  53269. * @param PHPUnit_Framework_Test $test
  53270. * @param Exception $e
  53271. * @param float $time
  53272. */
  53273. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  53274. {
  53275. }
  53276. /**
  53277. * A failure occurred.
  53278. *
  53279. * @param PHPUnit_Framework_Test $test
  53280. * @param PHPUnit_Framework_AssertionFailedError $e
  53281. * @param float $time
  53282. */
  53283. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  53284. {
  53285. }
  53286. /**
  53287. * Incomplete test.
  53288. *
  53289. * @param PHPUnit_Framework_Test $test
  53290. * @param Exception $e
  53291. * @param float $time
  53292. */
  53293. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  53294. {
  53295. }
  53296. /**
  53297. * Risky test.
  53298. *
  53299. * @param PHPUnit_Framework_Test $test
  53300. * @param Exception $e
  53301. * @param float $time
  53302. * @since Method available since Release 4.0.0
  53303. */
  53304. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  53305. {
  53306. }
  53307. /**
  53308. * Skipped test.
  53309. *
  53310. * @param PHPUnit_Framework_Test $test
  53311. * @param Exception $e
  53312. * @param float $time
  53313. * @since Method available since Release 3.0.0
  53314. */
  53315. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  53316. {
  53317. }
  53318. /**
  53319. * A test suite started.
  53320. *
  53321. * @param PHPUnit_Framework_TestSuite $suite
  53322. * @since Method available since Release 2.2.0
  53323. */
  53324. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  53325. {
  53326. }
  53327. /**
  53328. * A test suite ended.
  53329. *
  53330. * @param PHPUnit_Framework_TestSuite $suite
  53331. * @since Method available since Release 2.2.0
  53332. */
  53333. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  53334. {
  53335. }
  53336. /**
  53337. * A test started.
  53338. *
  53339. * @param PHPUnit_Framework_Test $test
  53340. */
  53341. public function startTest(PHPUnit_Framework_Test $test)
  53342. {
  53343. if (!$test instanceof PHPUnit_Framework_Warning) {
  53344. if ($this->ran) {
  53345. return;
  53346. }
  53347. $name = $test->getName(false);
  53348. $tickets = PHPUnit_Util_Test::getTickets(get_class($test), $name);
  53349. foreach ($tickets as $ticket) {
  53350. $this->ticketCounts[$ticket][$name] = 1;
  53351. }
  53352. $this->ran = true;
  53353. }
  53354. }
  53355. /**
  53356. * A test ended.
  53357. *
  53358. * @param PHPUnit_Framework_Test $test
  53359. * @param float $time
  53360. */
  53361. public function endTest(PHPUnit_Framework_Test $test, $time)
  53362. {
  53363. if (!$test instanceof PHPUnit_Framework_Warning) {
  53364. if ($test->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) {
  53365. $ifStatus = array('assigned', 'new', 'reopened');
  53366. $newStatus = 'closed';
  53367. $message = 'Automatically closed by PHPUnit (test passed).';
  53368. $resolution = 'fixed';
  53369. $cumulative = true;
  53370. } elseif ($test->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE) {
  53371. $ifStatus = array('closed');
  53372. $newStatus = 'reopened';
  53373. $message = 'Automatically reopened by PHPUnit (test failed).';
  53374. $resolution = '';
  53375. $cumulative = false;
  53376. } else {
  53377. return;
  53378. }
  53379. $name = $test->getName(false);
  53380. $tickets = PHPUnit_Util_Test::getTickets(get_class($test), $name);
  53381. foreach ($tickets as $ticket) {
  53382. // Remove this test from the totals (if it passed).
  53383. if ($test->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) {
  53384. unset($this->ticketCounts[$ticket][$name]);
  53385. }
  53386. // Only close tickets if ALL referenced cases pass
  53387. // but reopen tickets if a single test fails.
  53388. if ($cumulative) {
  53389. // Determine number of to-pass tests:
  53390. if (count($this->ticketCounts[$ticket]) > 0) {
  53391. // There exist remaining test cases with this reference.
  53392. $adjustTicket = false;
  53393. } else {
  53394. // No remaining tickets, go ahead and adjust.
  53395. $adjustTicket = true;
  53396. }
  53397. } else {
  53398. $adjustTicket = true;
  53399. }
  53400. $ticketInfo = $this->getTicketInfo($ticket);
  53401. if ($adjustTicket && in_array($ticketInfo['status'], $ifStatus)) {
  53402. $this->updateTicket($ticket, $newStatus, $message, $resolution);
  53403. }
  53404. }
  53405. }
  53406. }
  53407. abstract protected function getTicketInfo($ticketId = null);
  53408. abstract protected function updateTicket($ticketId, $newStatus, $message, $resolution);
  53409. }
  53410. <?php
  53411. /*
  53412. * This file is part of PHPUnit.
  53413. *
  53414. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53415. *
  53416. * For the full copyright and license information, please view the LICENSE
  53417. * file that was distributed with this source code.
  53418. */
  53419. /**
  53420. * A Decorator for Tests.
  53421. *
  53422. * Use TestDecorator as the base class for defining new
  53423. * test decorators. Test decorator subclasses can be introduced
  53424. * to add behaviour before or after a test is run.
  53425. *
  53426. * @since Class available since Release 2.0.0
  53427. */
  53428. class PHPUnit_Extensions_TestDecorator extends PHPUnit_Framework_Assert implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing
  53429. {
  53430. /**
  53431. * The Test to be decorated.
  53432. *
  53433. * @var object
  53434. */
  53435. protected $test = null;
  53436. /**
  53437. * Constructor.
  53438. *
  53439. * @param PHPUnit_Framework_Test $test
  53440. */
  53441. public function __construct(PHPUnit_Framework_Test $test)
  53442. {
  53443. $this->test = $test;
  53444. }
  53445. /**
  53446. * Returns a string representation of the test.
  53447. *
  53448. * @return string
  53449. */
  53450. public function toString()
  53451. {
  53452. return $this->test->toString();
  53453. }
  53454. /**
  53455. * Runs the test and collects the
  53456. * result in a TestResult.
  53457. *
  53458. * @param PHPUnit_Framework_TestResult $result
  53459. */
  53460. public function basicRun(PHPUnit_Framework_TestResult $result)
  53461. {
  53462. $this->test->run($result);
  53463. }
  53464. /**
  53465. * Counts the number of test cases that
  53466. * will be run by this test.
  53467. *
  53468. * @return int
  53469. */
  53470. public function count()
  53471. {
  53472. return count($this->test);
  53473. }
  53474. /**
  53475. * Creates a default TestResult object.
  53476. *
  53477. * @return PHPUnit_Framework_TestResult
  53478. */
  53479. protected function createResult()
  53480. {
  53481. return new PHPUnit_Framework_TestResult;
  53482. }
  53483. /**
  53484. * Returns the test to be run.
  53485. *
  53486. * @return PHPUnit_Framework_Test
  53487. */
  53488. public function getTest()
  53489. {
  53490. return $this->test;
  53491. }
  53492. /**
  53493. * Runs the decorated test and collects the
  53494. * result in a TestResult.
  53495. *
  53496. * @param PHPUnit_Framework_TestResult $result
  53497. * @return PHPUnit_Framework_TestResult
  53498. */
  53499. public function run(PHPUnit_Framework_TestResult $result = null)
  53500. {
  53501. if ($result === null) {
  53502. $result = $this->createResult();
  53503. }
  53504. $this->basicRun($result);
  53505. return $result;
  53506. }
  53507. }
  53508. <?php
  53509. /*
  53510. * This file is part of PHPUnit.
  53511. *
  53512. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53513. *
  53514. * For the full copyright and license information, please view the LICENSE
  53515. * file that was distributed with this source code.
  53516. */
  53517. /**
  53518. * Runner for PHPT test cases.
  53519. *
  53520. * @since Class available since Release 3.1.4
  53521. */
  53522. class PHPUnit_Extensions_PhptTestCase implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing
  53523. {
  53524. /**
  53525. * @var string
  53526. */
  53527. private $filename;
  53528. /**
  53529. * @var array
  53530. */
  53531. private $settings = array(
  53532. 'allow_url_fopen=1',
  53533. 'auto_append_file=',
  53534. 'auto_prepend_file=',
  53535. 'disable_functions=',
  53536. 'display_errors=1',
  53537. 'docref_root=',
  53538. 'docref_ext=.html',
  53539. 'error_append_string=',
  53540. 'error_prepend_string=',
  53541. 'error_reporting=-1',
  53542. 'html_errors=0',
  53543. 'log_errors=0',
  53544. 'magic_quotes_runtime=0',
  53545. 'output_handler=',
  53546. 'open_basedir=',
  53547. 'output_buffering=Off',
  53548. 'report_memleaks=0',
  53549. 'report_zend_debug=0',
  53550. 'safe_mode=0',
  53551. 'track_errors=1',
  53552. 'xdebug.default_enable=0'
  53553. );
  53554. /**
  53555. * Constructs a test case with the given filename.
  53556. *
  53557. * @param string $filename
  53558. * @throws PHPUnit_Framework_Exception
  53559. */
  53560. public function __construct($filename)
  53561. {
  53562. if (!is_string($filename)) {
  53563. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
  53564. }
  53565. if (!is_file($filename)) {
  53566. throw new PHPUnit_Framework_Exception(
  53567. sprintf(
  53568. 'File "%s" does not exist.',
  53569. $filename
  53570. )
  53571. );
  53572. }
  53573. $this->filename = $filename;
  53574. }
  53575. /**
  53576. * Counts the number of test cases executed by run(TestResult result).
  53577. *
  53578. * @return int
  53579. */
  53580. public function count()
  53581. {
  53582. return 1;
  53583. }
  53584. /**
  53585. * Runs a test and collects its result in a TestResult instance.
  53586. *
  53587. * @param PHPUnit_Framework_TestResult $result
  53588. * @return PHPUnit_Framework_TestResult
  53589. */
  53590. public function run(PHPUnit_Framework_TestResult $result = null)
  53591. {
  53592. $sections = $this->parse();
  53593. $code = $this->render($sections['FILE']);
  53594. if ($result === null) {
  53595. $result = new PHPUnit_Framework_TestResult;
  53596. }
  53597. $php = PHPUnit_Util_PHP::factory();
  53598. $skip = false;
  53599. $time = 0;
  53600. $settings = $this->settings;
  53601. $result->startTest($this);
  53602. if (isset($sections['INI'])) {
  53603. $settings = array_merge($settings, $this->parseIniSection($sections['INI']));
  53604. }
  53605. if (isset($sections['SKIPIF'])) {
  53606. $jobResult = $php->runJob($sections['SKIPIF'], $settings);
  53607. if (!strncasecmp('skip', ltrim($jobResult['stdout']), 4)) {
  53608. if (preg_match('/^\s*skip\s*(.+)\s*/i', $jobResult['stdout'], $message)) {
  53609. $message = substr($message[1], 2);
  53610. } else {
  53611. $message = '';
  53612. }
  53613. $result->addFailure($this, new PHPUnit_Framework_SkippedTestError($message), 0);
  53614. $skip = true;
  53615. }
  53616. }
  53617. if (!$skip) {
  53618. PHP_Timer::start();
  53619. $jobResult = $php->runJob($code, $settings);
  53620. $time = PHP_Timer::stop();
  53621. if (isset($sections['EXPECT'])) {
  53622. $assertion = 'assertEquals';
  53623. $expected = $sections['EXPECT'];
  53624. } else {
  53625. $assertion = 'assertStringMatchesFormat';
  53626. $expected = $sections['EXPECTF'];
  53627. }
  53628. $output = preg_replace('/\r\n/', "\n", trim($jobResult['stdout']));
  53629. $expected = preg_replace('/\r\n/', "\n", trim($expected));
  53630. try {
  53631. PHPUnit_Framework_Assert::$assertion($expected, $output);
  53632. } catch (PHPUnit_Framework_AssertionFailedError $e) {
  53633. $result->addFailure($this, $e, $time);
  53634. } catch (Throwable $t) {
  53635. $result->addError($this, $t, $time);
  53636. } catch (Exception $e) {
  53637. $result->addError($this, $e, $time);
  53638. }
  53639. }
  53640. $result->endTest($this, $time);
  53641. return $result;
  53642. }
  53643. /**
  53644. * Returns the name of the test case.
  53645. *
  53646. * @return string
  53647. */
  53648. public function getName()
  53649. {
  53650. return $this->toString();
  53651. }
  53652. /**
  53653. * Returns a string representation of the test case.
  53654. *
  53655. * @return string
  53656. */
  53657. public function toString()
  53658. {
  53659. return $this->filename;
  53660. }
  53661. /**
  53662. * @return array
  53663. * @throws PHPUnit_Framework_Exception
  53664. */
  53665. private function parse()
  53666. {
  53667. $sections = array();
  53668. $section = '';
  53669. foreach (file($this->filename) as $line) {
  53670. if (preg_match('/^--([_A-Z]+)--/', $line, $result)) {
  53671. $section = $result[1];
  53672. $sections[$section] = '';
  53673. continue;
  53674. } elseif (empty($section)) {
  53675. throw new PHPUnit_Framework_Exception('Invalid PHPT file');
  53676. }
  53677. $sections[$section] .= $line;
  53678. }
  53679. if (!isset($sections['FILE']) ||
  53680. (!isset($sections['EXPECT']) && !isset($sections['EXPECTF']))) {
  53681. throw new PHPUnit_Framework_Exception('Invalid PHPT file');
  53682. }
  53683. return $sections;
  53684. }
  53685. /**
  53686. * @param string $code
  53687. * @return string
  53688. */
  53689. private function render($code)
  53690. {
  53691. return str_replace(
  53692. array(
  53693. '__DIR__',
  53694. '__FILE__'
  53695. ),
  53696. array(
  53697. "'" . dirname($this->filename) . "'",
  53698. "'" . $this->filename . "'"
  53699. ),
  53700. $code
  53701. );
  53702. }
  53703. /**
  53704. * Parse --INI-- section key value pairs and return as array.
  53705. *
  53706. * @param string
  53707. * @return array
  53708. */
  53709. protected function parseIniSection($content)
  53710. {
  53711. return preg_split('/\n|\r/', $content, -1, PREG_SPLIT_NO_EMPTY);
  53712. }
  53713. }
  53714. <?php
  53715. /*
  53716. * This file is part of PHPUnit.
  53717. *
  53718. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  53719. *
  53720. * For the full copyright and license information, please view the LICENSE
  53721. * file that was distributed with this source code.
  53722. */
  53723. /**
  53724. * A TestRunner for the Command Line Interface (CLI)
  53725. * PHP SAPI Module.
  53726. *
  53727. * @since Class available since Release 3.0.0
  53728. */
  53729. class PHPUnit_TextUI_Command
  53730. {
  53731. /**
  53732. * @var array
  53733. */
  53734. protected $arguments = array(
  53735. 'listGroups' => false,
  53736. 'loader' => null,
  53737. 'useDefaultConfiguration' => true
  53738. );
  53739. /**
  53740. * @var array
  53741. */
  53742. protected $options = array();
  53743. /**
  53744. * @var array
  53745. */
  53746. protected $longOptions = array(
  53747. 'colors==' => null,
  53748. 'bootstrap=' => null,
  53749. 'columns=' => null,
  53750. 'configuration=' => null,
  53751. 'coverage-clover=' => null,
  53752. 'coverage-crap4j=' => null,
  53753. 'coverage-html=' => null,
  53754. 'coverage-php=' => null,
  53755. 'coverage-text==' => null,
  53756. 'coverage-xml=' => null,
  53757. 'debug' => null,
  53758. 'exclude-group=' => null,
  53759. 'filter=' => null,
  53760. 'testsuite=' => null,
  53761. 'group=' => null,
  53762. 'help' => null,
  53763. 'include-path=' => null,
  53764. 'list-groups' => null,
  53765. 'loader=' => null,
  53766. 'log-json=' => null,
  53767. 'log-junit=' => null,
  53768. 'log-tap=' => null,
  53769. 'process-isolation' => null,
  53770. 'repeat=' => null,
  53771. 'stderr' => null,
  53772. 'stop-on-error' => null,
  53773. 'stop-on-failure' => null,
  53774. 'stop-on-incomplete' => null,
  53775. 'stop-on-risky' => null,
  53776. 'stop-on-skipped' => null,
  53777. 'report-useless-tests' => null,
  53778. 'strict-coverage' => null,
  53779. 'disallow-test-output' => null,
  53780. 'enforce-time-limit' => null,
  53781. 'disallow-todo-tests' => null,
  53782. 'strict-global-state' => null,
  53783. 'strict' => null,
  53784. 'tap' => null,
  53785. 'testdox' => null,
  53786. 'testdox-html=' => null,
  53787. 'testdox-text=' => null,
  53788. 'test-suffix=' => null,
  53789. 'no-configuration' => null,
  53790. 'no-globals-backup' => null,
  53791. 'printer=' => null,
  53792. 'static-backup' => null,
  53793. 'verbose' => null,
  53794. 'version' => null
  53795. );
  53796. /**
  53797. * @var bool
  53798. */
  53799. private $versionStringPrinted = false;
  53800. /**
  53801. * @param bool $exit
  53802. */
  53803. public static function main($exit = true)
  53804. {
  53805. $command = new static;
  53806. return $command->run($_SERVER['argv'], $exit);
  53807. }
  53808. /**
  53809. * @param array $argv
  53810. * @param bool $exit
  53811. * @return int
  53812. */
  53813. public function run(array $argv, $exit = true)
  53814. {
  53815. $this->handleArguments($argv);
  53816. $runner = $this->createRunner();
  53817. if (is_object($this->arguments['test']) &&
  53818. $this->arguments['test'] instanceof PHPUnit_Framework_Test) {
  53819. $suite = $this->arguments['test'];
  53820. } else {
  53821. $suite = $runner->getTest(
  53822. $this->arguments['test'],
  53823. $this->arguments['testFile'],
  53824. $this->arguments['testSuffixes']
  53825. );
  53826. }
  53827. if ($this->arguments['listGroups']) {
  53828. $this->printVersionString();
  53829. print "Available test group(s):\n";
  53830. $groups = $suite->getGroups();
  53831. sort($groups);
  53832. foreach ($groups as $group) {
  53833. print " - $group\n";
  53834. }
  53835. if ($exit) {
  53836. exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
  53837. } else {
  53838. return PHPUnit_TextUI_TestRunner::SUCCESS_EXIT;
  53839. }
  53840. }
  53841. unset($this->arguments['test']);
  53842. unset($this->arguments['testFile']);
  53843. try {
  53844. $result = $runner->doRun($suite, $this->arguments);
  53845. } catch (PHPUnit_Framework_Exception $e) {
  53846. print $e->getMessage() . "\n";
  53847. }
  53848. $ret = PHPUnit_TextUI_TestRunner::FAILURE_EXIT;
  53849. if (isset($result) && $result->wasSuccessful()) {
  53850. $ret = PHPUnit_TextUI_TestRunner::SUCCESS_EXIT;
  53851. } elseif (!isset($result) || $result->errorCount() > 0) {
  53852. $ret = PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT;
  53853. }
  53854. if ($exit) {
  53855. exit($ret);
  53856. } else {
  53857. return $ret;
  53858. }
  53859. }
  53860. /**
  53861. * Create a TestRunner, override in subclasses.
  53862. *
  53863. * @return PHPUnit_TextUI_TestRunner
  53864. * @since Method available since Release 3.6.0
  53865. */
  53866. protected function createRunner()
  53867. {
  53868. return new PHPUnit_TextUI_TestRunner($this->arguments['loader']);
  53869. }
  53870. /**
  53871. * Handles the command-line arguments.
  53872. *
  53873. * A child class of PHPUnit_TextUI_Command can hook into the argument
  53874. * parsing by adding the switch(es) to the $longOptions array and point to a
  53875. * callback method that handles the switch(es) in the child class like this
  53876. *
  53877. * <code>
  53878. * <?php
  53879. * class MyCommand extends PHPUnit_TextUI_Command
  53880. * {
  53881. * public function __construct()
  53882. * {
  53883. * // my-switch won't accept a value, it's an on/off
  53884. * $this->longOptions['my-switch'] = 'myHandler';
  53885. * // my-secondswitch will accept a value - note the equals sign
  53886. * $this->longOptions['my-secondswitch='] = 'myOtherHandler';
  53887. * }
  53888. *
  53889. * // --my-switch -> myHandler()
  53890. * protected function myHandler()
  53891. * {
  53892. * }
  53893. *
  53894. * // --my-secondswitch foo -> myOtherHandler('foo')
  53895. * protected function myOtherHandler ($value)
  53896. * {
  53897. * }
  53898. *
  53899. * // You will also need this - the static keyword in the
  53900. * // PHPUnit_TextUI_Command will mean that it'll be
  53901. * // PHPUnit_TextUI_Command that gets instantiated,
  53902. * // not MyCommand
  53903. * public static function main($exit = true)
  53904. * {
  53905. * $command = new static;
  53906. *
  53907. * return $command->run($_SERVER['argv'], $exit);
  53908. * }
  53909. *
  53910. * }
  53911. * </code>
  53912. *
  53913. * @param array $argv
  53914. */
  53915. protected function handleArguments(array $argv)
  53916. {
  53917. if (defined('__PHPUNIT_PHAR__')) {
  53918. $this->longOptions['selfupdate'] = null;
  53919. $this->longOptions['self-update'] = null;
  53920. }
  53921. try {
  53922. $this->options = PHPUnit_Util_Getopt::getopt(
  53923. $argv,
  53924. 'd:c:hv',
  53925. array_keys($this->longOptions)
  53926. );
  53927. } catch (PHPUnit_Framework_Exception $e) {
  53928. $this->showError($e->getMessage());
  53929. }
  53930. foreach ($this->options[0] as $option) {
  53931. switch ($option[0]) {
  53932. case '--colors':
  53933. $this->arguments['colors'] = $option[1] ?: PHPUnit_TextUI_ResultPrinter::COLOR_AUTO;
  53934. break;
  53935. case '--bootstrap':
  53936. $this->arguments['bootstrap'] = $option[1];
  53937. break;
  53938. case '--columns':
  53939. if (is_numeric($option[1])) {
  53940. $this->arguments['columns'] = (int) $option[1];
  53941. } elseif ($option[1] == 'max') {
  53942. $this->arguments['columns'] = 'max';
  53943. }
  53944. break;
  53945. case 'c':
  53946. case '--configuration':
  53947. $this->arguments['configuration'] = $option[1];
  53948. break;
  53949. case '--coverage-clover':
  53950. $this->arguments['coverageClover'] = $option[1];
  53951. break;
  53952. case '--coverage-crap4j':
  53953. $this->arguments['coverageCrap4J'] = $option[1];
  53954. break;
  53955. case '--coverage-html':
  53956. $this->arguments['coverageHtml'] = $option[1];
  53957. break;
  53958. case '--coverage-php':
  53959. $this->arguments['coveragePHP'] = $option[1];
  53960. break;
  53961. case '--coverage-text':
  53962. if ($option[1] === null) {
  53963. $option[1] = 'php://stdout';
  53964. }
  53965. $this->arguments['coverageText'] = $option[1];
  53966. $this->arguments['coverageTextShowUncoveredFiles'] = false;
  53967. $this->arguments['coverageTextShowOnlySummary'] = false;
  53968. break;
  53969. case '--coverage-xml':
  53970. $this->arguments['coverageXml'] = $option[1];
  53971. break;
  53972. case 'd':
  53973. $ini = explode('=', $option[1]);
  53974. if (isset($ini[0])) {
  53975. if (isset($ini[1])) {
  53976. ini_set($ini[0], $ini[1]);
  53977. } else {
  53978. ini_set($ini[0], true);
  53979. }
  53980. }
  53981. break;
  53982. case '--debug':
  53983. $this->arguments['debug'] = true;
  53984. break;
  53985. case 'h':
  53986. case '--help':
  53987. $this->showHelp();
  53988. exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
  53989. break;
  53990. case '--filter':
  53991. $this->arguments['filter'] = $option[1];
  53992. break;
  53993. case '--testsuite':
  53994. $this->arguments['testsuite'] = $option[1];
  53995. break;
  53996. case '--group':
  53997. $this->arguments['groups'] = explode(',', $option[1]);
  53998. break;
  53999. case '--exclude-group':
  54000. $this->arguments['excludeGroups'] = explode(
  54001. ',',
  54002. $option[1]
  54003. );
  54004. break;
  54005. case '--test-suffix':
  54006. $this->arguments['testSuffixes'] = explode(
  54007. ',',
  54008. $option[1]
  54009. );
  54010. break;
  54011. case '--include-path':
  54012. $includePath = $option[1];
  54013. break;
  54014. case '--list-groups':
  54015. $this->arguments['listGroups'] = true;
  54016. break;
  54017. case '--printer':
  54018. $this->arguments['printer'] = $option[1];
  54019. break;
  54020. case '--loader':
  54021. $this->arguments['loader'] = $option[1];
  54022. break;
  54023. case '--log-json':
  54024. $this->arguments['jsonLogfile'] = $option[1];
  54025. break;
  54026. case '--log-junit':
  54027. $this->arguments['junitLogfile'] = $option[1];
  54028. break;
  54029. case '--log-tap':
  54030. $this->arguments['tapLogfile'] = $option[1];
  54031. break;
  54032. case '--process-isolation':
  54033. $this->arguments['processIsolation'] = true;
  54034. break;
  54035. case '--repeat':
  54036. $this->arguments['repeat'] = (int) $option[1];
  54037. break;
  54038. case '--stderr':
  54039. $this->arguments['stderr'] = true;
  54040. break;
  54041. case '--stop-on-error':
  54042. $this->arguments['stopOnError'] = true;
  54043. break;
  54044. case '--stop-on-failure':
  54045. $this->arguments['stopOnFailure'] = true;
  54046. break;
  54047. case '--stop-on-incomplete':
  54048. $this->arguments['stopOnIncomplete'] = true;
  54049. break;
  54050. case '--stop-on-risky':
  54051. $this->arguments['stopOnRisky'] = true;
  54052. break;
  54053. case '--stop-on-skipped':
  54054. $this->arguments['stopOnSkipped'] = true;
  54055. break;
  54056. case '--tap':
  54057. $this->arguments['printer'] = 'PHPUnit_Util_Log_TAP';
  54058. break;
  54059. case '--testdox':
  54060. $this->arguments['printer'] = 'PHPUnit_Util_TestDox_ResultPrinter_Text';
  54061. break;
  54062. case '--testdox-html':
  54063. $this->arguments['testdoxHTMLFile'] = $option[1];
  54064. break;
  54065. case '--testdox-text':
  54066. $this->arguments['testdoxTextFile'] = $option[1];
  54067. break;
  54068. case '--no-configuration':
  54069. $this->arguments['useDefaultConfiguration'] = false;
  54070. break;
  54071. case '--no-globals-backup':
  54072. $this->arguments['backupGlobals'] = false;
  54073. break;
  54074. case '--static-backup':
  54075. $this->arguments['backupStaticAttributes'] = true;
  54076. break;
  54077. case 'v':
  54078. case '--verbose':
  54079. $this->arguments['verbose'] = true;
  54080. break;
  54081. case '--version':
  54082. $this->printVersionString();
  54083. exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
  54084. break;
  54085. case '--report-useless-tests':
  54086. $this->arguments['reportUselessTests'] = true;
  54087. break;
  54088. case '--strict-coverage':
  54089. $this->arguments['strictCoverage'] = true;
  54090. break;
  54091. case '--strict-global-state':
  54092. $this->arguments['disallowChangesToGlobalState'] = true;
  54093. break;
  54094. case '--disallow-test-output':
  54095. $this->arguments['disallowTestOutput'] = true;
  54096. break;
  54097. case '--enforce-time-limit':
  54098. $this->arguments['enforceTimeLimit'] = true;
  54099. break;
  54100. case '--disallow-todo-tests':
  54101. $this->arguments['disallowTodoAnnotatedTests'] = true;
  54102. break;
  54103. case '--strict':
  54104. $this->arguments['reportUselessTests'] = true;
  54105. $this->arguments['strictCoverage'] = true;
  54106. $this->arguments['disallowTestOutput'] = true;
  54107. $this->arguments['enforceTimeLimit'] = true;
  54108. $this->arguments['disallowTodoAnnotatedTests'] = true;
  54109. $this->arguments['deprecatedStrictModeOption'] = true;
  54110. break;
  54111. case '--selfupdate':
  54112. case '--self-update':
  54113. $this->handleSelfUpdate();
  54114. break;
  54115. default:
  54116. $optionName = str_replace('--', '', $option[0]);
  54117. if (isset($this->longOptions[$optionName])) {
  54118. $handler = $this->longOptions[$optionName];
  54119. } elseif (isset($this->longOptions[$optionName . '='])) {
  54120. $handler = $this->longOptions[$optionName . '='];
  54121. }
  54122. if (isset($handler) && is_callable(array($this, $handler))) {
  54123. $this->$handler($option[1]);
  54124. }
  54125. }
  54126. }
  54127. $this->handleCustomTestSuite();
  54128. if (!isset($this->arguments['test'])) {
  54129. if (isset($this->options[1][0])) {
  54130. $this->arguments['test'] = $this->options[1][0];
  54131. }
  54132. if (isset($this->options[1][1])) {
  54133. $this->arguments['testFile'] = realpath($this->options[1][1]);
  54134. } else {
  54135. $this->arguments['testFile'] = '';
  54136. }
  54137. if (isset($this->arguments['test']) &&
  54138. is_file($this->arguments['test']) &&
  54139. substr($this->arguments['test'], -5, 5) != '.phpt') {
  54140. $this->arguments['testFile'] = realpath($this->arguments['test']);
  54141. $this->arguments['test'] = substr($this->arguments['test'], 0, strrpos($this->arguments['test'], '.'));
  54142. }
  54143. }
  54144. if (!isset($this->arguments['testSuffixes'])) {
  54145. $this->arguments['testSuffixes'] = array('Test.php', '.phpt');
  54146. }
  54147. if (isset($includePath)) {
  54148. ini_set(
  54149. 'include_path',
  54150. $includePath . PATH_SEPARATOR . ini_get('include_path')
  54151. );
  54152. }
  54153. if ($this->arguments['loader'] !== null) {
  54154. $this->arguments['loader'] = $this->handleLoader($this->arguments['loader']);
  54155. }
  54156. if (isset($this->arguments['configuration']) &&
  54157. is_dir($this->arguments['configuration'])) {
  54158. $configurationFile = $this->arguments['configuration'] . '/phpunit.xml';
  54159. if (file_exists($configurationFile)) {
  54160. $this->arguments['configuration'] = realpath(
  54161. $configurationFile
  54162. );
  54163. } elseif (file_exists($configurationFile . '.dist')) {
  54164. $this->arguments['configuration'] = realpath(
  54165. $configurationFile . '.dist'
  54166. );
  54167. }
  54168. } elseif (!isset($this->arguments['configuration']) &&
  54169. $this->arguments['useDefaultConfiguration']) {
  54170. if (file_exists('phpunit.xml')) {
  54171. $this->arguments['configuration'] = realpath('phpunit.xml');
  54172. } elseif (file_exists('phpunit.xml.dist')) {
  54173. $this->arguments['configuration'] = realpath(
  54174. 'phpunit.xml.dist'
  54175. );
  54176. }
  54177. }
  54178. if (isset($this->arguments['configuration'])) {
  54179. try {
  54180. $configuration = PHPUnit_Util_Configuration::getInstance(
  54181. $this->arguments['configuration']
  54182. );
  54183. } catch (Throwable $e) {
  54184. print $e->getMessage() . "\n";
  54185. exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT);
  54186. } catch (Exception $e) {
  54187. print $e->getMessage() . "\n";
  54188. exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT);
  54189. }
  54190. $phpunit = $configuration->getPHPUnitConfiguration();
  54191. $configuration->handlePHPConfiguration();
  54192. /*
  54193. * Issue #1216
  54194. */
  54195. if (isset($this->arguments['bootstrap'])) {
  54196. $this->handleBootstrap($this->arguments['bootstrap']);
  54197. } elseif (isset($phpunit['bootstrap'])) {
  54198. $this->handleBootstrap($phpunit['bootstrap']);
  54199. }
  54200. /*
  54201. * Issue #657
  54202. */
  54203. if (isset($phpunit['stderr']) && ! isset($this->arguments['stderr'])) {
  54204. $this->arguments['stderr'] = $phpunit['stderr'];
  54205. }
  54206. if (isset($phpunit['printerClass'])) {
  54207. if (isset($phpunit['printerFile'])) {
  54208. $file = $phpunit['printerFile'];
  54209. } else {
  54210. $file = '';
  54211. }
  54212. $this->arguments['printer'] = $this->handlePrinter(
  54213. $phpunit['printerClass'],
  54214. $file
  54215. );
  54216. }
  54217. if (isset($phpunit['testSuiteLoaderClass'])) {
  54218. if (isset($phpunit['testSuiteLoaderFile'])) {
  54219. $file = $phpunit['testSuiteLoaderFile'];
  54220. } else {
  54221. $file = '';
  54222. }
  54223. $this->arguments['loader'] = $this->handleLoader(
  54224. $phpunit['testSuiteLoaderClass'],
  54225. $file
  54226. );
  54227. }
  54228. $browsers = $configuration->getSeleniumBrowserConfiguration();
  54229. if (!empty($browsers)) {
  54230. $this->arguments['deprecatedSeleniumConfiguration'] = true;
  54231. if (class_exists('PHPUnit_Extensions_SeleniumTestCase')) {
  54232. PHPUnit_Extensions_SeleniumTestCase::$browsers = $browsers;
  54233. }
  54234. }
  54235. if (!isset($this->arguments['test'])) {
  54236. $testSuite = $configuration->getTestSuiteConfiguration(isset($this->arguments['testsuite']) ? $this->arguments['testsuite'] : null);
  54237. if ($testSuite !== null) {
  54238. $this->arguments['test'] = $testSuite;
  54239. }
  54240. }
  54241. } elseif (isset($this->arguments['bootstrap'])) {
  54242. $this->handleBootstrap($this->arguments['bootstrap']);
  54243. }
  54244. if (isset($this->arguments['printer']) &&
  54245. is_string($this->arguments['printer'])) {
  54246. $this->arguments['printer'] = $this->handlePrinter($this->arguments['printer']);
  54247. }
  54248. if (isset($this->arguments['test']) && is_string($this->arguments['test']) && substr($this->arguments['test'], -5, 5) == '.phpt') {
  54249. $test = new PHPUnit_Extensions_PhptTestCase($this->arguments['test']);
  54250. $this->arguments['test'] = new PHPUnit_Framework_TestSuite;
  54251. $this->arguments['test']->addTest($test);
  54252. }
  54253. if (!isset($this->arguments['test']) ||
  54254. (isset($this->arguments['testDatabaseLogRevision']) && !isset($this->arguments['testDatabaseDSN']))) {
  54255. $this->showHelp();
  54256. exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT);
  54257. }
  54258. }
  54259. /**
  54260. * Handles the loading of the PHPUnit_Runner_TestSuiteLoader implementation.
  54261. *
  54262. * @param string $loaderClass
  54263. * @param string $loaderFile
  54264. * @return PHPUnit_Runner_TestSuiteLoader
  54265. */
  54266. protected function handleLoader($loaderClass, $loaderFile = '')
  54267. {
  54268. if (!class_exists($loaderClass, false)) {
  54269. if ($loaderFile == '') {
  54270. $loaderFile = PHPUnit_Util_Filesystem::classNameToFilename(
  54271. $loaderClass
  54272. );
  54273. }
  54274. $loaderFile = stream_resolve_include_path($loaderFile);
  54275. if ($loaderFile) {
  54276. require $loaderFile;
  54277. }
  54278. }
  54279. if (class_exists($loaderClass, false)) {
  54280. $class = new ReflectionClass($loaderClass);
  54281. if ($class->implementsInterface('PHPUnit_Runner_TestSuiteLoader') &&
  54282. $class->isInstantiable()) {
  54283. return $class->newInstance();
  54284. }
  54285. }
  54286. if ($loaderClass == 'PHPUnit_Runner_StandardTestSuiteLoader') {
  54287. return;
  54288. }
  54289. $this->showError(
  54290. sprintf(
  54291. 'Could not use "%s" as loader.',
  54292. $loaderClass
  54293. )
  54294. );
  54295. }
  54296. /**
  54297. * Handles the loading of the PHPUnit_Util_Printer implementation.
  54298. *
  54299. * @param string $printerClass
  54300. * @param string $printerFile
  54301. * @return PHPUnit_Util_Printer
  54302. */
  54303. protected function handlePrinter($printerClass, $printerFile = '')
  54304. {
  54305. if (!class_exists($printerClass, false)) {
  54306. if ($printerFile == '') {
  54307. $printerFile = PHPUnit_Util_Filesystem::classNameToFilename(
  54308. $printerClass
  54309. );
  54310. }
  54311. $printerFile = stream_resolve_include_path($printerFile);
  54312. if ($printerFile) {
  54313. require $printerFile;
  54314. }
  54315. }
  54316. if (class_exists($printerClass)) {
  54317. $class = new ReflectionClass($printerClass);
  54318. if ($class->implementsInterface('PHPUnit_Framework_TestListener') &&
  54319. $class->isSubclassOf('PHPUnit_Util_Printer') &&
  54320. $class->isInstantiable()) {
  54321. if ($class->isSubclassOf('PHPUnit_TextUI_ResultPrinter')) {
  54322. return $printerClass;
  54323. }
  54324. $outputStream = isset($this->arguments['stderr']) ? 'php://stderr' : null;
  54325. return $class->newInstance($outputStream);
  54326. }
  54327. }
  54328. $this->showError(
  54329. sprintf(
  54330. 'Could not use "%s" as printer.',
  54331. $printerClass
  54332. )
  54333. );
  54334. }
  54335. /**
  54336. * Loads a bootstrap file.
  54337. *
  54338. * @param string $filename
  54339. */
  54340. protected function handleBootstrap($filename)
  54341. {
  54342. try {
  54343. PHPUnit_Util_Fileloader::checkAndLoad($filename);
  54344. } catch (PHPUnit_Framework_Exception $e) {
  54345. $this->showError($e->getMessage());
  54346. }
  54347. }
  54348. /**
  54349. * @since Method available since Release 4.0.0
  54350. */
  54351. protected function handleSelfUpdate()
  54352. {
  54353. $this->printVersionString();
  54354. $localFilename = realpath($_SERVER['argv'][0]);
  54355. if (!is_writable($localFilename)) {
  54356. print 'No write permission to update ' . $localFilename . "\n";
  54357. exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT);
  54358. }
  54359. if (!extension_loaded('openssl')) {
  54360. print "The OpenSSL extension is not loaded.\n";
  54361. exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT);
  54362. }
  54363. $remoteFilename = sprintf(
  54364. 'https://phar.phpunit.de/phpunit%s.phar',
  54365. PHPUnit_Runner_Version::getReleaseChannel()
  54366. );
  54367. $tempFilename = tempnam(sys_get_temp_dir(), 'phpunit') . '.phar';
  54368. // Workaround for https://bugs.php.net/bug.php?id=65538
  54369. $caFile = dirname($tempFilename) . '/ca.pem';
  54370. copy(__PHPUNIT_PHAR_ROOT__ . '/ca.pem', $caFile);
  54371. print 'Updating the PHPUnit PHAR ... ';
  54372. $options = array(
  54373. 'ssl' => array(
  54374. 'allow_self_signed' => false,
  54375. 'cafile' => $caFile,
  54376. 'verify_peer' => true
  54377. )
  54378. );
  54379. if (PHP_VERSION_ID < 50600) {
  54380. $options['ssl']['CN_match'] = 'phar.phpunit.de';
  54381. $options['ssl']['SNI_server_name'] = 'phar.phpunit.de';
  54382. }
  54383. file_put_contents(
  54384. $tempFilename,
  54385. file_get_contents(
  54386. $remoteFilename,
  54387. false,
  54388. stream_context_create($options)
  54389. )
  54390. );
  54391. chmod($tempFilename, 0777 & ~umask());
  54392. try {
  54393. $phar = new Phar($tempFilename);
  54394. unset($phar);
  54395. rename($tempFilename, $localFilename);
  54396. unlink($caFile);
  54397. } catch (Throwable $_e) {
  54398. $e = $_e;
  54399. } catch (Exception $_e) {
  54400. $e = $_e;
  54401. }
  54402. if (isset($e)) {
  54403. unlink($caFile);
  54404. unlink($tempFilename);
  54405. print " done\n\n" . $e->getMessage() . "\n";
  54406. exit(2);
  54407. }
  54408. print " done\n";
  54409. exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT);
  54410. }
  54411. /**
  54412. * Show the help message.
  54413. */
  54414. protected function showHelp()
  54415. {
  54416. $this->printVersionString();
  54417. print <<<EOT
  54418. Usage: phpunit [options] UnitTest [UnitTest.php]
  54419. phpunit [options] <directory>
  54420. Code Coverage Options:
  54421. --coverage-clover <file> Generate code coverage report in Clover XML format.
  54422. --coverage-crap4j <file> Generate code coverage report in Crap4J XML format.
  54423. --coverage-html <dir> Generate code coverage report in HTML format.
  54424. --coverage-php <file> Export PHP_CodeCoverage object to file.
  54425. --coverage-text=<file> Generate code coverage report in text format.
  54426. Default: Standard output.
  54427. --coverage-xml <dir> Generate code coverage report in PHPUnit XML format.
  54428. Logging Options:
  54429. --log-junit <file> Log test execution in JUnit XML format to file.
  54430. --log-tap <file> Log test execution in TAP format to file.
  54431. --log-json <file> Log test execution in JSON format.
  54432. --testdox-html <file> Write agile documentation in HTML format to file.
  54433. --testdox-text <file> Write agile documentation in Text format to file.
  54434. Test Selection Options:
  54435. --filter <pattern> Filter which tests to run.
  54436. --testsuite <pattern> Filter which testsuite to run.
  54437. --group ... Only runs tests from the specified group(s).
  54438. --exclude-group ... Exclude tests from the specified group(s).
  54439. --list-groups List available test groups.
  54440. --test-suffix ... Only search for test in files with specified
  54441. suffix(es). Default: Test.php,.phpt
  54442. Test Execution Options:
  54443. --report-useless-tests Be strict about tests that do not test anything.
  54444. --strict-coverage Be strict about unintentionally covered code.
  54445. --strict-global-state Be strict about changes to global state
  54446. --disallow-test-output Be strict about output during tests.
  54447. --enforce-time-limit Enforce time limit based on test size.
  54448. --disallow-todo-tests Disallow @todo-annotated tests.
  54449. --process-isolation Run each test in a separate PHP process.
  54450. --no-globals-backup Do not backup and restore \$GLOBALS for each test.
  54451. --static-backup Backup and restore static attributes for each test.
  54452. --colors=<flag> Use colors in output ("never", "auto" or "always").
  54453. --columns <n> Number of columns to use for progress output.
  54454. --columns max Use maximum number of columns for progress output.
  54455. --stderr Write to STDERR instead of STDOUT.
  54456. --stop-on-error Stop execution upon first error.
  54457. --stop-on-failure Stop execution upon first error or failure.
  54458. --stop-on-risky Stop execution upon first risky test.
  54459. --stop-on-skipped Stop execution upon first skipped test.
  54460. --stop-on-incomplete Stop execution upon first incomplete test.
  54461. -v|--verbose Output more verbose information.
  54462. --debug Display debugging information during test execution.
  54463. --loader <loader> TestSuiteLoader implementation to use.
  54464. --repeat <times> Runs the test(s) repeatedly.
  54465. --tap Report test execution progress in TAP format.
  54466. --testdox Report test execution progress in TestDox format.
  54467. --printer <printer> TestListener implementation to use.
  54468. Configuration Options:
  54469. --bootstrap <file> A "bootstrap" PHP file that is run before the tests.
  54470. -c|--configuration <file> Read configuration from XML file.
  54471. --no-configuration Ignore default configuration file (phpunit.xml).
  54472. --include-path <path(s)> Prepend PHP's include_path with given path(s).
  54473. -d key[=value] Sets a php.ini value.
  54474. Miscellaneous Options:
  54475. -h|--help Prints this usage information.
  54476. --version Prints the version and exits.
  54477. EOT;
  54478. if (defined('__PHPUNIT_PHAR__')) {
  54479. print "\n --self-update Update PHPUnit to the latest version.\n";
  54480. }
  54481. }
  54482. /**
  54483. * Custom callback for test suite discovery.
  54484. */
  54485. protected function handleCustomTestSuite()
  54486. {
  54487. }
  54488. private function printVersionString()
  54489. {
  54490. if ($this->versionStringPrinted) {
  54491. return;
  54492. }
  54493. print PHPUnit_Runner_Version::getVersionString() . "\n\n";
  54494. $this->versionStringPrinted = true;
  54495. }
  54496. /**
  54497. */
  54498. private function showError($message)
  54499. {
  54500. $this->printVersionString();
  54501. print $message . "\n";
  54502. exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT);
  54503. }
  54504. }
  54505. <?php
  54506. /*
  54507. * This file is part of PHPUnit.
  54508. *
  54509. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  54510. *
  54511. * For the full copyright and license information, please view the LICENSE
  54512. * file that was distributed with this source code.
  54513. */
  54514. use SebastianBergmann\Environment\Runtime;
  54515. /**
  54516. * A TestRunner for the Command Line Interface (CLI)
  54517. * PHP SAPI Module.
  54518. *
  54519. * @since Class available since Release 2.0.0
  54520. */
  54521. class PHPUnit_TextUI_TestRunner extends PHPUnit_Runner_BaseTestRunner
  54522. {
  54523. const SUCCESS_EXIT = 0;
  54524. const FAILURE_EXIT = 1;
  54525. const EXCEPTION_EXIT = 2;
  54526. /**
  54527. * @var PHP_CodeCoverage_Filter
  54528. */
  54529. protected $codeCoverageFilter;
  54530. /**
  54531. * @var PHPUnit_Runner_TestSuiteLoader
  54532. */
  54533. protected $loader = null;
  54534. /**
  54535. * @var PHPUnit_TextUI_ResultPrinter
  54536. */
  54537. protected $printer = null;
  54538. /**
  54539. * @var bool
  54540. */
  54541. protected static $versionStringPrinted = false;
  54542. /**
  54543. * @var array
  54544. */
  54545. private $missingExtensions = array();
  54546. /**
  54547. * @var Runtime
  54548. */
  54549. private $runtime;
  54550. /**
  54551. * @param PHPUnit_Runner_TestSuiteLoader $loader
  54552. * @param PHP_CodeCoverage_Filter $filter
  54553. * @since Method available since Release 3.4.0
  54554. */
  54555. public function __construct(PHPUnit_Runner_TestSuiteLoader $loader = null, PHP_CodeCoverage_Filter $filter = null)
  54556. {
  54557. if ($filter === null) {
  54558. $filter = $this->getCodeCoverageFilter();
  54559. }
  54560. $this->codeCoverageFilter = $filter;
  54561. $this->loader = $loader;
  54562. $this->runtime = new Runtime;
  54563. }
  54564. /**
  54565. * @param PHPUnit_Framework_Test|ReflectionClass $test
  54566. * @param array $arguments
  54567. * @return PHPUnit_Framework_TestResult
  54568. * @throws PHPUnit_Framework_Exception
  54569. */
  54570. public static function run($test, array $arguments = array())
  54571. {
  54572. if ($test instanceof ReflectionClass) {
  54573. $test = new PHPUnit_Framework_TestSuite($test);
  54574. }
  54575. if ($test instanceof PHPUnit_Framework_Test) {
  54576. $aTestRunner = new self;
  54577. return $aTestRunner->doRun(
  54578. $test,
  54579. $arguments
  54580. );
  54581. } else {
  54582. throw new PHPUnit_Framework_Exception(
  54583. 'No test case or test suite found.'
  54584. );
  54585. }
  54586. }
  54587. /**
  54588. * @return PHPUnit_Framework_TestResult
  54589. */
  54590. protected function createTestResult()
  54591. {
  54592. return new PHPUnit_Framework_TestResult;
  54593. }
  54594. private function processSuiteFilters(PHPUnit_Framework_TestSuite $suite, array $arguments)
  54595. {
  54596. if (!$arguments['filter'] &&
  54597. empty($arguments['groups']) &&
  54598. empty($arguments['excludeGroups'])) {
  54599. return;
  54600. }
  54601. $filterFactory = new PHPUnit_Runner_Filter_Factory();
  54602. if (!empty($arguments['excludeGroups'])) {
  54603. $filterFactory->addFilter(
  54604. new ReflectionClass('PHPUnit_Runner_Filter_Group_Exclude'),
  54605. $arguments['excludeGroups']
  54606. );
  54607. }
  54608. if (!empty($arguments['groups'])) {
  54609. $filterFactory->addFilter(
  54610. new ReflectionClass('PHPUnit_Runner_Filter_Group_Include'),
  54611. $arguments['groups']
  54612. );
  54613. }
  54614. if ($arguments['filter']) {
  54615. $filterFactory->addFilter(
  54616. new ReflectionClass('PHPUnit_Runner_Filter_Test'),
  54617. $arguments['filter']
  54618. );
  54619. }
  54620. $suite->injectFilter($filterFactory);
  54621. }
  54622. /**
  54623. * @param PHPUnit_Framework_Test $suite
  54624. * @param array $arguments
  54625. * @return PHPUnit_Framework_TestResult
  54626. */
  54627. public function doRun(PHPUnit_Framework_Test $suite, array $arguments = array())
  54628. {
  54629. $this->handleConfiguration($arguments);
  54630. $this->processSuiteFilters($suite, $arguments);
  54631. if (isset($arguments['bootstrap'])) {
  54632. $GLOBALS['__PHPUNIT_BOOTSTRAP'] = $arguments['bootstrap'];
  54633. }
  54634. if ($arguments['backupGlobals'] === false) {
  54635. $suite->setBackupGlobals(false);
  54636. }
  54637. if ($arguments['backupStaticAttributes'] === true) {
  54638. $suite->setBackupStaticAttributes(true);
  54639. }
  54640. if ($arguments['disallowChangesToGlobalState'] === true) {
  54641. $suite->setDisallowChangesToGlobalState(true);
  54642. }
  54643. if (is_integer($arguments['repeat'])) {
  54644. $test = new PHPUnit_Extensions_RepeatedTest(
  54645. $suite,
  54646. $arguments['repeat'],
  54647. $arguments['processIsolation']
  54648. );
  54649. $suite = new PHPUnit_Framework_TestSuite();
  54650. $suite->addTest($test);
  54651. }
  54652. $result = $this->createTestResult();
  54653. if (!$arguments['convertErrorsToExceptions']) {
  54654. $result->convertErrorsToExceptions(false);
  54655. }
  54656. if (!$arguments['convertNoticesToExceptions']) {
  54657. PHPUnit_Framework_Error_Notice::$enabled = false;
  54658. }
  54659. if (!$arguments['convertWarningsToExceptions']) {
  54660. PHPUnit_Framework_Error_Warning::$enabled = false;
  54661. }
  54662. if ($arguments['stopOnError']) {
  54663. $result->stopOnError(true);
  54664. }
  54665. if ($arguments['stopOnFailure']) {
  54666. $result->stopOnFailure(true);
  54667. }
  54668. if ($arguments['stopOnIncomplete']) {
  54669. $result->stopOnIncomplete(true);
  54670. }
  54671. if ($arguments['stopOnRisky']) {
  54672. $result->stopOnRisky(true);
  54673. }
  54674. if ($arguments['stopOnSkipped']) {
  54675. $result->stopOnSkipped(true);
  54676. }
  54677. if ($this->printer === null) {
  54678. if (isset($arguments['printer']) &&
  54679. $arguments['printer'] instanceof PHPUnit_Util_Printer) {
  54680. $this->printer = $arguments['printer'];
  54681. } else {
  54682. $printerClass = 'PHPUnit_TextUI_ResultPrinter';
  54683. if (isset($arguments['printer']) &&
  54684. is_string($arguments['printer']) &&
  54685. class_exists($arguments['printer'], false)) {
  54686. $class = new ReflectionClass($arguments['printer']);
  54687. if ($class->isSubclassOf('PHPUnit_TextUI_ResultPrinter')) {
  54688. $printerClass = $arguments['printer'];
  54689. }
  54690. }
  54691. $this->printer = new $printerClass(
  54692. isset($arguments['stderr']) ? 'php://stderr' : null,
  54693. $arguments['verbose'],
  54694. $arguments['colors'],
  54695. $arguments['debug'],
  54696. $arguments['columns']
  54697. );
  54698. }
  54699. }
  54700. if (!$this->printer instanceof PHPUnit_Util_Log_TAP) {
  54701. $this->printer->write(
  54702. PHPUnit_Runner_Version::getVersionString() . "\n"
  54703. );
  54704. self::$versionStringPrinted = true;
  54705. if ($arguments['verbose']) {
  54706. $this->printer->write(
  54707. sprintf(
  54708. "\nRuntime:\t%s",
  54709. $this->runtime->getNameWithVersion()
  54710. )
  54711. );
  54712. if ($this->runtime->hasXdebug()) {
  54713. $this->printer->write(
  54714. sprintf(
  54715. ' with Xdebug %s',
  54716. phpversion('xdebug')
  54717. )
  54718. );
  54719. }
  54720. if (isset($arguments['configuration'])) {
  54721. $this->printer->write(
  54722. sprintf(
  54723. "\nConfiguration:\t%s",
  54724. $arguments['configuration']->getFilename()
  54725. )
  54726. );
  54727. }
  54728. $this->printer->write("\n");
  54729. }
  54730. if (isset($arguments['deprecatedStrictModeOption'])) {
  54731. print "Warning:\tDeprecated option \"--strict\" used\n";
  54732. } elseif (isset($arguments['deprecatedStrictModeSetting'])) {
  54733. print "Warning:\tDeprecated configuration setting \"strict\" used\n";
  54734. }
  54735. if (isset($arguments['deprecatedSeleniumConfiguration'])) {
  54736. print "Warning:\tDeprecated configuration setting \"selenium\" used\n";
  54737. }
  54738. }
  54739. foreach ($arguments['listeners'] as $listener) {
  54740. $result->addListener($listener);
  54741. }
  54742. $result->addListener($this->printer);
  54743. if (isset($arguments['testdoxHTMLFile'])) {
  54744. $result->addListener(
  54745. new PHPUnit_Util_TestDox_ResultPrinter_HTML(
  54746. $arguments['testdoxHTMLFile']
  54747. )
  54748. );
  54749. }
  54750. if (isset($arguments['testdoxTextFile'])) {
  54751. $result->addListener(
  54752. new PHPUnit_Util_TestDox_ResultPrinter_Text(
  54753. $arguments['testdoxTextFile']
  54754. )
  54755. );
  54756. }
  54757. $codeCoverageReports = 0;
  54758. if (isset($arguments['coverageClover'])) {
  54759. $codeCoverageReports++;
  54760. }
  54761. if (isset($arguments['coverageCrap4J'])) {
  54762. $codeCoverageReports++;
  54763. }
  54764. if (isset($arguments['coverageHtml'])) {
  54765. $codeCoverageReports++;
  54766. }
  54767. if (isset($arguments['coveragePHP'])) {
  54768. $codeCoverageReports++;
  54769. }
  54770. if (isset($arguments['coverageText'])) {
  54771. $codeCoverageReports++;
  54772. }
  54773. if (isset($arguments['coverageXml'])) {
  54774. $codeCoverageReports++;
  54775. }
  54776. if ($codeCoverageReports > 0 && (!extension_loaded('tokenizer') || !$this->runtime->canCollectCodeCoverage())) {
  54777. if (!extension_loaded('tokenizer')) {
  54778. $this->showExtensionNotLoadedWarning(
  54779. 'tokenizer',
  54780. 'No code coverage will be generated.'
  54781. );
  54782. } elseif (!extension_loaded('Xdebug')) {
  54783. $this->showExtensionNotLoadedWarning(
  54784. 'Xdebug',
  54785. 'No code coverage will be generated.'
  54786. );
  54787. }
  54788. $codeCoverageReports = 0;
  54789. }
  54790. if (!$this->printer instanceof PHPUnit_Util_Log_TAP) {
  54791. if ($codeCoverageReports > 0 && !$this->codeCoverageFilter->hasWhitelist()) {
  54792. $this->printer->write("Warning:\tNo whitelist configured for code coverage\n");
  54793. }
  54794. $this->printer->write("\n");
  54795. }
  54796. if ($codeCoverageReports > 0) {
  54797. $codeCoverage = new PHP_CodeCoverage(
  54798. null,
  54799. $this->codeCoverageFilter
  54800. );
  54801. $codeCoverage->setAddUncoveredFilesFromWhitelist(
  54802. $arguments['addUncoveredFilesFromWhitelist']
  54803. );
  54804. $codeCoverage->setCheckForUnintentionallyCoveredCode(
  54805. $arguments['strictCoverage']
  54806. );
  54807. $codeCoverage->setProcessUncoveredFilesFromWhitelist(
  54808. $arguments['processUncoveredFilesFromWhitelist']
  54809. );
  54810. if (isset($arguments['forceCoversAnnotation'])) {
  54811. $codeCoverage->setForceCoversAnnotation(
  54812. $arguments['forceCoversAnnotation']
  54813. );
  54814. }
  54815. if (isset($arguments['mapTestClassNameToCoveredClassName'])) {
  54816. $codeCoverage->setMapTestClassNameToCoveredClassName(
  54817. $arguments['mapTestClassNameToCoveredClassName']
  54818. );
  54819. }
  54820. $result->setCodeCoverage($codeCoverage);
  54821. }
  54822. if ($codeCoverageReports > 1) {
  54823. if (isset($arguments['cacheTokens'])) {
  54824. $codeCoverage->setCacheTokens($arguments['cacheTokens']);
  54825. }
  54826. }
  54827. if (isset($arguments['jsonLogfile'])) {
  54828. $result->addListener(
  54829. new PHPUnit_Util_Log_JSON($arguments['jsonLogfile'])
  54830. );
  54831. }
  54832. if (isset($arguments['tapLogfile'])) {
  54833. $result->addListener(
  54834. new PHPUnit_Util_Log_TAP($arguments['tapLogfile'])
  54835. );
  54836. }
  54837. if (isset($arguments['junitLogfile'])) {
  54838. $result->addListener(
  54839. new PHPUnit_Util_Log_JUnit(
  54840. $arguments['junitLogfile'],
  54841. $arguments['logIncompleteSkipped']
  54842. )
  54843. );
  54844. }
  54845. $result->beStrictAboutTestsThatDoNotTestAnything($arguments['reportUselessTests']);
  54846. $result->beStrictAboutOutputDuringTests($arguments['disallowTestOutput']);
  54847. $result->beStrictAboutTodoAnnotatedTests($arguments['disallowTodoAnnotatedTests']);
  54848. $result->beStrictAboutTestSize($arguments['enforceTimeLimit']);
  54849. $result->setTimeoutForSmallTests($arguments['timeoutForSmallTests']);
  54850. $result->setTimeoutForMediumTests($arguments['timeoutForMediumTests']);
  54851. $result->setTimeoutForLargeTests($arguments['timeoutForLargeTests']);
  54852. if ($suite instanceof PHPUnit_Framework_TestSuite) {
  54853. $suite->setRunTestInSeparateProcess($arguments['processIsolation']);
  54854. }
  54855. $suite->run($result);
  54856. unset($suite);
  54857. $result->flushListeners();
  54858. if ($this->printer instanceof PHPUnit_TextUI_ResultPrinter) {
  54859. $this->printer->printResult($result);
  54860. }
  54861. if (isset($codeCoverage)) {
  54862. if (isset($arguments['coverageClover'])) {
  54863. $this->printer->write(
  54864. "\nGenerating code coverage report in Clover XML format ..."
  54865. );
  54866. $writer = new PHP_CodeCoverage_Report_Clover;
  54867. $writer->process($codeCoverage, $arguments['coverageClover']);
  54868. $this->printer->write(" done\n");
  54869. unset($writer);
  54870. }
  54871. if (isset($arguments['coverageCrap4J'])) {
  54872. $this->printer->write(
  54873. "\nGenerating Crap4J report XML file ..."
  54874. );
  54875. $writer = new PHP_CodeCoverage_Report_Crap4j;
  54876. $writer->process($codeCoverage, $arguments['coverageCrap4J']);
  54877. $this->printer->write(" done\n");
  54878. unset($writer);
  54879. }
  54880. if (isset($arguments['coverageHtml'])) {
  54881. $this->printer->write(
  54882. "\nGenerating code coverage report in HTML format ..."
  54883. );
  54884. $writer = new PHP_CodeCoverage_Report_HTML(
  54885. $arguments['reportLowUpperBound'],
  54886. $arguments['reportHighLowerBound'],
  54887. sprintf(
  54888. ' and <a href="http://phpunit.de/">PHPUnit %s</a>',
  54889. PHPUnit_Runner_Version::id()
  54890. )
  54891. );
  54892. $writer->process($codeCoverage, $arguments['coverageHtml']);
  54893. $this->printer->write(" done\n");
  54894. unset($writer);
  54895. }
  54896. if (isset($arguments['coveragePHP'])) {
  54897. $this->printer->write(
  54898. "\nGenerating code coverage report in PHP format ..."
  54899. );
  54900. $writer = new PHP_CodeCoverage_Report_PHP;
  54901. $writer->process($codeCoverage, $arguments['coveragePHP']);
  54902. $this->printer->write(" done\n");
  54903. unset($writer);
  54904. }
  54905. if (isset($arguments['coverageText'])) {
  54906. if ($arguments['coverageText'] == 'php://stdout') {
  54907. $outputStream = $this->printer;
  54908. $colors = $arguments['colors'];
  54909. } else {
  54910. $outputStream = new PHPUnit_Util_Printer($arguments['coverageText']);
  54911. $colors = false;
  54912. }
  54913. $processor = new PHP_CodeCoverage_Report_Text(
  54914. $arguments['reportLowUpperBound'],
  54915. $arguments['reportHighLowerBound'],
  54916. $arguments['coverageTextShowUncoveredFiles'],
  54917. $arguments['coverageTextShowOnlySummary']
  54918. );
  54919. $outputStream->write(
  54920. $processor->process($codeCoverage, $colors)
  54921. );
  54922. }
  54923. if (isset($arguments['coverageXml'])) {
  54924. $this->printer->write(
  54925. "\nGenerating code coverage report in PHPUnit XML format ..."
  54926. );
  54927. $writer = new PHP_CodeCoverage_Report_XML;
  54928. $writer->process($codeCoverage, $arguments['coverageXml']);
  54929. $this->printer->write(" done\n");
  54930. unset($writer);
  54931. }
  54932. }
  54933. return $result;
  54934. }
  54935. /**
  54936. * @param PHPUnit_TextUI_ResultPrinter $resultPrinter
  54937. */
  54938. public function setPrinter(PHPUnit_TextUI_ResultPrinter $resultPrinter)
  54939. {
  54940. $this->printer = $resultPrinter;
  54941. }
  54942. /**
  54943. * Override to define how to handle a failed loading of
  54944. * a test suite.
  54945. *
  54946. * @param string $message
  54947. */
  54948. protected function runFailed($message)
  54949. {
  54950. $this->write($message . PHP_EOL);
  54951. exit(self::FAILURE_EXIT);
  54952. }
  54953. /**
  54954. * @param string $buffer
  54955. * @since Method available since Release 3.1.0
  54956. */
  54957. protected function write($buffer)
  54958. {
  54959. if (PHP_SAPI != 'cli') {
  54960. $buffer = htmlspecialchars($buffer);
  54961. }
  54962. if ($this->printer !== null) {
  54963. $this->printer->write($buffer);
  54964. } else {
  54965. print $buffer;
  54966. }
  54967. }
  54968. /**
  54969. * Returns the loader to be used.
  54970. *
  54971. * @return PHPUnit_Runner_TestSuiteLoader
  54972. * @since Method available since Release 2.2.0
  54973. */
  54974. public function getLoader()
  54975. {
  54976. if ($this->loader === null) {
  54977. $this->loader = new PHPUnit_Runner_StandardTestSuiteLoader;
  54978. }
  54979. return $this->loader;
  54980. }
  54981. /**
  54982. * @param array $arguments
  54983. * @since Method available since Release 3.2.1
  54984. */
  54985. protected function handleConfiguration(array &$arguments)
  54986. {
  54987. if (isset($arguments['configuration']) &&
  54988. !$arguments['configuration'] instanceof PHPUnit_Util_Configuration) {
  54989. $arguments['configuration'] = PHPUnit_Util_Configuration::getInstance(
  54990. $arguments['configuration']
  54991. );
  54992. }
  54993. $arguments['debug'] = isset($arguments['debug']) ? $arguments['debug'] : false;
  54994. $arguments['filter'] = isset($arguments['filter']) ? $arguments['filter'] : false;
  54995. $arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array();
  54996. if (isset($arguments['configuration'])) {
  54997. $arguments['configuration']->handlePHPConfiguration();
  54998. $phpunitConfiguration = $arguments['configuration']->getPHPUnitConfiguration();
  54999. if (isset($phpunitConfiguration['deprecatedStrictModeSetting'])) {
  55000. $arguments['deprecatedStrictModeSetting'] = true;
  55001. }
  55002. if (isset($phpunitConfiguration['backupGlobals']) &&
  55003. !isset($arguments['backupGlobals'])) {
  55004. $arguments['backupGlobals'] = $phpunitConfiguration['backupGlobals'];
  55005. }
  55006. if (isset($phpunitConfiguration['backupStaticAttributes']) &&
  55007. !isset($arguments['backupStaticAttributes'])) {
  55008. $arguments['backupStaticAttributes'] = $phpunitConfiguration['backupStaticAttributes'];
  55009. }
  55010. if (isset($phpunitConfiguration['disallowChangesToGlobalState']) &&
  55011. !isset($arguments['disallowChangesToGlobalState'])) {
  55012. $arguments['disallowChangesToGlobalState'] = $phpunitConfiguration['disallowChangesToGlobalState'];
  55013. }
  55014. if (isset($phpunitConfiguration['bootstrap']) &&
  55015. !isset($arguments['bootstrap'])) {
  55016. $arguments['bootstrap'] = $phpunitConfiguration['bootstrap'];
  55017. }
  55018. if (isset($phpunitConfiguration['cacheTokens']) &&
  55019. !isset($arguments['cacheTokens'])) {
  55020. $arguments['cacheTokens'] = $phpunitConfiguration['cacheTokens'];
  55021. }
  55022. if (isset($phpunitConfiguration['colors']) &&
  55023. !isset($arguments['colors'])) {
  55024. $arguments['colors'] = $phpunitConfiguration['colors'];
  55025. }
  55026. if (isset($phpunitConfiguration['convertErrorsToExceptions']) &&
  55027. !isset($arguments['convertErrorsToExceptions'])) {
  55028. $arguments['convertErrorsToExceptions'] = $phpunitConfiguration['convertErrorsToExceptions'];
  55029. }
  55030. if (isset($phpunitConfiguration['convertNoticesToExceptions']) &&
  55031. !isset($arguments['convertNoticesToExceptions'])) {
  55032. $arguments['convertNoticesToExceptions'] = $phpunitConfiguration['convertNoticesToExceptions'];
  55033. }
  55034. if (isset($phpunitConfiguration['convertWarningsToExceptions']) &&
  55035. !isset($arguments['convertWarningsToExceptions'])) {
  55036. $arguments['convertWarningsToExceptions'] = $phpunitConfiguration['convertWarningsToExceptions'];
  55037. }
  55038. if (isset($phpunitConfiguration['processIsolation']) &&
  55039. !isset($arguments['processIsolation'])) {
  55040. $arguments['processIsolation'] = $phpunitConfiguration['processIsolation'];
  55041. }
  55042. if (isset($phpunitConfiguration['stopOnError']) &&
  55043. !isset($arguments['stopOnError'])) {
  55044. $arguments['stopOnError'] = $phpunitConfiguration['stopOnError'];
  55045. }
  55046. if (isset($phpunitConfiguration['stopOnFailure']) &&
  55047. !isset($arguments['stopOnFailure'])) {
  55048. $arguments['stopOnFailure'] = $phpunitConfiguration['stopOnFailure'];
  55049. }
  55050. if (isset($phpunitConfiguration['stopOnIncomplete']) &&
  55051. !isset($arguments['stopOnIncomplete'])) {
  55052. $arguments['stopOnIncomplete'] = $phpunitConfiguration['stopOnIncomplete'];
  55053. }
  55054. if (isset($phpunitConfiguration['stopOnRisky']) &&
  55055. !isset($arguments['stopOnRisky'])) {
  55056. $arguments['stopOnRisky'] = $phpunitConfiguration['stopOnRisky'];
  55057. }
  55058. if (isset($phpunitConfiguration['stopOnSkipped']) &&
  55059. !isset($arguments['stopOnSkipped'])) {
  55060. $arguments['stopOnSkipped'] = $phpunitConfiguration['stopOnSkipped'];
  55061. }
  55062. if (isset($phpunitConfiguration['timeoutForSmallTests']) &&
  55063. !isset($arguments['timeoutForSmallTests'])) {
  55064. $arguments['timeoutForSmallTests'] = $phpunitConfiguration['timeoutForSmallTests'];
  55065. }
  55066. if (isset($phpunitConfiguration['timeoutForMediumTests']) &&
  55067. !isset($arguments['timeoutForMediumTests'])) {
  55068. $arguments['timeoutForMediumTests'] = $phpunitConfiguration['timeoutForMediumTests'];
  55069. }
  55070. if (isset($phpunitConfiguration['timeoutForLargeTests']) &&
  55071. !isset($arguments['timeoutForLargeTests'])) {
  55072. $arguments['timeoutForLargeTests'] = $phpunitConfiguration['timeoutForLargeTests'];
  55073. }
  55074. if (isset($phpunitConfiguration['reportUselessTests']) &&
  55075. !isset($arguments['reportUselessTests'])) {
  55076. $arguments['reportUselessTests'] = $phpunitConfiguration['reportUselessTests'];
  55077. }
  55078. if (isset($phpunitConfiguration['strictCoverage']) &&
  55079. !isset($arguments['strictCoverage'])) {
  55080. $arguments['strictCoverage'] = $phpunitConfiguration['strictCoverage'];
  55081. }
  55082. if (isset($phpunitConfiguration['disallowTestOutput']) &&
  55083. !isset($arguments['disallowTestOutput'])) {
  55084. $arguments['disallowTestOutput'] = $phpunitConfiguration['disallowTestOutput'];
  55085. }
  55086. if (isset($phpunitConfiguration['enforceTimeLimit']) &&
  55087. !isset($arguments['enforceTimeLimit'])) {
  55088. $arguments['enforceTimeLimit'] = $phpunitConfiguration['enforceTimeLimit'];
  55089. }
  55090. if (isset($phpunitConfiguration['disallowTodoAnnotatedTests']) &&
  55091. !isset($arguments['disallowTodoAnnotatedTests'])) {
  55092. $arguments['disallowTodoAnnotatedTests'] = $phpunitConfiguration['disallowTodoAnnotatedTests'];
  55093. }
  55094. if (isset($phpunitConfiguration['verbose']) &&
  55095. !isset($arguments['verbose'])) {
  55096. $arguments['verbose'] = $phpunitConfiguration['verbose'];
  55097. }
  55098. if (isset($phpunitConfiguration['forceCoversAnnotation']) &&
  55099. !isset($arguments['forceCoversAnnotation'])) {
  55100. $arguments['forceCoversAnnotation'] = $phpunitConfiguration['forceCoversAnnotation'];
  55101. }
  55102. if (isset($phpunitConfiguration['mapTestClassNameToCoveredClassName']) &&
  55103. !isset($arguments['mapTestClassNameToCoveredClassName'])) {
  55104. $arguments['mapTestClassNameToCoveredClassName'] = $phpunitConfiguration['mapTestClassNameToCoveredClassName'];
  55105. }
  55106. $groupCliArgs = array();
  55107. if (!empty($arguments['groups'])) {
  55108. $groupCliArgs = $arguments['groups'];
  55109. }
  55110. $groupConfiguration = $arguments['configuration']->getGroupConfiguration();
  55111. if (!empty($groupConfiguration['include']) &&
  55112. !isset($arguments['groups'])) {
  55113. $arguments['groups'] = $groupConfiguration['include'];
  55114. }
  55115. if (!empty($groupConfiguration['exclude']) &&
  55116. !isset($arguments['excludeGroups'])) {
  55117. $arguments['excludeGroups'] = array_diff($groupConfiguration['exclude'], $groupCliArgs);
  55118. }
  55119. foreach ($arguments['configuration']->getListenerConfiguration() as $listener) {
  55120. if (!class_exists($listener['class'], false) &&
  55121. $listener['file'] !== '') {
  55122. require_once $listener['file'];
  55123. }
  55124. if (class_exists($listener['class'])) {
  55125. if (count($listener['arguments']) == 0) {
  55126. $listener = new $listener['class'];
  55127. } else {
  55128. $listenerClass = new ReflectionClass(
  55129. $listener['class']
  55130. );
  55131. $listener = $listenerClass->newInstanceArgs(
  55132. $listener['arguments']
  55133. );
  55134. }
  55135. if ($listener instanceof PHPUnit_Framework_TestListener) {
  55136. $arguments['listeners'][] = $listener;
  55137. }
  55138. }
  55139. }
  55140. $loggingConfiguration = $arguments['configuration']->getLoggingConfiguration();
  55141. if (isset($loggingConfiguration['coverage-clover']) &&
  55142. !isset($arguments['coverageClover'])) {
  55143. $arguments['coverageClover'] = $loggingConfiguration['coverage-clover'];
  55144. }
  55145. if (isset($loggingConfiguration['coverage-crap4j']) &&
  55146. !isset($arguments['coverageCrap4J'])) {
  55147. $arguments['coverageCrap4J'] = $loggingConfiguration['coverage-crap4j'];
  55148. }
  55149. if (isset($loggingConfiguration['coverage-html']) &&
  55150. !isset($arguments['coverageHtml'])) {
  55151. if (isset($loggingConfiguration['lowUpperBound']) &&
  55152. !isset($arguments['reportLowUpperBound'])) {
  55153. $arguments['reportLowUpperBound'] = $loggingConfiguration['lowUpperBound'];
  55154. }
  55155. if (isset($loggingConfiguration['highLowerBound']) &&
  55156. !isset($arguments['reportHighLowerBound'])) {
  55157. $arguments['reportHighLowerBound'] = $loggingConfiguration['highLowerBound'];
  55158. }
  55159. $arguments['coverageHtml'] = $loggingConfiguration['coverage-html'];
  55160. }
  55161. if (isset($loggingConfiguration['coverage-php']) &&
  55162. !isset($arguments['coveragePHP'])) {
  55163. $arguments['coveragePHP'] = $loggingConfiguration['coverage-php'];
  55164. }
  55165. if (isset($loggingConfiguration['coverage-text']) &&
  55166. !isset($arguments['coverageText'])) {
  55167. $arguments['coverageText'] = $loggingConfiguration['coverage-text'];
  55168. if (isset($loggingConfiguration['coverageTextShowUncoveredFiles'])) {
  55169. $arguments['coverageTextShowUncoveredFiles'] = $loggingConfiguration['coverageTextShowUncoveredFiles'];
  55170. } else {
  55171. $arguments['coverageTextShowUncoveredFiles'] = false;
  55172. }
  55173. if (isset($loggingConfiguration['coverageTextShowOnlySummary'])) {
  55174. $arguments['coverageTextShowOnlySummary'] = $loggingConfiguration['coverageTextShowOnlySummary'];
  55175. } else {
  55176. $arguments['coverageTextShowOnlySummary'] = false;
  55177. }
  55178. }
  55179. if (isset($loggingConfiguration['coverage-xml']) &&
  55180. !isset($arguments['coverageXml'])) {
  55181. $arguments['coverageXml'] = $loggingConfiguration['coverage-xml'];
  55182. }
  55183. if (isset($loggingConfiguration['json']) &&
  55184. !isset($arguments['jsonLogfile'])) {
  55185. $arguments['jsonLogfile'] = $loggingConfiguration['json'];
  55186. }
  55187. if (isset($loggingConfiguration['plain'])) {
  55188. $arguments['listeners'][] = new PHPUnit_TextUI_ResultPrinter(
  55189. $loggingConfiguration['plain'],
  55190. true
  55191. );
  55192. }
  55193. if (isset($loggingConfiguration['tap']) &&
  55194. !isset($arguments['tapLogfile'])) {
  55195. $arguments['tapLogfile'] = $loggingConfiguration['tap'];
  55196. }
  55197. if (isset($loggingConfiguration['junit']) &&
  55198. !isset($arguments['junitLogfile'])) {
  55199. $arguments['junitLogfile'] = $loggingConfiguration['junit'];
  55200. if (isset($loggingConfiguration['logIncompleteSkipped']) &&
  55201. !isset($arguments['logIncompleteSkipped'])) {
  55202. $arguments['logIncompleteSkipped'] = $loggingConfiguration['logIncompleteSkipped'];
  55203. }
  55204. }
  55205. if (isset($loggingConfiguration['testdox-html']) &&
  55206. !isset($arguments['testdoxHTMLFile'])) {
  55207. $arguments['testdoxHTMLFile'] = $loggingConfiguration['testdox-html'];
  55208. }
  55209. if (isset($loggingConfiguration['testdox-text']) &&
  55210. !isset($arguments['testdoxTextFile'])) {
  55211. $arguments['testdoxTextFile'] = $loggingConfiguration['testdox-text'];
  55212. }
  55213. if ((isset($arguments['coverageClover']) ||
  55214. isset($arguments['coverageCrap4J']) ||
  55215. isset($arguments['coverageHtml']) ||
  55216. isset($arguments['coveragePHP']) ||
  55217. isset($arguments['coverageText']) ||
  55218. isset($arguments['coverageXml'])) &&
  55219. $this->runtime->canCollectCodeCoverage()) {
  55220. $filterConfiguration = $arguments['configuration']->getFilterConfiguration();
  55221. $arguments['addUncoveredFilesFromWhitelist'] = $filterConfiguration['whitelist']['addUncoveredFilesFromWhitelist'];
  55222. $arguments['processUncoveredFilesFromWhitelist'] = $filterConfiguration['whitelist']['processUncoveredFilesFromWhitelist'];
  55223. if (empty($filterConfiguration['whitelist']['include']['directory']) &&
  55224. empty($filterConfiguration['whitelist']['include']['file'])) {
  55225. foreach ($filterConfiguration['blacklist']['include']['directory'] as $dir) {
  55226. $this->codeCoverageFilter->addDirectoryToBlacklist(
  55227. $dir['path'],
  55228. $dir['suffix'],
  55229. $dir['prefix'],
  55230. $dir['group']
  55231. );
  55232. }
  55233. foreach ($filterConfiguration['blacklist']['include']['file'] as $file) {
  55234. $this->codeCoverageFilter->addFileToBlacklist($file);
  55235. }
  55236. foreach ($filterConfiguration['blacklist']['exclude']['directory'] as $dir) {
  55237. $this->codeCoverageFilter->removeDirectoryFromBlacklist(
  55238. $dir['path'],
  55239. $dir['suffix'],
  55240. $dir['prefix'],
  55241. $dir['group']
  55242. );
  55243. }
  55244. foreach ($filterConfiguration['blacklist']['exclude']['file'] as $file) {
  55245. $this->codeCoverageFilter->removeFileFromBlacklist($file);
  55246. }
  55247. }
  55248. foreach ($filterConfiguration['whitelist']['include']['directory'] as $dir) {
  55249. $this->codeCoverageFilter->addDirectoryToWhitelist(
  55250. $dir['path'],
  55251. $dir['suffix'],
  55252. $dir['prefix']
  55253. );
  55254. }
  55255. foreach ($filterConfiguration['whitelist']['include']['file'] as $file) {
  55256. $this->codeCoverageFilter->addFileToWhitelist($file);
  55257. }
  55258. foreach ($filterConfiguration['whitelist']['exclude']['directory'] as $dir) {
  55259. $this->codeCoverageFilter->removeDirectoryFromWhitelist(
  55260. $dir['path'],
  55261. $dir['suffix'],
  55262. $dir['prefix']
  55263. );
  55264. }
  55265. foreach ($filterConfiguration['whitelist']['exclude']['file'] as $file) {
  55266. $this->codeCoverageFilter->removeFileFromWhitelist($file);
  55267. }
  55268. }
  55269. }
  55270. $arguments['addUncoveredFilesFromWhitelist'] = isset($arguments['addUncoveredFilesFromWhitelist']) ? $arguments['addUncoveredFilesFromWhitelist'] : true;
  55271. $arguments['processUncoveredFilesFromWhitelist'] = isset($arguments['processUncoveredFilesFromWhitelist']) ? $arguments['processUncoveredFilesFromWhitelist'] : false;
  55272. $arguments['backupGlobals'] = isset($arguments['backupGlobals']) ? $arguments['backupGlobals'] : null;
  55273. $arguments['backupStaticAttributes'] = isset($arguments['backupStaticAttributes']) ? $arguments['backupStaticAttributes'] : null;
  55274. $arguments['disallowChangesToGlobalState'] = isset($arguments['disallowChangesToGlobalState']) ? $arguments['disallowChangesToGlobalState'] : null;
  55275. $arguments['cacheTokens'] = isset($arguments['cacheTokens']) ? $arguments['cacheTokens'] : false;
  55276. $arguments['columns'] = isset($arguments['columns']) ? $arguments['columns'] : 80;
  55277. $arguments['colors'] = isset($arguments['colors']) ? $arguments['colors'] : PHPUnit_TextUI_ResultPrinter::COLOR_DEFAULT;
  55278. $arguments['convertErrorsToExceptions'] = isset($arguments['convertErrorsToExceptions']) ? $arguments['convertErrorsToExceptions'] : true;
  55279. $arguments['convertNoticesToExceptions'] = isset($arguments['convertNoticesToExceptions']) ? $arguments['convertNoticesToExceptions'] : true;
  55280. $arguments['convertWarningsToExceptions'] = isset($arguments['convertWarningsToExceptions']) ? $arguments['convertWarningsToExceptions'] : true;
  55281. $arguments['excludeGroups'] = isset($arguments['excludeGroups']) ? $arguments['excludeGroups'] : array();
  55282. $arguments['groups'] = isset($arguments['groups']) ? $arguments['groups'] : array();
  55283. $arguments['logIncompleteSkipped'] = isset($arguments['logIncompleteSkipped']) ? $arguments['logIncompleteSkipped'] : false;
  55284. $arguments['processIsolation'] = isset($arguments['processIsolation']) ? $arguments['processIsolation'] : false;
  55285. $arguments['repeat'] = isset($arguments['repeat']) ? $arguments['repeat'] : false;
  55286. $arguments['reportHighLowerBound'] = isset($arguments['reportHighLowerBound']) ? $arguments['reportHighLowerBound'] : 90;
  55287. $arguments['reportLowUpperBound'] = isset($arguments['reportLowUpperBound']) ? $arguments['reportLowUpperBound'] : 50;
  55288. $arguments['stopOnError'] = isset($arguments['stopOnError']) ? $arguments['stopOnError'] : false;
  55289. $arguments['stopOnFailure'] = isset($arguments['stopOnFailure']) ? $arguments['stopOnFailure'] : false;
  55290. $arguments['stopOnIncomplete'] = isset($arguments['stopOnIncomplete']) ? $arguments['stopOnIncomplete'] : false;
  55291. $arguments['stopOnRisky'] = isset($arguments['stopOnRisky']) ? $arguments['stopOnRisky'] : false;
  55292. $arguments['stopOnSkipped'] = isset($arguments['stopOnSkipped']) ? $arguments['stopOnSkipped'] : false;
  55293. $arguments['timeoutForSmallTests'] = isset($arguments['timeoutForSmallTests']) ? $arguments['timeoutForSmallTests'] : 1;
  55294. $arguments['timeoutForMediumTests'] = isset($arguments['timeoutForMediumTests']) ? $arguments['timeoutForMediumTests'] : 10;
  55295. $arguments['timeoutForLargeTests'] = isset($arguments['timeoutForLargeTests']) ? $arguments['timeoutForLargeTests'] : 60;
  55296. $arguments['reportUselessTests'] = isset($arguments['reportUselessTests']) ? $arguments['reportUselessTests'] : false;
  55297. $arguments['strictCoverage'] = isset($arguments['strictCoverage']) ? $arguments['strictCoverage'] : false;
  55298. $arguments['disallowTestOutput'] = isset($arguments['disallowTestOutput']) ? $arguments['disallowTestOutput'] : false;
  55299. $arguments['enforceTimeLimit'] = isset($arguments['enforceTimeLimit']) ? $arguments['enforceTimeLimit'] : false;
  55300. $arguments['disallowTodoAnnotatedTests'] = isset($arguments['disallowTodoAnnotatedTests']) ? $arguments['disallowTodoAnnotatedTests'] : false;
  55301. $arguments['verbose'] = isset($arguments['verbose']) ? $arguments['verbose'] : false;
  55302. }
  55303. /**
  55304. * @param $extension
  55305. * @param string $message
  55306. * @since Method available since Release 4.7.3
  55307. */
  55308. private function showExtensionNotLoadedWarning($extension, $message = '')
  55309. {
  55310. if (isset($this->missingExtensions[$extension])) {
  55311. return;
  55312. }
  55313. $this->write("Warning:\t" . 'The ' . $extension . ' extension is not loaded' . "\n");
  55314. if (!empty($message)) {
  55315. $this->write("\t\t" . $message . "\n");
  55316. }
  55317. $this->missingExtensions[$extension] = true;
  55318. }
  55319. /**
  55320. * @return PHP_CodeCoverage_Filter
  55321. */
  55322. private function getCodeCoverageFilter()
  55323. {
  55324. $filter = new PHP_CodeCoverage_Filter;
  55325. if (defined('__PHPUNIT_PHAR__')) {
  55326. $filter->addFileToBlacklist(__PHPUNIT_PHAR__);
  55327. }
  55328. $blacklist = new PHPUnit_Util_Blacklist;
  55329. foreach ($blacklist->getBlacklistedDirectories() as $directory) {
  55330. $filter->addDirectoryToBlacklist($directory);
  55331. }
  55332. return $filter;
  55333. }
  55334. }
  55335. <?php
  55336. /*
  55337. * This file is part of PHPUnit.
  55338. *
  55339. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55340. *
  55341. * For the full copyright and license information, please view the LICENSE
  55342. * file that was distributed with this source code.
  55343. */
  55344. use SebastianBergmann\Environment\Console;
  55345. /**
  55346. * Prints the result of a TextUI TestRunner run.
  55347. *
  55348. * @since Class available since Release 2.0.0
  55349. */
  55350. class PHPUnit_TextUI_ResultPrinter extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
  55351. {
  55352. const EVENT_TEST_START = 0;
  55353. const EVENT_TEST_END = 1;
  55354. const EVENT_TESTSUITE_START = 2;
  55355. const EVENT_TESTSUITE_END = 3;
  55356. const COLOR_NEVER = 'never';
  55357. const COLOR_AUTO = 'auto';
  55358. const COLOR_ALWAYS = 'always';
  55359. const COLOR_DEFAULT = self::COLOR_NEVER;
  55360. /**
  55361. * @var array
  55362. */
  55363. private static $ansiCodes = array(
  55364. 'bold' => 1,
  55365. 'fg-black' => 30,
  55366. 'fg-red' => 31,
  55367. 'fg-green' => 32,
  55368. 'fg-yellow' => 33,
  55369. 'fg-blue' => 34,
  55370. 'fg-magenta' => 35,
  55371. 'fg-cyan' => 36,
  55372. 'fg-white' => 37,
  55373. 'bg-black' => 40,
  55374. 'bg-red' => 41,
  55375. 'bg-green' => 42,
  55376. 'bg-yellow' => 43,
  55377. 'bg-blue' => 44,
  55378. 'bg-magenta' => 45,
  55379. 'bg-cyan' => 46,
  55380. 'bg-white' => 47
  55381. );
  55382. /**
  55383. * @var int
  55384. */
  55385. protected $column = 0;
  55386. /**
  55387. * @var int
  55388. */
  55389. protected $maxColumn;
  55390. /**
  55391. * @var bool
  55392. */
  55393. protected $lastTestFailed = false;
  55394. /**
  55395. * @var int
  55396. */
  55397. protected $numAssertions = 0;
  55398. /**
  55399. * @var int
  55400. */
  55401. protected $numTests = -1;
  55402. /**
  55403. * @var int
  55404. */
  55405. protected $numTestsRun = 0;
  55406. /**
  55407. * @var int
  55408. */
  55409. protected $numTestsWidth;
  55410. /**
  55411. * @var bool
  55412. */
  55413. protected $colors = false;
  55414. /**
  55415. * @var bool
  55416. */
  55417. protected $debug = false;
  55418. /**
  55419. * @var bool
  55420. */
  55421. protected $verbose = false;
  55422. /**
  55423. * @var int
  55424. */
  55425. private $numberOfColumns;
  55426. /**
  55427. * Constructor.
  55428. *
  55429. * @param mixed $out
  55430. * @param bool $verbose
  55431. * @param string $colors
  55432. * @param bool $debug
  55433. * @param int|string $numberOfColumns
  55434. * @throws PHPUnit_Framework_Exception
  55435. * @since Method available since Release 3.0.0
  55436. */
  55437. public function __construct($out = null, $verbose = false, $colors = self::COLOR_DEFAULT, $debug = false, $numberOfColumns = 80)
  55438. {
  55439. parent::__construct($out);
  55440. if (!is_bool($verbose)) {
  55441. throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'boolean');
  55442. }
  55443. $availableColors = array(self::COLOR_NEVER, self::COLOR_AUTO, self::COLOR_ALWAYS);
  55444. if (!in_array($colors, $availableColors)) {
  55445. throw PHPUnit_Util_InvalidArgumentHelper::factory(
  55446. 3,
  55447. vsprintf('value from "%s", "%s" or "%s"', $availableColors)
  55448. );
  55449. }
  55450. if (!is_bool($debug)) {
  55451. throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'boolean');
  55452. }
  55453. if (!is_int($numberOfColumns) && $numberOfColumns != 'max') {
  55454. throw PHPUnit_Util_InvalidArgumentHelper::factory(5, 'integer or "max"');
  55455. }
  55456. $console = new Console;
  55457. $maxNumberOfColumns = $console->getNumberOfColumns();
  55458. if ($numberOfColumns == 'max' || $numberOfColumns > $maxNumberOfColumns) {
  55459. $numberOfColumns = $maxNumberOfColumns;
  55460. }
  55461. $this->numberOfColumns = $numberOfColumns;
  55462. $this->verbose = $verbose;
  55463. $this->debug = $debug;
  55464. if ($colors === self::COLOR_AUTO && $console->hasColorSupport()) {
  55465. $this->colors = true;
  55466. } else {
  55467. $this->colors = (self::COLOR_ALWAYS === $colors);
  55468. }
  55469. }
  55470. /**
  55471. * @param PHPUnit_Framework_TestResult $result
  55472. */
  55473. public function printResult(PHPUnit_Framework_TestResult $result)
  55474. {
  55475. $this->printHeader();
  55476. $this->printErrors($result);
  55477. $printSeparator = $result->errorCount() > 0;
  55478. if ($printSeparator && $result->failureCount() > 0) {
  55479. $this->write("\n--\n\n");
  55480. }
  55481. $printSeparator = $printSeparator || $result->failureCount() > 0;
  55482. $this->printFailures($result);
  55483. if ($this->verbose) {
  55484. if ($printSeparator && $result->riskyCount() > 0) {
  55485. $this->write("\n--\n\n");
  55486. }
  55487. $printSeparator = $printSeparator ||
  55488. $result->riskyCount() > 0;
  55489. $this->printRisky($result);
  55490. if ($printSeparator && $result->notImplementedCount() > 0) {
  55491. $this->write("\n--\n\n");
  55492. }
  55493. $printSeparator = $printSeparator ||
  55494. $result->notImplementedCount() > 0;
  55495. $this->printIncompletes($result);
  55496. if ($printSeparator && $result->skippedCount() > 0) {
  55497. $this->write("\n--\n\n");
  55498. }
  55499. $this->printSkipped($result);
  55500. }
  55501. $this->printFooter($result);
  55502. }
  55503. /**
  55504. * @param array $defects
  55505. * @param string $type
  55506. */
  55507. protected function printDefects(array $defects, $type)
  55508. {
  55509. $count = count($defects);
  55510. if ($count == 0) {
  55511. return;
  55512. }
  55513. $this->write(
  55514. sprintf(
  55515. "There %s %d %s%s:\n",
  55516. ($count == 1) ? 'was' : 'were',
  55517. $count,
  55518. $type,
  55519. ($count == 1) ? '' : 's'
  55520. )
  55521. );
  55522. $i = 1;
  55523. foreach ($defects as $defect) {
  55524. $this->printDefect($defect, $i++);
  55525. }
  55526. }
  55527. /**
  55528. * @param PHPUnit_Framework_TestFailure $defect
  55529. * @param int $count
  55530. */
  55531. protected function printDefect(PHPUnit_Framework_TestFailure $defect, $count)
  55532. {
  55533. $this->printDefectHeader($defect, $count);
  55534. $this->printDefectTrace($defect);
  55535. }
  55536. /**
  55537. * @param PHPUnit_Framework_TestFailure $defect
  55538. * @param int $count
  55539. */
  55540. protected function printDefectHeader(PHPUnit_Framework_TestFailure $defect, $count)
  55541. {
  55542. $this->write(
  55543. sprintf(
  55544. "\n%d) %s\n",
  55545. $count,
  55546. $defect->getTestName()
  55547. )
  55548. );
  55549. }
  55550. /**
  55551. * @param PHPUnit_Framework_TestFailure $defect
  55552. */
  55553. protected function printDefectTrace(PHPUnit_Framework_TestFailure $defect)
  55554. {
  55555. $e = $defect->thrownException();
  55556. $this->write((string) $e);
  55557. while ($e = $e->getPrevious()) {
  55558. $this->write("\nCaused by\n" . $e);
  55559. }
  55560. }
  55561. /**
  55562. * @param PHPUnit_Framework_TestResult $result
  55563. */
  55564. protected function printErrors(PHPUnit_Framework_TestResult $result)
  55565. {
  55566. $this->printDefects($result->errors(), 'error');
  55567. }
  55568. /**
  55569. * @param PHPUnit_Framework_TestResult $result
  55570. */
  55571. protected function printFailures(PHPUnit_Framework_TestResult $result)
  55572. {
  55573. $this->printDefects($result->failures(), 'failure');
  55574. }
  55575. /**
  55576. * @param PHPUnit_Framework_TestResult $result
  55577. */
  55578. protected function printIncompletes(PHPUnit_Framework_TestResult $result)
  55579. {
  55580. $this->printDefects($result->notImplemented(), 'incomplete test');
  55581. }
  55582. /**
  55583. * @param PHPUnit_Framework_TestResult $result
  55584. * @since Method available since Release 4.0.0
  55585. */
  55586. protected function printRisky(PHPUnit_Framework_TestResult $result)
  55587. {
  55588. $this->printDefects($result->risky(), 'risky test');
  55589. }
  55590. /**
  55591. * @param PHPUnit_Framework_TestResult $result
  55592. * @since Method available since Release 3.0.0
  55593. */
  55594. protected function printSkipped(PHPUnit_Framework_TestResult $result)
  55595. {
  55596. $this->printDefects($result->skipped(), 'skipped test');
  55597. }
  55598. protected function printHeader()
  55599. {
  55600. $this->write("\n\n" . PHP_Timer::resourceUsage() . "\n\n");
  55601. }
  55602. /**
  55603. * @param PHPUnit_Framework_TestResult $result
  55604. */
  55605. protected function printFooter(PHPUnit_Framework_TestResult $result)
  55606. {
  55607. if (count($result) === 0) {
  55608. $this->writeWithColor(
  55609. 'fg-black, bg-yellow',
  55610. 'No tests executed!'
  55611. );
  55612. } elseif ($result->wasSuccessful() &&
  55613. $result->allHarmless() &&
  55614. $result->allCompletelyImplemented() &&
  55615. $result->noneSkipped()) {
  55616. $this->writeWithColor(
  55617. 'fg-black, bg-green',
  55618. sprintf(
  55619. 'OK (%d test%s, %d assertion%s)',
  55620. count($result),
  55621. (count($result) == 1) ? '' : 's',
  55622. $this->numAssertions,
  55623. ($this->numAssertions == 1) ? '' : 's'
  55624. )
  55625. );
  55626. } else {
  55627. if ($result->wasSuccessful()) {
  55628. $color = 'fg-black, bg-yellow';
  55629. if ($this->verbose) {
  55630. $this->write("\n");
  55631. }
  55632. $this->writeWithColor(
  55633. $color,
  55634. 'OK, but incomplete, skipped, or risky tests!'
  55635. );
  55636. } else {
  55637. $color = 'fg-white, bg-red';
  55638. $this->write("\n");
  55639. $this->writeWithColor($color, 'FAILURES!');
  55640. }
  55641. $this->writeCountString(count($result), 'Tests', $color, true);
  55642. $this->writeCountString($this->numAssertions, 'Assertions', $color, true);
  55643. $this->writeCountString($result->errorCount(), 'Errors', $color);
  55644. $this->writeCountString($result->failureCount(), 'Failures', $color);
  55645. $this->writeCountString($result->skippedCount(), 'Skipped', $color);
  55646. $this->writeCountString($result->notImplementedCount(), 'Incomplete', $color);
  55647. $this->writeCountString($result->riskyCount(), 'Risky', $color);
  55648. $this->writeWithColor($color, '.', true);
  55649. }
  55650. }
  55651. /**
  55652. */
  55653. public function printWaitPrompt()
  55654. {
  55655. $this->write("\n<RETURN> to continue\n");
  55656. }
  55657. /**
  55658. * An error occurred.
  55659. *
  55660. * @param PHPUnit_Framework_Test $test
  55661. * @param Exception $e
  55662. * @param float $time
  55663. */
  55664. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  55665. {
  55666. $this->writeProgressWithColor('fg-red, bold', 'E');
  55667. $this->lastTestFailed = true;
  55668. }
  55669. /**
  55670. * A failure occurred.
  55671. *
  55672. * @param PHPUnit_Framework_Test $test
  55673. * @param PHPUnit_Framework_AssertionFailedError $e
  55674. * @param float $time
  55675. */
  55676. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  55677. {
  55678. $this->writeProgressWithColor('bg-red, fg-white', 'F');
  55679. $this->lastTestFailed = true;
  55680. }
  55681. /**
  55682. * Incomplete test.
  55683. *
  55684. * @param PHPUnit_Framework_Test $test
  55685. * @param Exception $e
  55686. * @param float $time
  55687. */
  55688. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  55689. {
  55690. $this->writeProgressWithColor('fg-yellow, bold', 'I');
  55691. $this->lastTestFailed = true;
  55692. }
  55693. /**
  55694. * Risky test.
  55695. *
  55696. * @param PHPUnit_Framework_Test $test
  55697. * @param Exception $e
  55698. * @param float $time
  55699. * @since Method available since Release 4.0.0
  55700. */
  55701. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  55702. {
  55703. $this->writeProgressWithColor('fg-yellow, bold', 'R');
  55704. $this->lastTestFailed = true;
  55705. }
  55706. /**
  55707. * Skipped test.
  55708. *
  55709. * @param PHPUnit_Framework_Test $test
  55710. * @param Exception $e
  55711. * @param float $time
  55712. * @since Method available since Release 3.0.0
  55713. */
  55714. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  55715. {
  55716. $this->writeProgressWithColor('fg-cyan, bold', 'S');
  55717. $this->lastTestFailed = true;
  55718. }
  55719. /**
  55720. * A testsuite started.
  55721. *
  55722. * @param PHPUnit_Framework_TestSuite $suite
  55723. * @since Method available since Release 2.2.0
  55724. */
  55725. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  55726. {
  55727. if ($this->numTests == -1) {
  55728. $this->numTests = count($suite);
  55729. $this->numTestsWidth = strlen((string) $this->numTests);
  55730. $this->maxColumn = $this->numberOfColumns - strlen(' / (XXX%)') - (2 * $this->numTestsWidth);
  55731. }
  55732. }
  55733. /**
  55734. * A testsuite ended.
  55735. *
  55736. * @param PHPUnit_Framework_TestSuite $suite
  55737. * @since Method available since Release 2.2.0
  55738. */
  55739. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  55740. {
  55741. }
  55742. /**
  55743. * A test started.
  55744. *
  55745. * @param PHPUnit_Framework_Test $test
  55746. */
  55747. public function startTest(PHPUnit_Framework_Test $test)
  55748. {
  55749. if ($this->debug) {
  55750. $this->write(
  55751. sprintf(
  55752. "\nStarting test '%s'.\n",
  55753. PHPUnit_Util_Test::describe($test)
  55754. )
  55755. );
  55756. }
  55757. }
  55758. /**
  55759. * A test ended.
  55760. *
  55761. * @param PHPUnit_Framework_Test $test
  55762. * @param float $time
  55763. */
  55764. public function endTest(PHPUnit_Framework_Test $test, $time)
  55765. {
  55766. if (!$this->lastTestFailed) {
  55767. $this->writeProgress('.');
  55768. }
  55769. if ($test instanceof PHPUnit_Framework_TestCase) {
  55770. $this->numAssertions += $test->getNumAssertions();
  55771. } elseif ($test instanceof PHPUnit_Extensions_PhptTestCase) {
  55772. $this->numAssertions++;
  55773. }
  55774. $this->lastTestFailed = false;
  55775. if ($test instanceof PHPUnit_Framework_TestCase) {
  55776. if (!$test->hasExpectationOnOutput()) {
  55777. $this->write($test->getActualOutput());
  55778. }
  55779. }
  55780. }
  55781. /**
  55782. * @param string $progress
  55783. */
  55784. protected function writeProgress($progress)
  55785. {
  55786. $this->write($progress);
  55787. $this->column++;
  55788. $this->numTestsRun++;
  55789. if ($this->column == $this->maxColumn) {
  55790. $this->write(
  55791. sprintf(
  55792. ' %' . $this->numTestsWidth . 'd / %' .
  55793. $this->numTestsWidth . 'd (%3s%%)',
  55794. $this->numTestsRun,
  55795. $this->numTests,
  55796. floor(($this->numTestsRun / $this->numTests) * 100)
  55797. )
  55798. );
  55799. $this->writeNewLine();
  55800. }
  55801. }
  55802. protected function writeNewLine()
  55803. {
  55804. $this->column = 0;
  55805. $this->write("\n");
  55806. }
  55807. /**
  55808. * Formats a buffer with a specified ANSI color sequence if colors are
  55809. * enabled.
  55810. *
  55811. * @param string $color
  55812. * @param string $buffer
  55813. * @return string
  55814. * @since Method available since Release 4.0.0
  55815. */
  55816. protected function formatWithColor($color, $buffer)
  55817. {
  55818. if (!$this->colors) {
  55819. return $buffer;
  55820. }
  55821. $codes = array_map('trim', explode(',', $color));
  55822. $lines = explode("\n", $buffer);
  55823. $padding = max(array_map('strlen', $lines));
  55824. $styles = array();
  55825. foreach ($codes as $code) {
  55826. $styles[] = self::$ansiCodes[$code];
  55827. }
  55828. $style = sprintf("\x1b[%sm", implode(';', $styles));
  55829. $styledLines = array();
  55830. foreach ($lines as $line) {
  55831. $styledLines[] = $style . str_pad($line, $padding) . "\x1b[0m";
  55832. }
  55833. return implode("\n", $styledLines);
  55834. }
  55835. /**
  55836. * Writes a buffer out with a color sequence if colors are enabled.
  55837. *
  55838. * @param string $color
  55839. * @param string $buffer
  55840. * @param bool $lf
  55841. * @since Method available since Release 4.0.0
  55842. */
  55843. protected function writeWithColor($color, $buffer, $lf = true)
  55844. {
  55845. $this->write($this->formatWithColor($color, $buffer));
  55846. if ($lf) {
  55847. $this->write("\n");
  55848. }
  55849. }
  55850. /**
  55851. * Writes progress with a color sequence if colors are enabled.
  55852. *
  55853. * @param string $color
  55854. * @param string $buffer
  55855. * @since Method available since Release 4.0.0
  55856. */
  55857. protected function writeProgressWithColor($color, $buffer)
  55858. {
  55859. $buffer = $this->formatWithColor($color, $buffer);
  55860. $this->writeProgress($buffer);
  55861. }
  55862. /**
  55863. * @param int $count
  55864. * @param string $name
  55865. * @param string $color
  55866. * @param bool $always
  55867. * @since Method available since Release 4.6.5
  55868. */
  55869. private function writeCountString($count, $name, $color, $always = false)
  55870. {
  55871. static $first = true;
  55872. if ($always || $count > 0) {
  55873. $this->writeWithColor(
  55874. $color,
  55875. sprintf(
  55876. '%s%s: %d',
  55877. !$first ? ', ' : '',
  55878. $name,
  55879. $count
  55880. ),
  55881. false
  55882. );
  55883. $first = false;
  55884. }
  55885. }
  55886. }
  55887. <?php
  55888. /*
  55889. * This file is part of PHPUnit.
  55890. *
  55891. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  55892. *
  55893. * For the full copyright and license information, please view the LICENSE
  55894. * file that was distributed with this source code.
  55895. */
  55896. if (!function_exists('trait_exists')) {
  55897. function trait_exists($traitname, $autoload = true)
  55898. {
  55899. return false;
  55900. }
  55901. }
  55902. /**
  55903. * Test helpers.
  55904. *
  55905. * @since Class available since Release 3.0.0
  55906. */
  55907. class PHPUnit_Util_Test
  55908. {
  55909. const REGEX_DATA_PROVIDER = '/@dataProvider\s+([a-zA-Z0-9._:-\\\\x7f-\xff]+)/';
  55910. const REGEX_EXPECTED_EXCEPTION = '(@expectedException\s+([:.\w\\\\x7f-\xff]+)(?:[\t ]+(\S*))?(?:[\t ]+(\S*))?\s*$)m';
  55911. const REGEX_REQUIRES_VERSION = '/@requires\s+(?P<name>PHP(?:Unit)?)\s+(?P<value>[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m';
  55912. const REGEX_REQUIRES_OS = '/@requires\s+OS\s+(?P<value>.+?)[ \t]*\r?$/m';
  55913. const REGEX_REQUIRES = '/@requires\s+(?P<name>function|extension)\s+(?P<value>([^ ]+?))[ \t]*\r?$/m';
  55914. const UNKNOWN = -1;
  55915. const SMALL = 0;
  55916. const MEDIUM = 1;
  55917. const LARGE = 2;
  55918. private static $annotationCache = array();
  55919. private static $hookMethods = array();
  55920. /**
  55921. * @param PHPUnit_Framework_Test $test
  55922. * @param bool $asString
  55923. * @return mixed
  55924. */
  55925. public static function describe(PHPUnit_Framework_Test $test, $asString = true)
  55926. {
  55927. if ($asString) {
  55928. if ($test instanceof PHPUnit_Framework_SelfDescribing) {
  55929. return $test->toString();
  55930. } else {
  55931. return get_class($test);
  55932. }
  55933. } else {
  55934. if ($test instanceof PHPUnit_Framework_TestCase) {
  55935. return array(
  55936. get_class($test), $test->getName()
  55937. );
  55938. } elseif ($test instanceof PHPUnit_Framework_SelfDescribing) {
  55939. return array('', $test->toString());
  55940. } else {
  55941. return array('', get_class($test));
  55942. }
  55943. }
  55944. }
  55945. /**
  55946. * @param string $className
  55947. * @param string $methodName
  55948. * @return array|bool
  55949. * @throws PHPUnit_Framework_CodeCoverageException
  55950. * @since Method available since Release 4.0.0
  55951. */
  55952. public static function getLinesToBeCovered($className, $methodName)
  55953. {
  55954. $annotations = self::parseTestMethodAnnotations(
  55955. $className,
  55956. $methodName
  55957. );
  55958. if (isset($annotations['class']['coversNothing']) || isset($annotations['method']['coversNothing'])) {
  55959. return false;
  55960. }
  55961. return self::getLinesToBeCoveredOrUsed($className, $methodName, 'covers');
  55962. }
  55963. /**
  55964. * Returns lines of code specified with the @uses annotation.
  55965. *
  55966. * @param string $className
  55967. * @param string $methodName
  55968. * @return array
  55969. * @since Method available since Release 4.0.0
  55970. */
  55971. public static function getLinesToBeUsed($className, $methodName)
  55972. {
  55973. return self::getLinesToBeCoveredOrUsed($className, $methodName, 'uses');
  55974. }
  55975. /**
  55976. * @param string $className
  55977. * @param string $methodName
  55978. * @param string $mode
  55979. * @return array
  55980. * @throws PHPUnit_Framework_CodeCoverageException
  55981. * @since Method available since Release 4.2.0
  55982. */
  55983. private static function getLinesToBeCoveredOrUsed($className, $methodName, $mode)
  55984. {
  55985. $annotations = self::parseTestMethodAnnotations(
  55986. $className,
  55987. $methodName
  55988. );
  55989. $classShortcut = null;
  55990. if (!empty($annotations['class'][$mode . 'DefaultClass'])) {
  55991. if (count($annotations['class'][$mode . 'DefaultClass']) > 1) {
  55992. throw new PHPUnit_Framework_CodeCoverageException(
  55993. sprintf(
  55994. 'More than one @%sClass annotation in class or interface "%s".',
  55995. $mode,
  55996. $className
  55997. )
  55998. );
  55999. }
  56000. $classShortcut = $annotations['class'][$mode . 'DefaultClass'][0];
  56001. }
  56002. $list = array();
  56003. if (isset($annotations['class'][$mode])) {
  56004. $list = $annotations['class'][$mode];
  56005. }
  56006. if (isset($annotations['method'][$mode])) {
  56007. $list = array_merge($list, $annotations['method'][$mode]);
  56008. }
  56009. $codeList = array();
  56010. foreach (array_unique($list) as $element) {
  56011. if ($classShortcut && strncmp($element, '::', 2) === 0) {
  56012. $element = $classShortcut . $element;
  56013. }
  56014. $element = preg_replace('/[\s()]+$/', '', $element);
  56015. $codeList = array_merge(
  56016. $codeList,
  56017. self::resolveElementToReflectionObjects($element)
  56018. );
  56019. }
  56020. return self::resolveReflectionObjectsToLines($codeList);
  56021. }
  56022. /**
  56023. * Returns the requirements for a test.
  56024. *
  56025. * @param string $className
  56026. * @param string $methodName
  56027. * @return array
  56028. * @since Method available since Release 3.6.0
  56029. */
  56030. public static function getRequirements($className, $methodName)
  56031. {
  56032. $reflector = new ReflectionClass($className);
  56033. $docComment = $reflector->getDocComment();
  56034. $reflector = new ReflectionMethod($className, $methodName);
  56035. $docComment .= "\n" . $reflector->getDocComment();
  56036. $requires = array();
  56037. if ($count = preg_match_all(self::REGEX_REQUIRES_OS, $docComment, $matches)) {
  56038. $requires['OS'] = sprintf(
  56039. '/%s/i',
  56040. addcslashes($matches['value'][$count - 1], '/')
  56041. );
  56042. }
  56043. if ($count = preg_match_all(self::REGEX_REQUIRES_VERSION, $docComment, $matches)) {
  56044. for ($i = 0; $i < $count; $i++) {
  56045. $requires[$matches['name'][$i]] = $matches['value'][$i];
  56046. }
  56047. }
  56048. // https://bugs.php.net/bug.php?id=63055
  56049. $matches = array();
  56050. if ($count = preg_match_all(self::REGEX_REQUIRES, $docComment, $matches)) {
  56051. for ($i = 0; $i < $count; $i++) {
  56052. $name = $matches['name'][$i] . 's';
  56053. if (!isset($requires[$name])) {
  56054. $requires[$name] = array();
  56055. }
  56056. $requires[$name][] = $matches['value'][$i];
  56057. }
  56058. }
  56059. return $requires;
  56060. }
  56061. /**
  56062. * Returns the missing requirements for a test.
  56063. *
  56064. * @param string $className
  56065. * @param string $methodName
  56066. * @return array
  56067. * @since Method available since Release 4.3.0
  56068. */
  56069. public static function getMissingRequirements($className, $methodName)
  56070. {
  56071. $required = static::getRequirements($className, $methodName);
  56072. $missing = array();
  56073. if (!empty($required['PHP']) && version_compare(PHP_VERSION, $required['PHP'], '<')) {
  56074. $missing[] = sprintf('PHP %s (or later) is required.', $required['PHP']);
  56075. }
  56076. if (!empty($required['PHPUnit'])) {
  56077. $phpunitVersion = PHPUnit_Runner_Version::id();
  56078. if (version_compare($phpunitVersion, $required['PHPUnit'], '<')) {
  56079. $missing[] = sprintf('PHPUnit %s (or later) is required.', $required['PHPUnit']);
  56080. }
  56081. }
  56082. if (!empty($required['OS']) && !preg_match($required['OS'], PHP_OS)) {
  56083. $missing[] = sprintf('Operating system matching %s is required.', $required['OS']);
  56084. }
  56085. if (!empty($required['functions'])) {
  56086. foreach ($required['functions'] as $function) {
  56087. $pieces = explode('::', $function);
  56088. if (2 === count($pieces) && method_exists($pieces[0], $pieces[1])) {
  56089. continue;
  56090. }
  56091. if (function_exists($function)) {
  56092. continue;
  56093. }
  56094. $missing[] = sprintf('Function %s is required.', $function);
  56095. }
  56096. }
  56097. if (!empty($required['extensions'])) {
  56098. foreach ($required['extensions'] as $extension) {
  56099. if (!extension_loaded($extension)) {
  56100. $missing[] = sprintf('Extension %s is required.', $extension);
  56101. }
  56102. }
  56103. }
  56104. return $missing;
  56105. }
  56106. /**
  56107. * Returns the expected exception for a test.
  56108. *
  56109. * @param string $className
  56110. * @param string $methodName
  56111. * @return array
  56112. * @since Method available since Release 3.3.6
  56113. */
  56114. public static function getExpectedException($className, $methodName)
  56115. {
  56116. $reflector = new ReflectionMethod($className, $methodName);
  56117. $docComment = $reflector->getDocComment();
  56118. $docComment = substr($docComment, 3, -2);
  56119. if (preg_match(self::REGEX_EXPECTED_EXCEPTION, $docComment, $matches)) {
  56120. $annotations = self::parseTestMethodAnnotations(
  56121. $className,
  56122. $methodName
  56123. );
  56124. $class = $matches[1];
  56125. $code = null;
  56126. $message = '';
  56127. $messageRegExp = '';
  56128. if (isset($matches[2])) {
  56129. $message = trim($matches[2]);
  56130. } elseif (isset($annotations['method']['expectedExceptionMessage'])) {
  56131. $message = self::parseAnnotationContent(
  56132. $annotations['method']['expectedExceptionMessage'][0]
  56133. );
  56134. }
  56135. if (isset($annotations['method']['expectedExceptionMessageRegExp'])) {
  56136. $messageRegExp = self::parseAnnotationContent(
  56137. $annotations['method']['expectedExceptionMessageRegExp'][0]
  56138. );
  56139. }
  56140. if (isset($matches[3])) {
  56141. $code = $matches[3];
  56142. } elseif (isset($annotations['method']['expectedExceptionCode'])) {
  56143. $code = self::parseAnnotationContent(
  56144. $annotations['method']['expectedExceptionCode'][0]
  56145. );
  56146. }
  56147. if (is_numeric($code)) {
  56148. $code = (int) $code;
  56149. } elseif (is_string($code) && defined($code)) {
  56150. $code = (int) constant($code);
  56151. }
  56152. return array(
  56153. 'class' => $class, 'code' => $code, 'message' => $message, 'message_regex' => $messageRegExp
  56154. );
  56155. }
  56156. return false;
  56157. }
  56158. /**
  56159. * Parse annotation content to use constant/class constant values
  56160. *
  56161. * Constants are specified using a starting '@'. For example: @ClassName::CONST_NAME
  56162. *
  56163. * If the constant is not found the string is used as is to ensure maximum BC.
  56164. *
  56165. * @param string $message
  56166. * @return string
  56167. */
  56168. private static function parseAnnotationContent($message)
  56169. {
  56170. if (strpos($message, '::') !== false && count(explode('::', $message) == 2)) {
  56171. if (defined($message)) {
  56172. $message = constant($message);
  56173. }
  56174. }
  56175. return $message;
  56176. }
  56177. /**
  56178. * Returns the provided data for a method.
  56179. *
  56180. * @param string $className
  56181. * @param string $methodName
  56182. * @return array|Iterator when a data provider is specified and exists
  56183. * false when a data provider is specified but does not exist
  56184. * null when no data provider is specified
  56185. * @throws PHPUnit_Framework_Exception
  56186. * @since Method available since Release 3.2.0
  56187. */
  56188. public static function getProvidedData($className, $methodName)
  56189. {
  56190. $reflector = new ReflectionMethod($className, $methodName);
  56191. $docComment = $reflector->getDocComment();
  56192. $data = null;
  56193. if (preg_match(self::REGEX_DATA_PROVIDER, $docComment, $matches)) {
  56194. $dataProviderMethodNameNamespace = explode('\\', $matches[1]);
  56195. $leaf = explode('::', array_pop($dataProviderMethodNameNamespace));
  56196. $dataProviderMethodName = array_pop($leaf);
  56197. if (!empty($dataProviderMethodNameNamespace)) {
  56198. $dataProviderMethodNameNamespace = implode('\\', $dataProviderMethodNameNamespace) . '\\';
  56199. } else {
  56200. $dataProviderMethodNameNamespace = '';
  56201. }
  56202. if (!empty($leaf)) {
  56203. $dataProviderClassName = $dataProviderMethodNameNamespace . array_pop($leaf);
  56204. } else {
  56205. $dataProviderClassName = $className;
  56206. }
  56207. $dataProviderClass = new ReflectionClass($dataProviderClassName);
  56208. $dataProviderMethod = $dataProviderClass->getMethod(
  56209. $dataProviderMethodName
  56210. );
  56211. if ($dataProviderMethod->isStatic()) {
  56212. $object = null;
  56213. } else {
  56214. $object = $dataProviderClass->newInstance();
  56215. }
  56216. if ($dataProviderMethod->getNumberOfParameters() == 0) {
  56217. $data = $dataProviderMethod->invoke($object);
  56218. } else {
  56219. $data = $dataProviderMethod->invoke($object, $methodName);
  56220. }
  56221. }
  56222. if ($data !== null) {
  56223. if (is_object($data)) {
  56224. $data = iterator_to_array($data);
  56225. }
  56226. foreach ($data as $key => $value) {
  56227. if (!is_array($value)) {
  56228. throw new PHPUnit_Framework_Exception(
  56229. sprintf(
  56230. 'Data set %s is invalid.',
  56231. is_int($key) ? '#' . $key : '"' . $key . '"'
  56232. )
  56233. );
  56234. }
  56235. }
  56236. }
  56237. return $data;
  56238. }
  56239. /**
  56240. * @param string $className
  56241. * @param string $methodName
  56242. * @return array
  56243. * @throws ReflectionException
  56244. * @since Method available since Release 3.4.0
  56245. */
  56246. public static function parseTestMethodAnnotations($className, $methodName = '')
  56247. {
  56248. if (!isset(self::$annotationCache[$className])) {
  56249. $class = new ReflectionClass($className);
  56250. self::$annotationCache[$className] = self::parseAnnotations($class->getDocComment());
  56251. }
  56252. if (!empty($methodName) && !isset(self::$annotationCache[$className . '::' . $methodName])) {
  56253. try {
  56254. $method = new ReflectionMethod($className, $methodName);
  56255. $annotations = self::parseAnnotations($method->getDocComment());
  56256. } catch (ReflectionException $e) {
  56257. $annotations = array();
  56258. }
  56259. self::$annotationCache[$className . '::' . $methodName] = $annotations;
  56260. }
  56261. return array(
  56262. 'class' => self::$annotationCache[$className],
  56263. 'method' => !empty($methodName) ? self::$annotationCache[$className . '::' . $methodName] : array()
  56264. );
  56265. }
  56266. /**
  56267. * @param string $docblock
  56268. * @return array
  56269. * @since Method available since Release 3.4.0
  56270. */
  56271. private static function parseAnnotations($docblock)
  56272. {
  56273. $annotations = array();
  56274. // Strip away the docblock header and footer to ease parsing of one line annotations
  56275. $docblock = substr($docblock, 3, -2);
  56276. if (preg_match_all('/@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \t]*\r?$/m', $docblock, $matches)) {
  56277. $numMatches = count($matches[0]);
  56278. for ($i = 0; $i < $numMatches; ++$i) {
  56279. $annotations[$matches['name'][$i]][] = $matches['value'][$i];
  56280. }
  56281. }
  56282. return $annotations;
  56283. }
  56284. /**
  56285. * Returns the backup settings for a test.
  56286. *
  56287. * @param string $className
  56288. * @param string $methodName
  56289. * @return array
  56290. * @since Method available since Release 3.4.0
  56291. */
  56292. public static function getBackupSettings($className, $methodName)
  56293. {
  56294. return array(
  56295. 'backupGlobals' => self::getBooleanAnnotationSetting(
  56296. $className,
  56297. $methodName,
  56298. 'backupGlobals'
  56299. ),
  56300. 'backupStaticAttributes' => self::getBooleanAnnotationSetting(
  56301. $className,
  56302. $methodName,
  56303. 'backupStaticAttributes'
  56304. )
  56305. );
  56306. }
  56307. /**
  56308. * Returns the dependencies for a test class or method.
  56309. *
  56310. * @param string $className
  56311. * @param string $methodName
  56312. * @return array
  56313. * @since Method available since Release 3.4.0
  56314. */
  56315. public static function getDependencies($className, $methodName)
  56316. {
  56317. $annotations = self::parseTestMethodAnnotations(
  56318. $className,
  56319. $methodName
  56320. );
  56321. $dependencies = array();
  56322. if (isset($annotations['class']['depends'])) {
  56323. $dependencies = $annotations['class']['depends'];
  56324. }
  56325. if (isset($annotations['method']['depends'])) {
  56326. $dependencies = array_merge(
  56327. $dependencies,
  56328. $annotations['method']['depends']
  56329. );
  56330. }
  56331. return array_unique($dependencies);
  56332. }
  56333. /**
  56334. * Returns the error handler settings for a test.
  56335. *
  56336. * @param string $className
  56337. * @param string $methodName
  56338. * @return bool
  56339. * @since Method available since Release 3.4.0
  56340. */
  56341. public static function getErrorHandlerSettings($className, $methodName)
  56342. {
  56343. return self::getBooleanAnnotationSetting(
  56344. $className,
  56345. $methodName,
  56346. 'errorHandler'
  56347. );
  56348. }
  56349. /**
  56350. * Returns the groups for a test class or method.
  56351. *
  56352. * @param string $className
  56353. * @param string $methodName
  56354. * @return array
  56355. * @since Method available since Release 3.2.0
  56356. */
  56357. public static function getGroups($className, $methodName = '')
  56358. {
  56359. $annotations = self::parseTestMethodAnnotations(
  56360. $className,
  56361. $methodName
  56362. );
  56363. $groups = array();
  56364. if (isset($annotations['method']['author'])) {
  56365. $groups = $annotations['method']['author'];
  56366. } elseif (isset($annotations['class']['author'])) {
  56367. $groups = $annotations['class']['author'];
  56368. }
  56369. if (isset($annotations['class']['group'])) {
  56370. $groups = array_merge($groups, $annotations['class']['group']);
  56371. }
  56372. if (isset($annotations['method']['group'])) {
  56373. $groups = array_merge($groups, $annotations['method']['group']);
  56374. }
  56375. if (isset($annotations['class']['ticket'])) {
  56376. $groups = array_merge($groups, $annotations['class']['ticket']);
  56377. }
  56378. if (isset($annotations['method']['ticket'])) {
  56379. $groups = array_merge($groups, $annotations['method']['ticket']);
  56380. }
  56381. foreach (array('method', 'class') as $element) {
  56382. foreach (array('small', 'medium', 'large') as $size) {
  56383. if (isset($annotations[$element][$size])) {
  56384. $groups[] = $size;
  56385. break 2;
  56386. }
  56387. if (isset($annotations[$element][$size])) {
  56388. $groups[] = $size;
  56389. break 2;
  56390. }
  56391. }
  56392. }
  56393. return array_unique($groups);
  56394. }
  56395. /**
  56396. * Returns the size of the test.
  56397. *
  56398. * @param string $className
  56399. * @param string $methodName
  56400. * @return int
  56401. * @since Method available since Release 3.6.0
  56402. */
  56403. public static function getSize($className, $methodName)
  56404. {
  56405. $groups = array_flip(self::getGroups($className, $methodName));
  56406. $size = self::UNKNOWN;
  56407. $class = new ReflectionClass($className);
  56408. if (isset($groups['large']) ||
  56409. (class_exists('PHPUnit_Extensions_Database_TestCase', false) &&
  56410. $class->isSubclassOf('PHPUnit_Extensions_Database_TestCase')) ||
  56411. (class_exists('PHPUnit_Extensions_SeleniumTestCase', false) &&
  56412. $class->isSubclassOf('PHPUnit_Extensions_SeleniumTestCase'))) {
  56413. $size = self::LARGE;
  56414. } elseif (isset($groups['medium'])) {
  56415. $size = self::MEDIUM;
  56416. } elseif (isset($groups['small'])) {
  56417. $size = self::SMALL;
  56418. }
  56419. return $size;
  56420. }
  56421. /**
  56422. * Returns the tickets for a test class or method.
  56423. *
  56424. * @param string $className
  56425. * @param string $methodName
  56426. * @return array
  56427. * @since Method available since Release 3.4.0
  56428. */
  56429. public static function getTickets($className, $methodName)
  56430. {
  56431. $annotations = self::parseTestMethodAnnotations(
  56432. $className,
  56433. $methodName
  56434. );
  56435. $tickets = array();
  56436. if (isset($annotations['class']['ticket'])) {
  56437. $tickets = $annotations['class']['ticket'];
  56438. }
  56439. if (isset($annotations['method']['ticket'])) {
  56440. $tickets = array_merge($tickets, $annotations['method']['ticket']);
  56441. }
  56442. return array_unique($tickets);
  56443. }
  56444. /**
  56445. * Returns the process isolation settings for a test.
  56446. *
  56447. * @param string $className
  56448. * @param string $methodName
  56449. * @return bool
  56450. * @since Method available since Release 3.4.1
  56451. */
  56452. public static function getProcessIsolationSettings($className, $methodName)
  56453. {
  56454. $annotations = self::parseTestMethodAnnotations(
  56455. $className,
  56456. $methodName
  56457. );
  56458. if (isset($annotations['class']['runTestsInSeparateProcesses']) ||
  56459. isset($annotations['method']['runInSeparateProcess'])) {
  56460. return true;
  56461. } else {
  56462. return false;
  56463. }
  56464. }
  56465. /**
  56466. * Returns the preserve global state settings for a test.
  56467. *
  56468. * @param string $className
  56469. * @param string $methodName
  56470. * @return bool
  56471. * @since Method available since Release 3.4.0
  56472. */
  56473. public static function getPreserveGlobalStateSettings($className, $methodName)
  56474. {
  56475. return self::getBooleanAnnotationSetting(
  56476. $className,
  56477. $methodName,
  56478. 'preserveGlobalState'
  56479. );
  56480. }
  56481. /**
  56482. * @param string $className
  56483. * @return array
  56484. * @since Method available since Release 4.0.8
  56485. */
  56486. public static function getHookMethods($className)
  56487. {
  56488. if (!class_exists($className, false)) {
  56489. return self::emptyHookMethodsArray();
  56490. }
  56491. if (!isset(self::$hookMethods[$className])) {
  56492. self::$hookMethods[$className] = self::emptyHookMethodsArray();
  56493. try {
  56494. $class = new ReflectionClass($className);
  56495. foreach ($class->getMethods() as $method) {
  56496. if (self::isBeforeClassMethod($method)) {
  56497. self::$hookMethods[$className]['beforeClass'][] = $method->getName();
  56498. }
  56499. if (self::isBeforeMethod($method)) {
  56500. self::$hookMethods[$className]['before'][] = $method->getName();
  56501. }
  56502. if (self::isAfterMethod($method)) {
  56503. self::$hookMethods[$className]['after'][] = $method->getName();
  56504. }
  56505. if (self::isAfterClassMethod($method)) {
  56506. self::$hookMethods[$className]['afterClass'][] = $method->getName();
  56507. }
  56508. }
  56509. } catch (ReflectionException $e) {
  56510. }
  56511. }
  56512. return self::$hookMethods[$className];
  56513. }
  56514. /**
  56515. * @return array
  56516. * @since Method available since Release 4.0.9
  56517. */
  56518. private static function emptyHookMethodsArray()
  56519. {
  56520. return array(
  56521. 'beforeClass' => array('setUpBeforeClass'),
  56522. 'before' => array('setUp'),
  56523. 'after' => array('tearDown'),
  56524. 'afterClass' => array('tearDownAfterClass')
  56525. );
  56526. }
  56527. /**
  56528. * @param string $className
  56529. * @param string $methodName
  56530. * @param string $settingName
  56531. * @return bool
  56532. * @since Method available since Release 3.4.0
  56533. */
  56534. private static function getBooleanAnnotationSetting($className, $methodName, $settingName)
  56535. {
  56536. $annotations = self::parseTestMethodAnnotations(
  56537. $className,
  56538. $methodName
  56539. );
  56540. $result = null;
  56541. if (isset($annotations['class'][$settingName])) {
  56542. if ($annotations['class'][$settingName][0] == 'enabled') {
  56543. $result = true;
  56544. } elseif ($annotations['class'][$settingName][0] == 'disabled') {
  56545. $result = false;
  56546. }
  56547. }
  56548. if (isset($annotations['method'][$settingName])) {
  56549. if ($annotations['method'][$settingName][0] == 'enabled') {
  56550. $result = true;
  56551. } elseif ($annotations['method'][$settingName][0] == 'disabled') {
  56552. $result = false;
  56553. }
  56554. }
  56555. return $result;
  56556. }
  56557. /**
  56558. * @param string $element
  56559. * @return array
  56560. * @throws PHPUnit_Framework_InvalidCoversTargetException
  56561. * @since Method available since Release 4.0.0
  56562. */
  56563. private static function resolveElementToReflectionObjects($element)
  56564. {
  56565. $codeToCoverList = array();
  56566. if (strpos($element, '::') !== false) {
  56567. list($className, $methodName) = explode('::', $element);
  56568. if (isset($methodName[0]) && $methodName[0] == '<') {
  56569. $classes = array($className);
  56570. foreach ($classes as $className) {
  56571. if (!class_exists($className) &&
  56572. !interface_exists($className)) {
  56573. throw new PHPUnit_Framework_InvalidCoversTargetException(
  56574. sprintf(
  56575. 'Trying to @cover or @use not existing class or ' .
  56576. 'interface "%s".',
  56577. $className
  56578. )
  56579. );
  56580. }
  56581. $class = new ReflectionClass($className);
  56582. $methods = $class->getMethods();
  56583. $inverse = isset($methodName[1]) && $methodName[1] == '!';
  56584. if (strpos($methodName, 'protected')) {
  56585. $visibility = 'isProtected';
  56586. } elseif (strpos($methodName, 'private')) {
  56587. $visibility = 'isPrivate';
  56588. } elseif (strpos($methodName, 'public')) {
  56589. $visibility = 'isPublic';
  56590. }
  56591. foreach ($methods as $method) {
  56592. if ($inverse && !$method->$visibility()) {
  56593. $codeToCoverList[] = $method;
  56594. } elseif (!$inverse && $method->$visibility()) {
  56595. $codeToCoverList[] = $method;
  56596. }
  56597. }
  56598. }
  56599. } else {
  56600. $classes = array($className);
  56601. foreach ($classes as $className) {
  56602. if ($className == '' && function_exists($methodName)) {
  56603. $codeToCoverList[] = new ReflectionFunction(
  56604. $methodName
  56605. );
  56606. } else {
  56607. if (!((class_exists($className) ||
  56608. interface_exists($className) ||
  56609. trait_exists($className)) &&
  56610. method_exists($className, $methodName))) {
  56611. throw new PHPUnit_Framework_InvalidCoversTargetException(
  56612. sprintf(
  56613. 'Trying to @cover or @use not existing method "%s::%s".',
  56614. $className,
  56615. $methodName
  56616. )
  56617. );
  56618. }
  56619. $codeToCoverList[] = new ReflectionMethod(
  56620. $className,
  56621. $methodName
  56622. );
  56623. }
  56624. }
  56625. }
  56626. } else {
  56627. $extended = false;
  56628. if (strpos($element, '<extended>') !== false) {
  56629. $element = str_replace('<extended>', '', $element);
  56630. $extended = true;
  56631. }
  56632. $classes = array($element);
  56633. if ($extended) {
  56634. $classes = array_merge(
  56635. $classes,
  56636. class_implements($element),
  56637. class_parents($element)
  56638. );
  56639. }
  56640. foreach ($classes as $className) {
  56641. if (!class_exists($className) &&
  56642. !interface_exists($className) &&
  56643. !trait_exists($className)) {
  56644. throw new PHPUnit_Framework_InvalidCoversTargetException(
  56645. sprintf(
  56646. 'Trying to @cover or @use not existing class or ' .
  56647. 'interface "%s".',
  56648. $className
  56649. )
  56650. );
  56651. }
  56652. $codeToCoverList[] = new ReflectionClass($className);
  56653. }
  56654. }
  56655. return $codeToCoverList;
  56656. }
  56657. /**
  56658. * @param array $reflectors
  56659. * @return array
  56660. */
  56661. private static function resolveReflectionObjectsToLines(array $reflectors)
  56662. {
  56663. $result = array();
  56664. foreach ($reflectors as $reflector) {
  56665. $filename = $reflector->getFileName();
  56666. if (!isset($result[$filename])) {
  56667. $result[$filename] = array();
  56668. }
  56669. $result[$filename] = array_unique(
  56670. array_merge(
  56671. $result[$filename],
  56672. range($reflector->getStartLine(), $reflector->getEndLine())
  56673. )
  56674. );
  56675. }
  56676. return $result;
  56677. }
  56678. /**
  56679. * @param ReflectionMethod $method
  56680. * @return bool
  56681. * @since Method available since Release 4.0.8
  56682. */
  56683. private static function isBeforeClassMethod(ReflectionMethod $method)
  56684. {
  56685. return $method->isStatic() && strpos($method->getDocComment(), '@beforeClass') !== false;
  56686. }
  56687. /**
  56688. * @param ReflectionMethod $method
  56689. * @return bool
  56690. * @since Method available since Release 4.0.8
  56691. */
  56692. private static function isBeforeMethod(ReflectionMethod $method)
  56693. {
  56694. return preg_match('/@before\b/', $method->getDocComment());
  56695. }
  56696. /**
  56697. * @param ReflectionMethod $method
  56698. * @return bool
  56699. * @since Method available since Release 4.0.8
  56700. */
  56701. private static function isAfterClassMethod(ReflectionMethod $method)
  56702. {
  56703. return $method->isStatic() && strpos($method->getDocComment(), '@afterClass') !== false;
  56704. }
  56705. /**
  56706. * @param ReflectionMethod $method
  56707. * @return bool
  56708. * @since Method available since Release 4.0.8
  56709. */
  56710. private static function isAfterMethod(ReflectionMethod $method)
  56711. {
  56712. return preg_match('/@after\b/', $method->getDocComment());
  56713. }
  56714. }
  56715. <?php
  56716. /*
  56717. * This file is part of PHPUnit.
  56718. *
  56719. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56720. *
  56721. * For the full copyright and license information, please view the LICENSE
  56722. * file that was distributed with this source code.
  56723. */
  56724. /**
  56725. * Filesystem helpers.
  56726. *
  56727. * @since Class available since Release 3.0.0
  56728. */
  56729. class PHPUnit_Util_Filesystem
  56730. {
  56731. /**
  56732. * @var array
  56733. */
  56734. protected static $buffer = array();
  56735. /**
  56736. * Maps class names to source file names:
  56737. * - PEAR CS: Foo_Bar_Baz -> Foo/Bar/Baz.php
  56738. * - Namespace: Foo\Bar\Baz -> Foo/Bar/Baz.php
  56739. *
  56740. * @param string $className
  56741. * @return string
  56742. * @since Method available since Release 3.4.0
  56743. */
  56744. public static function classNameToFilename($className)
  56745. {
  56746. return str_replace(
  56747. array('_', '\\'),
  56748. DIRECTORY_SEPARATOR,
  56749. $className
  56750. ) . '.php';
  56751. }
  56752. }
  56753. <?php
  56754. /*
  56755. * This file is part of PHPUnit.
  56756. *
  56757. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56758. *
  56759. * For the full copyright and license information, please view the LICENSE
  56760. * file that was distributed with this source code.
  56761. */
  56762. /**
  56763. * Command-line options parsing class.
  56764. *
  56765. * @since Class available since Release 3.0.0
  56766. */
  56767. class PHPUnit_Util_Getopt
  56768. {
  56769. public static function getopt(array $args, $short_options, $long_options = null)
  56770. {
  56771. if (empty($args)) {
  56772. return array(array(), array());
  56773. }
  56774. $opts = array();
  56775. $non_opts = array();
  56776. if ($long_options) {
  56777. sort($long_options);
  56778. }
  56779. if (isset($args[0][0]) && $args[0][0] != '-') {
  56780. array_shift($args);
  56781. }
  56782. reset($args);
  56783. array_map('trim', $args);
  56784. while (list($i, $arg) = each($args)) {
  56785. if ($arg == '') {
  56786. continue;
  56787. }
  56788. if ($arg == '--') {
  56789. $non_opts = array_merge($non_opts, array_slice($args, $i + 1));
  56790. break;
  56791. }
  56792. if ($arg[0] != '-' ||
  56793. (strlen($arg) > 1 && $arg[1] == '-' && !$long_options)) {
  56794. $non_opts = array_merge($non_opts, array_slice($args, $i));
  56795. break;
  56796. } elseif (strlen($arg) > 1 && $arg[1] == '-') {
  56797. self::parseLongOption(
  56798. substr($arg, 2),
  56799. $long_options,
  56800. $opts,
  56801. $args
  56802. );
  56803. } else {
  56804. self::parseShortOption(
  56805. substr($arg, 1),
  56806. $short_options,
  56807. $opts,
  56808. $args
  56809. );
  56810. }
  56811. }
  56812. return array($opts, $non_opts);
  56813. }
  56814. protected static function parseShortOption($arg, $short_options, &$opts, &$args)
  56815. {
  56816. $argLen = strlen($arg);
  56817. for ($i = 0; $i < $argLen; $i++) {
  56818. $opt = $arg[$i];
  56819. $opt_arg = null;
  56820. if (($spec = strstr($short_options, $opt)) === false ||
  56821. $arg[$i] == ':') {
  56822. throw new PHPUnit_Framework_Exception(
  56823. "unrecognized option -- $opt"
  56824. );
  56825. }
  56826. if (strlen($spec) > 1 && $spec[1] == ':') {
  56827. if (strlen($spec) > 2 && $spec[2] == ':') {
  56828. if ($i + 1 < $argLen) {
  56829. $opts[] = array($opt, substr($arg, $i + 1));
  56830. break;
  56831. }
  56832. } else {
  56833. if ($i + 1 < $argLen) {
  56834. $opts[] = array($opt, substr($arg, $i + 1));
  56835. break;
  56836. } elseif (list(, $opt_arg) = each($args)) {
  56837. } else {
  56838. throw new PHPUnit_Framework_Exception(
  56839. "option requires an argument -- $opt"
  56840. );
  56841. }
  56842. }
  56843. }
  56844. $opts[] = array($opt, $opt_arg);
  56845. }
  56846. }
  56847. protected static function parseLongOption($arg, $long_options, &$opts, &$args)
  56848. {
  56849. $count = count($long_options);
  56850. $list = explode('=', $arg);
  56851. $opt = $list[0];
  56852. $opt_arg = null;
  56853. if (count($list) > 1) {
  56854. $opt_arg = $list[1];
  56855. }
  56856. $opt_len = strlen($opt);
  56857. for ($i = 0; $i < $count; $i++) {
  56858. $long_opt = $long_options[$i];
  56859. $opt_start = substr($long_opt, 0, $opt_len);
  56860. if ($opt_start != $opt) {
  56861. continue;
  56862. }
  56863. $opt_rest = substr($long_opt, $opt_len);
  56864. if ($opt_rest != '' && $opt[0] != '=' && $i + 1 < $count &&
  56865. $opt == substr($long_options[$i+1], 0, $opt_len)) {
  56866. throw new PHPUnit_Framework_Exception(
  56867. "option --$opt is ambiguous"
  56868. );
  56869. }
  56870. if (substr($long_opt, -1) == '=') {
  56871. if (substr($long_opt, -2) != '==') {
  56872. if (!strlen($opt_arg) &&
  56873. !(list(, $opt_arg) = each($args))) {
  56874. throw new PHPUnit_Framework_Exception(
  56875. "option --$opt requires an argument"
  56876. );
  56877. }
  56878. }
  56879. } elseif ($opt_arg) {
  56880. throw new PHPUnit_Framework_Exception(
  56881. "option --$opt doesn't allow an argument"
  56882. );
  56883. }
  56884. $full_option = '--' . preg_replace('/={1,2}$/', '', $long_opt);
  56885. $opts[] = array($full_option, $opt_arg);
  56886. return;
  56887. }
  56888. throw new PHPUnit_Framework_Exception("unrecognized option --$opt");
  56889. }
  56890. }
  56891. <?php
  56892. /*
  56893. * This file is part of PHPUnit.
  56894. *
  56895. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56896. *
  56897. * For the full copyright and license information, please view the LICENSE
  56898. * file that was distributed with this source code.
  56899. */
  56900. // Workaround for http://bugs.php.net/bug.php?id=47987,
  56901. // see https://github.com/sebastianbergmann/phpunit/issues#issue/125 for details
  56902. // Use dirname(__DIR__) instead of using /../ because of https://github.com/facebook/hhvm/issues/5215
  56903. require_once dirname(__DIR__) . '/Framework/Error.php';
  56904. require_once dirname(__DIR__) . '/Framework/Error/Notice.php';
  56905. require_once dirname(__DIR__) . '/Framework/Error/Warning.php';
  56906. require_once dirname(__DIR__) . '/Framework/Error/Deprecated.php';
  56907. /**
  56908. * Error handler that converts PHP errors and warnings to exceptions.
  56909. *
  56910. * @since Class available since Release 3.3.0
  56911. */
  56912. class PHPUnit_Util_ErrorHandler
  56913. {
  56914. protected static $errorStack = array();
  56915. /**
  56916. * Returns the error stack.
  56917. *
  56918. * @return array
  56919. */
  56920. public static function getErrorStack()
  56921. {
  56922. return self::$errorStack;
  56923. }
  56924. /**
  56925. * @param int $errno
  56926. * @param string $errstr
  56927. * @param string $errfile
  56928. * @param int $errline
  56929. * @throws PHPUnit_Framework_Error
  56930. */
  56931. public static function handleError($errno, $errstr, $errfile, $errline)
  56932. {
  56933. if (!($errno & error_reporting())) {
  56934. return false;
  56935. }
  56936. self::$errorStack[] = array($errno, $errstr, $errfile, $errline);
  56937. $trace = debug_backtrace(false);
  56938. array_shift($trace);
  56939. foreach ($trace as $frame) {
  56940. if ($frame['function'] == '__toString') {
  56941. return false;
  56942. }
  56943. }
  56944. if ($errno == E_NOTICE || $errno == E_USER_NOTICE || $errno == E_STRICT) {
  56945. if (PHPUnit_Framework_Error_Notice::$enabled !== true) {
  56946. return false;
  56947. }
  56948. $exception = 'PHPUnit_Framework_Error_Notice';
  56949. } elseif ($errno == E_WARNING || $errno == E_USER_WARNING) {
  56950. if (PHPUnit_Framework_Error_Warning::$enabled !== true) {
  56951. return false;
  56952. }
  56953. $exception = 'PHPUnit_Framework_Error_Warning';
  56954. } elseif ($errno == E_DEPRECATED || $errno == E_USER_DEPRECATED) {
  56955. if (PHPUnit_Framework_Error_Deprecated::$enabled !== true) {
  56956. return false;
  56957. }
  56958. $exception = 'PHPUnit_Framework_Error_Deprecated';
  56959. } else {
  56960. $exception = 'PHPUnit_Framework_Error';
  56961. }
  56962. throw new $exception($errstr, $errno, $errfile, $errline);
  56963. }
  56964. /**
  56965. * Registers an error handler and returns a function that will restore
  56966. * the previous handler when invoked
  56967. * @param int $severity PHP predefined error constant
  56968. * @throws Exception if event of specified severity is emitted
  56969. */
  56970. public static function handleErrorOnce($severity = E_WARNING)
  56971. {
  56972. $terminator = function () {
  56973. static $expired = false;
  56974. if (!$expired) {
  56975. $expired = true;
  56976. // cleans temporary error handler
  56977. return restore_error_handler();
  56978. }
  56979. };
  56980. set_error_handler(function ($errno, $errstr) use ($severity) {
  56981. if ($errno === $severity) {
  56982. return;
  56983. }
  56984. return false;
  56985. });
  56986. return $terminator;
  56987. }
  56988. }
  56989. <?php
  56990. /*
  56991. * This file is part of PHPUnit.
  56992. *
  56993. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  56994. *
  56995. * For the full copyright and license information, please view the LICENSE
  56996. * file that was distributed with this source code.
  56997. */
  56998. /**
  56999. * String helpers.
  57000. *
  57001. * @since Class available since Release 3.6.0
  57002. */
  57003. class PHPUnit_Util_String
  57004. {
  57005. /**
  57006. * Converts a string to UTF-8 encoding.
  57007. *
  57008. * @param string $string
  57009. * @return string
  57010. */
  57011. public static function convertToUtf8($string)
  57012. {
  57013. if (!self::isUtf8($string)) {
  57014. if (function_exists('mb_convert_encoding')) {
  57015. $string = mb_convert_encoding($string, 'UTF-8');
  57016. } else {
  57017. $string = utf8_encode($string);
  57018. }
  57019. }
  57020. return $string;
  57021. }
  57022. /**
  57023. * Checks a string for UTF-8 encoding.
  57024. *
  57025. * @param string $string
  57026. * @return bool
  57027. */
  57028. protected static function isUtf8($string)
  57029. {
  57030. $length = strlen($string);
  57031. for ($i = 0; $i < $length; $i++) {
  57032. if (ord($string[$i]) < 0x80) {
  57033. $n = 0;
  57034. } elseif ((ord($string[$i]) & 0xE0) == 0xC0) {
  57035. $n = 1;
  57036. } elseif ((ord($string[$i]) & 0xF0) == 0xE0) {
  57037. $n = 2;
  57038. } elseif ((ord($string[$i]) & 0xF0) == 0xF0) {
  57039. $n = 3;
  57040. } else {
  57041. return false;
  57042. }
  57043. for ($j = 0; $j < $n; $j++) {
  57044. if ((++$i == $length) || ((ord($string[$i]) & 0xC0) != 0x80)) {
  57045. return false;
  57046. }
  57047. }
  57048. }
  57049. return true;
  57050. }
  57051. }
  57052. <?php
  57053. /*
  57054. * This file is part of PHPUnit.
  57055. *
  57056. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  57057. *
  57058. * For the full copyright and license information, please view the LICENSE
  57059. * file that was distributed with this source code.
  57060. */
  57061. /**
  57062. * Factory for PHPUnit_Framework_Exception objects that are used to describe
  57063. * invalid arguments passed to a function or method.
  57064. *
  57065. * @since Class available since Release 3.4.0
  57066. */
  57067. class PHPUnit_Util_InvalidArgumentHelper
  57068. {
  57069. /**
  57070. * @param int $argument
  57071. * @param string $type
  57072. * @param mixed $value
  57073. * @return PHPUnit_Framework_Exception
  57074. */
  57075. public static function factory($argument, $type, $value = null)
  57076. {
  57077. $stack = debug_backtrace(false);
  57078. return new PHPUnit_Framework_Exception(
  57079. sprintf(
  57080. 'Argument #%d%sof %s::%s() must be a %s',
  57081. $argument,
  57082. $value !== null ? ' (' . gettype($value) . '#' . $value . ')' : ' (No Value) ',
  57083. $stack[1]['class'],
  57084. $stack[1]['function'],
  57085. $type
  57086. )
  57087. );
  57088. }
  57089. }
  57090. <?php
  57091. /*
  57092. * This file is part of PHPUnit.
  57093. *
  57094. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  57095. *
  57096. * For the full copyright and license information, please view the LICENSE
  57097. * file that was distributed with this source code.
  57098. */
  57099. /**
  57100. * Utility class that can print to STDOUT or write to a file.
  57101. *
  57102. * @since Class available since Release 2.0.0
  57103. */
  57104. class PHPUnit_Util_Printer
  57105. {
  57106. /**
  57107. * If true, flush output after every write.
  57108. *
  57109. * @var bool
  57110. */
  57111. protected $autoFlush = false;
  57112. /**
  57113. * @var resource
  57114. */
  57115. protected $out;
  57116. /**
  57117. * @var string
  57118. */
  57119. protected $outTarget;
  57120. /**
  57121. * @var bool
  57122. */
  57123. protected $printsHTML = false;
  57124. /**
  57125. * Constructor.
  57126. *
  57127. * @param mixed $out
  57128. * @throws PHPUnit_Framework_Exception
  57129. */
  57130. public function __construct($out = null)
  57131. {
  57132. if ($out !== null) {
  57133. if (is_string($out)) {
  57134. if (strpos($out, 'socket://') === 0) {
  57135. $out = explode(':', str_replace('socket://', '', $out));
  57136. if (sizeof($out) != 2) {
  57137. throw new PHPUnit_Framework_Exception;
  57138. }
  57139. $this->out = fsockopen($out[0], $out[1]);
  57140. } else {
  57141. if (strpos($out, 'php://') === false &&
  57142. !is_dir(dirname($out))) {
  57143. mkdir(dirname($out), 0777, true);
  57144. }
  57145. $this->out = fopen($out, 'wt');
  57146. }
  57147. $this->outTarget = $out;
  57148. } else {
  57149. $this->out = $out;
  57150. }
  57151. }
  57152. }
  57153. /**
  57154. * Flush buffer, optionally tidy up HTML, and close output if it's not to a php stream
  57155. */
  57156. public function flush()
  57157. {
  57158. if ($this->out && strncmp($this->outTarget, 'php://', 6) !== 0) {
  57159. fclose($this->out);
  57160. }
  57161. if ($this->printsHTML === true &&
  57162. $this->outTarget !== null &&
  57163. strpos($this->outTarget, 'php://') !== 0 &&
  57164. strpos($this->outTarget, 'socket://') !== 0 &&
  57165. extension_loaded('tidy')) {
  57166. file_put_contents(
  57167. $this->outTarget,
  57168. tidy_repair_file(
  57169. $this->outTarget,
  57170. array('indent' => true, 'wrap' => 0),
  57171. 'utf8'
  57172. )
  57173. );
  57174. }
  57175. }
  57176. /**
  57177. * Performs a safe, incremental flush.
  57178. *
  57179. * Do not confuse this function with the flush() function of this class,
  57180. * since the flush() function may close the file being written to, rendering
  57181. * the current object no longer usable.
  57182. *
  57183. * @since Method available since Release 3.3.0
  57184. */
  57185. public function incrementalFlush()
  57186. {
  57187. if ($this->out) {
  57188. fflush($this->out);
  57189. } else {
  57190. flush();
  57191. }
  57192. }
  57193. /**
  57194. * @param string $buffer
  57195. */
  57196. public function write($buffer)
  57197. {
  57198. if ($this->out) {
  57199. fwrite($this->out, $buffer);
  57200. if ($this->autoFlush) {
  57201. $this->incrementalFlush();
  57202. }
  57203. } else {
  57204. if (PHP_SAPI != 'cli') {
  57205. $buffer = htmlspecialchars($buffer);
  57206. }
  57207. print $buffer;
  57208. if ($this->autoFlush) {
  57209. $this->incrementalFlush();
  57210. }
  57211. }
  57212. }
  57213. /**
  57214. * Check auto-flush mode.
  57215. *
  57216. * @return bool
  57217. * @since Method available since Release 3.3.0
  57218. */
  57219. public function getAutoFlush()
  57220. {
  57221. return $this->autoFlush;
  57222. }
  57223. /**
  57224. * Set auto-flushing mode.
  57225. *
  57226. * If set, *incremental* flushes will be done after each write. This should
  57227. * not be confused with the different effects of this class' flush() method.
  57228. *
  57229. * @param bool $autoFlush
  57230. * @since Method available since Release 3.3.0
  57231. */
  57232. public function setAutoFlush($autoFlush)
  57233. {
  57234. if (is_bool($autoFlush)) {
  57235. $this->autoFlush = $autoFlush;
  57236. } else {
  57237. throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
  57238. }
  57239. }
  57240. }
  57241. <?php
  57242. /*
  57243. * This file is part of PHPUnit.
  57244. *
  57245. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  57246. *
  57247. * For the full copyright and license information, please view the LICENSE
  57248. * file that was distributed with this source code.
  57249. */
  57250. /**
  57251. * Wrapper for the PHPUnit XML configuration file.
  57252. *
  57253. * Example XML configuration file:
  57254. * <code>
  57255. * <?xml version="1.0" encoding="utf-8" ?>
  57256. *
  57257. * <phpunit backupGlobals="true"
  57258. * backupStaticAttributes="false"
  57259. * bootstrap="/path/to/bootstrap.php"
  57260. * cacheTokens="false"
  57261. * columns="80"
  57262. * colors="false"
  57263. * stderr="false"
  57264. * convertErrorsToExceptions="true"
  57265. * convertNoticesToExceptions="true"
  57266. * convertWarningsToExceptions="true"
  57267. * forceCoversAnnotation="false"
  57268. * mapTestClassNameToCoveredClassName="false"
  57269. * printerClass="PHPUnit_TextUI_ResultPrinter"
  57270. * processIsolation="false"
  57271. * stopOnError="false"
  57272. * stopOnFailure="false"
  57273. * stopOnIncomplete="false"
  57274. * stopOnRisky="false"
  57275. * stopOnSkipped="false"
  57276. * testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
  57277. * timeoutForSmallTests="1"
  57278. * timeoutForMediumTests="10"
  57279. * timeoutForLargeTests="60"
  57280. * beStrictAboutTestsThatDoNotTestAnything="false"
  57281. * beStrictAboutOutputDuringTests="false"
  57282. * beStrictAboutTestSize="false"
  57283. * beStrictAboutTodoAnnotatedTests="false"
  57284. * checkForUnintentionallyCoveredCode="false"
  57285. * disallowChangesToGlobalState="false"
  57286. * verbose="false">
  57287. * <testsuites>
  57288. * <testsuite name="My Test Suite">
  57289. * <directory suffix="Test.php" phpVersion="5.3.0" phpVersionOperator=">=">/path/to/files</directory>
  57290. * <file phpVersion="5.3.0" phpVersionOperator=">=">/path/to/MyTest.php</file>
  57291. * <exclude>/path/to/files/exclude</exclude>
  57292. * </testsuite>
  57293. * </testsuites>
  57294. *
  57295. * <groups>
  57296. * <include>
  57297. * <group>name</group>
  57298. * </include>
  57299. * <exclude>
  57300. * <group>name</group>
  57301. * </exclude>
  57302. * </groups>
  57303. *
  57304. * <filter>
  57305. * <blacklist>
  57306. * <directory suffix=".php">/path/to/files</directory>
  57307. * <file>/path/to/file</file>
  57308. * <exclude>
  57309. * <directory suffix=".php">/path/to/files</directory>
  57310. * <file>/path/to/file</file>
  57311. * </exclude>
  57312. * </blacklist>
  57313. * <whitelist addUncoveredFilesFromWhitelist="true"
  57314. * processUncoveredFilesFromWhitelist="false">
  57315. * <directory suffix=".php">/path/to/files</directory>
  57316. * <file>/path/to/file</file>
  57317. * <exclude>
  57318. * <directory suffix=".php">/path/to/files</directory>
  57319. * <file>/path/to/file</file>
  57320. * </exclude>
  57321. * </whitelist>
  57322. * </filter>
  57323. *
  57324. * <listeners>
  57325. * <listener class="MyListener" file="/optional/path/to/MyListener.php">
  57326. * <arguments>
  57327. * <array>
  57328. * <element key="0">
  57329. * <string>Sebastian</string>
  57330. * </element>
  57331. * </array>
  57332. * <integer>22</integer>
  57333. * <string>April</string>
  57334. * <double>19.78</double>
  57335. * <null/>
  57336. * <object class="stdClass"/>
  57337. * <file>MyRelativeFile.php</file>
  57338. * <directory>MyRelativeDir</directory>
  57339. * </arguments>
  57340. * </listener>
  57341. * </listeners>
  57342. *
  57343. * <logging>
  57344. * <log type="coverage-html" target="/tmp/report" lowUpperBound="50" highLowerBound="90"/>
  57345. * <log type="coverage-clover" target="/tmp/clover.xml"/>
  57346. * <log type="json" target="/tmp/logfile.json"/>
  57347. * <log type="plain" target="/tmp/logfile.txt"/>
  57348. * <log type="tap" target="/tmp/logfile.tap"/>
  57349. * <log type="junit" target="/tmp/logfile.xml" logIncompleteSkipped="false"/>
  57350. * <log type="testdox-html" target="/tmp/testdox.html"/>
  57351. * <log type="testdox-text" target="/tmp/testdox.txt"/>
  57352. * <log type="coverage-crap4j" target="/tmp/crap.xml"/>
  57353. * </logging>
  57354. *
  57355. * <php>
  57356. * <includePath>.</includePath>
  57357. * <ini name="foo" value="bar"/>
  57358. * <const name="foo" value="bar"/>
  57359. * <var name="foo" value="bar"/>
  57360. * <env name="foo" value="bar"/>
  57361. * <post name="foo" value="bar"/>
  57362. * <get name="foo" value="bar"/>
  57363. * <cookie name="foo" value="bar"/>
  57364. * <server name="foo" value="bar"/>
  57365. * <files name="foo" value="bar"/>
  57366. * <request name="foo" value="bar"/>
  57367. * </php>
  57368. *
  57369. * <selenium>
  57370. * <browser name="Firefox on Linux"
  57371. * browser="*firefox /usr/lib/firefox/firefox-bin"
  57372. * host="my.linux.box"
  57373. * port="4444"
  57374. * timeout="30000"/>
  57375. * </selenium>
  57376. * </phpunit>
  57377. * </code>
  57378. *
  57379. * @since Class available since Release 3.2.0
  57380. */
  57381. class PHPUnit_Util_Configuration
  57382. {
  57383. private static $instances = array();
  57384. protected $document;
  57385. protected $xpath;
  57386. protected $filename;
  57387. /**
  57388. * Loads a PHPUnit configuration file.
  57389. *
  57390. * @param string $filename
  57391. */
  57392. protected function __construct($filename)
  57393. {
  57394. $this->filename = $filename;
  57395. $this->document = PHPUnit_Util_XML::loadFile($filename, false, true, true);
  57396. $this->xpath = new DOMXPath($this->document);
  57397. }
  57398. /**
  57399. * @since Method available since Release 3.4.0
  57400. */
  57401. final private function __clone()
  57402. {
  57403. }
  57404. /**
  57405. * Returns a PHPUnit configuration object.
  57406. *
  57407. * @param string $filename
  57408. * @return PHPUnit_Util_Configuration
  57409. * @since Method available since Release 3.4.0
  57410. */
  57411. public static function getInstance($filename)
  57412. {
  57413. $realpath = realpath($filename);
  57414. if ($realpath === false) {
  57415. throw new PHPUnit_Framework_Exception(
  57416. sprintf(
  57417. 'Could not read "%s".',
  57418. $filename
  57419. )
  57420. );
  57421. }
  57422. if (!isset(self::$instances[$realpath])) {
  57423. self::$instances[$realpath] = new self($realpath);
  57424. }
  57425. return self::$instances[$realpath];
  57426. }
  57427. /**
  57428. * Returns the realpath to the configuration file.
  57429. *
  57430. * @return string
  57431. * @since Method available since Release 3.6.0
  57432. */
  57433. public function getFilename()
  57434. {
  57435. return $this->filename;
  57436. }
  57437. /**
  57438. * Returns the configuration for SUT filtering.
  57439. *
  57440. * @return array
  57441. * @since Method available since Release 3.2.1
  57442. */
  57443. public function getFilterConfiguration()
  57444. {
  57445. $addUncoveredFilesFromWhitelist = true;
  57446. $processUncoveredFilesFromWhitelist = false;
  57447. $tmp = $this->xpath->query('filter/whitelist');
  57448. if ($tmp->length == 1) {
  57449. if ($tmp->item(0)->hasAttribute('addUncoveredFilesFromWhitelist')) {
  57450. $addUncoveredFilesFromWhitelist = $this->getBoolean(
  57451. (string) $tmp->item(0)->getAttribute(
  57452. 'addUncoveredFilesFromWhitelist'
  57453. ),
  57454. true
  57455. );
  57456. }
  57457. if ($tmp->item(0)->hasAttribute('processUncoveredFilesFromWhitelist')) {
  57458. $processUncoveredFilesFromWhitelist = $this->getBoolean(
  57459. (string) $tmp->item(0)->getAttribute(
  57460. 'processUncoveredFilesFromWhitelist'
  57461. ),
  57462. false
  57463. );
  57464. }
  57465. }
  57466. return array(
  57467. 'blacklist' => array(
  57468. 'include' => array(
  57469. 'directory' => $this->readFilterDirectories(
  57470. 'filter/blacklist/directory'
  57471. ),
  57472. 'file' => $this->readFilterFiles(
  57473. 'filter/blacklist/file'
  57474. )
  57475. ),
  57476. 'exclude' => array(
  57477. 'directory' => $this->readFilterDirectories(
  57478. 'filter/blacklist/exclude/directory'
  57479. ),
  57480. 'file' => $this->readFilterFiles(
  57481. 'filter/blacklist/exclude/file'
  57482. )
  57483. )
  57484. ),
  57485. 'whitelist' => array(
  57486. 'addUncoveredFilesFromWhitelist' => $addUncoveredFilesFromWhitelist,
  57487. 'processUncoveredFilesFromWhitelist' => $processUncoveredFilesFromWhitelist,
  57488. 'include' => array(
  57489. 'directory' => $this->readFilterDirectories(
  57490. 'filter/whitelist/directory'
  57491. ),
  57492. 'file' => $this->readFilterFiles(
  57493. 'filter/whitelist/file'
  57494. )
  57495. ),
  57496. 'exclude' => array(
  57497. 'directory' => $this->readFilterDirectories(
  57498. 'filter/whitelist/exclude/directory'
  57499. ),
  57500. 'file' => $this->readFilterFiles(
  57501. 'filter/whitelist/exclude/file'
  57502. )
  57503. )
  57504. )
  57505. );
  57506. }
  57507. /**
  57508. * Returns the configuration for groups.
  57509. *
  57510. * @return array
  57511. * @since Method available since Release 3.2.1
  57512. */
  57513. public function getGroupConfiguration()
  57514. {
  57515. $groups = array(
  57516. 'include' => array(),
  57517. 'exclude' => array()
  57518. );
  57519. foreach ($this->xpath->query('groups/include/group') as $group) {
  57520. $groups['include'][] = (string) $group->nodeValue;
  57521. }
  57522. foreach ($this->xpath->query('groups/exclude/group') as $group) {
  57523. $groups['exclude'][] = (string) $group->nodeValue;
  57524. }
  57525. return $groups;
  57526. }
  57527. /**
  57528. * Returns the configuration for listeners.
  57529. *
  57530. * @return array
  57531. * @since Method available since Release 3.4.0
  57532. */
  57533. public function getListenerConfiguration()
  57534. {
  57535. $result = array();
  57536. foreach ($this->xpath->query('listeners/listener') as $listener) {
  57537. $class = (string) $listener->getAttribute('class');
  57538. $file = '';
  57539. $arguments = array();
  57540. if ($listener->getAttribute('file')) {
  57541. $file = $this->toAbsolutePath(
  57542. (string) $listener->getAttribute('file'),
  57543. true
  57544. );
  57545. }
  57546. foreach ($listener->childNodes as $node) {
  57547. if ($node instanceof DOMElement && $node->tagName == 'arguments') {
  57548. foreach ($node->childNodes as $argument) {
  57549. if ($argument instanceof DOMElement) {
  57550. if ($argument->tagName == 'file' ||
  57551. $argument->tagName == 'directory') {
  57552. $arguments[] = $this->toAbsolutePath((string) $argument->nodeValue);
  57553. } else {
  57554. $arguments[] = PHPUnit_Util_XML::xmlToVariable($argument);
  57555. }
  57556. }
  57557. }
  57558. }
  57559. }
  57560. $result[] = array(
  57561. 'class' => $class,
  57562. 'file' => $file,
  57563. 'arguments' => $arguments
  57564. );
  57565. }
  57566. return $result;
  57567. }
  57568. /**
  57569. * Returns the logging configuration.
  57570. *
  57571. * @return array
  57572. */
  57573. public function getLoggingConfiguration()
  57574. {
  57575. $result = array();
  57576. foreach ($this->xpath->query('logging/log') as $log) {
  57577. $type = (string) $log->getAttribute('type');
  57578. $target = (string) $log->getAttribute('target');
  57579. if (!$target) {
  57580. continue;
  57581. }
  57582. $target = $this->toAbsolutePath($target);
  57583. if ($type == 'coverage-html') {
  57584. if ($log->hasAttribute('lowUpperBound')) {
  57585. $result['lowUpperBound'] = $this->getInteger(
  57586. (string) $log->getAttribute('lowUpperBound'),
  57587. 50
  57588. );
  57589. }
  57590. if ($log->hasAttribute('highLowerBound')) {
  57591. $result['highLowerBound'] = $this->getInteger(
  57592. (string) $log->getAttribute('highLowerBound'),
  57593. 90
  57594. );
  57595. }
  57596. } elseif ($type == 'junit') {
  57597. if ($log->hasAttribute('logIncompleteSkipped')) {
  57598. $result['logIncompleteSkipped'] = $this->getBoolean(
  57599. (string) $log->getAttribute('logIncompleteSkipped'),
  57600. false
  57601. );
  57602. }
  57603. } elseif ($type == 'coverage-text') {
  57604. if ($log->hasAttribute('showUncoveredFiles')) {
  57605. $result['coverageTextShowUncoveredFiles'] = $this->getBoolean(
  57606. (string) $log->getAttribute('showUncoveredFiles'),
  57607. false
  57608. );
  57609. }
  57610. if ($log->hasAttribute('showOnlySummary')) {
  57611. $result['coverageTextShowOnlySummary'] = $this->getBoolean(
  57612. (string) $log->getAttribute('showOnlySummary'),
  57613. false
  57614. );
  57615. }
  57616. }
  57617. $result[$type] = $target;
  57618. }
  57619. return $result;
  57620. }
  57621. /**
  57622. * Returns the PHP configuration.
  57623. *
  57624. * @return array
  57625. * @since Method available since Release 3.2.1
  57626. */
  57627. public function getPHPConfiguration()
  57628. {
  57629. $result = array(
  57630. 'include_path' => array(),
  57631. 'ini' => array(),
  57632. 'const' => array(),
  57633. 'var' => array(),
  57634. 'env' => array(),
  57635. 'post' => array(),
  57636. 'get' => array(),
  57637. 'cookie' => array(),
  57638. 'server' => array(),
  57639. 'files' => array(),
  57640. 'request' => array()
  57641. );
  57642. foreach ($this->xpath->query('php/includePath') as $includePath) {
  57643. $path = (string) $includePath->nodeValue;
  57644. if ($path) {
  57645. $result['include_path'][] = $this->toAbsolutePath($path);
  57646. }
  57647. }
  57648. foreach ($this->xpath->query('php/ini') as $ini) {
  57649. $name = (string) $ini->getAttribute('name');
  57650. $value = (string) $ini->getAttribute('value');
  57651. $result['ini'][$name] = $value;
  57652. }
  57653. foreach ($this->xpath->query('php/const') as $const) {
  57654. $name = (string) $const->getAttribute('name');
  57655. $value = (string) $const->getAttribute('value');
  57656. $result['const'][$name] = $this->getBoolean($value, $value);
  57657. }
  57658. foreach (array('var', 'env', 'post', 'get', 'cookie', 'server', 'files', 'request') as $array) {
  57659. foreach ($this->xpath->query('php/' . $array) as $var) {
  57660. $name = (string) $var->getAttribute('name');
  57661. $value = (string) $var->getAttribute('value');
  57662. $result[$array][$name] = $this->getBoolean($value, $value);
  57663. }
  57664. }
  57665. return $result;
  57666. }
  57667. /**
  57668. * Handles the PHP configuration.
  57669. *
  57670. * @since Method available since Release 3.2.20
  57671. */
  57672. public function handlePHPConfiguration()
  57673. {
  57674. $configuration = $this->getPHPConfiguration();
  57675. if (! empty($configuration['include_path'])) {
  57676. ini_set(
  57677. 'include_path',
  57678. implode(PATH_SEPARATOR, $configuration['include_path']) .
  57679. PATH_SEPARATOR .
  57680. ini_get('include_path')
  57681. );
  57682. }
  57683. foreach ($configuration['ini'] as $name => $value) {
  57684. if (defined($value)) {
  57685. $value = constant($value);
  57686. }
  57687. ini_set($name, $value);
  57688. }
  57689. foreach ($configuration['const'] as $name => $value) {
  57690. if (!defined($name)) {
  57691. define($name, $value);
  57692. }
  57693. }
  57694. foreach (array('var', 'post', 'get', 'cookie', 'server', 'files', 'request') as $array) {
  57695. // See https://github.com/sebastianbergmann/phpunit/issues/277
  57696. switch ($array) {
  57697. case 'var':
  57698. $target = &$GLOBALS;
  57699. break;
  57700. case 'server':
  57701. $target = &$_SERVER;
  57702. break;
  57703. default:
  57704. $target = &$GLOBALS['_' . strtoupper($array)];
  57705. break;
  57706. }
  57707. foreach ($configuration[$array] as $name => $value) {
  57708. $target[$name] = $value;
  57709. }
  57710. }
  57711. foreach ($configuration['env'] as $name => $value) {
  57712. if (false === getenv($name)) {
  57713. putenv("{$name}={$value}");
  57714. }
  57715. if (!isset($_ENV[$name])) {
  57716. $_ENV[$name] = $value;
  57717. }
  57718. }
  57719. }
  57720. /**
  57721. * Returns the PHPUnit configuration.
  57722. *
  57723. * @return array
  57724. * @since Method available since Release 3.2.14
  57725. */
  57726. public function getPHPUnitConfiguration()
  57727. {
  57728. $result = array();
  57729. $root = $this->document->documentElement;
  57730. if ($root->hasAttribute('cacheTokens')) {
  57731. $result['cacheTokens'] = $this->getBoolean(
  57732. (string) $root->getAttribute('cacheTokens'),
  57733. false
  57734. );
  57735. }
  57736. if ($root->hasAttribute('columns')) {
  57737. $columns = (string) $root->getAttribute('columns');
  57738. if ($columns == 'max') {
  57739. $result['columns'] = 'max';
  57740. } else {
  57741. $result['columns'] = $this->getInteger($columns, 80);
  57742. }
  57743. }
  57744. if ($root->hasAttribute('colors')) {
  57745. /* only allow boolean for compatibility with previous versions
  57746. 'always' only allowed from command line */
  57747. if ($this->getBoolean($root->getAttribute('colors'), false)) {
  57748. $result['colors'] = PHPUnit_TextUI_ResultPrinter::COLOR_AUTO;
  57749. } else {
  57750. $result['colors'] = PHPUnit_TextUI_ResultPrinter::COLOR_NEVER;
  57751. }
  57752. }
  57753. /*
  57754. * Issue #657
  57755. */
  57756. if ($root->hasAttribute('stderr')) {
  57757. $result['stderr'] = $this->getBoolean(
  57758. (string) $root->getAttribute('stderr'),
  57759. false
  57760. );
  57761. }
  57762. if ($root->hasAttribute('backupGlobals')) {
  57763. $result['backupGlobals'] = $this->getBoolean(
  57764. (string) $root->getAttribute('backupGlobals'),
  57765. true
  57766. );
  57767. }
  57768. if ($root->hasAttribute('backupStaticAttributes')) {
  57769. $result['backupStaticAttributes'] = $this->getBoolean(
  57770. (string) $root->getAttribute('backupStaticAttributes'),
  57771. false
  57772. );
  57773. }
  57774. if ($root->getAttribute('bootstrap')) {
  57775. $result['bootstrap'] = $this->toAbsolutePath(
  57776. (string) $root->getAttribute('bootstrap')
  57777. );
  57778. }
  57779. if ($root->hasAttribute('convertErrorsToExceptions')) {
  57780. $result['convertErrorsToExceptions'] = $this->getBoolean(
  57781. (string) $root->getAttribute('convertErrorsToExceptions'),
  57782. true
  57783. );
  57784. }
  57785. if ($root->hasAttribute('convertNoticesToExceptions')) {
  57786. $result['convertNoticesToExceptions'] = $this->getBoolean(
  57787. (string) $root->getAttribute('convertNoticesToExceptions'),
  57788. true
  57789. );
  57790. }
  57791. if ($root->hasAttribute('convertWarningsToExceptions')) {
  57792. $result['convertWarningsToExceptions'] = $this->getBoolean(
  57793. (string) $root->getAttribute('convertWarningsToExceptions'),
  57794. true
  57795. );
  57796. }
  57797. if ($root->hasAttribute('forceCoversAnnotation')) {
  57798. $result['forceCoversAnnotation'] = $this->getBoolean(
  57799. (string) $root->getAttribute('forceCoversAnnotation'),
  57800. false
  57801. );
  57802. }
  57803. if ($root->hasAttribute('mapTestClassNameToCoveredClassName')) {
  57804. $result['mapTestClassNameToCoveredClassName'] = $this->getBoolean(
  57805. (string) $root->getAttribute('mapTestClassNameToCoveredClassName'),
  57806. false
  57807. );
  57808. }
  57809. if ($root->hasAttribute('processIsolation')) {
  57810. $result['processIsolation'] = $this->getBoolean(
  57811. (string) $root->getAttribute('processIsolation'),
  57812. false
  57813. );
  57814. }
  57815. if ($root->hasAttribute('stopOnError')) {
  57816. $result['stopOnError'] = $this->getBoolean(
  57817. (string) $root->getAttribute('stopOnError'),
  57818. false
  57819. );
  57820. }
  57821. if ($root->hasAttribute('stopOnFailure')) {
  57822. $result['stopOnFailure'] = $this->getBoolean(
  57823. (string) $root->getAttribute('stopOnFailure'),
  57824. false
  57825. );
  57826. }
  57827. if ($root->hasAttribute('stopOnIncomplete')) {
  57828. $result['stopOnIncomplete'] = $this->getBoolean(
  57829. (string) $root->getAttribute('stopOnIncomplete'),
  57830. false
  57831. );
  57832. }
  57833. if ($root->hasAttribute('stopOnRisky')) {
  57834. $result['stopOnRisky'] = $this->getBoolean(
  57835. (string) $root->getAttribute('stopOnRisky'),
  57836. false
  57837. );
  57838. }
  57839. if ($root->hasAttribute('stopOnSkipped')) {
  57840. $result['stopOnSkipped'] = $this->getBoolean(
  57841. (string) $root->getAttribute('stopOnSkipped'),
  57842. false
  57843. );
  57844. }
  57845. if ($root->hasAttribute('testSuiteLoaderClass')) {
  57846. $result['testSuiteLoaderClass'] = (string) $root->getAttribute(
  57847. 'testSuiteLoaderClass'
  57848. );
  57849. }
  57850. if ($root->getAttribute('testSuiteLoaderFile')) {
  57851. $result['testSuiteLoaderFile'] = $this->toAbsolutePath(
  57852. (string) $root->getAttribute('testSuiteLoaderFile')
  57853. );
  57854. }
  57855. if ($root->hasAttribute('printerClass')) {
  57856. $result['printerClass'] = (string) $root->getAttribute(
  57857. 'printerClass'
  57858. );
  57859. }
  57860. if ($root->getAttribute('printerFile')) {
  57861. $result['printerFile'] = $this->toAbsolutePath(
  57862. (string) $root->getAttribute('printerFile')
  57863. );
  57864. }
  57865. if ($root->hasAttribute('timeoutForSmallTests')) {
  57866. $result['timeoutForSmallTests'] = $this->getInteger(
  57867. (string) $root->getAttribute('timeoutForSmallTests'),
  57868. 1
  57869. );
  57870. }
  57871. if ($root->hasAttribute('timeoutForMediumTests')) {
  57872. $result['timeoutForMediumTests'] = $this->getInteger(
  57873. (string) $root->getAttribute('timeoutForMediumTests'),
  57874. 10
  57875. );
  57876. }
  57877. if ($root->hasAttribute('timeoutForLargeTests')) {
  57878. $result['timeoutForLargeTests'] = $this->getInteger(
  57879. (string) $root->getAttribute('timeoutForLargeTests'),
  57880. 60
  57881. );
  57882. }
  57883. if ($root->hasAttribute('beStrictAboutTestsThatDoNotTestAnything')) {
  57884. $result['reportUselessTests'] = $this->getBoolean(
  57885. (string) $root->getAttribute('beStrictAboutTestsThatDoNotTestAnything'),
  57886. false
  57887. );
  57888. }
  57889. if ($root->hasAttribute('checkForUnintentionallyCoveredCode')) {
  57890. $result['strictCoverage'] = $this->getBoolean(
  57891. (string) $root->getAttribute('checkForUnintentionallyCoveredCode'),
  57892. false
  57893. );
  57894. }
  57895. if ($root->hasAttribute('beStrictAboutOutputDuringTests')) {
  57896. $result['disallowTestOutput'] = $this->getBoolean(
  57897. (string) $root->getAttribute('beStrictAboutOutputDuringTests'),
  57898. false
  57899. );
  57900. }
  57901. if ($root->hasAttribute('beStrictAboutChangesToGlobalState')) {
  57902. $result['disallowChangesToGlobalState'] = $this->getBoolean(
  57903. (string) $root->getAttribute('beStrictAboutChangesToGlobalState'),
  57904. false
  57905. );
  57906. }
  57907. if ($root->hasAttribute('beStrictAboutTestSize')) {
  57908. $result['enforceTimeLimit'] = $this->getBoolean(
  57909. (string) $root->getAttribute('beStrictAboutTestSize'),
  57910. false
  57911. );
  57912. }
  57913. if ($root->hasAttribute('beStrictAboutTodoAnnotatedTests')) {
  57914. $result['disallowTodoAnnotatedTests'] = $this->getBoolean(
  57915. (string) $root->getAttribute('beStrictAboutTodoAnnotatedTests'),
  57916. false
  57917. );
  57918. }
  57919. if ($root->hasAttribute('strict')) {
  57920. $flag = $this->getBoolean(
  57921. (string) $root->getAttribute('strict'),
  57922. false
  57923. );
  57924. $result['reportUselessTests'] = $flag;
  57925. $result['strictCoverage'] = $flag;
  57926. $result['disallowTestOutput'] = $flag;
  57927. $result['enforceTimeLimit'] = $flag;
  57928. $result['disallowTodoAnnotatedTests'] = $flag;
  57929. $result['deprecatedStrictModeSetting'] = true;
  57930. }
  57931. if ($root->hasAttribute('verbose')) {
  57932. $result['verbose'] = $this->getBoolean(
  57933. (string) $root->getAttribute('verbose'),
  57934. false
  57935. );
  57936. }
  57937. return $result;
  57938. }
  57939. /**
  57940. * Returns the SeleniumTestCase browser configuration.
  57941. *
  57942. * @return array
  57943. * @since Method available since Release 3.2.9
  57944. */
  57945. public function getSeleniumBrowserConfiguration()
  57946. {
  57947. $result = array();
  57948. foreach ($this->xpath->query('selenium/browser') as $config) {
  57949. $name = (string) $config->getAttribute('name');
  57950. $browser = (string) $config->getAttribute('browser');
  57951. if ($config->hasAttribute('host')) {
  57952. $host = (string) $config->getAttribute('host');
  57953. } else {
  57954. $host = 'localhost';
  57955. }
  57956. if ($config->hasAttribute('port')) {
  57957. $port = $this->getInteger(
  57958. (string) $config->getAttribute('port'),
  57959. 4444
  57960. );
  57961. } else {
  57962. $port = 4444;
  57963. }
  57964. if ($config->hasAttribute('timeout')) {
  57965. $timeout = $this->getInteger(
  57966. (string) $config->getAttribute('timeout'),
  57967. 30000
  57968. );
  57969. } else {
  57970. $timeout = 30000;
  57971. }
  57972. $result[] = array(
  57973. 'name' => $name,
  57974. 'browser' => $browser,
  57975. 'host' => $host,
  57976. 'port' => $port,
  57977. 'timeout' => $timeout
  57978. );
  57979. }
  57980. return $result;
  57981. }
  57982. /**
  57983. * Returns the test suite configuration.
  57984. *
  57985. * @return PHPUnit_Framework_TestSuite
  57986. * @since Method available since Release 3.2.1
  57987. */
  57988. public function getTestSuiteConfiguration($testSuiteFilter = null)
  57989. {
  57990. $testSuiteNodes = $this->xpath->query('testsuites/testsuite');
  57991. if ($testSuiteNodes->length == 0) {
  57992. $testSuiteNodes = $this->xpath->query('testsuite');
  57993. }
  57994. if ($testSuiteNodes->length == 1) {
  57995. return $this->getTestSuite($testSuiteNodes->item(0), $testSuiteFilter);
  57996. }
  57997. if ($testSuiteNodes->length > 1) {
  57998. $suite = new PHPUnit_Framework_TestSuite;
  57999. foreach ($testSuiteNodes as $testSuiteNode) {
  58000. $suite->addTestSuite(
  58001. $this->getTestSuite($testSuiteNode, $testSuiteFilter)
  58002. );
  58003. }
  58004. return $suite;
  58005. }
  58006. }
  58007. /**
  58008. * @param DOMElement $testSuiteNode
  58009. * @return PHPUnit_Framework_TestSuite
  58010. * @since Method available since Release 3.4.0
  58011. */
  58012. protected function getTestSuite(DOMElement $testSuiteNode, $testSuiteFilter = null)
  58013. {
  58014. if ($testSuiteNode->hasAttribute('name')) {
  58015. $suite = new PHPUnit_Framework_TestSuite(
  58016. (string) $testSuiteNode->getAttribute('name')
  58017. );
  58018. } else {
  58019. $suite = new PHPUnit_Framework_TestSuite;
  58020. }
  58021. $exclude = array();
  58022. foreach ($testSuiteNode->getElementsByTagName('exclude') as $excludeNode) {
  58023. $excludeFile = (string) $excludeNode->nodeValue;
  58024. if ($excludeFile) {
  58025. $exclude[] = $this->toAbsolutePath($excludeFile);
  58026. }
  58027. }
  58028. $fileIteratorFacade = new File_Iterator_Facade;
  58029. foreach ($testSuiteNode->getElementsByTagName('directory') as $directoryNode) {
  58030. if ($testSuiteFilter && $directoryNode->parentNode->getAttribute('name') != $testSuiteFilter) {
  58031. continue;
  58032. }
  58033. $directory = (string) $directoryNode->nodeValue;
  58034. if (empty($directory)) {
  58035. continue;
  58036. }
  58037. if ($directoryNode->hasAttribute('phpVersion')) {
  58038. $phpVersion = (string) $directoryNode->getAttribute('phpVersion');
  58039. } else {
  58040. $phpVersion = PHP_VERSION;
  58041. }
  58042. if ($directoryNode->hasAttribute('phpVersionOperator')) {
  58043. $phpVersionOperator = (string) $directoryNode->getAttribute('phpVersionOperator');
  58044. } else {
  58045. $phpVersionOperator = '>=';
  58046. }
  58047. if (!version_compare(PHP_VERSION, $phpVersion, $phpVersionOperator)) {
  58048. continue;
  58049. }
  58050. if ($directoryNode->hasAttribute('prefix')) {
  58051. $prefix = (string) $directoryNode->getAttribute('prefix');
  58052. } else {
  58053. $prefix = '';
  58054. }
  58055. if ($directoryNode->hasAttribute('suffix')) {
  58056. $suffix = (string) $directoryNode->getAttribute('suffix');
  58057. } else {
  58058. $suffix = 'Test.php';
  58059. }
  58060. $files = $fileIteratorFacade->getFilesAsArray(
  58061. $this->toAbsolutePath($directory),
  58062. $suffix,
  58063. $prefix,
  58064. $exclude
  58065. );
  58066. $suite->addTestFiles($files);
  58067. }
  58068. foreach ($testSuiteNode->getElementsByTagName('file') as $fileNode) {
  58069. if ($testSuiteFilter && $fileNode->parentNode->getAttribute('name') != $testSuiteFilter) {
  58070. continue;
  58071. }
  58072. $file = (string) $fileNode->nodeValue;
  58073. if (empty($file)) {
  58074. continue;
  58075. }
  58076. // Get the absolute path to the file
  58077. $file = $fileIteratorFacade->getFilesAsArray(
  58078. $this->toAbsolutePath($file)
  58079. );
  58080. if (!isset($file[0])) {
  58081. continue;
  58082. }
  58083. $file = $file[0];
  58084. if ($fileNode->hasAttribute('phpVersion')) {
  58085. $phpVersion = (string) $fileNode->getAttribute('phpVersion');
  58086. } else {
  58087. $phpVersion = PHP_VERSION;
  58088. }
  58089. if ($fileNode->hasAttribute('phpVersionOperator')) {
  58090. $phpVersionOperator = (string) $fileNode->getAttribute('phpVersionOperator');
  58091. } else {
  58092. $phpVersionOperator = '>=';
  58093. }
  58094. if (!version_compare(PHP_VERSION, $phpVersion, $phpVersionOperator)) {
  58095. continue;
  58096. }
  58097. $suite->addTestFile($file);
  58098. }
  58099. return $suite;
  58100. }
  58101. /**
  58102. * @param string $value
  58103. * @param bool $default
  58104. * @return bool
  58105. * @since Method available since Release 3.2.3
  58106. */
  58107. protected function getBoolean($value, $default)
  58108. {
  58109. if (strtolower($value) == 'false') {
  58110. return false;
  58111. } elseif (strtolower($value) == 'true') {
  58112. return true;
  58113. }
  58114. return $default;
  58115. }
  58116. /**
  58117. * @param string $value
  58118. * @param bool $default
  58119. * @return bool
  58120. * @since Method available since Release 3.6.0
  58121. */
  58122. protected function getInteger($value, $default)
  58123. {
  58124. if (is_numeric($value)) {
  58125. return (int) $value;
  58126. }
  58127. return $default;
  58128. }
  58129. /**
  58130. * @param string $query
  58131. * @return array
  58132. * @since Method available since Release 3.2.3
  58133. */
  58134. protected function readFilterDirectories($query)
  58135. {
  58136. $directories = array();
  58137. foreach ($this->xpath->query($query) as $directory) {
  58138. $directoryPath = (string) $directory->nodeValue;
  58139. if (!$directoryPath) {
  58140. continue;
  58141. }
  58142. if ($directory->hasAttribute('prefix')) {
  58143. $prefix = (string) $directory->getAttribute('prefix');
  58144. } else {
  58145. $prefix = '';
  58146. }
  58147. if ($directory->hasAttribute('suffix')) {
  58148. $suffix = (string) $directory->getAttribute('suffix');
  58149. } else {
  58150. $suffix = '.php';
  58151. }
  58152. if ($directory->hasAttribute('group')) {
  58153. $group = (string) $directory->getAttribute('group');
  58154. } else {
  58155. $group = 'DEFAULT';
  58156. }
  58157. $directories[] = array(
  58158. 'path' => $this->toAbsolutePath($directoryPath),
  58159. 'prefix' => $prefix,
  58160. 'suffix' => $suffix,
  58161. 'group' => $group
  58162. );
  58163. }
  58164. return $directories;
  58165. }
  58166. /**
  58167. * @param string $query
  58168. * @return array
  58169. * @since Method available since Release 3.2.3
  58170. */
  58171. protected function readFilterFiles($query)
  58172. {
  58173. $files = array();
  58174. foreach ($this->xpath->query($query) as $file) {
  58175. $filePath = (string) $file->nodeValue;
  58176. if ($filePath) {
  58177. $files[] = $this->toAbsolutePath($filePath);
  58178. }
  58179. }
  58180. return $files;
  58181. }
  58182. /**
  58183. * @param string $path
  58184. * @param bool $useIncludePath
  58185. * @return string
  58186. * @since Method available since Release 3.5.0
  58187. */
  58188. protected function toAbsolutePath($path, $useIncludePath = false)
  58189. {
  58190. if ($path[0] === '/') {
  58191. return $path;
  58192. }
  58193. // Matches the following on Windows:
  58194. // - \\NetworkComputer\Path
  58195. // - \\.\D:
  58196. // - \\.\c:
  58197. // - C:\Windows
  58198. // - C:\windows
  58199. // - C:/windows
  58200. // - c:/windows
  58201. if (defined('PHP_WINDOWS_VERSION_BUILD') &&
  58202. ($path[0] === '\\' ||
  58203. (strlen($path) >= 3 && preg_match('#^[A-Z]\:[/\\\]#i', substr($path, 0, 3))))) {
  58204. return $path;
  58205. }
  58206. // Stream
  58207. if (strpos($path, '://') !== false) {
  58208. return $path;
  58209. }
  58210. $file = dirname($this->filename) . DIRECTORY_SEPARATOR . $path;
  58211. if ($useIncludePath && !file_exists($file)) {
  58212. $includePathFile = stream_resolve_include_path($path);
  58213. if ($includePathFile) {
  58214. $file = $includePathFile;
  58215. }
  58216. }
  58217. return $file;
  58218. }
  58219. }
  58220. <?php
  58221. /*
  58222. * This file is part of PHPUnit.
  58223. *
  58224. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58225. *
  58226. * For the full copyright and license information, please view the LICENSE
  58227. * file that was distributed with this source code.
  58228. */
  58229. /**
  58230. * @since Class available since Release 3.4.0
  58231. */
  58232. class PHPUnit_Util_GlobalState
  58233. {
  58234. /**
  58235. * @var array
  58236. */
  58237. protected static $superGlobalArrays = array(
  58238. '_ENV',
  58239. '_POST',
  58240. '_GET',
  58241. '_COOKIE',
  58242. '_SERVER',
  58243. '_FILES',
  58244. '_REQUEST'
  58245. );
  58246. /**
  58247. * @var array
  58248. */
  58249. protected static $superGlobalArraysLong = array(
  58250. 'HTTP_ENV_VARS',
  58251. 'HTTP_POST_VARS',
  58252. 'HTTP_GET_VARS',
  58253. 'HTTP_COOKIE_VARS',
  58254. 'HTTP_SERVER_VARS',
  58255. 'HTTP_POST_FILES'
  58256. );
  58257. public static function getIncludedFilesAsString()
  58258. {
  58259. return static::processIncludedFilesAsString(get_included_files());
  58260. }
  58261. public static function processIncludedFilesAsString(array $files)
  58262. {
  58263. $blacklist = new PHPUnit_Util_Blacklist;
  58264. $prefix = false;
  58265. $result = '';
  58266. if (defined('__PHPUNIT_PHAR__')) {
  58267. $prefix = 'phar://' . __PHPUNIT_PHAR__ . '/';
  58268. }
  58269. for ($i = count($files) - 1; $i > 0; $i--) {
  58270. $file = $files[$i];
  58271. if ($prefix !== false && strpos($file, $prefix) === 0) {
  58272. continue;
  58273. }
  58274. // Skip virtual file system protocols
  58275. if (preg_match('/^(vfs|phpvfs[a-z0-9]+):/', $file)) {
  58276. continue;
  58277. }
  58278. if (!$blacklist->isBlacklisted($file) && is_file($file)) {
  58279. $result = 'require_once \'' . $file . "';\n" . $result;
  58280. }
  58281. }
  58282. return $result;
  58283. }
  58284. public static function getIniSettingsAsString()
  58285. {
  58286. $result = '';
  58287. $iniSettings = ini_get_all(null, false);
  58288. foreach ($iniSettings as $key => $value) {
  58289. $result .= sprintf(
  58290. '@ini_set(%s, %s);' . "\n",
  58291. self::exportVariable($key),
  58292. self::exportVariable($value)
  58293. );
  58294. }
  58295. return $result;
  58296. }
  58297. public static function getConstantsAsString()
  58298. {
  58299. $constants = get_defined_constants(true);
  58300. $result = '';
  58301. if (isset($constants['user'])) {
  58302. foreach ($constants['user'] as $name => $value) {
  58303. $result .= sprintf(
  58304. 'if (!defined(\'%s\')) define(\'%s\', %s);' . "\n",
  58305. $name,
  58306. $name,
  58307. self::exportVariable($value)
  58308. );
  58309. }
  58310. }
  58311. return $result;
  58312. }
  58313. public static function getGlobalsAsString()
  58314. {
  58315. $result = '';
  58316. $superGlobalArrays = self::getSuperGlobalArrays();
  58317. foreach ($superGlobalArrays as $superGlobalArray) {
  58318. if (isset($GLOBALS[$superGlobalArray]) &&
  58319. is_array($GLOBALS[$superGlobalArray])) {
  58320. foreach (array_keys($GLOBALS[$superGlobalArray]) as $key) {
  58321. if ($GLOBALS[$superGlobalArray][$key] instanceof Closure) {
  58322. continue;
  58323. }
  58324. $result .= sprintf(
  58325. '$GLOBALS[\'%s\'][\'%s\'] = %s;' . "\n",
  58326. $superGlobalArray,
  58327. $key,
  58328. self::exportVariable($GLOBALS[$superGlobalArray][$key])
  58329. );
  58330. }
  58331. }
  58332. }
  58333. $blacklist = $superGlobalArrays;
  58334. $blacklist[] = 'GLOBALS';
  58335. foreach (array_keys($GLOBALS) as $key) {
  58336. if (!in_array($key, $blacklist) && !$GLOBALS[$key] instanceof Closure) {
  58337. $result .= sprintf(
  58338. '$GLOBALS[\'%s\'] = %s;' . "\n",
  58339. $key,
  58340. self::exportVariable($GLOBALS[$key])
  58341. );
  58342. }
  58343. }
  58344. return $result;
  58345. }
  58346. protected static function getSuperGlobalArrays()
  58347. {
  58348. if (ini_get('register_long_arrays') == '1') {
  58349. return array_merge(
  58350. self::$superGlobalArrays,
  58351. self::$superGlobalArraysLong
  58352. );
  58353. } else {
  58354. return self::$superGlobalArrays;
  58355. }
  58356. }
  58357. protected static function exportVariable($variable)
  58358. {
  58359. if (is_scalar($variable) || is_null($variable) ||
  58360. (is_array($variable) && self::arrayOnlyContainsScalars($variable))) {
  58361. return var_export($variable, true);
  58362. }
  58363. return 'unserialize(' .
  58364. var_export(serialize($variable), true) .
  58365. ')';
  58366. }
  58367. protected static function arrayOnlyContainsScalars(array $array)
  58368. {
  58369. $result = true;
  58370. foreach ($array as $element) {
  58371. if (is_array($element)) {
  58372. $result = self::arrayOnlyContainsScalars($element);
  58373. } elseif (!is_scalar($element) && !is_null($element)) {
  58374. $result = false;
  58375. }
  58376. if ($result === false) {
  58377. break;
  58378. }
  58379. }
  58380. return $result;
  58381. }
  58382. }
  58383. <?php
  58384. /*
  58385. * This file is part of PHPUnit.
  58386. *
  58387. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58388. *
  58389. * For the full copyright and license information, please view the LICENSE
  58390. * file that was distributed with this source code.
  58391. */
  58392. /**
  58393. * A TestListener that generates JSON messages.
  58394. *
  58395. * @since Class available since Release 3.0.0
  58396. */
  58397. class PHPUnit_Util_Log_JSON extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
  58398. {
  58399. /**
  58400. * @var string
  58401. */
  58402. protected $currentTestSuiteName = '';
  58403. /**
  58404. * @var string
  58405. */
  58406. protected $currentTestName = '';
  58407. /**
  58408. * @var bool
  58409. */
  58410. protected $currentTestPass = true;
  58411. /**
  58412. * An error occurred.
  58413. *
  58414. * @param PHPUnit_Framework_Test $test
  58415. * @param Exception $e
  58416. * @param float $time
  58417. */
  58418. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  58419. {
  58420. $this->writeCase(
  58421. 'error',
  58422. $time,
  58423. PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
  58424. $e->getMessage(),
  58425. $test
  58426. );
  58427. $this->currentTestPass = false;
  58428. }
  58429. /**
  58430. * A failure occurred.
  58431. *
  58432. * @param PHPUnit_Framework_Test $test
  58433. * @param PHPUnit_Framework_AssertionFailedError $e
  58434. * @param float $time
  58435. */
  58436. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  58437. {
  58438. $this->writeCase(
  58439. 'fail',
  58440. $time,
  58441. PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
  58442. $e->getMessage(),
  58443. $test
  58444. );
  58445. $this->currentTestPass = false;
  58446. }
  58447. /**
  58448. * Incomplete test.
  58449. *
  58450. * @param PHPUnit_Framework_Test $test
  58451. * @param Exception $e
  58452. * @param float $time
  58453. */
  58454. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  58455. {
  58456. $this->writeCase(
  58457. 'error',
  58458. $time,
  58459. PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
  58460. 'Incomplete Test: ' . $e->getMessage(),
  58461. $test
  58462. );
  58463. $this->currentTestPass = false;
  58464. }
  58465. /**
  58466. * Risky test.
  58467. *
  58468. * @param PHPUnit_Framework_Test $test
  58469. * @param Exception $e
  58470. * @param float $time
  58471. * @since Method available since Release 4.0.0
  58472. */
  58473. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  58474. {
  58475. $this->writeCase(
  58476. 'error',
  58477. $time,
  58478. PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
  58479. 'Risky Test: ' . $e->getMessage(),
  58480. $test
  58481. );
  58482. $this->currentTestPass = false;
  58483. }
  58484. /**
  58485. * Skipped test.
  58486. *
  58487. * @param PHPUnit_Framework_Test $test
  58488. * @param Exception $e
  58489. * @param float $time
  58490. */
  58491. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  58492. {
  58493. $this->writeCase(
  58494. 'error',
  58495. $time,
  58496. PHPUnit_Util_Filter::getFilteredStacktrace($e, false),
  58497. 'Skipped Test: ' . $e->getMessage(),
  58498. $test
  58499. );
  58500. $this->currentTestPass = false;
  58501. }
  58502. /**
  58503. * A testsuite started.
  58504. *
  58505. * @param PHPUnit_Framework_TestSuite $suite
  58506. */
  58507. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  58508. {
  58509. $this->currentTestSuiteName = $suite->getName();
  58510. $this->currentTestName = '';
  58511. $this->write(
  58512. array(
  58513. 'event' => 'suiteStart',
  58514. 'suite' => $this->currentTestSuiteName,
  58515. 'tests' => count($suite)
  58516. )
  58517. );
  58518. }
  58519. /**
  58520. * A testsuite ended.
  58521. *
  58522. * @param PHPUnit_Framework_TestSuite $suite
  58523. */
  58524. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  58525. {
  58526. $this->currentTestSuiteName = '';
  58527. $this->currentTestName = '';
  58528. }
  58529. /**
  58530. * A test started.
  58531. *
  58532. * @param PHPUnit_Framework_Test $test
  58533. */
  58534. public function startTest(PHPUnit_Framework_Test $test)
  58535. {
  58536. $this->currentTestName = PHPUnit_Util_Test::describe($test);
  58537. $this->currentTestPass = true;
  58538. $this->write(
  58539. array(
  58540. 'event' => 'testStart',
  58541. 'suite' => $this->currentTestSuiteName,
  58542. 'test' => $this->currentTestName
  58543. )
  58544. );
  58545. }
  58546. /**
  58547. * A test ended.
  58548. *
  58549. * @param PHPUnit_Framework_Test $test
  58550. * @param float $time
  58551. */
  58552. public function endTest(PHPUnit_Framework_Test $test, $time)
  58553. {
  58554. if ($this->currentTestPass) {
  58555. $this->writeCase('pass', $time, array(), '', $test);
  58556. }
  58557. }
  58558. /**
  58559. * @param string $status
  58560. * @param float $time
  58561. * @param array $trace
  58562. * @param string $message
  58563. * @param PHPUnit_Framework_TestCase|null $test
  58564. */
  58565. protected function writeCase($status, $time, array $trace = array(), $message = '', $test = null)
  58566. {
  58567. $output = '';
  58568. // take care of TestSuite producing error (e.g. by running into exception) as TestSuite doesn't have hasOutput
  58569. if ($test !== null && method_exists($test, 'hasOutput') && $test->hasOutput()) {
  58570. $output = $test->getActualOutput();
  58571. }
  58572. $this->write(
  58573. array(
  58574. 'event' => 'test',
  58575. 'suite' => $this->currentTestSuiteName,
  58576. 'test' => $this->currentTestName,
  58577. 'status' => $status,
  58578. 'time' => $time,
  58579. 'trace' => $trace,
  58580. 'message' => PHPUnit_Util_String::convertToUtf8($message),
  58581. 'output' => $output,
  58582. )
  58583. );
  58584. }
  58585. /**
  58586. * @param string $buffer
  58587. */
  58588. public function write($buffer)
  58589. {
  58590. array_walk_recursive($buffer, function (&$input) {
  58591. if (is_string($input)) {
  58592. $input = PHPUnit_Util_String::convertToUtf8($input);
  58593. }
  58594. });
  58595. $flags = 0;
  58596. if (defined('JSON_PRETTY_PRINT')) {
  58597. $flags |= JSON_PRETTY_PRINT;
  58598. }
  58599. parent::write(json_encode($buffer, $flags));
  58600. }
  58601. }
  58602. <?php
  58603. /*
  58604. * This file is part of PHPUnit.
  58605. *
  58606. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58607. *
  58608. * For the full copyright and license information, please view the LICENSE
  58609. * file that was distributed with this source code.
  58610. */
  58611. /**
  58612. * A TestListener that generates a logfile of the
  58613. * test execution using the Test Anything Protocol (TAP).
  58614. *
  58615. * @since Class available since Release 3.0.0
  58616. */
  58617. class PHPUnit_Util_Log_TAP extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
  58618. {
  58619. /**
  58620. * @var int
  58621. */
  58622. protected $testNumber = 0;
  58623. /**
  58624. * @var int
  58625. */
  58626. protected $testSuiteLevel = 0;
  58627. /**
  58628. * @var bool
  58629. */
  58630. protected $testSuccessful = true;
  58631. /**
  58632. * Constructor.
  58633. *
  58634. * @param mixed $out
  58635. * @throws PHPUnit_Framework_Exception
  58636. * @since Method available since Release 3.3.4
  58637. */
  58638. public function __construct($out = null)
  58639. {
  58640. parent::__construct($out);
  58641. $this->write("TAP version 13\n");
  58642. }
  58643. /**
  58644. * An error occurred.
  58645. *
  58646. * @param PHPUnit_Framework_Test $test
  58647. * @param Exception $e
  58648. * @param float $time
  58649. */
  58650. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  58651. {
  58652. $this->writeNotOk($test, 'Error');
  58653. }
  58654. /**
  58655. * A failure occurred.
  58656. *
  58657. * @param PHPUnit_Framework_Test $test
  58658. * @param PHPUnit_Framework_AssertionFailedError $e
  58659. * @param float $time
  58660. */
  58661. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  58662. {
  58663. $this->writeNotOk($test, 'Failure');
  58664. $message = explode(
  58665. "\n",
  58666. PHPUnit_Framework_TestFailure::exceptionToString($e)
  58667. );
  58668. $diagnostic = array(
  58669. 'message' => $message[0],
  58670. 'severity' => 'fail'
  58671. );
  58672. if ($e instanceof PHPUnit_Framework_ExpectationFailedException) {
  58673. $cf = $e->getComparisonFailure();
  58674. if ($cf !== null) {
  58675. $diagnostic['data'] = array(
  58676. 'got' => $cf->getActual(),
  58677. 'expected' => $cf->getExpected()
  58678. );
  58679. }
  58680. }
  58681. $yaml = new Symfony\Component\Yaml\Dumper;
  58682. $this->write(
  58683. sprintf(
  58684. " ---\n%s ...\n",
  58685. $yaml->dump($diagnostic, 2, 2)
  58686. )
  58687. );
  58688. }
  58689. /**
  58690. * Incomplete test.
  58691. *
  58692. * @param PHPUnit_Framework_Test $test
  58693. * @param Exception $e
  58694. * @param float $time
  58695. */
  58696. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  58697. {
  58698. $this->writeNotOk($test, '', 'TODO Incomplete Test');
  58699. }
  58700. /**
  58701. * Risky test.
  58702. *
  58703. * @param PHPUnit_Framework_Test $test
  58704. * @param Exception $e
  58705. * @param float $time
  58706. * @since Method available since Release 4.0.0
  58707. */
  58708. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  58709. {
  58710. $this->write(
  58711. sprintf(
  58712. "ok %d - # RISKY%s\n",
  58713. $this->testNumber,
  58714. $e->getMessage() != '' ? ' ' . $e->getMessage() : ''
  58715. )
  58716. );
  58717. $this->testSuccessful = false;
  58718. }
  58719. /**
  58720. * Skipped test.
  58721. *
  58722. * @param PHPUnit_Framework_Test $test
  58723. * @param Exception $e
  58724. * @param float $time
  58725. * @since Method available since Release 3.0.0
  58726. */
  58727. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  58728. {
  58729. $this->write(
  58730. sprintf(
  58731. "ok %d - # SKIP%s\n",
  58732. $this->testNumber,
  58733. $e->getMessage() != '' ? ' ' . $e->getMessage() : ''
  58734. )
  58735. );
  58736. $this->testSuccessful = false;
  58737. }
  58738. /**
  58739. * A testsuite started.
  58740. *
  58741. * @param PHPUnit_Framework_TestSuite $suite
  58742. */
  58743. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  58744. {
  58745. $this->testSuiteLevel++;
  58746. }
  58747. /**
  58748. * A testsuite ended.
  58749. *
  58750. * @param PHPUnit_Framework_TestSuite $suite
  58751. */
  58752. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  58753. {
  58754. $this->testSuiteLevel--;
  58755. if ($this->testSuiteLevel == 0) {
  58756. $this->write(sprintf("1..%d\n", $this->testNumber));
  58757. }
  58758. }
  58759. /**
  58760. * A test started.
  58761. *
  58762. * @param PHPUnit_Framework_Test $test
  58763. */
  58764. public function startTest(PHPUnit_Framework_Test $test)
  58765. {
  58766. $this->testNumber++;
  58767. $this->testSuccessful = true;
  58768. }
  58769. /**
  58770. * A test ended.
  58771. *
  58772. * @param PHPUnit_Framework_Test $test
  58773. * @param float $time
  58774. */
  58775. public function endTest(PHPUnit_Framework_Test $test, $time)
  58776. {
  58777. if ($this->testSuccessful === true) {
  58778. $this->write(
  58779. sprintf(
  58780. "ok %d - %s\n",
  58781. $this->testNumber,
  58782. PHPUnit_Util_Test::describe($test)
  58783. )
  58784. );
  58785. }
  58786. $this->writeDiagnostics($test);
  58787. }
  58788. /**
  58789. * @param PHPUnit_Framework_Test $test
  58790. * @param string $prefix
  58791. * @param string $directive
  58792. */
  58793. protected function writeNotOk(PHPUnit_Framework_Test $test, $prefix = '', $directive = '')
  58794. {
  58795. $this->write(
  58796. sprintf(
  58797. "not ok %d - %s%s%s\n",
  58798. $this->testNumber,
  58799. $prefix != '' ? $prefix . ': ' : '',
  58800. PHPUnit_Util_Test::describe($test),
  58801. $directive != '' ? ' # ' . $directive : ''
  58802. )
  58803. );
  58804. $this->testSuccessful = false;
  58805. }
  58806. /**
  58807. * @param PHPUnit_Framework_Test $test
  58808. */
  58809. private function writeDiagnostics(PHPUnit_Framework_Test $test)
  58810. {
  58811. if (!$test instanceof PHPUnit_Framework_TestCase) {
  58812. return;
  58813. }
  58814. if (!$test->hasOutput()) {
  58815. return;
  58816. }
  58817. foreach (explode("\n", trim($test->getActualOutput())) as $line) {
  58818. $this->write(
  58819. sprintf(
  58820. "# %s\n",
  58821. $line
  58822. )
  58823. );
  58824. }
  58825. }
  58826. }
  58827. <?php
  58828. /*
  58829. * This file is part of PHPUnit.
  58830. *
  58831. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  58832. *
  58833. * For the full copyright and license information, please view the LICENSE
  58834. * file that was distributed with this source code.
  58835. */
  58836. /**
  58837. * A TestListener that generates a logfile of the test execution in XML markup.
  58838. *
  58839. * The XML markup used is the same as the one that is used by the JUnit Ant task.
  58840. *
  58841. * @since Class available since Release 2.1.0
  58842. */
  58843. class PHPUnit_Util_Log_JUnit extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
  58844. {
  58845. /**
  58846. * @var DOMDocument
  58847. */
  58848. protected $document;
  58849. /**
  58850. * @var DOMElement
  58851. */
  58852. protected $root;
  58853. /**
  58854. * @var bool
  58855. */
  58856. protected $logIncompleteSkipped = false;
  58857. /**
  58858. * @var bool
  58859. */
  58860. protected $writeDocument = true;
  58861. /**
  58862. * @var DOMElement[]
  58863. */
  58864. protected $testSuites = array();
  58865. /**
  58866. * @var integer[]
  58867. */
  58868. protected $testSuiteTests = array(0);
  58869. /**
  58870. * @var integer[]
  58871. */
  58872. protected $testSuiteAssertions = array(0);
  58873. /**
  58874. * @var integer[]
  58875. */
  58876. protected $testSuiteErrors = array(0);
  58877. /**
  58878. * @var integer[]
  58879. */
  58880. protected $testSuiteFailures = array(0);
  58881. /**
  58882. * @var integer[]
  58883. */
  58884. protected $testSuiteTimes = array(0);
  58885. /**
  58886. * @var int
  58887. */
  58888. protected $testSuiteLevel = 0;
  58889. /**
  58890. * @var DOMElement
  58891. */
  58892. protected $currentTestCase = null;
  58893. /**
  58894. * @var bool
  58895. */
  58896. protected $attachCurrentTestCase = true;
  58897. /**
  58898. * Constructor.
  58899. *
  58900. * @param mixed $out
  58901. * @param bool $logIncompleteSkipped
  58902. */
  58903. public function __construct($out = null, $logIncompleteSkipped = false)
  58904. {
  58905. $this->document = new DOMDocument('1.0', 'UTF-8');
  58906. $this->document->formatOutput = true;
  58907. $this->root = $this->document->createElement('testsuites');
  58908. $this->document->appendChild($this->root);
  58909. parent::__construct($out);
  58910. $this->logIncompleteSkipped = $logIncompleteSkipped;
  58911. }
  58912. /**
  58913. * Flush buffer and close output.
  58914. */
  58915. public function flush()
  58916. {
  58917. if ($this->writeDocument === true) {
  58918. $this->write($this->getXML());
  58919. }
  58920. parent::flush();
  58921. }
  58922. /**
  58923. * An error occurred.
  58924. *
  58925. * @param PHPUnit_Framework_Test $test
  58926. * @param Exception $e
  58927. * @param float $time
  58928. */
  58929. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  58930. {
  58931. if ($this->currentTestCase === null) {
  58932. return;
  58933. }
  58934. if ($test instanceof PHPUnit_Framework_SelfDescribing) {
  58935. $buffer = $test->toString() . "\n";
  58936. } else {
  58937. $buffer = '';
  58938. }
  58939. $buffer .= PHPUnit_Framework_TestFailure::exceptionToString($e) .
  58940. "\n" .
  58941. PHPUnit_Util_Filter::getFilteredStacktrace($e);
  58942. $error = $this->document->createElement(
  58943. 'error',
  58944. PHPUnit_Util_XML::prepareString($buffer)
  58945. );
  58946. $error->setAttribute('type', get_class($e));
  58947. $this->currentTestCase->appendChild($error);
  58948. $this->testSuiteErrors[$this->testSuiteLevel]++;
  58949. }
  58950. /**
  58951. * A failure occurred.
  58952. *
  58953. * @param PHPUnit_Framework_Test $test
  58954. * @param PHPUnit_Framework_AssertionFailedError $e
  58955. * @param float $time
  58956. */
  58957. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  58958. {
  58959. if ($this->currentTestCase === null) {
  58960. return;
  58961. }
  58962. if ($test instanceof PHPUnit_Framework_SelfDescribing) {
  58963. $buffer = $test->toString() . "\n";
  58964. } else {
  58965. $buffer = '';
  58966. }
  58967. $buffer .= PHPUnit_Framework_TestFailure::exceptionToString($e) .
  58968. "\n" .
  58969. PHPUnit_Util_Filter::getFilteredStacktrace($e);
  58970. $failure = $this->document->createElement(
  58971. 'failure',
  58972. PHPUnit_Util_XML::prepareString($buffer)
  58973. );
  58974. $failure->setAttribute('type', get_class($e));
  58975. $this->currentTestCase->appendChild($failure);
  58976. $this->testSuiteFailures[$this->testSuiteLevel]++;
  58977. }
  58978. /**
  58979. * Incomplete test.
  58980. *
  58981. * @param PHPUnit_Framework_Test $test
  58982. * @param Exception $e
  58983. * @param float $time
  58984. */
  58985. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  58986. {
  58987. if ($this->logIncompleteSkipped && $this->currentTestCase !== null) {
  58988. $error = $this->document->createElement(
  58989. 'error',
  58990. PHPUnit_Util_XML::prepareString(
  58991. "Incomplete Test\n" .
  58992. PHPUnit_Util_Filter::getFilteredStacktrace($e)
  58993. )
  58994. );
  58995. $error->setAttribute('type', get_class($e));
  58996. $this->currentTestCase->appendChild($error);
  58997. $this->testSuiteErrors[$this->testSuiteLevel]++;
  58998. } else {
  58999. $this->attachCurrentTestCase = false;
  59000. }
  59001. }
  59002. /**
  59003. * Risky test.
  59004. *
  59005. * @param PHPUnit_Framework_Test $test
  59006. * @param Exception $e
  59007. * @param float $time
  59008. * @since Method available since Release 4.0.0
  59009. */
  59010. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  59011. {
  59012. if ($this->logIncompleteSkipped && $this->currentTestCase !== null) {
  59013. $error = $this->document->createElement(
  59014. 'error',
  59015. PHPUnit_Util_XML::prepareString(
  59016. "Risky Test\n" .
  59017. PHPUnit_Util_Filter::getFilteredStacktrace($e)
  59018. )
  59019. );
  59020. $error->setAttribute('type', get_class($e));
  59021. $this->currentTestCase->appendChild($error);
  59022. $this->testSuiteErrors[$this->testSuiteLevel]++;
  59023. } else {
  59024. $this->attachCurrentTestCase = false;
  59025. }
  59026. }
  59027. /**
  59028. * Skipped test.
  59029. *
  59030. * @param PHPUnit_Framework_Test $test
  59031. * @param Exception $e
  59032. * @param float $time
  59033. * @since Method available since Release 3.0.0
  59034. */
  59035. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  59036. {
  59037. if ($this->logIncompleteSkipped && $this->currentTestCase !== null) {
  59038. $error = $this->document->createElement(
  59039. 'error',
  59040. PHPUnit_Util_XML::prepareString(
  59041. "Skipped Test\n" .
  59042. PHPUnit_Util_Filter::getFilteredStacktrace($e)
  59043. )
  59044. );
  59045. $error->setAttribute('type', get_class($e));
  59046. $this->currentTestCase->appendChild($error);
  59047. $this->testSuiteErrors[$this->testSuiteLevel]++;
  59048. } else {
  59049. $this->attachCurrentTestCase = false;
  59050. }
  59051. }
  59052. /**
  59053. * A testsuite started.
  59054. *
  59055. * @param PHPUnit_Framework_TestSuite $suite
  59056. * @since Method available since Release 2.2.0
  59057. */
  59058. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  59059. {
  59060. $testSuite = $this->document->createElement('testsuite');
  59061. $testSuite->setAttribute('name', $suite->getName());
  59062. if (class_exists($suite->getName(), false)) {
  59063. try {
  59064. $class = new ReflectionClass($suite->getName());
  59065. $testSuite->setAttribute('file', $class->getFileName());
  59066. } catch (ReflectionException $e) {
  59067. }
  59068. }
  59069. if ($this->testSuiteLevel > 0) {
  59070. $this->testSuites[$this->testSuiteLevel]->appendChild($testSuite);
  59071. } else {
  59072. $this->root->appendChild($testSuite);
  59073. }
  59074. $this->testSuiteLevel++;
  59075. $this->testSuites[$this->testSuiteLevel] = $testSuite;
  59076. $this->testSuiteTests[$this->testSuiteLevel] = 0;
  59077. $this->testSuiteAssertions[$this->testSuiteLevel] = 0;
  59078. $this->testSuiteErrors[$this->testSuiteLevel] = 0;
  59079. $this->testSuiteFailures[$this->testSuiteLevel] = 0;
  59080. $this->testSuiteTimes[$this->testSuiteLevel] = 0;
  59081. }
  59082. /**
  59083. * A testsuite ended.
  59084. *
  59085. * @param PHPUnit_Framework_TestSuite $suite
  59086. * @since Method available since Release 2.2.0
  59087. */
  59088. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  59089. {
  59090. $this->testSuites[$this->testSuiteLevel]->setAttribute(
  59091. 'tests',
  59092. $this->testSuiteTests[$this->testSuiteLevel]
  59093. );
  59094. $this->testSuites[$this->testSuiteLevel]->setAttribute(
  59095. 'assertions',
  59096. $this->testSuiteAssertions[$this->testSuiteLevel]
  59097. );
  59098. $this->testSuites[$this->testSuiteLevel]->setAttribute(
  59099. 'failures',
  59100. $this->testSuiteFailures[$this->testSuiteLevel]
  59101. );
  59102. $this->testSuites[$this->testSuiteLevel]->setAttribute(
  59103. 'errors',
  59104. $this->testSuiteErrors[$this->testSuiteLevel]
  59105. );
  59106. $this->testSuites[$this->testSuiteLevel]->setAttribute(
  59107. 'time',
  59108. sprintf('%F', $this->testSuiteTimes[$this->testSuiteLevel])
  59109. );
  59110. if ($this->testSuiteLevel > 1) {
  59111. $this->testSuiteTests[$this->testSuiteLevel - 1] += $this->testSuiteTests[$this->testSuiteLevel];
  59112. $this->testSuiteAssertions[$this->testSuiteLevel - 1] += $this->testSuiteAssertions[$this->testSuiteLevel];
  59113. $this->testSuiteErrors[$this->testSuiteLevel - 1] += $this->testSuiteErrors[$this->testSuiteLevel];
  59114. $this->testSuiteFailures[$this->testSuiteLevel - 1] += $this->testSuiteFailures[$this->testSuiteLevel];
  59115. $this->testSuiteTimes[$this->testSuiteLevel - 1] += $this->testSuiteTimes[$this->testSuiteLevel];
  59116. }
  59117. $this->testSuiteLevel--;
  59118. }
  59119. /**
  59120. * A test started.
  59121. *
  59122. * @param PHPUnit_Framework_Test $test
  59123. */
  59124. public function startTest(PHPUnit_Framework_Test $test)
  59125. {
  59126. $testCase = $this->document->createElement('testcase');
  59127. $testCase->setAttribute('name', $test->getName());
  59128. if ($test instanceof PHPUnit_Framework_TestCase) {
  59129. $class = new ReflectionClass($test);
  59130. $methodName = $test->getName();
  59131. if ($class->hasMethod($methodName)) {
  59132. $method = $class->getMethod($test->getName());
  59133. $testCase->setAttribute('class', $class->getName());
  59134. $testCase->setAttribute('file', $class->getFileName());
  59135. $testCase->setAttribute('line', $method->getStartLine());
  59136. }
  59137. }
  59138. $this->currentTestCase = $testCase;
  59139. }
  59140. /**
  59141. * A test ended.
  59142. *
  59143. * @param PHPUnit_Framework_Test $test
  59144. * @param float $time
  59145. */
  59146. public function endTest(PHPUnit_Framework_Test $test, $time)
  59147. {
  59148. if ($this->attachCurrentTestCase) {
  59149. if ($test instanceof PHPUnit_Framework_TestCase) {
  59150. $numAssertions = $test->getNumAssertions();
  59151. $this->testSuiteAssertions[$this->testSuiteLevel] += $numAssertions;
  59152. $this->currentTestCase->setAttribute(
  59153. 'assertions',
  59154. $numAssertions
  59155. );
  59156. }
  59157. $this->currentTestCase->setAttribute(
  59158. 'time',
  59159. sprintf('%F', $time)
  59160. );
  59161. $this->testSuites[$this->testSuiteLevel]->appendChild(
  59162. $this->currentTestCase
  59163. );
  59164. $this->testSuiteTests[$this->testSuiteLevel]++;
  59165. $this->testSuiteTimes[$this->testSuiteLevel] += $time;
  59166. if (method_exists($test, 'hasOutput') && $test->hasOutput()) {
  59167. $systemOut = $this->document->createElement('system-out');
  59168. $systemOut->appendChild(
  59169. $this->document->createTextNode($test->getActualOutput())
  59170. );
  59171. $this->currentTestCase->appendChild($systemOut);
  59172. }
  59173. }
  59174. $this->attachCurrentTestCase = true;
  59175. $this->currentTestCase = null;
  59176. }
  59177. /**
  59178. * Returns the XML as a string.
  59179. *
  59180. * @return string
  59181. * @since Method available since Release 2.2.0
  59182. */
  59183. public function getXML()
  59184. {
  59185. return $this->document->saveXML();
  59186. }
  59187. /**
  59188. * Enables or disables the writing of the document
  59189. * in flush().
  59190. *
  59191. * This is a "hack" needed for the integration of
  59192. * PHPUnit with Phing.
  59193. *
  59194. * @return string
  59195. * @since Method available since Release 2.2.0
  59196. */
  59197. public function setWriteDocument($flag)
  59198. {
  59199. if (is_bool($flag)) {
  59200. $this->writeDocument = $flag;
  59201. }
  59202. }
  59203. }
  59204. <?php
  59205. /*
  59206. * This file is part of PHPUnit.
  59207. *
  59208. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59209. *
  59210. * For the full copyright and license information, please view the LICENSE
  59211. * file that was distributed with this source code.
  59212. */
  59213. /**
  59214. * Utility class for blacklisting PHPUnit's own source code files.
  59215. *
  59216. * @since Class available since Release 4.0.0
  59217. */
  59218. class PHPUnit_Util_Blacklist
  59219. {
  59220. /**
  59221. * @var array
  59222. */
  59223. public static $blacklistedClassNames = array(
  59224. 'File_Iterator' => 1,
  59225. 'PHP_CodeCoverage' => 1,
  59226. 'PHP_Invoker' => 1,
  59227. 'PHP_Timer' => 1,
  59228. 'PHP_Token' => 1,
  59229. 'PHPUnit_Framework_TestCase' => 2,
  59230. 'PHPUnit_Extensions_Database_TestCase' => 2,
  59231. 'PHPUnit_Framework_MockObject_Generator' => 2,
  59232. 'PHPUnit_Extensions_SeleniumTestCase' => 2,
  59233. 'PHPUnit_Extensions_Story_TestCase' => 2,
  59234. 'Text_Template' => 1,
  59235. 'Symfony\Component\Yaml\Yaml' => 1,
  59236. 'SebastianBergmann\Diff\Diff' => 1,
  59237. 'SebastianBergmann\Environment\Runtime' => 1,
  59238. 'SebastianBergmann\Comparator\Comparator' => 1,
  59239. 'SebastianBergmann\Exporter\Exporter' => 1,
  59240. 'SebastianBergmann\GlobalState\Snapshot' => 1,
  59241. 'SebastianBergmann\RecursionContext\Context' => 1,
  59242. 'SebastianBergmann\Version' => 1,
  59243. 'Composer\Autoload\ClassLoader' => 1,
  59244. 'Doctrine\Instantiator\Instantiator' => 1,
  59245. 'phpDocumentor\Reflection\DocBlock' => 1,
  59246. 'Prophecy\Prophet' => 1
  59247. );
  59248. /**
  59249. * @var array
  59250. */
  59251. private static $directories;
  59252. /**
  59253. * @return array
  59254. * @since Method available since Release 4.1.0
  59255. */
  59256. public function getBlacklistedDirectories()
  59257. {
  59258. $this->initialize();
  59259. return self::$directories;
  59260. }
  59261. /**
  59262. * @param string $file
  59263. * @return bool
  59264. */
  59265. public function isBlacklisted($file)
  59266. {
  59267. if (defined('PHPUNIT_TESTSUITE')) {
  59268. return false;
  59269. }
  59270. $this->initialize();
  59271. foreach (self::$directories as $directory) {
  59272. if (strpos($file, $directory) === 0) {
  59273. return true;
  59274. }
  59275. }
  59276. return false;
  59277. }
  59278. private function initialize()
  59279. {
  59280. if (self::$directories === null) {
  59281. self::$directories = array();
  59282. foreach (self::$blacklistedClassNames as $className => $parent) {
  59283. if (!class_exists($className)) {
  59284. continue;
  59285. }
  59286. $reflector = new ReflectionClass($className);
  59287. $directory = $reflector->getFileName();
  59288. for ($i = 0; $i < $parent; $i++) {
  59289. $directory = dirname($directory);
  59290. }
  59291. self::$directories[] = $directory;
  59292. }
  59293. // Hide process isolation workaround on Windows.
  59294. // @see PHPUnit_Util_PHP::factory()
  59295. // @see PHPUnit_Util_PHP_Windows::process()
  59296. if (DIRECTORY_SEPARATOR === '\\') {
  59297. // tempnam() prefix is limited to first 3 chars.
  59298. // @see http://php.net/manual/en/function.tempnam.php
  59299. self::$directories[] = sys_get_temp_dir() . '\\PHP';
  59300. }
  59301. }
  59302. }
  59303. }
  59304. <?php
  59305. /*
  59306. * This file is part of PHPUnit.
  59307. *
  59308. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59309. *
  59310. * For the full copyright and license information, please view the LICENSE
  59311. * file that was distributed with this source code.
  59312. */
  59313. /**
  59314. * Iterator for test suites.
  59315. *
  59316. * @since Class available since Release 3.1.0
  59317. */
  59318. class PHPUnit_Util_TestSuiteIterator implements RecursiveIterator
  59319. {
  59320. /**
  59321. * @var int
  59322. */
  59323. protected $position;
  59324. /**
  59325. * @var PHPUnit_Framework_Test[]
  59326. */
  59327. protected $tests;
  59328. /**
  59329. * @param PHPUnit_Framework_TestSuite $testSuite
  59330. */
  59331. public function __construct(PHPUnit_Framework_TestSuite $testSuite)
  59332. {
  59333. $this->tests = $testSuite->tests();
  59334. }
  59335. /**
  59336. * Rewinds the Iterator to the first element.
  59337. */
  59338. public function rewind()
  59339. {
  59340. $this->position = 0;
  59341. }
  59342. /**
  59343. * Checks if there is a current element after calls to rewind() or next().
  59344. *
  59345. * @return bool
  59346. */
  59347. public function valid()
  59348. {
  59349. return $this->position < count($this->tests);
  59350. }
  59351. /**
  59352. * Returns the key of the current element.
  59353. *
  59354. * @return int
  59355. */
  59356. public function key()
  59357. {
  59358. return $this->position;
  59359. }
  59360. /**
  59361. * Returns the current element.
  59362. *
  59363. * @return PHPUnit_Framework_Test
  59364. */
  59365. public function current()
  59366. {
  59367. return $this->valid() ? $this->tests[$this->position] : null;
  59368. }
  59369. /**
  59370. * Moves forward to next element.
  59371. */
  59372. public function next()
  59373. {
  59374. $this->position++;
  59375. }
  59376. /**
  59377. * Returns the sub iterator for the current element.
  59378. *
  59379. * @return PHPUnit_Util_TestSuiteIterator
  59380. */
  59381. public function getChildren()
  59382. {
  59383. return new self(
  59384. $this->tests[$this->position]
  59385. );
  59386. }
  59387. /**
  59388. * Checks whether the current element has children.
  59389. *
  59390. * @return bool
  59391. */
  59392. public function hasChildren()
  59393. {
  59394. return $this->tests[$this->position] instanceof PHPUnit_Framework_TestSuite;
  59395. }
  59396. }
  59397. <?php
  59398. /*
  59399. * This file is part of PHPUnit.
  59400. *
  59401. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59402. *
  59403. * For the full copyright and license information, please view the LICENSE
  59404. * file that was distributed with this source code.
  59405. */
  59406. /**
  59407. * Utility class for code filtering.
  59408. *
  59409. * @since Class available since Release 2.0.0
  59410. */
  59411. class PHPUnit_Util_Filter
  59412. {
  59413. /**
  59414. * Filters stack frames from PHPUnit classes.
  59415. *
  59416. * @param Exception $e
  59417. * @param bool $asString
  59418. * @return string
  59419. */
  59420. public static function getFilteredStacktrace(Exception $e, $asString = true)
  59421. {
  59422. $prefix = false;
  59423. $script = realpath($GLOBALS['_SERVER']['SCRIPT_NAME']);
  59424. if (defined('__PHPUNIT_PHAR_ROOT__')) {
  59425. $prefix = __PHPUNIT_PHAR_ROOT__;
  59426. }
  59427. if ($asString === true) {
  59428. $filteredStacktrace = '';
  59429. } else {
  59430. $filteredStacktrace = array();
  59431. }
  59432. if ($e instanceof PHPUnit_Framework_SyntheticError) {
  59433. $eTrace = $e->getSyntheticTrace();
  59434. $eFile = $e->getSyntheticFile();
  59435. $eLine = $e->getSyntheticLine();
  59436. } elseif ($e instanceof PHPUnit_Framework_Exception) {
  59437. $eTrace = $e->getSerializableTrace();
  59438. $eFile = $e->getFile();
  59439. $eLine = $e->getLine();
  59440. } else {
  59441. if ($e->getPrevious()) {
  59442. $e = $e->getPrevious();
  59443. }
  59444. $eTrace = $e->getTrace();
  59445. $eFile = $e->getFile();
  59446. $eLine = $e->getLine();
  59447. }
  59448. if (!self::frameExists($eTrace, $eFile, $eLine)) {
  59449. array_unshift(
  59450. $eTrace,
  59451. array('file' => $eFile, 'line' => $eLine)
  59452. );
  59453. }
  59454. $blacklist = new PHPUnit_Util_Blacklist;
  59455. foreach ($eTrace as $frame) {
  59456. if (isset($frame['file']) && is_file($frame['file']) &&
  59457. !$blacklist->isBlacklisted($frame['file']) &&
  59458. ($prefix === false || strpos($frame['file'], $prefix) !== 0) &&
  59459. $frame['file'] !== $script) {
  59460. if ($asString === true) {
  59461. $filteredStacktrace .= sprintf(
  59462. "%s:%s\n",
  59463. $frame['file'],
  59464. isset($frame['line']) ? $frame['line'] : '?'
  59465. );
  59466. } else {
  59467. $filteredStacktrace[] = $frame;
  59468. }
  59469. }
  59470. }
  59471. return $filteredStacktrace;
  59472. }
  59473. /**
  59474. * @param array $trace
  59475. * @param string $file
  59476. * @param int $line
  59477. * @return bool
  59478. * @since Method available since Release 3.3.2
  59479. */
  59480. private static function frameExists(array $trace, $file, $line)
  59481. {
  59482. foreach ($trace as $frame) {
  59483. if (isset($frame['file']) && $frame['file'] == $file &&
  59484. isset($frame['line']) && $frame['line'] == $line) {
  59485. return true;
  59486. }
  59487. }
  59488. return false;
  59489. }
  59490. }
  59491. <?php
  59492. /*
  59493. * This file is part of PHPUnit.
  59494. *
  59495. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59496. *
  59497. * For the full copyright and license information, please view the LICENSE
  59498. * file that was distributed with this source code.
  59499. */
  59500. /**
  59501. * Prints TestDox documentation in HTML format.
  59502. *
  59503. * @since Class available since Release 2.1.0
  59504. */
  59505. class PHPUnit_Util_TestDox_ResultPrinter_HTML extends PHPUnit_Util_TestDox_ResultPrinter
  59506. {
  59507. /**
  59508. * @var bool
  59509. */
  59510. protected $printsHTML = true;
  59511. /**
  59512. * Handler for 'start run' event.
  59513. */
  59514. protected function startRun()
  59515. {
  59516. $this->write('<html><body>');
  59517. }
  59518. /**
  59519. * Handler for 'start class' event.
  59520. *
  59521. * @param string $name
  59522. */
  59523. protected function startClass($name)
  59524. {
  59525. $this->write(
  59526. '<h2 id="' . $name . '">' . $this->currentTestClassPrettified .
  59527. '</h2><ul>'
  59528. );
  59529. }
  59530. /**
  59531. * Handler for 'on test' event.
  59532. *
  59533. * @param string $name
  59534. * @param bool $success
  59535. */
  59536. protected function onTest($name, $success = true)
  59537. {
  59538. if (!$success) {
  59539. $strikeOpen = '<span style="text-decoration:line-through;">';
  59540. $strikeClose = '</span>';
  59541. } else {
  59542. $strikeOpen = '';
  59543. $strikeClose = '';
  59544. }
  59545. $this->write('<li>' . $strikeOpen . $name . $strikeClose . '</li>');
  59546. }
  59547. /**
  59548. * Handler for 'end class' event.
  59549. *
  59550. * @param string $name
  59551. */
  59552. protected function endClass($name)
  59553. {
  59554. $this->write('</ul>');
  59555. }
  59556. /**
  59557. * Handler for 'end run' event.
  59558. */
  59559. protected function endRun()
  59560. {
  59561. $this->write('</body></html>');
  59562. }
  59563. }
  59564. <?php
  59565. /*
  59566. * This file is part of PHPUnit.
  59567. *
  59568. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59569. *
  59570. * For the full copyright and license information, please view the LICENSE
  59571. * file that was distributed with this source code.
  59572. */
  59573. /**
  59574. * Prints TestDox documentation in text format.
  59575. *
  59576. * @since Class available since Release 2.1.0
  59577. */
  59578. class PHPUnit_Util_TestDox_ResultPrinter_Text extends PHPUnit_Util_TestDox_ResultPrinter
  59579. {
  59580. /**
  59581. * Handler for 'start class' event.
  59582. *
  59583. * @param string $name
  59584. */
  59585. protected function startClass($name)
  59586. {
  59587. $this->write($this->currentTestClassPrettified . "\n");
  59588. }
  59589. /**
  59590. * Handler for 'on test' event.
  59591. *
  59592. * @param string $name
  59593. * @param bool $success
  59594. */
  59595. protected function onTest($name, $success = true)
  59596. {
  59597. if ($success) {
  59598. $this->write(' [x] ');
  59599. } else {
  59600. $this->write(' [ ] ');
  59601. }
  59602. $this->write($name . "\n");
  59603. }
  59604. /**
  59605. * Handler for 'end class' event.
  59606. *
  59607. * @param string $name
  59608. */
  59609. protected function endClass($name)
  59610. {
  59611. $this->write("\n");
  59612. }
  59613. }
  59614. <?php
  59615. /*
  59616. * This file is part of PHPUnit.
  59617. *
  59618. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59619. *
  59620. * For the full copyright and license information, please view the LICENSE
  59621. * file that was distributed with this source code.
  59622. */
  59623. /**
  59624. * Base class for printers of TestDox documentation.
  59625. *
  59626. * @since Class available since Release 2.1.0
  59627. */
  59628. abstract class PHPUnit_Util_TestDox_ResultPrinter extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
  59629. {
  59630. /**
  59631. * @var PHPUnit_Util_TestDox_NamePrettifier
  59632. */
  59633. protected $prettifier;
  59634. /**
  59635. * @var string
  59636. */
  59637. protected $testClass = '';
  59638. /**
  59639. * @var int
  59640. */
  59641. protected $testStatus = false;
  59642. /**
  59643. * @var array
  59644. */
  59645. protected $tests = array();
  59646. /**
  59647. * @var int
  59648. */
  59649. protected $successful = 0;
  59650. /**
  59651. * @var int
  59652. */
  59653. protected $failed = 0;
  59654. /**
  59655. * @var int
  59656. */
  59657. protected $risky = 0;
  59658. /**
  59659. * @var int
  59660. */
  59661. protected $skipped = 0;
  59662. /**
  59663. * @var int
  59664. */
  59665. protected $incomplete = 0;
  59666. /**
  59667. * @var string
  59668. */
  59669. protected $currentTestClassPrettified;
  59670. /**
  59671. * @var string
  59672. */
  59673. protected $currentTestMethodPrettified;
  59674. /**
  59675. * Constructor.
  59676. *
  59677. * @param resource $out
  59678. */
  59679. public function __construct($out = null)
  59680. {
  59681. parent::__construct($out);
  59682. $this->prettifier = new PHPUnit_Util_TestDox_NamePrettifier;
  59683. $this->startRun();
  59684. }
  59685. /**
  59686. * Flush buffer and close output.
  59687. */
  59688. public function flush()
  59689. {
  59690. $this->doEndClass();
  59691. $this->endRun();
  59692. parent::flush();
  59693. }
  59694. /**
  59695. * An error occurred.
  59696. *
  59697. * @param PHPUnit_Framework_Test $test
  59698. * @param Exception $e
  59699. * @param float $time
  59700. */
  59701. public function addError(PHPUnit_Framework_Test $test, Exception $e, $time)
  59702. {
  59703. if (!$this->isOfInterest($test)) {
  59704. return;
  59705. }
  59706. $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_ERROR;
  59707. $this->failed++;
  59708. }
  59709. /**
  59710. * A failure occurred.
  59711. *
  59712. * @param PHPUnit_Framework_Test $test
  59713. * @param PHPUnit_Framework_AssertionFailedError $e
  59714. * @param float $time
  59715. */
  59716. public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
  59717. {
  59718. if (!$this->isOfInterest($test)) {
  59719. return;
  59720. }
  59721. $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
  59722. $this->failed++;
  59723. }
  59724. /**
  59725. * Incomplete test.
  59726. *
  59727. * @param PHPUnit_Framework_Test $test
  59728. * @param Exception $e
  59729. * @param float $time
  59730. */
  59731. public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  59732. {
  59733. if (!$this->isOfInterest($test)) {
  59734. return;
  59735. }
  59736. $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE;
  59737. $this->incomplete++;
  59738. }
  59739. /**
  59740. * Risky test.
  59741. *
  59742. * @param PHPUnit_Framework_Test $test
  59743. * @param Exception $e
  59744. * @param float $time
  59745. * @since Method available since Release 4.0.0
  59746. */
  59747. public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  59748. {
  59749. if (!$this->isOfInterest($test)) {
  59750. return;
  59751. }
  59752. $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_RISKY;
  59753. $this->risky++;
  59754. }
  59755. /**
  59756. * Skipped test.
  59757. *
  59758. * @param PHPUnit_Framework_Test $test
  59759. * @param Exception $e
  59760. * @param float $time
  59761. * @since Method available since Release 3.0.0
  59762. */
  59763. public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time)
  59764. {
  59765. if (!$this->isOfInterest($test)) {
  59766. return;
  59767. }
  59768. $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED;
  59769. $this->skipped++;
  59770. }
  59771. /**
  59772. * A testsuite started.
  59773. *
  59774. * @param PHPUnit_Framework_TestSuite $suite
  59775. * @since Method available since Release 2.2.0
  59776. */
  59777. public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
  59778. {
  59779. }
  59780. /**
  59781. * A testsuite ended.
  59782. *
  59783. * @param PHPUnit_Framework_TestSuite $suite
  59784. * @since Method available since Release 2.2.0
  59785. */
  59786. public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
  59787. {
  59788. }
  59789. /**
  59790. * A test started.
  59791. *
  59792. * @param PHPUnit_Framework_Test $test
  59793. */
  59794. public function startTest(PHPUnit_Framework_Test $test)
  59795. {
  59796. if (!$this->isOfInterest($test)) {
  59797. return;
  59798. }
  59799. $class = get_class($test);
  59800. if ($this->testClass != $class) {
  59801. if ($this->testClass != '') {
  59802. $this->doEndClass();
  59803. }
  59804. $this->currentTestClassPrettified = $this->prettifier->prettifyTestClass($class);
  59805. $this->startClass($class);
  59806. $this->testClass = $class;
  59807. $this->tests = array();
  59808. }
  59809. $prettified = false;
  59810. $annotations = $test->getAnnotations();
  59811. if (isset($annotations['method']['testdox'][0])) {
  59812. $this->currentTestMethodPrettified = $annotations['method']['testdox'][0];
  59813. $prettified = true;
  59814. }
  59815. if (!$prettified) {
  59816. $this->currentTestMethodPrettified = $this->prettifier->prettifyTestMethod($test->getName(false));
  59817. }
  59818. $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_PASSED;
  59819. }
  59820. /**
  59821. * A test ended.
  59822. *
  59823. * @param PHPUnit_Framework_Test $test
  59824. * @param float $time
  59825. */
  59826. public function endTest(PHPUnit_Framework_Test $test, $time)
  59827. {
  59828. if (!$this->isOfInterest($test)) {
  59829. return;
  59830. }
  59831. if (!isset($this->tests[$this->currentTestMethodPrettified])) {
  59832. if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) {
  59833. $this->tests[$this->currentTestMethodPrettified]['success'] = 1;
  59834. $this->tests[$this->currentTestMethodPrettified]['failure'] = 0;
  59835. } else {
  59836. $this->tests[$this->currentTestMethodPrettified]['success'] = 0;
  59837. $this->tests[$this->currentTestMethodPrettified]['failure'] = 1;
  59838. }
  59839. } else {
  59840. if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) {
  59841. $this->tests[$this->currentTestMethodPrettified]['success']++;
  59842. } else {
  59843. $this->tests[$this->currentTestMethodPrettified]['failure']++;
  59844. }
  59845. }
  59846. $this->currentTestClassPrettified = null;
  59847. $this->currentTestMethodPrettified = null;
  59848. }
  59849. /**
  59850. * @since Method available since Release 2.3.0
  59851. */
  59852. protected function doEndClass()
  59853. {
  59854. foreach ($this->tests as $name => $data) {
  59855. $this->onTest($name, $data['failure'] == 0);
  59856. }
  59857. $this->endClass($this->testClass);
  59858. }
  59859. /**
  59860. * Handler for 'start run' event.
  59861. */
  59862. protected function startRun()
  59863. {
  59864. }
  59865. /**
  59866. * Handler for 'start class' event.
  59867. *
  59868. * @param string $name
  59869. */
  59870. protected function startClass($name)
  59871. {
  59872. }
  59873. /**
  59874. * Handler for 'on test' event.
  59875. *
  59876. * @param string $name
  59877. * @param bool $success
  59878. */
  59879. protected function onTest($name, $success = true)
  59880. {
  59881. }
  59882. /**
  59883. * Handler for 'end class' event.
  59884. *
  59885. * @param string $name
  59886. */
  59887. protected function endClass($name)
  59888. {
  59889. }
  59890. /**
  59891. * Handler for 'end run' event.
  59892. */
  59893. protected function endRun()
  59894. {
  59895. }
  59896. private function isOfInterest(PHPUnit_Framework_Test $test)
  59897. {
  59898. return $test instanceof PHPUnit_Framework_TestCase && get_class($test) != 'PHPUnit_Framework_Warning';
  59899. }
  59900. }
  59901. <?php
  59902. /*
  59903. * This file is part of PHPUnit.
  59904. *
  59905. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  59906. *
  59907. * For the full copyright and license information, please view the LICENSE
  59908. * file that was distributed with this source code.
  59909. */
  59910. /**
  59911. * Prettifies class and method names for use in TestDox documentation.
  59912. *
  59913. * @since Class available since Release 2.1.0
  59914. */
  59915. class PHPUnit_Util_TestDox_NamePrettifier
  59916. {
  59917. /**
  59918. * @var string
  59919. */
  59920. protected $prefix = 'Test';
  59921. /**
  59922. * @var string
  59923. */
  59924. protected $suffix = 'Test';
  59925. /**
  59926. * @var array
  59927. */
  59928. protected $strings = array();
  59929. /**
  59930. * Prettifies the name of a test class.
  59931. *
  59932. * @param string $name
  59933. * @return string
  59934. */
  59935. public function prettifyTestClass($name)
  59936. {
  59937. $title = $name;
  59938. if ($this->suffix !== null &&
  59939. $this->suffix == substr($name, -1 * strlen($this->suffix))) {
  59940. $title = substr($title, 0, strripos($title, $this->suffix));
  59941. }
  59942. if ($this->prefix !== null &&
  59943. $this->prefix == substr($name, 0, strlen($this->prefix))) {
  59944. $title = substr($title, strlen($this->prefix));
  59945. }
  59946. if (substr($title, 0, 1) == '\\') {
  59947. $title = substr($title, 1);
  59948. }
  59949. return $title;
  59950. }
  59951. /**
  59952. * Prettifies the name of a test method.
  59953. *
  59954. * @param string $name
  59955. * @return string
  59956. */
  59957. public function prettifyTestMethod($name)
  59958. {
  59959. $buffer = '';
  59960. if (!is_string($name) || strlen($name) == 0) {
  59961. return $buffer;
  59962. }
  59963. $string = preg_replace('#\d+$#', '', $name, -1, $count);
  59964. if (in_array($string, $this->strings)) {
  59965. $name = $string;
  59966. } elseif ($count == 0) {
  59967. $this->strings[] = $string;
  59968. }
  59969. if (strpos($name, '_') !== false) {
  59970. return str_replace('_', ' ', $name);
  59971. }
  59972. $max = strlen($name);
  59973. if (substr($name, 0, 4) == 'test') {
  59974. $offset = 4;
  59975. } else {
  59976. $offset = 0;
  59977. $name[0] = strtoupper($name[0]);
  59978. }
  59979. $wasNumeric = false;
  59980. for ($i = $offset; $i < $max; $i++) {
  59981. if ($i > $offset &&
  59982. ord($name[$i]) >= 65 &&
  59983. ord($name[$i]) <= 90) {
  59984. $buffer .= ' ' . strtolower($name[$i]);
  59985. } else {
  59986. $isNumeric = is_numeric($name[$i]);
  59987. if (!$wasNumeric && $isNumeric) {
  59988. $buffer .= ' ';
  59989. $wasNumeric = true;
  59990. }
  59991. if ($wasNumeric && !$isNumeric) {
  59992. $wasNumeric = false;
  59993. }
  59994. $buffer .= $name[$i];
  59995. }
  59996. }
  59997. return $buffer;
  59998. }
  59999. /**
  60000. * Sets the prefix of test names.
  60001. *
  60002. * @param string $prefix
  60003. */
  60004. public function setPrefix($prefix)
  60005. {
  60006. $this->prefix = $prefix;
  60007. }
  60008. /**
  60009. * Sets the suffix of test names.
  60010. *
  60011. * @param string $suffix
  60012. */
  60013. public function setSuffix($suffix)
  60014. {
  60015. $this->suffix = $suffix;
  60016. }
  60017. }
  60018. <?php
  60019. /*
  60020. * This file is part of PHPUnit.
  60021. *
  60022. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60023. *
  60024. * For the full copyright and license information, please view the LICENSE
  60025. * file that was distributed with this source code.
  60026. */
  60027. /**
  60028. * Error handler that converts PHP errors and warnings to exceptions.
  60029. *
  60030. * @since Class available since Release 4.2.0
  60031. */
  60032. class PHPUnit_Util_Regex
  60033. {
  60034. public static function pregMatchSafe($pattern, $subject, $matches = null, $flags = 0, $offset = 0)
  60035. {
  60036. $handler_terminator = PHPUnit_Util_ErrorHandler::handleErrorOnce(E_WARNING);
  60037. $match = preg_match($pattern, $subject, $matches, $flags, $offset);
  60038. $handler_terminator(); // cleaning
  60039. return $match;
  60040. }
  60041. }
  60042. <?php
  60043. /*
  60044. * This file is part of PHPUnit.
  60045. *
  60046. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60047. *
  60048. * For the full copyright and license information, please view the LICENSE
  60049. * file that was distributed with this source code.
  60050. */
  60051. /**
  60052. * Utility class for textual type (and value) representation.
  60053. *
  60054. * @since Class available since Release 3.0.0
  60055. */
  60056. class PHPUnit_Util_Type
  60057. {
  60058. public static function isType($type)
  60059. {
  60060. return in_array(
  60061. $type,
  60062. array(
  60063. 'numeric',
  60064. 'integer',
  60065. 'int',
  60066. 'float',
  60067. 'string',
  60068. 'boolean',
  60069. 'bool',
  60070. 'null',
  60071. 'array',
  60072. 'object',
  60073. 'resource',
  60074. 'scalar'
  60075. )
  60076. );
  60077. }
  60078. }
  60079. <?php
  60080. /*
  60081. * This file is part of PHPUnit.
  60082. *
  60083. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60084. *
  60085. * For the full copyright and license information, please view the LICENSE
  60086. * file that was distributed with this source code.
  60087. */
  60088. use SebastianBergmann\Environment\Runtime;
  60089. /**
  60090. * Default utility for PHP sub-processes.
  60091. *
  60092. * @since Class available since Release 3.5.12
  60093. */
  60094. class PHPUnit_Util_PHP_Default extends PHPUnit_Util_PHP
  60095. {
  60096. /**
  60097. * Runs a single job (PHP code) using a separate PHP process.
  60098. *
  60099. * @param string $job
  60100. * @param array $settings
  60101. * @return array
  60102. * @throws PHPUnit_Framework_Exception
  60103. */
  60104. public function runJob($job, array $settings = array())
  60105. {
  60106. $runtime = new Runtime;
  60107. $process = proc_open(
  60108. $runtime->getBinary() . $this->settingsToParameters($settings),
  60109. array(
  60110. 0 => array('pipe', 'r'),
  60111. 1 => array('pipe', 'w'),
  60112. 2 => array('pipe', 'w')
  60113. ),
  60114. $pipes
  60115. );
  60116. if (!is_resource($process)) {
  60117. throw new PHPUnit_Framework_Exception(
  60118. 'Unable to spawn worker process'
  60119. );
  60120. }
  60121. $this->process($pipes[0], $job);
  60122. fclose($pipes[0]);
  60123. $stdout = stream_get_contents($pipes[1]);
  60124. fclose($pipes[1]);
  60125. $stderr = stream_get_contents($pipes[2]);
  60126. fclose($pipes[2]);
  60127. proc_close($process);
  60128. $this->cleanup();
  60129. return array('stdout' => $stdout, 'stderr' => $stderr);
  60130. }
  60131. /**
  60132. * @param resource $pipe
  60133. * @param string $job
  60134. * @throws PHPUnit_Framework_Exception
  60135. * @since Method available since Release 3.5.12
  60136. */
  60137. protected function process($pipe, $job)
  60138. {
  60139. fwrite($pipe, $job);
  60140. }
  60141. /**
  60142. * @since Method available since Release 3.5.12
  60143. */
  60144. protected function cleanup()
  60145. {
  60146. }
  60147. }
  60148. <?php
  60149. if (!defined('STDOUT')) {
  60150. // php://stdout does not obey output buffering. Any output would break
  60151. // unserialization of child process results in the parent process.
  60152. define('STDOUT', fopen('php://temp', 'w+b'));
  60153. define('STDERR', fopen('php://stderr', 'wb'));
  60154. }
  60155. {iniSettings}
  60156. ini_set('display_errors', 'stderr');
  60157. set_include_path('{include_path}');
  60158. $composerAutoload = {composerAutoload};
  60159. $phar = {phar};
  60160. ob_start();
  60161. if ($composerAutoload) {
  60162. require_once $composerAutoload;
  60163. define('PHPUNIT_COMPOSER_INSTALL', $composerAutoload);
  60164. } else if ($phar) {
  60165. require $phar;
  60166. }
  60167. function __phpunit_run_isolated_test()
  60168. {
  60169. if (!class_exists('{className}')) {
  60170. require_once '{filename}';
  60171. }
  60172. $result = new PHPUnit_Framework_TestResult;
  60173. if ({collectCodeCoverageInformation}) {
  60174. $result->setCodeCoverage(
  60175. new PHP_CodeCoverage(
  60176. null,
  60177. unserialize('{codeCoverageFilter}')
  60178. )
  60179. );
  60180. }
  60181. $result->beStrictAboutTestsThatDoNotTestAnything({isStrictAboutTestsThatDoNotTestAnything});
  60182. $result->beStrictAboutOutputDuringTests({isStrictAboutOutputDuringTests});
  60183. $result->beStrictAboutTestSize({isStrictAboutTestSize});
  60184. $result->beStrictAboutTodoAnnotatedTests({isStrictAboutTodoAnnotatedTests});
  60185. $test = new {className}('{methodName}', unserialize('{data}'), '{dataName}');
  60186. $test->setDependencyInput(unserialize('{dependencyInput}'));
  60187. $test->setInIsolation(TRUE);
  60188. ob_end_clean();
  60189. $test->run($result);
  60190. $output = '';
  60191. if (!$test->hasExpectationOnOutput()) {
  60192. $output = $test->getActualOutput();
  60193. }
  60194. rewind(STDOUT);
  60195. if ($stdout = stream_get_contents(STDOUT)) {
  60196. $output = $stdout . $output;
  60197. }
  60198. print serialize(
  60199. array(
  60200. 'testResult' => $test->getResult(),
  60201. 'numAssertions' => $test->getNumAssertions(),
  60202. 'result' => $result,
  60203. 'output' => $output
  60204. )
  60205. );
  60206. }
  60207. {constants}
  60208. {included_files}
  60209. {globals}
  60210. if (isset($GLOBALS['__PHPUNIT_BOOTSTRAP'])) {
  60211. require_once $GLOBALS['__PHPUNIT_BOOTSTRAP'];
  60212. unset($GLOBALS['__PHPUNIT_BOOTSTRAP']);
  60213. }
  60214. __phpunit_run_isolated_test();
  60215. <?php
  60216. /*
  60217. * This file is part of PHPUnit.
  60218. *
  60219. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60220. *
  60221. * For the full copyright and license information, please view the LICENSE
  60222. * file that was distributed with this source code.
  60223. */
  60224. use SebastianBergmann\Environment\Runtime;
  60225. /**
  60226. * Windows utility for PHP sub-processes.
  60227. *
  60228. * @since Class available since Release 3.5.12
  60229. */
  60230. class PHPUnit_Util_PHP_Windows extends PHPUnit_Util_PHP_Default
  60231. {
  60232. /**
  60233. * @var string
  60234. */
  60235. private $tempFile;
  60236. /**
  60237. * {@inheritdoc}
  60238. *
  60239. * Reading from STDOUT or STDERR hangs forever on Windows if the output is
  60240. * too large.
  60241. *
  60242. * @see https://bugs.php.net/bug.php?id=51800
  60243. */
  60244. public function runJob($job, array $settings = array())
  60245. {
  60246. $runtime = new Runtime;
  60247. if (false === $stdout_handle = tmpfile()) {
  60248. throw new PHPUnit_Framework_Exception(
  60249. 'A temporary file could not be created; verify that your TEMP environment variable is writable'
  60250. );
  60251. }
  60252. $process = proc_open(
  60253. $runtime->getBinary() . $this->settingsToParameters($settings),
  60254. array(
  60255. 0 => array('pipe', 'r'),
  60256. 1 => $stdout_handle,
  60257. 2 => array('pipe', 'w')
  60258. ),
  60259. $pipes
  60260. );
  60261. if (!is_resource($process)) {
  60262. throw new PHPUnit_Framework_Exception(
  60263. 'Unable to spawn worker process'
  60264. );
  60265. }
  60266. $this->process($pipes[0], $job);
  60267. fclose($pipes[0]);
  60268. $stderr = stream_get_contents($pipes[2]);
  60269. fclose($pipes[2]);
  60270. proc_close($process);
  60271. rewind($stdout_handle);
  60272. $stdout = stream_get_contents($stdout_handle);
  60273. fclose($stdout_handle);
  60274. $this->cleanup();
  60275. return array('stdout' => $stdout, 'stderr' => $stderr);
  60276. }
  60277. /**
  60278. * @param resource $pipe
  60279. * @param string $job
  60280. * @throws PHPUnit_Framework_Exception
  60281. * @since Method available since Release 3.5.12
  60282. */
  60283. protected function process($pipe, $job)
  60284. {
  60285. if (!($this->tempFile = tempnam(sys_get_temp_dir(), 'PHPUnit')) ||
  60286. file_put_contents($this->tempFile, $job) === false) {
  60287. throw new PHPUnit_Framework_Exception(
  60288. 'Unable to write temporary file'
  60289. );
  60290. }
  60291. fwrite(
  60292. $pipe,
  60293. '<?php require_once ' . var_export($this->tempFile, true) . '; ?>'
  60294. );
  60295. }
  60296. /**
  60297. * @since Method available since Release 3.5.12
  60298. */
  60299. protected function cleanup()
  60300. {
  60301. unlink($this->tempFile);
  60302. }
  60303. }
  60304. <?php
  60305. /*
  60306. * This file is part of PHPUnit.
  60307. *
  60308. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60309. *
  60310. * For the full copyright and license information, please view the LICENSE
  60311. * file that was distributed with this source code.
  60312. */
  60313. /**
  60314. * Utility methods to load PHP sourcefiles.
  60315. *
  60316. * @since Class available since Release 2.3.0
  60317. */
  60318. class PHPUnit_Util_Fileloader
  60319. {
  60320. /**
  60321. * Checks if a PHP sourcefile is readable.
  60322. * The sourcefile is loaded through the load() method.
  60323. *
  60324. * @param string $filename
  60325. * @return string
  60326. * @throws PHPUnit_Framework_Exception
  60327. */
  60328. public static function checkAndLoad($filename)
  60329. {
  60330. $includePathFilename = stream_resolve_include_path($filename);
  60331. if (!$includePathFilename || !is_readable($includePathFilename)) {
  60332. throw new PHPUnit_Framework_Exception(
  60333. sprintf('Cannot open file "%s".' . "\n", $filename)
  60334. );
  60335. }
  60336. self::load($includePathFilename);
  60337. return $includePathFilename;
  60338. }
  60339. /**
  60340. * Loads a PHP sourcefile.
  60341. *
  60342. * @param string $filename
  60343. * @return mixed
  60344. * @since Method available since Release 3.0.0
  60345. */
  60346. public static function load($filename)
  60347. {
  60348. $oldVariableNames = array_keys(get_defined_vars());
  60349. include_once $filename;
  60350. $newVariables = get_defined_vars();
  60351. $newVariableNames = array_diff(
  60352. array_keys($newVariables),
  60353. $oldVariableNames
  60354. );
  60355. foreach ($newVariableNames as $variableName) {
  60356. if ($variableName != 'oldVariableNames') {
  60357. $GLOBALS[$variableName] = $newVariables[$variableName];
  60358. }
  60359. }
  60360. return $filename;
  60361. }
  60362. }
  60363. <?php
  60364. /*
  60365. * This file is part of PHPUnit.
  60366. *
  60367. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  60368. *
  60369. * For the full copyright and license information, please view the LICENSE
  60370. * file that was distributed with this source code.
  60371. */
  60372. /**
  60373. * XML helpers.
  60374. *
  60375. * @since Class available since Release 3.2.0
  60376. */
  60377. class PHPUnit_Util_XML
  60378. {
  60379. /**
  60380. * Escapes a string for the use in XML documents
  60381. * Any Unicode character is allowed, excluding the surrogate blocks, FFFE,
  60382. * and FFFF (not even as character reference).
  60383. * See http://www.w3.org/TR/xml/#charsets
  60384. *
  60385. * @param string $string
  60386. * @return string
  60387. * @since Method available since Release 3.4.6
  60388. */
  60389. public static function prepareString($string)
  60390. {
  60391. return preg_replace(
  60392. '/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]/',
  60393. '',
  60394. htmlspecialchars(
  60395. PHPUnit_Util_String::convertToUtf8($string),
  60396. ENT_QUOTES,
  60397. 'UTF-8'
  60398. )
  60399. );
  60400. }
  60401. /**
  60402. * Loads an XML (or HTML) file into a DOMDocument object.
  60403. *
  60404. * @param string $filename
  60405. * @param bool $isHtml
  60406. * @param bool $xinclude
  60407. * @param bool $strict
  60408. * @return DOMDocument
  60409. * @since Method available since Release 3.3.0
  60410. */
  60411. public static function loadFile($filename, $isHtml = false, $xinclude = false, $strict = false)
  60412. {
  60413. $reporting = error_reporting(0);
  60414. $contents = file_get_contents($filename);
  60415. error_reporting($reporting);
  60416. if ($contents === false) {
  60417. throw new PHPUnit_Framework_Exception(
  60418. sprintf(
  60419. 'Could not read "%s".',
  60420. $filename
  60421. )
  60422. );
  60423. }
  60424. return self::load($contents, $isHtml, $filename, $xinclude, $strict);
  60425. }
  60426. /**
  60427. * Load an $actual document into a DOMDocument. This is called
  60428. * from the selector assertions.
  60429. *
  60430. * If $actual is already a DOMDocument, it is returned with
  60431. * no changes. Otherwise, $actual is loaded into a new DOMDocument
  60432. * as either HTML or XML, depending on the value of $isHtml. If $isHtml is
  60433. * false and $xinclude is true, xinclude is performed on the loaded
  60434. * DOMDocument.
  60435. *
  60436. * Note: prior to PHPUnit 3.3.0, this method loaded a file and
  60437. * not a string as it currently does. To load a file into a
  60438. * DOMDocument, use loadFile() instead.
  60439. *
  60440. * @param string|DOMDocument $actual
  60441. * @param bool $isHtml
  60442. * @param string $filename
  60443. * @param bool $xinclude
  60444. * @param bool $strict
  60445. * @return DOMDocument
  60446. * @since Method available since Release 3.3.0
  60447. */
  60448. public static function load($actual, $isHtml = false, $filename = '', $xinclude = false, $strict = false)
  60449. {
  60450. if ($actual instanceof DOMDocument) {
  60451. return $actual;
  60452. }
  60453. // Required for XInclude on Windows.
  60454. if ($xinclude) {
  60455. $cwd = getcwd();
  60456. @chdir(dirname($filename));
  60457. }
  60458. $document = new DOMDocument;
  60459. $internal = libxml_use_internal_errors(true);
  60460. $message = '';
  60461. $reporting = error_reporting(0);
  60462. if ('' !== $filename) {
  60463. // Necessary for xinclude
  60464. $document->documentURI = $filename;
  60465. }
  60466. if ($isHtml) {
  60467. $loaded = $document->loadHTML($actual);
  60468. } else {
  60469. $loaded = $document->loadXML($actual);
  60470. }
  60471. if (!$isHtml && $xinclude) {
  60472. $document->xinclude();
  60473. }
  60474. foreach (libxml_get_errors() as $error) {
  60475. $message .= "\n" . $error->message;
  60476. }
  60477. libxml_use_internal_errors($internal);
  60478. error_reporting($reporting);
  60479. if ($xinclude) {
  60480. @chdir($cwd);
  60481. }
  60482. if ($loaded === false || ($strict && $message !== '')) {
  60483. if ($filename !== '') {
  60484. throw new PHPUnit_Framework_Exception(
  60485. sprintf(
  60486. 'Could not load "%s".%s',
  60487. $filename,
  60488. $message != '' ? "\n" . $message : ''
  60489. )
  60490. );
  60491. } else {
  60492. throw new PHPUnit_Framework_Exception($message);
  60493. }
  60494. }
  60495. return $document;
  60496. }
  60497. /**
  60498. * @param DOMNode $node
  60499. * @return string
  60500. * @since Method available since Release 3.4.0
  60501. */
  60502. public static function nodeToText(DOMNode $node)
  60503. {
  60504. if ($node->childNodes->length == 1) {
  60505. return $node->nodeValue;
  60506. }
  60507. $result = '';
  60508. foreach ($node->childNodes as $childNode) {
  60509. $result .= $node->ownerDocument->saveXML($childNode);
  60510. }
  60511. return $result;
  60512. }
  60513. /**
  60514. * @param DOMNode $node
  60515. * @since Method available since Release 3.3.0
  60516. */
  60517. public static function removeCharacterDataNodes(DOMNode $node)
  60518. {
  60519. if ($node->hasChildNodes()) {
  60520. for ($i = $node->childNodes->length - 1; $i >= 0; $i--) {
  60521. if (($child = $node->childNodes->item($i)) instanceof DOMCharacterData) {
  60522. $node->removeChild($child);
  60523. }
  60524. }
  60525. }
  60526. }
  60527. /**
  60528. * "Convert" a DOMElement object into a PHP variable.
  60529. *
  60530. * @param DOMElement $element
  60531. * @return mixed
  60532. * @since Method available since Release 3.4.0
  60533. */
  60534. public static function xmlToVariable(DOMElement $element)
  60535. {
  60536. $variable = null;
  60537. switch ($element->tagName) {
  60538. case 'array':
  60539. $variable = array();
  60540. foreach ($element->getElementsByTagName('element') as $element) {
  60541. $value = self::xmlToVariable($element->childNodes->item(1));
  60542. if ($element->hasAttribute('key')) {
  60543. $variable[(string) $element->getAttribute('key')] = $value;
  60544. } else {
  60545. $variable[] = $value;
  60546. }
  60547. }
  60548. break;
  60549. case 'object':
  60550. $className = $element->getAttribute('class');
  60551. if ($element->hasChildNodes()) {
  60552. $arguments = $element->childNodes->item(1)->childNodes;
  60553. $constructorArgs = array();
  60554. foreach ($arguments as $argument) {
  60555. if ($argument instanceof DOMElement) {
  60556. $constructorArgs[] = self::xmlToVariable($argument);
  60557. }
  60558. }
  60559. $class = new ReflectionClass($className);
  60560. $variable = $class->newInstanceArgs($constructorArgs);
  60561. } else {
  60562. $variable = new $className;
  60563. }
  60564. break;
  60565. case 'boolean':
  60566. $variable = $element->nodeValue == 'true' ? true : false;
  60567. break;
  60568. case 'integer':
  60569. case 'double':
  60570. case 'string':
  60571. $variable = $element->nodeValue;
  60572. settype($variable, $element->tagName);
  60573. break;
  60574. }
  60575. return $variable;
  60576. }
  60577. /**
  60578. * Validate list of keys in the associative array.
  60579. *
  60580. * @param array $hash
  60581. * @param array $validKeys
  60582. * @return array
  60583. * @throws PHPUnit_Framework_Exception
  60584. * @since Method available since Release 3.3.0
  60585. */
  60586. public static function assertValidKeys(array $hash, array $validKeys)
  60587. {
  60588. $valids = array();
  60589. // Normalize validation keys so that we can use both indexed and
  60590. // associative arrays.
  60591. foreach ($validKeys as $key => $val) {
  60592. is_int($key) ? $valids[$val] = null : $valids[$key] = $val;
  60593. }
  60594. $validKeys = array_keys($valids);
  60595. // Check for invalid keys.
  60596. foreach ($hash as $key => $value) {
  60597. if (!in_array($key, $validKeys)) {
  60598. $unknown[] = $key;
  60599. }
  60600. }
  60601. if (!empty($unknown)) {
  60602. throw new PHPUnit_Framework_Exception(
  60603. 'Unknown key(s): ' . implode(', ', $unknown)
  60604. );
  60605. }
  60606. // Add default values for any valid keys that are empty.
  60607. foreach ($valids as $key => $value) {
  60608. if (!isset($hash[$key])) {
  60609. $hash[$key] = $value;
  60610. }
  60611. }
  60612. return $hash;
  60613. }
  60614. /**
  60615. * Parse a CSS selector into an associative array suitable for
  60616. * use with findNodes().
  60617. *
  60618. * @param string $selector
  60619. * @param mixed $content
  60620. * @return array
  60621. * @since Method available since Release 3.3.0
  60622. */
  60623. public static function convertSelectToTag($selector, $content = true)
  60624. {
  60625. $selector = trim(preg_replace("/\s+/", ' ', $selector));
  60626. // substitute spaces within attribute value
  60627. while (preg_match('/\[[^\]]+"[^"]+\s[^"]+"\]/', $selector)) {
  60628. $selector = preg_replace(
  60629. '/(\[[^\]]+"[^"]+)\s([^"]+"\])/',
  60630. '$1__SPACE__$2',
  60631. $selector
  60632. );
  60633. }
  60634. if (strstr($selector, ' ')) {
  60635. $elements = explode(' ', $selector);
  60636. } else {
  60637. $elements = array($selector);
  60638. }
  60639. $previousTag = array();
  60640. foreach (array_reverse($elements) as $element) {
  60641. $element = str_replace('__SPACE__', ' ', $element);
  60642. // child selector
  60643. if ($element == '>') {
  60644. $previousTag = array('child' => $previousTag['descendant']);
  60645. continue;
  60646. }
  60647. // adjacent-sibling selector
  60648. if ($element == '+') {
  60649. $previousTag = array('adjacent-sibling' => $previousTag['descendant']);
  60650. continue;
  60651. }
  60652. $tag = array();
  60653. // match element tag
  60654. preg_match("/^([^\.#\[]*)/", $element, $eltMatches);
  60655. if (!empty($eltMatches[1])) {
  60656. $tag['tag'] = $eltMatches[1];
  60657. }
  60658. // match attributes (\[[^\]]*\]*), ids (#[^\.#\[]*),
  60659. // and classes (\.[^\.#\[]*))
  60660. preg_match_all(
  60661. "/(\[[^\]]*\]*|#[^\.#\[]*|\.[^\.#\[]*)/",
  60662. $element,
  60663. $matches
  60664. );
  60665. if (!empty($matches[1])) {
  60666. $classes = array();
  60667. $attrs = array();
  60668. foreach ($matches[1] as $match) {
  60669. // id matched
  60670. if (substr($match, 0, 1) == '#') {
  60671. $tag['id'] = substr($match, 1);
  60672. } // class matched
  60673. elseif (substr($match, 0, 1) == '.') {
  60674. $classes[] = substr($match, 1);
  60675. } // attribute matched
  60676. elseif (substr($match, 0, 1) == '[' &&
  60677. substr($match, -1, 1) == ']') {
  60678. $attribute = substr($match, 1, strlen($match) - 2);
  60679. $attribute = str_replace('"', '', $attribute);
  60680. // match single word
  60681. if (strstr($attribute, '~=')) {
  60682. list($key, $value) = explode('~=', $attribute);
  60683. $value = "regexp:/.*\b$value\b.*/";
  60684. } // match substring
  60685. elseif (strstr($attribute, '*=')) {
  60686. list($key, $value) = explode('*=', $attribute);
  60687. $value = "regexp:/.*$value.*/";
  60688. } // exact match
  60689. else {
  60690. list($key, $value) = explode('=', $attribute);
  60691. }
  60692. $attrs[$key] = $value;
  60693. }
  60694. }
  60695. if ($classes) {
  60696. $tag['class'] = implode(' ', $classes);
  60697. }
  60698. if ($attrs) {
  60699. $tag['attributes'] = $attrs;
  60700. }
  60701. }
  60702. // tag content
  60703. if (is_string($content)) {
  60704. $tag['content'] = $content;
  60705. }
  60706. // determine previous child/descendants
  60707. if (!empty($previousTag['descendant'])) {
  60708. $tag['descendant'] = $previousTag['descendant'];
  60709. } elseif (!empty($previousTag['child'])) {
  60710. $tag['child'] = $previousTag['child'];
  60711. } elseif (!empty($previousTag['adjacent-sibling'])) {
  60712. $tag['adjacent-sibling'] = $previousTag['adjacent-sibling'];
  60713. unset($tag['content']);
  60714. }
  60715. $previousTag = array('descendant' => $tag);
  60716. }
  60717. return $tag;
  60718. }
  60719. /**
  60720. * Parse an $actual document and return an array of DOMNodes
  60721. * matching the CSS $selector. If an error occurs, it will
  60722. * return false.
  60723. *
  60724. * To only return nodes containing a certain content, give
  60725. * the $content to match as a string. Otherwise, setting
  60726. * $content to true will return all nodes matching $selector.
  60727. *
  60728. * The $actual document may be a DOMDocument or a string
  60729. * containing XML or HTML, identified by $isHtml.
  60730. *
  60731. * @param array $selector
  60732. * @param string $content
  60733. * @param mixed $actual
  60734. * @param bool $isHtml
  60735. * @return bool|array
  60736. * @since Method available since Release 3.3.0
  60737. */
  60738. public static function cssSelect($selector, $content, $actual, $isHtml = true)
  60739. {
  60740. $matcher = self::convertSelectToTag($selector, $content);
  60741. $dom = self::load($actual, $isHtml);
  60742. $tags = self::findNodes($dom, $matcher, $isHtml);
  60743. return $tags;
  60744. }
  60745. /**
  60746. * Parse out the options from the tag using DOM object tree.
  60747. *
  60748. * @param DOMDocument $dom
  60749. * @param array $options
  60750. * @param bool $isHtml
  60751. * @return array
  60752. * @since Method available since Release 3.3.0
  60753. */
  60754. public static function findNodes(DOMDocument $dom, array $options, $isHtml = true)
  60755. {
  60756. $valid = array(
  60757. 'id', 'class', 'tag', 'content', 'attributes', 'parent',
  60758. 'child', 'ancestor', 'descendant', 'children', 'adjacent-sibling'
  60759. );
  60760. $filtered = array();
  60761. $options = self::assertValidKeys($options, $valid);
  60762. // find the element by id
  60763. if ($options['id']) {
  60764. $options['attributes']['id'] = $options['id'];
  60765. }
  60766. if ($options['class']) {
  60767. $options['attributes']['class'] = $options['class'];
  60768. }
  60769. // find the element by a tag type
  60770. if ($options['tag']) {
  60771. if ($isHtml) {
  60772. $elements = self::getElementsByCaseInsensitiveTagName(
  60773. $dom,
  60774. $options['tag']
  60775. );
  60776. } else {
  60777. $elements = $dom->getElementsByTagName($options['tag']);
  60778. }
  60779. foreach ($elements as $element) {
  60780. $nodes[] = $element;
  60781. }
  60782. if (empty($nodes)) {
  60783. return false;
  60784. }
  60785. } // no tag selected, get them all
  60786. else {
  60787. $tags = array(
  60788. 'a', 'abbr', 'acronym', 'address', 'area', 'b', 'base', 'bdo',
  60789. 'big', 'blockquote', 'body', 'br', 'button', 'caption', 'cite',
  60790. 'code', 'col', 'colgroup', 'dd', 'del', 'div', 'dfn', 'dl',
  60791. 'dt', 'em', 'fieldset', 'form', 'frame', 'frameset', 'h1', 'h2',
  60792. 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html', 'i', 'iframe',
  60793. 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'link',
  60794. 'map', 'meta', 'noframes', 'noscript', 'object', 'ol', 'optgroup',
  60795. 'option', 'p', 'param', 'pre', 'q', 'samp', 'script', 'select',
  60796. 'small', 'span', 'strong', 'style', 'sub', 'sup', 'table',
  60797. 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'title',
  60798. 'tr', 'tt', 'ul', 'var',
  60799. // HTML5
  60800. 'article', 'aside', 'audio', 'bdi', 'canvas', 'command',
  60801. 'datalist', 'details', 'dialog', 'embed', 'figure', 'figcaption',
  60802. 'footer', 'header', 'hgroup', 'keygen', 'mark', 'meter', 'nav',
  60803. 'output', 'progress', 'ruby', 'rt', 'rp', 'track', 'section',
  60804. 'source', 'summary', 'time', 'video', 'wbr'
  60805. );
  60806. foreach ($tags as $tag) {
  60807. if ($isHtml) {
  60808. $elements = self::getElementsByCaseInsensitiveTagName(
  60809. $dom,
  60810. $tag
  60811. );
  60812. } else {
  60813. $elements = $dom->getElementsByTagName($tag);
  60814. }
  60815. foreach ($elements as $element) {
  60816. $nodes[] = $element;
  60817. }
  60818. }
  60819. if (empty($nodes)) {
  60820. return false;
  60821. }
  60822. }
  60823. // filter by attributes
  60824. if ($options['attributes']) {
  60825. foreach ($nodes as $node) {
  60826. $invalid = false;
  60827. foreach ($options['attributes'] as $name => $value) {
  60828. // match by regexp if like "regexp:/foo/i"
  60829. if (preg_match('/^regexp\s*:\s*(.*)/i', $value, $matches)) {
  60830. if (!preg_match($matches[1], $node->getAttribute($name))) {
  60831. $invalid = true;
  60832. }
  60833. } // class can match only a part
  60834. elseif ($name == 'class') {
  60835. // split to individual classes
  60836. $findClasses = explode(
  60837. ' ',
  60838. preg_replace("/\s+/", ' ', $value)
  60839. );
  60840. $allClasses = explode(
  60841. ' ',
  60842. preg_replace("/\s+/", ' ', $node->getAttribute($name))
  60843. );
  60844. // make sure each class given is in the actual node
  60845. foreach ($findClasses as $findClass) {
  60846. if (!in_array($findClass, $allClasses)) {
  60847. $invalid = true;
  60848. }
  60849. }
  60850. } // match by exact string
  60851. else {
  60852. if ($node->getAttribute($name) != $value) {
  60853. $invalid = true;
  60854. }
  60855. }
  60856. }
  60857. // if every attribute given matched
  60858. if (!$invalid) {
  60859. $filtered[] = $node;
  60860. }
  60861. }
  60862. $nodes = $filtered;
  60863. $filtered = array();
  60864. if (empty($nodes)) {
  60865. return false;
  60866. }
  60867. }
  60868. // filter by content
  60869. if ($options['content'] !== null) {
  60870. foreach ($nodes as $node) {
  60871. $invalid = false;
  60872. // match by regexp if like "regexp:/foo/i"
  60873. if (preg_match('/^regexp\s*:\s*(.*)/i', $options['content'], $matches)) {
  60874. if (!preg_match($matches[1], self::getNodeText($node))) {
  60875. $invalid = true;
  60876. }
  60877. } // match empty string
  60878. elseif ($options['content'] === '') {
  60879. if (self::getNodeText($node) !== '') {
  60880. $invalid = true;
  60881. }
  60882. } // match by exact string
  60883. elseif (strstr(self::getNodeText($node), $options['content']) === false) {
  60884. $invalid = true;
  60885. }
  60886. if (!$invalid) {
  60887. $filtered[] = $node;
  60888. }
  60889. }
  60890. $nodes = $filtered;
  60891. $filtered = array();
  60892. if (empty($nodes)) {
  60893. return false;
  60894. }
  60895. }
  60896. // filter by parent node
  60897. if ($options['parent']) {
  60898. $parentNodes = self::findNodes($dom, $options['parent'], $isHtml);
  60899. $parentNode = isset($parentNodes[0]) ? $parentNodes[0] : null;
  60900. foreach ($nodes as $node) {
  60901. if ($parentNode !== $node->parentNode) {
  60902. continue;
  60903. }
  60904. $filtered[] = $node;
  60905. }
  60906. $nodes = $filtered;
  60907. $filtered = array();
  60908. if (empty($nodes)) {
  60909. return false;
  60910. }
  60911. }
  60912. // filter by child node
  60913. if ($options['child']) {
  60914. $childNodes = self::findNodes($dom, $options['child'], $isHtml);
  60915. $childNodes = !empty($childNodes) ? $childNodes : array();
  60916. foreach ($nodes as $node) {
  60917. foreach ($node->childNodes as $child) {
  60918. foreach ($childNodes as $childNode) {
  60919. if ($childNode === $child) {
  60920. $filtered[] = $node;
  60921. }
  60922. }
  60923. }
  60924. }
  60925. $nodes = $filtered;
  60926. $filtered = array();
  60927. if (empty($nodes)) {
  60928. return false;
  60929. }
  60930. }
  60931. // filter by adjacent-sibling
  60932. if ($options['adjacent-sibling']) {
  60933. $adjacentSiblingNodes = self::findNodes($dom, $options['adjacent-sibling'], $isHtml);
  60934. $adjacentSiblingNodes = !empty($adjacentSiblingNodes) ? $adjacentSiblingNodes : array();
  60935. foreach ($nodes as $node) {
  60936. $sibling = $node;
  60937. while ($sibling = $sibling->nextSibling) {
  60938. if ($sibling->nodeType !== XML_ELEMENT_NODE) {
  60939. continue;
  60940. }
  60941. foreach ($adjacentSiblingNodes as $adjacentSiblingNode) {
  60942. if ($sibling === $adjacentSiblingNode) {
  60943. $filtered[] = $node;
  60944. break;
  60945. }
  60946. }
  60947. break;
  60948. }
  60949. }
  60950. $nodes = $filtered;
  60951. $filtered = array();
  60952. if (empty($nodes)) {
  60953. return false;
  60954. }
  60955. }
  60956. // filter by ancestor
  60957. if ($options['ancestor']) {
  60958. $ancestorNodes = self::findNodes($dom, $options['ancestor'], $isHtml);
  60959. $ancestorNode = isset($ancestorNodes[0]) ? $ancestorNodes[0] : null;
  60960. foreach ($nodes as $node) {
  60961. $parent = $node->parentNode;
  60962. while ($parent && $parent->nodeType != XML_HTML_DOCUMENT_NODE) {
  60963. if ($parent === $ancestorNode) {
  60964. $filtered[] = $node;
  60965. }
  60966. $parent = $parent->parentNode;
  60967. }
  60968. }
  60969. $nodes = $filtered;
  60970. $filtered = array();
  60971. if (empty($nodes)) {
  60972. return false;
  60973. }
  60974. }
  60975. // filter by descendant
  60976. if ($options['descendant']) {
  60977. $descendantNodes = self::findNodes($dom, $options['descendant'], $isHtml);
  60978. $descendantNodes = !empty($descendantNodes) ? $descendantNodes : array();
  60979. foreach ($nodes as $node) {
  60980. foreach (self::getDescendants($node) as $descendant) {
  60981. foreach ($descendantNodes as $descendantNode) {
  60982. if ($descendantNode === $descendant) {
  60983. $filtered[] = $node;
  60984. }
  60985. }
  60986. }
  60987. }
  60988. $nodes = $filtered;
  60989. $filtered = array();
  60990. if (empty($nodes)) {
  60991. return false;
  60992. }
  60993. }
  60994. // filter by children
  60995. if ($options['children']) {
  60996. $validChild = array('count', 'greater_than', 'less_than', 'only');
  60997. $childOptions = self::assertValidKeys(
  60998. $options['children'],
  60999. $validChild
  61000. );
  61001. foreach ($nodes as $node) {
  61002. $childNodes = $node->childNodes;
  61003. foreach ($childNodes as $childNode) {
  61004. if ($childNode->nodeType !== XML_CDATA_SECTION_NODE &&
  61005. $childNode->nodeType !== XML_TEXT_NODE) {
  61006. $children[] = $childNode;
  61007. }
  61008. }
  61009. // we must have children to pass this filter
  61010. if (!empty($children)) {
  61011. // exact count of children
  61012. if ($childOptions['count'] !== null) {
  61013. if (count($children) !== $childOptions['count']) {
  61014. break;
  61015. }
  61016. } // range count of children
  61017. elseif ($childOptions['less_than'] !== null &&
  61018. $childOptions['greater_than'] !== null) {
  61019. if (count($children) >= $childOptions['less_than'] ||
  61020. count($children) <= $childOptions['greater_than']) {
  61021. break;
  61022. }
  61023. } // less than a given count
  61024. elseif ($childOptions['less_than'] !== null) {
  61025. if (count($children) >= $childOptions['less_than']) {
  61026. break;
  61027. }
  61028. } // more than a given count
  61029. elseif ($childOptions['greater_than'] !== null) {
  61030. if (count($children) <= $childOptions['greater_than']) {
  61031. break;
  61032. }
  61033. }
  61034. // match each child against a specific tag
  61035. if ($childOptions['only']) {
  61036. $onlyNodes = self::findNodes(
  61037. $dom,
  61038. $childOptions['only'],
  61039. $isHtml
  61040. );
  61041. // try to match each child to one of the 'only' nodes
  61042. foreach ($children as $child) {
  61043. $matched = false;
  61044. foreach ($onlyNodes as $onlyNode) {
  61045. if ($onlyNode === $child) {
  61046. $matched = true;
  61047. }
  61048. }
  61049. if (!$matched) {
  61050. break 2;
  61051. }
  61052. }
  61053. }
  61054. $filtered[] = $node;
  61055. }
  61056. }
  61057. $nodes = $filtered;
  61058. if (empty($nodes)) {
  61059. return;
  61060. }
  61061. }
  61062. // return the first node that matches all criteria
  61063. return !empty($nodes) ? $nodes : array();
  61064. }
  61065. /**
  61066. * Recursively get flat array of all descendants of this node.
  61067. *
  61068. * @param DOMNode $node
  61069. * @return array
  61070. * @since Method available since Release 3.3.0
  61071. */
  61072. protected static function getDescendants(DOMNode $node)
  61073. {
  61074. $allChildren = array();
  61075. $childNodes = $node->childNodes ? $node->childNodes : array();
  61076. foreach ($childNodes as $child) {
  61077. if ($child->nodeType === XML_CDATA_SECTION_NODE ||
  61078. $child->nodeType === XML_TEXT_NODE) {
  61079. continue;
  61080. }
  61081. $children = self::getDescendants($child);
  61082. $allChildren = array_merge($allChildren, $children, array($child));
  61083. }
  61084. return isset($allChildren) ? $allChildren : array();
  61085. }
  61086. /**
  61087. * Gets elements by case insensitive tagname.
  61088. *
  61089. * @param DOMDocument $dom
  61090. * @param string $tag
  61091. * @return DOMNodeList
  61092. * @since Method available since Release 3.4.0
  61093. */
  61094. protected static function getElementsByCaseInsensitiveTagName(DOMDocument $dom, $tag)
  61095. {
  61096. $elements = $dom->getElementsByTagName(strtolower($tag));
  61097. if ($elements->length == 0) {
  61098. $elements = $dom->getElementsByTagName(strtoupper($tag));
  61099. }
  61100. return $elements;
  61101. }
  61102. /**
  61103. * Get the text value of this node's child text node.
  61104. *
  61105. * @param DOMNode $node
  61106. * @return string
  61107. * @since Method available since Release 3.3.0
  61108. */
  61109. protected static function getNodeText(DOMNode $node)
  61110. {
  61111. if (!$node->childNodes instanceof DOMNodeList) {
  61112. return '';
  61113. }
  61114. $result = '';
  61115. foreach ($node->childNodes as $childNode) {
  61116. if ($childNode->nodeType === XML_TEXT_NODE ||
  61117. $childNode->nodeType === XML_CDATA_SECTION_NODE) {
  61118. $result .= trim($childNode->data) . ' ';
  61119. } else {
  61120. $result .= self::getNodeText($childNode);
  61121. }
  61122. }
  61123. return str_replace(' ', ' ', $result);
  61124. }
  61125. }
  61126. <?php
  61127. /*
  61128. * This file is part of PHPUnit.
  61129. *
  61130. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61131. *
  61132. * For the full copyright and license information, please view the LICENSE
  61133. * file that was distributed with this source code.
  61134. */
  61135. /**
  61136. * Utility methods for PHP sub-processes.
  61137. *
  61138. * @since Class available since Release 3.4.0
  61139. */
  61140. abstract class PHPUnit_Util_PHP
  61141. {
  61142. /**
  61143. * @return PHPUnit_Util_PHP
  61144. * @since Method available since Release 3.5.12
  61145. */
  61146. public static function factory()
  61147. {
  61148. if (DIRECTORY_SEPARATOR == '\\') {
  61149. return new PHPUnit_Util_PHP_Windows;
  61150. }
  61151. return new PHPUnit_Util_PHP_Default;
  61152. }
  61153. /**
  61154. * Runs a single test in a separate PHP process.
  61155. *
  61156. * @param string $job
  61157. * @param PHPUnit_Framework_Test $test
  61158. * @param PHPUnit_Framework_TestResult $result
  61159. * @throws PHPUnit_Framework_Exception
  61160. */
  61161. public function runTestJob($job, PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result)
  61162. {
  61163. $result->startTest($test);
  61164. $_result = $this->runJob($job);
  61165. $this->processChildResult(
  61166. $test,
  61167. $result,
  61168. $_result['stdout'],
  61169. $_result['stderr']
  61170. );
  61171. }
  61172. /**
  61173. * Runs a single job (PHP code) using a separate PHP process.
  61174. *
  61175. * @param string $job
  61176. * @param array $settings
  61177. * @return array
  61178. * @throws PHPUnit_Framework_Exception
  61179. */
  61180. abstract public function runJob($job, array $settings = array());
  61181. /**
  61182. * @param array $settings
  61183. * @return string
  61184. * @since Method available since Release 4.0.0
  61185. */
  61186. protected function settingsToParameters(array $settings)
  61187. {
  61188. $buffer = '';
  61189. foreach ($settings as $setting) {
  61190. $buffer .= ' -d ' . $setting;
  61191. }
  61192. return $buffer;
  61193. }
  61194. /**
  61195. * Processes the TestResult object from an isolated process.
  61196. *
  61197. * @param PHPUnit_Framework_Test $test
  61198. * @param PHPUnit_Framework_TestResult $result
  61199. * @param string $stdout
  61200. * @param string $stderr
  61201. * @since Method available since Release 3.5.0
  61202. */
  61203. private function processChildResult(PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result, $stdout, $stderr)
  61204. {
  61205. $time = 0;
  61206. if (!empty($stderr)) {
  61207. $result->addError(
  61208. $test,
  61209. new PHPUnit_Framework_Exception(trim($stderr)),
  61210. $time
  61211. );
  61212. } else {
  61213. set_error_handler(function ($errno, $errstr, $errfile, $errline) {
  61214. throw new ErrorException($errstr, $errno, $errno, $errfile, $errline);
  61215. });
  61216. try {
  61217. if (strpos($stdout, "#!/usr/bin/env php\n") === 0) {
  61218. $stdout = substr($stdout, 19);
  61219. }
  61220. $childResult = unserialize(str_replace("#!/usr/bin/env php\n", '', $stdout));
  61221. restore_error_handler();
  61222. } catch (ErrorException $e) {
  61223. restore_error_handler();
  61224. $childResult = false;
  61225. $result->addError(
  61226. $test,
  61227. new PHPUnit_Framework_Exception(trim($stdout), 0, $e),
  61228. $time
  61229. );
  61230. }
  61231. if ($childResult !== false) {
  61232. if (!empty($childResult['output'])) {
  61233. $output = $childResult['output'];
  61234. }
  61235. $test->setResult($childResult['testResult']);
  61236. $test->addToAssertionCount($childResult['numAssertions']);
  61237. $childResult = $childResult['result'];
  61238. if ($result->getCollectCodeCoverageInformation()) {
  61239. $result->getCodeCoverage()->merge(
  61240. $childResult->getCodeCoverage()
  61241. );
  61242. }
  61243. $time = $childResult->time();
  61244. $notImplemented = $childResult->notImplemented();
  61245. $risky = $childResult->risky();
  61246. $skipped = $childResult->skipped();
  61247. $errors = $childResult->errors();
  61248. $failures = $childResult->failures();
  61249. if (!empty($notImplemented)) {
  61250. $result->addError(
  61251. $test,
  61252. $this->getException($notImplemented[0]),
  61253. $time
  61254. );
  61255. } elseif (!empty($risky)) {
  61256. $result->addError(
  61257. $test,
  61258. $this->getException($risky[0]),
  61259. $time
  61260. );
  61261. } elseif (!empty($skipped)) {
  61262. $result->addError(
  61263. $test,
  61264. $this->getException($skipped[0]),
  61265. $time
  61266. );
  61267. } elseif (!empty($errors)) {
  61268. $result->addError(
  61269. $test,
  61270. $this->getException($errors[0]),
  61271. $time
  61272. );
  61273. } elseif (!empty($failures)) {
  61274. $result->addFailure(
  61275. $test,
  61276. $this->getException($failures[0]),
  61277. $time
  61278. );
  61279. }
  61280. }
  61281. }
  61282. $result->endTest($test, $time);
  61283. if (!empty($output)) {
  61284. print $output;
  61285. }
  61286. }
  61287. /**
  61288. * Gets the thrown exception from a PHPUnit_Framework_TestFailure.
  61289. *
  61290. * @param PHPUnit_Framework_TestFailure $error
  61291. * @return Exception
  61292. * @since Method available since Release 3.6.0
  61293. * @see https://github.com/sebastianbergmann/phpunit/issues/74
  61294. */
  61295. private function getException(PHPUnit_Framework_TestFailure $error)
  61296. {
  61297. $exception = $error->thrownException();
  61298. if ($exception instanceof __PHP_Incomplete_Class) {
  61299. $exceptionArray = array();
  61300. foreach ((array) $exception as $key => $value) {
  61301. $key = substr($key, strrpos($key, "\0") + 1);
  61302. $exceptionArray[$key] = $value;
  61303. }
  61304. $exception = new PHPUnit_Framework_SyntheticError(
  61305. sprintf(
  61306. '%s: %s',
  61307. $exceptionArray['_PHP_Incomplete_Class_Name'],
  61308. $exceptionArray['message']
  61309. ),
  61310. $exceptionArray['code'],
  61311. $exceptionArray['file'],
  61312. $exceptionArray['line'],
  61313. $exceptionArray['trace']
  61314. );
  61315. }
  61316. return $exception;
  61317. }
  61318. }
  61319. <?php
  61320. /*
  61321. * This file is part of PHPUnit.
  61322. *
  61323. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61324. *
  61325. * For the full copyright and license information, please view the LICENSE
  61326. * file that was distributed with this source code.
  61327. */
  61328. /**
  61329. * @since Class available since Release 4.0.0
  61330. */
  61331. class PHPUnit_Runner_Exception extends RuntimeException implements PHPUnit_Exception
  61332. {
  61333. }
  61334. <?php
  61335. /*
  61336. * This file is part of PHPUnit.
  61337. *
  61338. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61339. *
  61340. * For the full copyright and license information, please view the LICENSE
  61341. * file that was distributed with this source code.
  61342. */
  61343. /**
  61344. * @since Class available since Release 4.0.0
  61345. */
  61346. class PHPUnit_Runner_Filter_Test extends RecursiveFilterIterator
  61347. {
  61348. /**
  61349. * @var string
  61350. */
  61351. protected $filter = null;
  61352. /**
  61353. * @var int
  61354. */
  61355. protected $filterMin;
  61356. /**
  61357. * @var int
  61358. */
  61359. protected $filterMax;
  61360. /**
  61361. * @param RecursiveIterator $iterator
  61362. * @param string $filter
  61363. */
  61364. public function __construct(RecursiveIterator $iterator, $filter)
  61365. {
  61366. parent::__construct($iterator);
  61367. $this->setFilter($filter);
  61368. }
  61369. /**
  61370. * @param string $filter
  61371. */
  61372. protected function setFilter($filter)
  61373. {
  61374. if (PHPUnit_Util_Regex::pregMatchSafe($filter, '') === false) {
  61375. // Handles:
  61376. // * testAssertEqualsSucceeds#4
  61377. // * testAssertEqualsSucceeds#4-8
  61378. if (preg_match('/^(.*?)#(\d+)(?:-(\d+))?$/', $filter, $matches)) {
  61379. if (isset($matches[3]) && $matches[2] < $matches[3]) {
  61380. $filter = sprintf(
  61381. '%s.*with data set #(\d+)$',
  61382. $matches[1]
  61383. );
  61384. $this->filterMin = $matches[2];
  61385. $this->filterMax = $matches[3];
  61386. } else {
  61387. $filter = sprintf(
  61388. '%s.*with data set #%s$',
  61389. $matches[1],
  61390. $matches[2]
  61391. );
  61392. }
  61393. } // Handles:
  61394. // * testDetermineJsonError@JSON_ERROR_NONE
  61395. // * testDetermineJsonError@JSON.*
  61396. elseif (preg_match('/^(.*?)@(.+)$/', $filter, $matches)) {
  61397. $filter = sprintf(
  61398. '%s.*with data set "%s"$',
  61399. $matches[1],
  61400. $matches[2]
  61401. );
  61402. }
  61403. // Escape delimiters in regular expression. Do NOT use preg_quote,
  61404. // to keep magic characters.
  61405. $filter = sprintf('/%s/', str_replace(
  61406. '/',
  61407. '\\/',
  61408. $filter
  61409. ));
  61410. }
  61411. $this->filter = $filter;
  61412. }
  61413. /**
  61414. * @return bool
  61415. */
  61416. public function accept()
  61417. {
  61418. $test = $this->getInnerIterator()->current();
  61419. if ($test instanceof PHPUnit_Framework_TestSuite) {
  61420. return true;
  61421. }
  61422. $tmp = PHPUnit_Util_Test::describe($test, false);
  61423. if ($tmp[0] != '') {
  61424. $name = implode('::', $tmp);
  61425. } else {
  61426. $name = $tmp[1];
  61427. }
  61428. $accepted = preg_match($this->filter, $name, $matches);
  61429. if ($accepted && isset($this->filterMax)) {
  61430. $set = end($matches);
  61431. $accepted = $set >= $this->filterMin && $set <= $this->filterMax;
  61432. }
  61433. return $accepted;
  61434. }
  61435. }
  61436. <?php
  61437. /*
  61438. * This file is part of PHPUnit.
  61439. *
  61440. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61441. *
  61442. * For the full copyright and license information, please view the LICENSE
  61443. * file that was distributed with this source code.
  61444. */
  61445. /**
  61446. * @since Class available since Release 4.0.0
  61447. */
  61448. class PHPUnit_Runner_Filter_Group_Exclude extends PHPUnit_Runner_Filter_GroupFilterIterator
  61449. {
  61450. protected function doAccept($hash)
  61451. {
  61452. return !in_array($hash, $this->groupTests);
  61453. }
  61454. }
  61455. <?php
  61456. /*
  61457. * This file is part of PHPUnit.
  61458. *
  61459. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61460. *
  61461. * For the full copyright and license information, please view the LICENSE
  61462. * file that was distributed with this source code.
  61463. */
  61464. /**
  61465. * @since Class available since Release 4.0.0
  61466. */
  61467. class PHPUnit_Runner_Filter_Group_Include extends PHPUnit_Runner_Filter_GroupFilterIterator
  61468. {
  61469. protected function doAccept($hash)
  61470. {
  61471. return in_array($hash, $this->groupTests);
  61472. }
  61473. }
  61474. <?php
  61475. /*
  61476. * This file is part of PHPUnit.
  61477. *
  61478. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61479. *
  61480. * For the full copyright and license information, please view the LICENSE
  61481. * file that was distributed with this source code.
  61482. */
  61483. /**
  61484. * @since Class available since Release 4.0.0
  61485. */
  61486. class PHPUnit_Runner_Filter_Factory
  61487. {
  61488. /**
  61489. * @var array
  61490. */
  61491. private $filters = array();
  61492. /**
  61493. * @param ReflectionClass $filter
  61494. * @param mixed $args
  61495. */
  61496. public function addFilter(ReflectionClass $filter, $args)
  61497. {
  61498. if (!$filter->isSubclassOf('RecursiveFilterIterator')) {
  61499. throw new InvalidArgumentException(
  61500. sprintf(
  61501. 'Class "%s" does not extend RecursiveFilterIterator',
  61502. $filter->name
  61503. )
  61504. );
  61505. }
  61506. $this->filters[] = array($filter, $args);
  61507. }
  61508. /**
  61509. * @return FilterIterator
  61510. */
  61511. public function factory(Iterator $iterator, PHPUnit_Framework_TestSuite $suite)
  61512. {
  61513. foreach ($this->filters as $filter) {
  61514. list($class, $args) = $filter;
  61515. $iterator = $class->newInstance($iterator, $args, $suite);
  61516. }
  61517. return $iterator;
  61518. }
  61519. }
  61520. <?php
  61521. /*
  61522. * This file is part of PHPUnit.
  61523. *
  61524. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61525. *
  61526. * For the full copyright and license information, please view the LICENSE
  61527. * file that was distributed with this source code.
  61528. */
  61529. /**
  61530. * @since Class available since Release 4.0.0
  61531. */
  61532. abstract class PHPUnit_Runner_Filter_GroupFilterIterator extends RecursiveFilterIterator
  61533. {
  61534. /**
  61535. * @var array
  61536. */
  61537. protected $groupTests = array();
  61538. /**
  61539. * @param RecursiveIterator $iterator
  61540. * @param array $groups
  61541. * @param PHPUnit_Framework_TestSuite $suite
  61542. */
  61543. public function __construct(RecursiveIterator $iterator, array $groups, PHPUnit_Framework_TestSuite $suite)
  61544. {
  61545. parent::__construct($iterator);
  61546. foreach ($suite->getGroupDetails() as $group => $tests) {
  61547. if (in_array($group, $groups)) {
  61548. $testHashes = array_map(
  61549. function ($test) {
  61550. return spl_object_hash($test);
  61551. },
  61552. $tests
  61553. );
  61554. $this->groupTests = array_merge($this->groupTests, $testHashes);
  61555. }
  61556. }
  61557. }
  61558. /**
  61559. * @return bool
  61560. */
  61561. public function accept()
  61562. {
  61563. $test = $this->getInnerIterator()->current();
  61564. if ($test instanceof PHPUnit_Framework_TestSuite) {
  61565. return true;
  61566. }
  61567. return $this->doAccept(spl_object_hash($test));
  61568. }
  61569. abstract protected function doAccept($hash);
  61570. }
  61571. <?php
  61572. /*
  61573. * This file is part of PHPUnit.
  61574. *
  61575. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61576. *
  61577. * For the full copyright and license information, please view the LICENSE
  61578. * file that was distributed with this source code.
  61579. */
  61580. /**
  61581. * An interface to define how a test suite should be loaded.
  61582. *
  61583. * @since Interface available since Release 2.0.0
  61584. */
  61585. interface PHPUnit_Runner_TestSuiteLoader
  61586. {
  61587. /**
  61588. * @param string $suiteClassName
  61589. * @param string $suiteClassFile
  61590. * @return ReflectionClass
  61591. */
  61592. public function load($suiteClassName, $suiteClassFile = '');
  61593. /**
  61594. * @param ReflectionClass $aClass
  61595. * @return ReflectionClass
  61596. */
  61597. public function reload(ReflectionClass $aClass);
  61598. }
  61599. <?php
  61600. /*
  61601. * This file is part of PHPUnit.
  61602. *
  61603. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61604. *
  61605. * For the full copyright and license information, please view the LICENSE
  61606. * file that was distributed with this source code.
  61607. */
  61608. /**
  61609. * Base class for all test runners.
  61610. *
  61611. * @since Class available since Release 2.0.0
  61612. */
  61613. abstract class PHPUnit_Runner_BaseTestRunner
  61614. {
  61615. const STATUS_PASSED = 0;
  61616. const STATUS_SKIPPED = 1;
  61617. const STATUS_INCOMPLETE = 2;
  61618. const STATUS_FAILURE = 3;
  61619. const STATUS_ERROR = 4;
  61620. const STATUS_RISKY = 5;
  61621. const SUITE_METHODNAME = 'suite';
  61622. /**
  61623. * Returns the loader to be used.
  61624. *
  61625. * @return PHPUnit_Runner_TestSuiteLoader
  61626. */
  61627. public function getLoader()
  61628. {
  61629. return new PHPUnit_Runner_StandardTestSuiteLoader;
  61630. }
  61631. /**
  61632. * Returns the Test corresponding to the given suite.
  61633. * This is a template method, subclasses override
  61634. * the runFailed() and clearStatus() methods.
  61635. *
  61636. * @param string $suiteClassName
  61637. * @param string $suiteClassFile
  61638. * @param mixed $suffixes
  61639. * @return PHPUnit_Framework_Test
  61640. */
  61641. public function getTest($suiteClassName, $suiteClassFile = '', $suffixes = '')
  61642. {
  61643. if (is_dir($suiteClassName) &&
  61644. !is_file($suiteClassName . '.php') && empty($suiteClassFile)) {
  61645. $facade = new File_Iterator_Facade;
  61646. $files = $facade->getFilesAsArray(
  61647. $suiteClassName,
  61648. $suffixes
  61649. );
  61650. $suite = new PHPUnit_Framework_TestSuite($suiteClassName);
  61651. $suite->addTestFiles($files);
  61652. return $suite;
  61653. }
  61654. try {
  61655. $testClass = $this->loadSuiteClass(
  61656. $suiteClassName,
  61657. $suiteClassFile
  61658. );
  61659. } catch (PHPUnit_Framework_Exception $e) {
  61660. $this->runFailed($e->getMessage());
  61661. return;
  61662. }
  61663. try {
  61664. $suiteMethod = $testClass->getMethod(self::SUITE_METHODNAME);
  61665. if (!$suiteMethod->isStatic()) {
  61666. $this->runFailed(
  61667. 'suite() method must be static.'
  61668. );
  61669. return;
  61670. }
  61671. try {
  61672. $test = $suiteMethod->invoke(null, $testClass->getName());
  61673. } catch (ReflectionException $e) {
  61674. $this->runFailed(
  61675. sprintf(
  61676. "Failed to invoke suite() method.\n%s",
  61677. $e->getMessage()
  61678. )
  61679. );
  61680. return;
  61681. }
  61682. } catch (ReflectionException $e) {
  61683. try {
  61684. $test = new PHPUnit_Framework_TestSuite($testClass);
  61685. } catch (PHPUnit_Framework_Exception $e) {
  61686. $test = new PHPUnit_Framework_TestSuite;
  61687. $test->setName($suiteClassName);
  61688. }
  61689. }
  61690. $this->clearStatus();
  61691. return $test;
  61692. }
  61693. /**
  61694. * Returns the loaded ReflectionClass for a suite name.
  61695. *
  61696. * @param string $suiteClassName
  61697. * @param string $suiteClassFile
  61698. * @return ReflectionClass
  61699. */
  61700. protected function loadSuiteClass($suiteClassName, $suiteClassFile = '')
  61701. {
  61702. $loader = $this->getLoader();
  61703. return $loader->load($suiteClassName, $suiteClassFile);
  61704. }
  61705. /**
  61706. * Clears the status message.
  61707. */
  61708. protected function clearStatus()
  61709. {
  61710. }
  61711. /**
  61712. * Override to define how to handle a failed loading of
  61713. * a test suite.
  61714. *
  61715. * @param string $message
  61716. */
  61717. abstract protected function runFailed($message);
  61718. }
  61719. <?php
  61720. /*
  61721. * This file is part of PHPUnit.
  61722. *
  61723. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61724. *
  61725. * For the full copyright and license information, please view the LICENSE
  61726. * file that was distributed with this source code.
  61727. */
  61728. /**
  61729. * The standard test suite loader.
  61730. *
  61731. * @since Class available since Release 2.0.0
  61732. */
  61733. class PHPUnit_Runner_StandardTestSuiteLoader implements PHPUnit_Runner_TestSuiteLoader
  61734. {
  61735. /**
  61736. * @param string $suiteClassName
  61737. * @param string $suiteClassFile
  61738. * @return ReflectionClass
  61739. * @throws PHPUnit_Framework_Exception
  61740. */
  61741. public function load($suiteClassName, $suiteClassFile = '')
  61742. {
  61743. $suiteClassName = str_replace('.php', '', $suiteClassName);
  61744. if (empty($suiteClassFile)) {
  61745. $suiteClassFile = PHPUnit_Util_Filesystem::classNameToFilename(
  61746. $suiteClassName
  61747. );
  61748. }
  61749. if (!class_exists($suiteClassName, false)) {
  61750. $loadedClasses = get_declared_classes();
  61751. $filename = PHPUnit_Util_Fileloader::checkAndLoad($suiteClassFile);
  61752. $loadedClasses = array_values(
  61753. array_diff(get_declared_classes(), $loadedClasses)
  61754. );
  61755. }
  61756. if (!class_exists($suiteClassName, false) && !empty($loadedClasses)) {
  61757. $offset = 0 - strlen($suiteClassName);
  61758. foreach ($loadedClasses as $loadedClass) {
  61759. $class = new ReflectionClass($loadedClass);
  61760. if (substr($loadedClass, $offset) === $suiteClassName &&
  61761. $class->getFileName() == $filename) {
  61762. $suiteClassName = $loadedClass;
  61763. break;
  61764. }
  61765. }
  61766. }
  61767. if (!class_exists($suiteClassName, false) && !empty($loadedClasses)) {
  61768. $testCaseClass = 'PHPUnit_Framework_TestCase';
  61769. foreach ($loadedClasses as $loadedClass) {
  61770. $class = new ReflectionClass($loadedClass);
  61771. $classFile = $class->getFileName();
  61772. if ($class->isSubclassOf($testCaseClass) &&
  61773. !$class->isAbstract()) {
  61774. $suiteClassName = $loadedClass;
  61775. $testCaseClass = $loadedClass;
  61776. if ($classFile == realpath($suiteClassFile)) {
  61777. break;
  61778. }
  61779. }
  61780. if ($class->hasMethod('suite')) {
  61781. $method = $class->getMethod('suite');
  61782. if (!$method->isAbstract() &&
  61783. $method->isPublic() &&
  61784. $method->isStatic()) {
  61785. $suiteClassName = $loadedClass;
  61786. if ($classFile == realpath($suiteClassFile)) {
  61787. break;
  61788. }
  61789. }
  61790. }
  61791. }
  61792. }
  61793. if (class_exists($suiteClassName, false)) {
  61794. $class = new ReflectionClass($suiteClassName);
  61795. if ($class->getFileName() == realpath($suiteClassFile)) {
  61796. return $class;
  61797. }
  61798. }
  61799. throw new PHPUnit_Framework_Exception(
  61800. sprintf(
  61801. "Class '%s' could not be found in '%s'.",
  61802. $suiteClassName,
  61803. $suiteClassFile
  61804. )
  61805. );
  61806. }
  61807. /**
  61808. * @param ReflectionClass $aClass
  61809. * @return ReflectionClass
  61810. */
  61811. public function reload(ReflectionClass $aClass)
  61812. {
  61813. return $aClass;
  61814. }
  61815. }
  61816. <?php
  61817. /*
  61818. * This file is part of PHPUnit.
  61819. *
  61820. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61821. *
  61822. * For the full copyright and license information, please view the LICENSE
  61823. * file that was distributed with this source code.
  61824. */
  61825. /**
  61826. * This class defines the current version of PHPUnit.
  61827. *
  61828. * @since Class available since Release 2.0.0
  61829. */
  61830. class PHPUnit_Runner_Version
  61831. {
  61832. private static $pharVersion = "4.7.7";
  61833. private static $version;
  61834. /**
  61835. * Returns the current version of PHPUnit.
  61836. *
  61837. * @return string
  61838. */
  61839. public static function id()
  61840. {
  61841. if (self::$pharVersion !== null) {
  61842. return self::$pharVersion;
  61843. }
  61844. if (self::$version === null) {
  61845. $version = new SebastianBergmann\Version('4.7.7', dirname(dirname(__DIR__)));
  61846. self::$version = $version->getVersion();
  61847. }
  61848. return self::$version;
  61849. }
  61850. /**
  61851. * @return string
  61852. */
  61853. public static function getVersionString()
  61854. {
  61855. return 'PHPUnit ' . self::id() . ' by Sebastian Bergmann and contributors.';
  61856. }
  61857. /**
  61858. * @return string
  61859. * @since Method available since Release 4.0.0
  61860. */
  61861. public static function getReleaseChannel()
  61862. {
  61863. if (strpos(self::$pharVersion, 'alpha') !== false) {
  61864. return '-alpha';
  61865. }
  61866. if (strpos(self::$pharVersion, 'beta') !== false) {
  61867. return '-beta';
  61868. }
  61869. return '';
  61870. }
  61871. }
  61872. Environment
  61873. Copyright (c) 2014-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  61874. All rights reserved.
  61875. Redistribution and use in source and binary forms, with or without
  61876. modification, are permitted provided that the following conditions
  61877. are met:
  61878. * Redistributions of source code must retain the above copyright
  61879. notice, this list of conditions and the following disclaimer.
  61880. * Redistributions in binary form must reproduce the above copyright
  61881. notice, this list of conditions and the following disclaimer in
  61882. the documentation and/or other materials provided with the
  61883. distribution.
  61884. * Neither the name of Sebastian Bergmann nor the names of his
  61885. contributors may be used to endorse or promote products derived
  61886. from this software without specific prior written permission.
  61887. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  61888. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  61889. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  61890. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  61891. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  61892. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  61893. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  61894. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  61895. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  61896. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  61897. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  61898. POSSIBILITY OF SUCH DAMAGE.
  61899. <?php
  61900. /*
  61901. * This file is part of the Environment package.
  61902. *
  61903. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  61904. *
  61905. * For the full copyright and license information, please view the LICENSE
  61906. * file that was distributed with this source code.
  61907. */
  61908. namespace SebastianBergmann\Environment;
  61909. /**
  61910. * Utility class for HHVM/PHP environment handling.
  61911. *
  61912. * @package Environment
  61913. * @author Sebastian Bergmann <sebastian@phpunit.de>
  61914. * @copyright Sebastian Bergmann <sebastian@phpunit.de>
  61915. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  61916. * @link http://www.github.com/sebastianbergmann/environment
  61917. */
  61918. class Runtime
  61919. {
  61920. /**
  61921. * @var string
  61922. */
  61923. private static $binary;
  61924. /**
  61925. * Returns true when the runtime used is HHVM or
  61926. * the runtime used is PHP + Xdebug.
  61927. *
  61928. * @return boolean
  61929. */
  61930. public function canCollectCodeCoverage()
  61931. {
  61932. return $this->isHHVM() || $this->hasXdebug();
  61933. }
  61934. /**
  61935. * Returns the path to the binary of the current runtime.
  61936. * Appends ' --php' to the path when the runtime is HHVM.
  61937. *
  61938. * @return string
  61939. */
  61940. public function getBinary()
  61941. {
  61942. // HHVM
  61943. if (self::$binary === null && $this->isHHVM()) {
  61944. if ((self::$binary = getenv('PHP_BINARY')) === false) {
  61945. self::$binary = PHP_BINARY;
  61946. }
  61947. self::$binary = escapeshellarg(self::$binary) . ' --php';
  61948. }
  61949. // PHP >= 5.4.0
  61950. if (self::$binary === null && defined('PHP_BINARY')) {
  61951. self::$binary = escapeshellarg(PHP_BINARY);
  61952. }
  61953. // PHP < 5.4.0
  61954. if (self::$binary === null) {
  61955. if (PHP_SAPI == 'cli' && isset($_SERVER['_'])) {
  61956. if (strpos($_SERVER['_'], 'phpunit') !== false) {
  61957. $file = file($_SERVER['_']);
  61958. if (strpos($file[0], ' ') !== false) {
  61959. $tmp = explode(' ', $file[0]);
  61960. self::$binary = escapeshellarg(trim($tmp[1]));
  61961. } else {
  61962. self::$binary = escapeshellarg(ltrim(trim($file[0]), '#!'));
  61963. }
  61964. } elseif (strpos(basename($_SERVER['_']), 'php') !== false) {
  61965. self::$binary = escapeshellarg($_SERVER['_']);
  61966. }
  61967. }
  61968. }
  61969. if (self::$binary === null) {
  61970. $possibleBinaryLocations = array(
  61971. PHP_BINDIR . '/php',
  61972. PHP_BINDIR . '/php-cli.exe',
  61973. PHP_BINDIR . '/php.exe'
  61974. );
  61975. foreach ($possibleBinaryLocations as $binary) {
  61976. if (is_readable($binary)) {
  61977. self::$binary = escapeshellarg($binary);
  61978. break;
  61979. }
  61980. }
  61981. }
  61982. if (self::$binary === null) {
  61983. self::$binary = 'php';
  61984. }
  61985. return self::$binary;
  61986. }
  61987. /**
  61988. * @return string
  61989. */
  61990. public function getNameWithVersion()
  61991. {
  61992. return $this->getName() . ' ' . $this->getVersion();
  61993. }
  61994. /**
  61995. * @return string
  61996. */
  61997. public function getName()
  61998. {
  61999. if ($this->isHHVM()) {
  62000. return 'HHVM';
  62001. } else {
  62002. return 'PHP';
  62003. }
  62004. }
  62005. /**
  62006. * @return string
  62007. */
  62008. public function getVendorUrl()
  62009. {
  62010. if ($this->isHHVM()) {
  62011. return 'http://hhvm.com/';
  62012. } else {
  62013. return 'http://php.net/';
  62014. }
  62015. }
  62016. /**
  62017. * @return string
  62018. */
  62019. public function getVersion()
  62020. {
  62021. if ($this->isHHVM()) {
  62022. return HHVM_VERSION;
  62023. } else {
  62024. return PHP_VERSION;
  62025. }
  62026. }
  62027. /**
  62028. * Returns true when the runtime used is PHP and Xdebug is loaded.
  62029. *
  62030. * @return boolean
  62031. */
  62032. public function hasXdebug()
  62033. {
  62034. return $this->isPHP() && extension_loaded('xdebug');
  62035. }
  62036. /**
  62037. * Returns true when the runtime used is HHVM.
  62038. *
  62039. * @return boolean
  62040. */
  62041. public function isHHVM()
  62042. {
  62043. return defined('HHVM_VERSION');
  62044. }
  62045. /**
  62046. * Returns true when the runtime used is PHP.
  62047. *
  62048. * @return boolean
  62049. */
  62050. public function isPHP()
  62051. {
  62052. return !$this->isHHVM();
  62053. }
  62054. }
  62055. <?php
  62056. /*
  62057. * This file is part of the Environment package.
  62058. *
  62059. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  62060. *
  62061. * For the full copyright and license information, please view the LICENSE
  62062. * file that was distributed with this source code.
  62063. */
  62064. namespace SebastianBergmann\Environment;
  62065. /**
  62066. * @package Environment
  62067. * @author Sebastian Bergmann <sebastian@phpunit.de>
  62068. * @copyright 2014 Sebastian Bergmann <sebastian@phpunit.de>
  62069. * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
  62070. * @link http://www.github.com/sebastianbergmann/environment
  62071. */
  62072. class Console
  62073. {
  62074. const STDIN = 0;
  62075. const STDOUT = 1;
  62076. const STDERR = 2;
  62077. /**
  62078. * Returns true if STDOUT supports colorization.
  62079. *
  62080. * This code has been copied and adapted from
  62081. * Symfony\Component\Console\Output\OutputStream.
  62082. *
  62083. * @return boolean
  62084. */
  62085. public function hasColorSupport()
  62086. {
  62087. if (DIRECTORY_SEPARATOR == '\\') {
  62088. return false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI');
  62089. }
  62090. if (!defined('STDOUT')) {
  62091. return false;
  62092. }
  62093. return $this->isInteractive(STDOUT);
  62094. }
  62095. /**
  62096. * Returns the number of columns of the terminal.
  62097. *
  62098. * @return integer
  62099. */
  62100. public function getNumberOfColumns()
  62101. {
  62102. // Windows terminals have a fixed size of 80
  62103. // but one column is used for the cursor.
  62104. if (DIRECTORY_SEPARATOR == '\\') {
  62105. return 79;
  62106. }
  62107. if (!$this->isInteractive(self::STDIN)) {
  62108. return 80;
  62109. }
  62110. if (preg_match('#\d+ (\d+)#', shell_exec('stty size'), $match) === 1) {
  62111. return (int) $match[1];
  62112. }
  62113. if (preg_match('#columns = (\d+);#', shell_exec('stty'), $match) === 1) {
  62114. return (int) $match[1];
  62115. }
  62116. return 80;
  62117. }
  62118. /**
  62119. * Returns if the file descriptor is an interactive terminal or not.
  62120. *
  62121. * @param int|resource $fileDescriptor
  62122. *
  62123. * @return boolean
  62124. */
  62125. public function isInteractive($fileDescriptor = self::STDOUT)
  62126. {
  62127. return function_exists('posix_isatty') && @posix_isatty($fileDescriptor);
  62128. }
  62129. }
  62130. The MIT License (MIT)
  62131. Copyright (c) 2010 Mike van Riel
  62132. Permission is hereby granted, free of charge, to any person obtaining a copy
  62133. of this software and associated documentation files (the "Software"), to deal
  62134. in the Software without restriction, including without limitation the rights
  62135. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  62136. copies of the Software, and to permit persons to whom the Software is
  62137. furnished to do so, subject to the following conditions:
  62138. The above copyright notice and this permission notice shall be included in
  62139. all copies or substantial portions of the Software.
  62140. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  62141. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  62142. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  62143. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  62144. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  62145. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  62146. THE SOFTWARE.
  62147. <?php
  62148. /**
  62149. * phpDocumentor
  62150. *
  62151. * PHP Version 5.3
  62152. *
  62153. * @author Mike van Riel <mike.vanriel@naenius.com>
  62154. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  62155. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62156. * @link http://phpdoc.org
  62157. */
  62158. namespace phpDocumentor\Reflection;
  62159. use phpDocumentor\Reflection\DocBlock\Tag;
  62160. use phpDocumentor\Reflection\DocBlock\Context;
  62161. use phpDocumentor\Reflection\DocBlock\Location;
  62162. /**
  62163. * Parses the DocBlock for any structure.
  62164. *
  62165. * @author Mike van Riel <mike.vanriel@naenius.com>
  62166. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62167. * @link http://phpdoc.org
  62168. */
  62169. class DocBlock implements \Reflector
  62170. {
  62171. /** @var string The opening line for this docblock. */
  62172. protected $short_description = '';
  62173. /**
  62174. * @var DocBlock\Description The actual
  62175. * description for this docblock.
  62176. */
  62177. protected $long_description = null;
  62178. /**
  62179. * @var Tag[] An array containing all
  62180. * the tags in this docblock; except inline.
  62181. */
  62182. protected $tags = array();
  62183. /** @var Context Information about the context of this DocBlock. */
  62184. protected $context = null;
  62185. /** @var Location Information about the location of this DocBlock. */
  62186. protected $location = null;
  62187. /** @var bool Is this DocBlock (the start of) a template? */
  62188. protected $isTemplateStart = false;
  62189. /** @var bool Does this DocBlock signify the end of a DocBlock template? */
  62190. protected $isTemplateEnd = false;
  62191. /**
  62192. * Parses the given docblock and populates the member fields.
  62193. *
  62194. * The constructor may also receive namespace information such as the
  62195. * current namespace and aliases. This information is used by some tags
  62196. * (e.g. @return, @param, etc.) to turn a relative Type into a FQCN.
  62197. *
  62198. * @param \Reflector|string $docblock A docblock comment (including
  62199. * asterisks) or reflector supporting the getDocComment method.
  62200. * @param Context $context The context in which the DocBlock
  62201. * occurs.
  62202. * @param Location $location The location within the file that this
  62203. * DocBlock occurs in.
  62204. *
  62205. * @throws \InvalidArgumentException if the given argument does not have the
  62206. * getDocComment method.
  62207. */
  62208. public function __construct(
  62209. $docblock,
  62210. Context $context = null,
  62211. Location $location = null
  62212. ) {
  62213. if (is_object($docblock)) {
  62214. if (!method_exists($docblock, 'getDocComment')) {
  62215. throw new \InvalidArgumentException(
  62216. 'Invalid object passed; the given reflector must support '
  62217. . 'the getDocComment method'
  62218. );
  62219. }
  62220. $docblock = $docblock->getDocComment();
  62221. }
  62222. $docblock = $this->cleanInput($docblock);
  62223. list($templateMarker, $short, $long, $tags) = $this->splitDocBlock($docblock);
  62224. $this->isTemplateStart = $templateMarker === '#@+';
  62225. $this->isTemplateEnd = $templateMarker === '#@-';
  62226. $this->short_description = $short;
  62227. $this->long_description = new DocBlock\Description($long, $this);
  62228. $this->parseTags($tags);
  62229. $this->context = $context;
  62230. $this->location = $location;
  62231. }
  62232. /**
  62233. * Strips the asterisks from the DocBlock comment.
  62234. *
  62235. * @param string $comment String containing the comment text.
  62236. *
  62237. * @return string
  62238. */
  62239. protected function cleanInput($comment)
  62240. {
  62241. $comment = trim(
  62242. preg_replace(
  62243. '#[ \t]*(?:\/\*\*|\*\/|\*)?[ \t]{0,1}(.*)?#u',
  62244. '$1',
  62245. $comment
  62246. )
  62247. );
  62248. // reg ex above is not able to remove */ from a single line docblock
  62249. if (substr($comment, -2) == '*/') {
  62250. $comment = trim(substr($comment, 0, -2));
  62251. }
  62252. // normalize strings
  62253. $comment = str_replace(array("\r\n", "\r"), "\n", $comment);
  62254. return $comment;
  62255. }
  62256. /**
  62257. * Splits the DocBlock into a template marker, summary, description and block of tags.
  62258. *
  62259. * @param string $comment Comment to split into the sub-parts.
  62260. *
  62261. * @author Richard van Velzen (@_richardJ) Special thanks to Richard for the regex responsible for the split.
  62262. * @author Mike van Riel <me@mikevanriel.com> for extending the regex with template marker support.
  62263. *
  62264. * @return string[] containing the template marker (if any), summary, description and a string containing the tags.
  62265. */
  62266. protected function splitDocBlock($comment)
  62267. {
  62268. // Performance improvement cheat: if the first character is an @ then only tags are in this DocBlock. This
  62269. // method does not split tags so we return this verbatim as the fourth result (tags). This saves us the
  62270. // performance impact of running a regular expression
  62271. if (strpos($comment, '@') === 0) {
  62272. return array('', '', '', $comment);
  62273. }
  62274. // clears all extra horizontal whitespace from the line endings to prevent parsing issues
  62275. $comment = preg_replace('/\h*$/Sum', '', $comment);
  62276. /*
  62277. * Splits the docblock into a template marker, short description, long description and tags section
  62278. *
  62279. * - The template marker is empty, #@+ or #@- if the DocBlock starts with either of those (a newline may
  62280. * occur after it and will be stripped).
  62281. * - The short description is started from the first character until a dot is encountered followed by a
  62282. * newline OR two consecutive newlines (horizontal whitespace is taken into account to consider spacing
  62283. * errors). This is optional.
  62284. * - The long description, any character until a new line is encountered followed by an @ and word
  62285. * characters (a tag). This is optional.
  62286. * - Tags; the remaining characters
  62287. *
  62288. * Big thanks to RichardJ for contributing this Regular Expression
  62289. */
  62290. preg_match(
  62291. '/
  62292. \A
  62293. # 1. Extract the template marker
  62294. (?:(\#\@\+|\#\@\-)\n?)?
  62295. # 2. Extract the summary
  62296. (?:
  62297. (?! @\pL ) # The summary may not start with an @
  62298. (
  62299. [^\n.]+
  62300. (?:
  62301. (?! \. \n | \n{2} ) # End summary upon a dot followed by newline or two newlines
  62302. [\n.] (?! [ \t]* @\pL ) # End summary when an @ is found as first character on a new line
  62303. [^\n.]+ # Include anything else
  62304. )*
  62305. \.?
  62306. )?
  62307. )
  62308. # 3. Extract the description
  62309. (?:
  62310. \s* # Some form of whitespace _must_ precede a description because a summary must be there
  62311. (?! @\pL ) # The description may not start with an @
  62312. (
  62313. [^\n]+
  62314. (?: \n+
  62315. (?! [ \t]* @\pL ) # End description when an @ is found as first character on a new line
  62316. [^\n]+ # Include anything else
  62317. )*
  62318. )
  62319. )?
  62320. # 4. Extract the tags (anything that follows)
  62321. (\s+ [\s\S]*)? # everything that follows
  62322. /ux',
  62323. $comment,
  62324. $matches
  62325. );
  62326. array_shift($matches);
  62327. while (count($matches) < 4) {
  62328. $matches[] = '';
  62329. }
  62330. return $matches;
  62331. }
  62332. /**
  62333. * Creates the tag objects.
  62334. *
  62335. * @param string $tags Tag block to parse.
  62336. *
  62337. * @return void
  62338. */
  62339. protected function parseTags($tags)
  62340. {
  62341. $result = array();
  62342. $tags = trim($tags);
  62343. if ('' !== $tags) {
  62344. if ('@' !== $tags[0]) {
  62345. throw new \LogicException(
  62346. 'A tag block started with text instead of an actual tag,'
  62347. . ' this makes the tag block invalid: ' . $tags
  62348. );
  62349. }
  62350. foreach (explode("\n", $tags) as $tag_line) {
  62351. if (isset($tag_line[0]) && ($tag_line[0] === '@')) {
  62352. $result[] = $tag_line;
  62353. } else {
  62354. $result[count($result) - 1] .= "\n" . $tag_line;
  62355. }
  62356. }
  62357. // create proper Tag objects
  62358. foreach ($result as $key => $tag_line) {
  62359. $result[$key] = Tag::createInstance(trim($tag_line), $this);
  62360. }
  62361. }
  62362. $this->tags = $result;
  62363. }
  62364. /**
  62365. * Gets the text portion of the doc block.
  62366. *
  62367. * Gets the text portion (short and long description combined) of the doc
  62368. * block.
  62369. *
  62370. * @return string The text portion of the doc block.
  62371. */
  62372. public function getText()
  62373. {
  62374. $short = $this->getShortDescription();
  62375. $long = $this->getLongDescription()->getContents();
  62376. if ($long) {
  62377. return "{$short}\n\n{$long}";
  62378. } else {
  62379. return $short;
  62380. }
  62381. }
  62382. /**
  62383. * Set the text portion of the doc block.
  62384. *
  62385. * Sets the text portion (short and long description combined) of the doc
  62386. * block.
  62387. *
  62388. * @param string $docblock The new text portion of the doc block.
  62389. *
  62390. * @return $this This doc block.
  62391. */
  62392. public function setText($comment)
  62393. {
  62394. list(,$short, $long) = $this->splitDocBlock($comment);
  62395. $this->short_description = $short;
  62396. $this->long_description = new DocBlock\Description($long, $this);
  62397. return $this;
  62398. }
  62399. /**
  62400. * Returns the opening line or also known as short description.
  62401. *
  62402. * @return string
  62403. */
  62404. public function getShortDescription()
  62405. {
  62406. return $this->short_description;
  62407. }
  62408. /**
  62409. * Returns the full description or also known as long description.
  62410. *
  62411. * @return DocBlock\Description
  62412. */
  62413. public function getLongDescription()
  62414. {
  62415. return $this->long_description;
  62416. }
  62417. /**
  62418. * Returns whether this DocBlock is the start of a Template section.
  62419. *
  62420. * A Docblock may serve as template for a series of subsequent DocBlocks. This is indicated by a special marker
  62421. * (`#@+`) that is appended directly after the opening `/**` of a DocBlock.
  62422. *
  62423. * An example of such an opening is:
  62424. *
  62425. * ```
  62426. * /**#@+
  62427. * * My DocBlock
  62428. * * /
  62429. * ```
  62430. *
  62431. * The description and tags (not the summary!) are copied onto all subsequent DocBlocks and also applied to all
  62432. * elements that follow until another DocBlock is found that contains the closing marker (`#@-`).
  62433. *
  62434. * @see self::isTemplateEnd() for the check whether a closing marker was provided.
  62435. *
  62436. * @return boolean
  62437. */
  62438. public function isTemplateStart()
  62439. {
  62440. return $this->isTemplateStart;
  62441. }
  62442. /**
  62443. * Returns whether this DocBlock is the end of a Template section.
  62444. *
  62445. * @see self::isTemplateStart() for a more complete description of the Docblock Template functionality.
  62446. *
  62447. * @return boolean
  62448. */
  62449. public function isTemplateEnd()
  62450. {
  62451. return $this->isTemplateEnd;
  62452. }
  62453. /**
  62454. * Returns the current context.
  62455. *
  62456. * @return Context
  62457. */
  62458. public function getContext()
  62459. {
  62460. return $this->context;
  62461. }
  62462. /**
  62463. * Returns the current location.
  62464. *
  62465. * @return Location
  62466. */
  62467. public function getLocation()
  62468. {
  62469. return $this->location;
  62470. }
  62471. /**
  62472. * Returns the tags for this DocBlock.
  62473. *
  62474. * @return Tag[]
  62475. */
  62476. public function getTags()
  62477. {
  62478. return $this->tags;
  62479. }
  62480. /**
  62481. * Returns an array of tags matching the given name. If no tags are found
  62482. * an empty array is returned.
  62483. *
  62484. * @param string $name String to search by.
  62485. *
  62486. * @return Tag[]
  62487. */
  62488. public function getTagsByName($name)
  62489. {
  62490. $result = array();
  62491. /** @var Tag $tag */
  62492. foreach ($this->getTags() as $tag) {
  62493. if ($tag->getName() != $name) {
  62494. continue;
  62495. }
  62496. $result[] = $tag;
  62497. }
  62498. return $result;
  62499. }
  62500. /**
  62501. * Checks if a tag of a certain type is present in this DocBlock.
  62502. *
  62503. * @param string $name Tag name to check for.
  62504. *
  62505. * @return bool
  62506. */
  62507. public function hasTag($name)
  62508. {
  62509. /** @var Tag $tag */
  62510. foreach ($this->getTags() as $tag) {
  62511. if ($tag->getName() == $name) {
  62512. return true;
  62513. }
  62514. }
  62515. return false;
  62516. }
  62517. /**
  62518. * Appends a tag at the end of the list of tags.
  62519. *
  62520. * @param Tag $tag The tag to add.
  62521. *
  62522. * @return Tag The newly added tag.
  62523. *
  62524. * @throws \LogicException When the tag belongs to a different DocBlock.
  62525. */
  62526. public function appendTag(Tag $tag)
  62527. {
  62528. if (null === $tag->getDocBlock()) {
  62529. $tag->setDocBlock($this);
  62530. }
  62531. if ($tag->getDocBlock() === $this) {
  62532. $this->tags[] = $tag;
  62533. } else {
  62534. throw new \LogicException(
  62535. 'This tag belongs to a different DocBlock object.'
  62536. );
  62537. }
  62538. return $tag;
  62539. }
  62540. /**
  62541. * Builds a string representation of this object.
  62542. *
  62543. * @todo determine the exact format as used by PHP Reflection and
  62544. * implement it.
  62545. *
  62546. * @return string
  62547. * @codeCoverageIgnore Not yet implemented
  62548. */
  62549. public static function export()
  62550. {
  62551. throw new \Exception('Not yet implemented');
  62552. }
  62553. /**
  62554. * Returns the exported information (we should use the export static method
  62555. * BUT this throws an exception at this point).
  62556. *
  62557. * @return string
  62558. * @codeCoverageIgnore Not yet implemented
  62559. */
  62560. public function __toString()
  62561. {
  62562. return 'Not yet implemented';
  62563. }
  62564. }
  62565. <?php
  62566. /**
  62567. * phpDocumentor
  62568. *
  62569. * PHP Version 5.3
  62570. *
  62571. * @author Vasil Rangelov <boen.robot@gmail.com>
  62572. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  62573. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62574. * @link http://phpdoc.org
  62575. */
  62576. namespace phpDocumentor\Reflection\DocBlock;
  62577. /**
  62578. * The location a DocBlock occurs within a file.
  62579. *
  62580. * @author Vasil Rangelov <boen.robot@gmail.com>
  62581. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62582. * @link http://phpdoc.org
  62583. */
  62584. class Location
  62585. {
  62586. /** @var int Line where the DocBlock text starts. */
  62587. protected $lineNumber = 0;
  62588. /** @var int Column where the DocBlock text starts. */
  62589. protected $columnNumber = 0;
  62590. public function __construct(
  62591. $lineNumber = 0,
  62592. $columnNumber = 0
  62593. ) {
  62594. $this->setLineNumber($lineNumber)->setColumnNumber($columnNumber);
  62595. }
  62596. /**
  62597. * @return int Line where the DocBlock text starts.
  62598. */
  62599. public function getLineNumber()
  62600. {
  62601. return $this->lineNumber;
  62602. }
  62603. /**
  62604. *
  62605. * @param type $lineNumber
  62606. * @return $this
  62607. */
  62608. public function setLineNumber($lineNumber)
  62609. {
  62610. $this->lineNumber = (int)$lineNumber;
  62611. return $this;
  62612. }
  62613. /**
  62614. * @return int Column where the DocBlock text starts.
  62615. */
  62616. public function getColumnNumber()
  62617. {
  62618. return $this->columnNumber;
  62619. }
  62620. /**
  62621. *
  62622. * @param int $columnNumber
  62623. * @return $this
  62624. */
  62625. public function setColumnNumber($columnNumber)
  62626. {
  62627. $this->columnNumber = (int)$columnNumber;
  62628. return $this;
  62629. }
  62630. }
  62631. <?php
  62632. /**
  62633. * phpDocumentor
  62634. *
  62635. * PHP Version 5.3
  62636. *
  62637. * @author Vasil Rangelov <boen.robot@gmail.com>
  62638. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  62639. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62640. * @link http://phpdoc.org
  62641. */
  62642. namespace phpDocumentor\Reflection\DocBlock\Tag;
  62643. use phpDocumentor\Reflection\DocBlock\Tag\VersionTag;
  62644. /**
  62645. * Reflection class for a @since tag in a Docblock.
  62646. *
  62647. * @author Vasil Rangelov <boen.robot@gmail.com>
  62648. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62649. * @link http://phpdoc.org
  62650. */
  62651. class SinceTag extends VersionTag
  62652. {
  62653. }
  62654. <?php
  62655. /**
  62656. * phpDocumentor
  62657. *
  62658. * PHP Version 5.3
  62659. *
  62660. * @author Mike van Riel <mike.vanriel@naenius.com>
  62661. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  62662. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62663. * @link http://phpdoc.org
  62664. */
  62665. namespace phpDocumentor\Reflection\DocBlock\Tag;
  62666. use phpDocumentor\Reflection\DocBlock\Tag;
  62667. /**
  62668. * Reflection class for a @see tag in a Docblock.
  62669. *
  62670. * @author Mike van Riel <mike.vanriel@naenius.com>
  62671. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62672. * @link http://phpdoc.org
  62673. */
  62674. class SeeTag extends Tag
  62675. {
  62676. /** @var string */
  62677. protected $refers = null;
  62678. /**
  62679. * {@inheritdoc}
  62680. */
  62681. public function getContent()
  62682. {
  62683. if (null === $this->content) {
  62684. $this->content = "{$this->refers} {$this->description}";
  62685. }
  62686. return $this->content;
  62687. }
  62688. /**
  62689. * {@inheritdoc}
  62690. */
  62691. public function setContent($content)
  62692. {
  62693. parent::setContent($content);
  62694. $parts = preg_split('/\s+/Su', $this->description, 2);
  62695. // any output is considered a type
  62696. $this->refers = $parts[0];
  62697. $this->setDescription(isset($parts[1]) ? $parts[1] : '');
  62698. $this->content = $content;
  62699. return $this;
  62700. }
  62701. /**
  62702. * Gets the structural element this tag refers to.
  62703. *
  62704. * @return string
  62705. */
  62706. public function getReference()
  62707. {
  62708. return $this->refers;
  62709. }
  62710. /**
  62711. * Sets the structural element this tag refers to.
  62712. *
  62713. * @param string $refers The new type this tag refers to.
  62714. *
  62715. * @return $this
  62716. */
  62717. public function setReference($refers)
  62718. {
  62719. $this->refers = $refers;
  62720. $this->content = null;
  62721. return $this;
  62722. }
  62723. }
  62724. <?php
  62725. /**
  62726. * phpDocumentor
  62727. *
  62728. * PHP Version 5.3
  62729. *
  62730. * @author Vasil Rangelov <boen.robot@gmail.com>
  62731. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  62732. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62733. * @link http://phpdoc.org
  62734. */
  62735. namespace phpDocumentor\Reflection\DocBlock\Tag;
  62736. use phpDocumentor\Reflection\DocBlock\Tag;
  62737. /**
  62738. * Reflection class for a @version tag in a Docblock.
  62739. *
  62740. * @author Vasil Rangelov <boen.robot@gmail.com>
  62741. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62742. * @link http://phpdoc.org
  62743. */
  62744. class VersionTag extends Tag
  62745. {
  62746. /**
  62747. * PCRE regular expression matching a version vector.
  62748. * Assumes the "x" modifier.
  62749. */
  62750. const REGEX_VECTOR = '(?:
  62751. # Normal release vectors.
  62752. \d\S*
  62753. |
  62754. # VCS version vectors. Per PHPCS, they are expected to
  62755. # follow the form of the VCS name, followed by ":", followed
  62756. # by the version vector itself.
  62757. # By convention, popular VCSes like CVS, SVN and GIT use "$"
  62758. # around the actual version vector.
  62759. [^\s\:]+\:\s*\$[^\$]+\$
  62760. )';
  62761. /** @var string The version vector. */
  62762. protected $version = '';
  62763. public function getContent()
  62764. {
  62765. if (null === $this->content) {
  62766. $this->content = "{$this->version} {$this->description}";
  62767. }
  62768. return $this->content;
  62769. }
  62770. /**
  62771. * {@inheritdoc}
  62772. */
  62773. public function setContent($content)
  62774. {
  62775. parent::setContent($content);
  62776. if (preg_match(
  62777. '/^
  62778. # The version vector
  62779. (' . self::REGEX_VECTOR . ')
  62780. \s*
  62781. # The description
  62782. (.+)?
  62783. $/sux',
  62784. $this->description,
  62785. $matches
  62786. )) {
  62787. $this->version = $matches[1];
  62788. $this->setDescription(isset($matches[2]) ? $matches[2] : '');
  62789. $this->content = $content;
  62790. }
  62791. return $this;
  62792. }
  62793. /**
  62794. * Gets the version section of the tag.
  62795. *
  62796. * @return string The version section of the tag.
  62797. */
  62798. public function getVersion()
  62799. {
  62800. return $this->version;
  62801. }
  62802. /**
  62803. * Sets the version section of the tag.
  62804. *
  62805. * @param string $version The new version section of the tag.
  62806. * An invalid value will set an empty string.
  62807. *
  62808. * @return $this
  62809. */
  62810. public function setVersion($version)
  62811. {
  62812. $this->version
  62813. = preg_match('/^' . self::REGEX_VECTOR . '$/ux', $version)
  62814. ? $version
  62815. : '';
  62816. $this->content = null;
  62817. return $this;
  62818. }
  62819. }
  62820. <?php
  62821. /**
  62822. * phpDocumentor
  62823. *
  62824. * PHP Version 5.3
  62825. *
  62826. * @author Mike van Riel <mike.vanriel@naenius.com>
  62827. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  62828. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62829. * @link http://phpdoc.org
  62830. */
  62831. namespace phpDocumentor\Reflection\DocBlock\Tag;
  62832. /**
  62833. * Reflection class for a @property tag in a Docblock.
  62834. *
  62835. * @author Mike van Riel <mike.vanriel@naenius.com>
  62836. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62837. * @link http://phpdoc.org
  62838. */
  62839. class PropertyTag extends ParamTag
  62840. {
  62841. }
  62842. <?php
  62843. /**
  62844. * phpDocumentor
  62845. *
  62846. * PHP Version 5.3
  62847. *
  62848. * @author Mike van Riel <mike.vanriel@naenius.com>
  62849. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  62850. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62851. * @link http://phpdoc.org
  62852. */
  62853. namespace phpDocumentor\Reflection\DocBlock\Tag;
  62854. use phpDocumentor\Reflection\DocBlock\Tag;
  62855. use phpDocumentor\Reflection\DocBlock\Type\Collection;
  62856. /**
  62857. * Reflection class for a @return tag in a Docblock.
  62858. *
  62859. * @author Mike van Riel <mike.vanriel@naenius.com>
  62860. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62861. * @link http://phpdoc.org
  62862. */
  62863. class ReturnTag extends Tag
  62864. {
  62865. /** @var string The raw type component. */
  62866. protected $type = '';
  62867. /** @var Collection The parsed type component. */
  62868. protected $types = null;
  62869. /**
  62870. * {@inheritdoc}
  62871. */
  62872. public function getContent()
  62873. {
  62874. if (null === $this->content) {
  62875. $this->content = "{$this->type} {$this->description}";
  62876. }
  62877. return $this->content;
  62878. }
  62879. /**
  62880. * {@inheritdoc}
  62881. */
  62882. public function setContent($content)
  62883. {
  62884. parent::setContent($content);
  62885. $parts = preg_split('/\s+/Su', $this->description, 2);
  62886. // any output is considered a type
  62887. $this->type = $parts[0];
  62888. $this->types = null;
  62889. $this->setDescription(isset($parts[1]) ? $parts[1] : '');
  62890. $this->content = $content;
  62891. return $this;
  62892. }
  62893. /**
  62894. * Returns the unique types of the variable.
  62895. *
  62896. * @return string[]
  62897. */
  62898. public function getTypes()
  62899. {
  62900. return $this->getTypesCollection()->getArrayCopy();
  62901. }
  62902. /**
  62903. * Returns the type section of the variable.
  62904. *
  62905. * @return string
  62906. */
  62907. public function getType()
  62908. {
  62909. return (string) $this->getTypesCollection();
  62910. }
  62911. /**
  62912. * Returns the type collection.
  62913. *
  62914. * @return void
  62915. */
  62916. protected function getTypesCollection()
  62917. {
  62918. if (null === $this->types) {
  62919. $this->types = new Collection(
  62920. array($this->type),
  62921. $this->docblock ? $this->docblock->getContext() : null
  62922. );
  62923. }
  62924. return $this->types;
  62925. }
  62926. }
  62927. <?php
  62928. /**
  62929. * phpDocumentor
  62930. *
  62931. * PHP Version 5.3
  62932. *
  62933. * @author Vasil Rangelov <boen.robot@gmail.com>
  62934. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  62935. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62936. * @link http://phpdoc.org
  62937. */
  62938. namespace phpDocumentor\Reflection\DocBlock\Tag;
  62939. use phpDocumentor\Reflection\DocBlock\Tag\VersionTag;
  62940. /**
  62941. * Reflection class for a @deprecated tag in a Docblock.
  62942. *
  62943. * @author Vasil Rangelov <boen.robot@gmail.com>
  62944. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62945. * @link http://phpdoc.org
  62946. */
  62947. class DeprecatedTag extends VersionTag
  62948. {
  62949. }
  62950. <?php
  62951. /**
  62952. * phpDocumentor
  62953. *
  62954. * PHP Version 5.3
  62955. *
  62956. * @author Mike van Riel <mike.vanriel@naenius.com>
  62957. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  62958. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62959. * @link http://phpdoc.org
  62960. */
  62961. namespace phpDocumentor\Reflection\DocBlock\Tag;
  62962. /**
  62963. * Reflection class for a @throws tag in a Docblock.
  62964. *
  62965. * @author Mike van Riel <mike.vanriel@naenius.com>
  62966. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62967. * @link http://phpdoc.org
  62968. */
  62969. class ThrowsTag extends ReturnTag
  62970. {
  62971. }
  62972. <?php
  62973. /**
  62974. * phpDocumentor
  62975. *
  62976. * PHP Version 5.3
  62977. *
  62978. * @author Mike van Riel <mike.vanriel@naenius.com>
  62979. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  62980. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62981. * @link http://phpdoc.org
  62982. */
  62983. namespace phpDocumentor\Reflection\DocBlock\Tag;
  62984. /**
  62985. * Reflection class for a @covers tag in a Docblock.
  62986. *
  62987. * @author Mike van Riel <mike.vanriel@naenius.com>
  62988. * @license http://www.opensource.org/licenses/mit-license.php MIT
  62989. * @link http://phpdoc.org
  62990. */
  62991. class CoversTag extends SeeTag
  62992. {
  62993. }
  62994. <?php
  62995. /**
  62996. * phpDocumentor
  62997. *
  62998. * PHP Version 5.3
  62999. *
  63000. * @author Vasil Rangelov <boen.robot@gmail.com>
  63001. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  63002. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63003. * @link http://phpdoc.org
  63004. */
  63005. namespace phpDocumentor\Reflection\DocBlock\Tag;
  63006. use phpDocumentor\Reflection\DocBlock\Tag;
  63007. /**
  63008. * Reflection class for a @source tag in a Docblock.
  63009. *
  63010. * @author Vasil Rangelov <boen.robot@gmail.com>
  63011. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63012. * @link http://phpdoc.org
  63013. */
  63014. class SourceTag extends Tag
  63015. {
  63016. /**
  63017. * @var int The starting line, relative to the structural element's
  63018. * location.
  63019. */
  63020. protected $startingLine = 1;
  63021. /**
  63022. * @var int|null The number of lines, relative to the starting line. NULL
  63023. * means "to the end".
  63024. */
  63025. protected $lineCount = null;
  63026. /**
  63027. * {@inheritdoc}
  63028. */
  63029. public function getContent()
  63030. {
  63031. if (null === $this->content) {
  63032. $this->content
  63033. = "{$this->startingLine} {$this->lineCount} {$this->description}";
  63034. }
  63035. return $this->content;
  63036. }
  63037. /**
  63038. * {@inheritdoc}
  63039. */
  63040. public function setContent($content)
  63041. {
  63042. parent::setContent($content);
  63043. if (preg_match(
  63044. '/^
  63045. # Starting line
  63046. ([1-9]\d*)
  63047. \s*
  63048. # Number of lines
  63049. (?:
  63050. ((?1))
  63051. \s+
  63052. )?
  63053. # Description
  63054. (.*)
  63055. $/sux',
  63056. $this->description,
  63057. $matches
  63058. )) {
  63059. $this->startingLine = (int)$matches[1];
  63060. if (isset($matches[2]) && '' !== $matches[2]) {
  63061. $this->lineCount = (int)$matches[2];
  63062. }
  63063. $this->setDescription($matches[3]);
  63064. $this->content = $content;
  63065. }
  63066. return $this;
  63067. }
  63068. /**
  63069. * Gets the starting line.
  63070. *
  63071. * @return int The starting line, relative to the structural element's
  63072. * location.
  63073. */
  63074. public function getStartingLine()
  63075. {
  63076. return $this->startingLine;
  63077. }
  63078. /**
  63079. * Sets the starting line.
  63080. *
  63081. * @param int $startingLine The new starting line, relative to the
  63082. * structural element's location.
  63083. *
  63084. * @return $this
  63085. */
  63086. public function setStartingLine($startingLine)
  63087. {
  63088. $this->startingLine = $startingLine;
  63089. $this->content = null;
  63090. return $this;
  63091. }
  63092. /**
  63093. * Returns the number of lines.
  63094. *
  63095. * @return int|null The number of lines, relative to the starting line. NULL
  63096. * means "to the end".
  63097. */
  63098. public function getLineCount()
  63099. {
  63100. return $this->lineCount;
  63101. }
  63102. /**
  63103. * Sets the number of lines.
  63104. *
  63105. * @param int|null $lineCount The new number of lines, relative to the
  63106. * starting line. NULL means "to the end".
  63107. *
  63108. * @return $this
  63109. */
  63110. public function setLineCount($lineCount)
  63111. {
  63112. $this->lineCount = $lineCount;
  63113. $this->content = null;
  63114. return $this;
  63115. }
  63116. }
  63117. <?php
  63118. /**
  63119. * phpDocumentor
  63120. *
  63121. * PHP Version 5.3
  63122. *
  63123. * @author Mike van Riel <mike.vanriel@naenius.com>
  63124. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  63125. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63126. * @link http://phpdoc.org
  63127. */
  63128. namespace phpDocumentor\Reflection\DocBlock\Tag;
  63129. /**
  63130. * Reflection class for a @uses tag in a Docblock.
  63131. *
  63132. * @author Mike van Riel <mike.vanriel@naenius.com>
  63133. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63134. * @link http://phpdoc.org
  63135. */
  63136. class UsesTag extends SeeTag
  63137. {
  63138. }
  63139. <?php
  63140. /**
  63141. * phpDocumentor
  63142. *
  63143. * PHP Version 5.3
  63144. *
  63145. * @author Mike van Riel <mike.vanriel@naenius.com>
  63146. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  63147. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63148. * @link http://phpdoc.org
  63149. */
  63150. namespace phpDocumentor\Reflection\DocBlock\Tag;
  63151. use phpDocumentor\Reflection\DocBlock\Tag;
  63152. /**
  63153. * Reflection class for a @method in a Docblock.
  63154. *
  63155. * @author Mike van Riel <mike.vanriel@naenius.com>
  63156. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63157. * @link http://phpdoc.org
  63158. */
  63159. class MethodTag extends ReturnTag
  63160. {
  63161. /** @var string */
  63162. protected $method_name = '';
  63163. /** @var string */
  63164. protected $arguments = '';
  63165. /** @var bool */
  63166. protected $isStatic = false;
  63167. /**
  63168. * {@inheritdoc}
  63169. */
  63170. public function getContent()
  63171. {
  63172. if (null === $this->content) {
  63173. $this->content = '';
  63174. if ($this->isStatic) {
  63175. $this->content .= 'static ';
  63176. }
  63177. $this->content .= $this->type .
  63178. " {$this->method_name}({$this->arguments}) " .
  63179. $this->description;
  63180. }
  63181. return $this->content;
  63182. }
  63183. /**
  63184. * {@inheritdoc}
  63185. */
  63186. public function setContent($content)
  63187. {
  63188. Tag::setContent($content);
  63189. // 1. none or more whitespace
  63190. // 2. optionally the keyword "static" followed by whitespace
  63191. // 3. optionally a word with underscores followed by whitespace : as
  63192. // type for the return value
  63193. // 4. then optionally a word with underscores followed by () and
  63194. // whitespace : as method name as used by phpDocumentor
  63195. // 5. then a word with underscores, followed by ( and any character
  63196. // until a ) and whitespace : as method name with signature
  63197. // 6. any remaining text : as description
  63198. if (preg_match(
  63199. '/^
  63200. # Static keyword
  63201. # Declates a static method ONLY if type is also present
  63202. (?:
  63203. (static)
  63204. \s+
  63205. )?
  63206. # Return type
  63207. (?:
  63208. ([\w\|_\\\\]+)
  63209. \s+
  63210. )?
  63211. # Legacy method name (not captured)
  63212. (?:
  63213. [\w_]+\(\)\s+
  63214. )?
  63215. # Method name
  63216. ([\w\|_\\\\]+)
  63217. # Arguments
  63218. \(([^\)]*)\)
  63219. \s*
  63220. # Description
  63221. (.*)
  63222. $/sux',
  63223. $this->description,
  63224. $matches
  63225. )) {
  63226. list(
  63227. ,
  63228. $static,
  63229. $this->type,
  63230. $this->method_name,
  63231. $this->arguments,
  63232. $this->description
  63233. ) = $matches;
  63234. if ($static) {
  63235. if (!$this->type) {
  63236. $this->type = 'static';
  63237. } else {
  63238. $this->isStatic = true;
  63239. }
  63240. } else {
  63241. if (!$this->type) {
  63242. $this->type = 'void';
  63243. }
  63244. }
  63245. $this->parsedDescription = null;
  63246. }
  63247. return $this;
  63248. }
  63249. /**
  63250. * Sets the name of this method.
  63251. *
  63252. * @param string $method_name The name of the method.
  63253. *
  63254. * @return $this
  63255. */
  63256. public function setMethodName($method_name)
  63257. {
  63258. $this->method_name = $method_name;
  63259. $this->content = null;
  63260. return $this;
  63261. }
  63262. /**
  63263. * Retrieves the method name.
  63264. *
  63265. * @return string
  63266. */
  63267. public function getMethodName()
  63268. {
  63269. return $this->method_name;
  63270. }
  63271. /**
  63272. * Sets the arguments for this method.
  63273. *
  63274. * @param string $arguments A comma-separated arguments line.
  63275. *
  63276. * @return void
  63277. */
  63278. public function setArguments($arguments)
  63279. {
  63280. $this->arguments = $arguments;
  63281. $this->content = null;
  63282. return $this;
  63283. }
  63284. /**
  63285. * Returns an array containing each argument as array of type and name.
  63286. *
  63287. * Please note that the argument sub-array may only contain 1 element if no
  63288. * type was specified.
  63289. *
  63290. * @return string[]
  63291. */
  63292. public function getArguments()
  63293. {
  63294. if (empty($this->arguments)) {
  63295. return array();
  63296. }
  63297. $arguments = explode(',', $this->arguments);
  63298. foreach ($arguments as $key => $value) {
  63299. $arguments[$key] = explode(' ', trim($value));
  63300. }
  63301. return $arguments;
  63302. }
  63303. /**
  63304. * Checks whether the method tag describes a static method or not.
  63305. *
  63306. * @return bool TRUE if the method declaration is for a static method, FALSE
  63307. * otherwise.
  63308. */
  63309. public function isStatic()
  63310. {
  63311. return $this->isStatic;
  63312. }
  63313. /**
  63314. * Sets a new value for whether the method is static or not.
  63315. *
  63316. * @param bool $isStatic The new value to set.
  63317. *
  63318. * @return $this
  63319. */
  63320. public function setIsStatic($isStatic)
  63321. {
  63322. $this->isStatic = $isStatic;
  63323. $this->content = null;
  63324. return $this;
  63325. }
  63326. }
  63327. <?php
  63328. /**
  63329. * phpDocumentor
  63330. *
  63331. * PHP Version 5.3
  63332. *
  63333. * @author Mike van Riel <mike.vanriel@naenius.com>
  63334. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  63335. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63336. * @link http://phpdoc.org
  63337. */
  63338. namespace phpDocumentor\Reflection\DocBlock\Tag;
  63339. /**
  63340. * Reflection class for a @property-read tag in a Docblock.
  63341. *
  63342. * @author Mike van Riel <mike.vanriel@naenius.com>
  63343. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63344. * @link http://phpdoc.org
  63345. */
  63346. class PropertyReadTag extends PropertyTag
  63347. {
  63348. }
  63349. <?php
  63350. /**
  63351. * phpDocumentor
  63352. *
  63353. * PHP Version 5.3
  63354. *
  63355. * @author Vasil Rangelov <boen.robot@gmail.com>
  63356. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  63357. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63358. * @link http://phpdoc.org
  63359. */
  63360. namespace phpDocumentor\Reflection\DocBlock\Tag;
  63361. use phpDocumentor\Reflection\DocBlock\Tag;
  63362. /**
  63363. * Reflection class for an @author tag in a Docblock.
  63364. *
  63365. * @author Mike van Riel <mike.vanriel@naenius.com>
  63366. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63367. * @link http://phpdoc.org
  63368. */
  63369. class AuthorTag extends Tag
  63370. {
  63371. /**
  63372. * PCRE regular expression matching any valid value for the name component.
  63373. */
  63374. const REGEX_AUTHOR_NAME = '[^\<]*';
  63375. /**
  63376. * PCRE regular expression matching any valid value for the email component.
  63377. */
  63378. const REGEX_AUTHOR_EMAIL = '[^\>]*';
  63379. /** @var string The name of the author */
  63380. protected $authorName = '';
  63381. /** @var string The email of the author */
  63382. protected $authorEmail = '';
  63383. public function getContent()
  63384. {
  63385. if (null === $this->content) {
  63386. $this->content = $this->authorName;
  63387. if ('' != $this->authorEmail) {
  63388. $this->content .= "<{$this->authorEmail}>";
  63389. }
  63390. }
  63391. return $this->content;
  63392. }
  63393. /**
  63394. * {@inheritdoc}
  63395. */
  63396. public function setContent($content)
  63397. {
  63398. parent::setContent($content);
  63399. if (preg_match(
  63400. '/^(' . self::REGEX_AUTHOR_NAME .
  63401. ')(\<(' . self::REGEX_AUTHOR_EMAIL .
  63402. ')\>)?$/u',
  63403. $this->description,
  63404. $matches
  63405. )) {
  63406. $this->authorName = trim($matches[1]);
  63407. if (isset($matches[3])) {
  63408. $this->authorEmail = trim($matches[3]);
  63409. }
  63410. }
  63411. return $this;
  63412. }
  63413. /**
  63414. * Gets the author's name.
  63415. *
  63416. * @return string The author's name.
  63417. */
  63418. public function getAuthorName()
  63419. {
  63420. return $this->authorName;
  63421. }
  63422. /**
  63423. * Sets the author's name.
  63424. *
  63425. * @param string $authorName The new author name.
  63426. * An invalid value will set an empty string.
  63427. *
  63428. * @return $this
  63429. */
  63430. public function setAuthorName($authorName)
  63431. {
  63432. $this->content = null;
  63433. $this->authorName
  63434. = preg_match('/^' . self::REGEX_AUTHOR_NAME . '$/u', $authorName)
  63435. ? $authorName : '';
  63436. return $this;
  63437. }
  63438. /**
  63439. * Gets the author's email.
  63440. *
  63441. * @return string The author's email.
  63442. */
  63443. public function getAuthorEmail()
  63444. {
  63445. return $this->authorEmail;
  63446. }
  63447. /**
  63448. * Sets the author's email.
  63449. *
  63450. * @param string $authorEmail The new author email.
  63451. * An invalid value will set an empty string.
  63452. *
  63453. * @return $this
  63454. */
  63455. public function setAuthorEmail($authorEmail)
  63456. {
  63457. $this->authorEmail
  63458. = preg_match('/^' . self::REGEX_AUTHOR_EMAIL . '$/u', $authorEmail)
  63459. ? $authorEmail : '';
  63460. $this->content = null;
  63461. return $this;
  63462. }
  63463. }
  63464. <?php
  63465. /**
  63466. * phpDocumentor
  63467. *
  63468. * PHP Version 5.3
  63469. *
  63470. * @author Mike van Riel <mike.vanriel@naenius.com>
  63471. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  63472. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63473. * @link http://phpdoc.org
  63474. */
  63475. namespace phpDocumentor\Reflection\DocBlock\Tag;
  63476. /**
  63477. * Reflection class for a @var tag in a Docblock.
  63478. *
  63479. * @author Mike van Riel <mike.vanriel@naenius.com>
  63480. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63481. * @link http://phpdoc.org
  63482. */
  63483. class VarTag extends ParamTag
  63484. {
  63485. }
  63486. <?php
  63487. /**
  63488. * phpDocumentor
  63489. *
  63490. * PHP Version 5.3
  63491. *
  63492. * @author Ben Selby <benmatselby@gmail.com>
  63493. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  63494. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63495. * @link http://phpdoc.org
  63496. */
  63497. namespace phpDocumentor\Reflection\DocBlock\Tag;
  63498. use phpDocumentor\Reflection\DocBlock\Tag;
  63499. /**
  63500. * Reflection class for a @link tag in a Docblock.
  63501. *
  63502. * @author Ben Selby <benmatselby@gmail.com>
  63503. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63504. * @link http://phpdoc.org
  63505. */
  63506. class LinkTag extends Tag
  63507. {
  63508. /** @var string */
  63509. protected $link = '';
  63510. /**
  63511. * {@inheritdoc}
  63512. */
  63513. public function getContent()
  63514. {
  63515. if (null === $this->content) {
  63516. $this->content = "{$this->link} {$this->description}";
  63517. }
  63518. return $this->content;
  63519. }
  63520. /**
  63521. * {@inheritdoc}
  63522. */
  63523. public function setContent($content)
  63524. {
  63525. parent::setContent($content);
  63526. $parts = preg_split('/\s+/Su', $this->description, 2);
  63527. $this->link = $parts[0];
  63528. $this->setDescription(isset($parts[1]) ? $parts[1] : $parts[0]);
  63529. $this->content = $content;
  63530. return $this;
  63531. }
  63532. /**
  63533. * Gets the link
  63534. *
  63535. * @return string
  63536. */
  63537. public function getLink()
  63538. {
  63539. return $this->link;
  63540. }
  63541. /**
  63542. * Sets the link
  63543. *
  63544. * @param string $link The link
  63545. *
  63546. * @return $this
  63547. */
  63548. public function setLink($link)
  63549. {
  63550. $this->link = $link;
  63551. $this->content = null;
  63552. return $this;
  63553. }
  63554. }
  63555. <?php
  63556. /**
  63557. * phpDocumentor
  63558. *
  63559. * PHP Version 5.3
  63560. *
  63561. * @author Vasil Rangelov <boen.robot@gmail.com>
  63562. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  63563. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63564. * @link http://phpdoc.org
  63565. */
  63566. namespace phpDocumentor\Reflection\DocBlock\Tag;
  63567. use phpDocumentor\Reflection\DocBlock\Tag;
  63568. /**
  63569. * Reflection class for a @example tag in a Docblock.
  63570. *
  63571. * @author Vasil Rangelov <boen.robot@gmail.com>
  63572. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63573. * @link http://phpdoc.org
  63574. */
  63575. class ExampleTag extends SourceTag
  63576. {
  63577. /**
  63578. * @var string Path to a file to use as an example.
  63579. * May also be an absolute URI.
  63580. */
  63581. protected $filePath = '';
  63582. /**
  63583. * @var bool Whether the file path component represents an URI.
  63584. * This determines how the file portion appears at {@link getContent()}.
  63585. */
  63586. protected $isURI = false;
  63587. /**
  63588. * {@inheritdoc}
  63589. */
  63590. public function getContent()
  63591. {
  63592. if (null === $this->content) {
  63593. $filePath = '';
  63594. if ($this->isURI) {
  63595. if (false === strpos($this->filePath, ':')) {
  63596. $filePath = str_replace(
  63597. '%2F',
  63598. '/',
  63599. rawurlencode($this->filePath)
  63600. );
  63601. } else {
  63602. $filePath = $this->filePath;
  63603. }
  63604. } else {
  63605. $filePath = '"' . $this->filePath . '"';
  63606. }
  63607. $this->content = $filePath . ' ' . parent::getContent();
  63608. }
  63609. return $this->content;
  63610. }
  63611. /**
  63612. * {@inheritdoc}
  63613. */
  63614. public function setContent($content)
  63615. {
  63616. Tag::setContent($content);
  63617. if (preg_match(
  63618. '/^
  63619. # File component
  63620. (?:
  63621. # File path in quotes
  63622. \"([^\"]+)\"
  63623. |
  63624. # File URI
  63625. (\S+)
  63626. )
  63627. # Remaining content (parsed by SourceTag)
  63628. (?:\s+(.*))?
  63629. $/sux',
  63630. $this->description,
  63631. $matches
  63632. )) {
  63633. if ('' !== $matches[1]) {
  63634. $this->setFilePath($matches[1]);
  63635. } else {
  63636. $this->setFileURI($matches[2]);
  63637. }
  63638. if (isset($matches[3])) {
  63639. parent::setContent($matches[3]);
  63640. } else {
  63641. $this->setDescription('');
  63642. }
  63643. $this->content = $content;
  63644. }
  63645. return $this;
  63646. }
  63647. /**
  63648. * Returns the file path.
  63649. *
  63650. * @return string Path to a file to use as an example.
  63651. * May also be an absolute URI.
  63652. */
  63653. public function getFilePath()
  63654. {
  63655. return $this->filePath;
  63656. }
  63657. /**
  63658. * Sets the file path.
  63659. *
  63660. * @param string $filePath The new file path to use for the example.
  63661. *
  63662. * @return $this
  63663. */
  63664. public function setFilePath($filePath)
  63665. {
  63666. $this->isURI = false;
  63667. $this->filePath = trim($filePath);
  63668. $this->content = null;
  63669. return $this;
  63670. }
  63671. /**
  63672. * Sets the file path as an URI.
  63673. *
  63674. * This function is equivalent to {@link setFilePath()}, except that it
  63675. * convers an URI to a file path before that.
  63676. *
  63677. * There is no getFileURI(), as {@link getFilePath()} is compatible.
  63678. *
  63679. * @param type $uri The new file URI to use as an example.
  63680. */
  63681. public function setFileURI($uri)
  63682. {
  63683. $this->isURI = true;
  63684. if (false === strpos($uri, ':')) {
  63685. //Relative URL
  63686. $this->filePath = rawurldecode(
  63687. str_replace(array('/', '\\'), '%2F', $uri)
  63688. );
  63689. } else {
  63690. //Absolute URL or URI.
  63691. $this->filePath = $uri;
  63692. }
  63693. $this->content = null;
  63694. return $this;
  63695. }
  63696. }
  63697. <?php
  63698. /**
  63699. * phpDocumentor
  63700. *
  63701. * PHP Version 5.3
  63702. *
  63703. * @author Mike van Riel <mike.vanriel@naenius.com>
  63704. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  63705. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63706. * @link http://phpdoc.org
  63707. */
  63708. namespace phpDocumentor\Reflection\DocBlock\Tag;
  63709. use phpDocumentor\Reflection\DocBlock\Tag;
  63710. /**
  63711. * Reflection class for a @param tag in a Docblock.
  63712. *
  63713. * @author Mike van Riel <mike.vanriel@naenius.com>
  63714. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63715. * @link http://phpdoc.org
  63716. */
  63717. class ParamTag extends ReturnTag
  63718. {
  63719. /** @var string */
  63720. protected $variableName = '';
  63721. /** @var bool determines whether this is a variadic argument */
  63722. protected $isVariadic = false;
  63723. /**
  63724. * {@inheritdoc}
  63725. */
  63726. public function getContent()
  63727. {
  63728. if (null === $this->content) {
  63729. $this->content
  63730. = "{$this->type} {$this->variableName} {$this->description}";
  63731. }
  63732. return $this->content;
  63733. }
  63734. /**
  63735. * {@inheritdoc}
  63736. */
  63737. public function setContent($content)
  63738. {
  63739. Tag::setContent($content);
  63740. $parts = preg_split(
  63741. '/(\s+)/Su',
  63742. $this->description,
  63743. 3,
  63744. PREG_SPLIT_DELIM_CAPTURE
  63745. );
  63746. // if the first item that is encountered is not a variable; it is a type
  63747. if (isset($parts[0])
  63748. && (strlen($parts[0]) > 0)
  63749. && ($parts[0][0] !== '$')
  63750. ) {
  63751. $this->type = array_shift($parts);
  63752. array_shift($parts);
  63753. }
  63754. // if the next item starts with a $ or ...$ it must be the variable name
  63755. if (isset($parts[0])
  63756. && (strlen($parts[0]) > 0)
  63757. && ($parts[0][0] == '$' || substr($parts[0], 0, 4) === '...$')
  63758. ) {
  63759. $this->variableName = array_shift($parts);
  63760. array_shift($parts);
  63761. if (substr($this->variableName, 0, 3) === '...') {
  63762. $this->isVariadic = true;
  63763. $this->variableName = substr($this->variableName, 3);
  63764. }
  63765. }
  63766. $this->setDescription(implode('', $parts));
  63767. $this->content = $content;
  63768. return $this;
  63769. }
  63770. /**
  63771. * Returns the variable's name.
  63772. *
  63773. * @return string
  63774. */
  63775. public function getVariableName()
  63776. {
  63777. return $this->variableName;
  63778. }
  63779. /**
  63780. * Sets the variable's name.
  63781. *
  63782. * @param string $name The new name for this variable.
  63783. *
  63784. * @return $this
  63785. */
  63786. public function setVariableName($name)
  63787. {
  63788. $this->variableName = $name;
  63789. $this->content = null;
  63790. return $this;
  63791. }
  63792. /**
  63793. * Returns whether this tag is variadic.
  63794. *
  63795. * @return boolean
  63796. */
  63797. public function isVariadic()
  63798. {
  63799. return $this->isVariadic;
  63800. }
  63801. }
  63802. <?php
  63803. /**
  63804. * phpDocumentor
  63805. *
  63806. * PHP Version 5.3
  63807. *
  63808. * @author Mike van Riel <mike.vanriel@naenius.com>
  63809. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  63810. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63811. * @link http://phpdoc.org
  63812. */
  63813. namespace phpDocumentor\Reflection\DocBlock\Tag;
  63814. /**
  63815. * Reflection class for a @property-write tag in a Docblock.
  63816. *
  63817. * @author Mike van Riel <mike.vanriel@naenius.com>
  63818. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63819. * @link http://phpdoc.org
  63820. */
  63821. class PropertyWriteTag extends PropertyTag
  63822. {
  63823. }
  63824. <?php
  63825. /**
  63826. * phpDocumentor
  63827. *
  63828. * PHP Version 5.3
  63829. *
  63830. * @author Barry vd. Heuvel <barryvdh@gmail.com>
  63831. * @copyright 2013 Mike van Riel / Naenius (http://www.naenius.com)
  63832. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63833. * @link http://phpdoc.org
  63834. */
  63835. namespace phpDocumentor\Reflection\DocBlock;
  63836. use phpDocumentor\Reflection\DocBlock;
  63837. /**
  63838. * Serializes a DocBlock instance.
  63839. *
  63840. * @author Barry vd. Heuvel <barryvdh@gmail.com>
  63841. * @license http://www.opensource.org/licenses/mit-license.php MIT
  63842. * @link http://phpdoc.org
  63843. */
  63844. class Serializer
  63845. {
  63846. /** @var string The string to indent the comment with. */
  63847. protected $indentString = ' ';
  63848. /** @var int The number of times the indent string is repeated. */
  63849. protected $indent = 0;
  63850. /** @var bool Whether to indent the first line. */
  63851. protected $isFirstLineIndented = true;
  63852. /** @var int|null The max length of a line. */
  63853. protected $lineLength = null;
  63854. /**
  63855. * Create a Serializer instance.
  63856. *
  63857. * @param int $indent The number of times the indent string is
  63858. * repeated.
  63859. * @param string $indentString The string to indent the comment with.
  63860. * @param bool $indentFirstLine Whether to indent the first line.
  63861. * @param int|null $lineLength The max length of a line or NULL to
  63862. * disable line wrapping.
  63863. */
  63864. public function __construct(
  63865. $indent = 0,
  63866. $indentString = ' ',
  63867. $indentFirstLine = true,
  63868. $lineLength = null
  63869. ) {
  63870. $this->setIndentationString($indentString);
  63871. $this->setIndent($indent);
  63872. $this->setIsFirstLineIndented($indentFirstLine);
  63873. $this->setLineLength($lineLength);
  63874. }
  63875. /**
  63876. * Sets the string to indent comments with.
  63877. *
  63878. * @param string $indentationString The string to indent comments with.
  63879. *
  63880. * @return $this This serializer object.
  63881. */
  63882. public function setIndentationString($indentString)
  63883. {
  63884. $this->indentString = (string)$indentString;
  63885. return $this;
  63886. }
  63887. /**
  63888. * Gets the string to indent comments with.
  63889. *
  63890. * @return string The indent string.
  63891. */
  63892. public function getIndentationString()
  63893. {
  63894. return $this->indentString;
  63895. }
  63896. /**
  63897. * Sets the number of indents.
  63898. *
  63899. * @param int $indent The number of times the indent string is repeated.
  63900. *
  63901. * @return $this This serializer object.
  63902. */
  63903. public function setIndent($indent)
  63904. {
  63905. $this->indent = (int)$indent;
  63906. return $this;
  63907. }
  63908. /**
  63909. * Gets the number of indents.
  63910. *
  63911. * @return int The number of times the indent string is repeated.
  63912. */
  63913. public function getIndent()
  63914. {
  63915. return $this->indent;
  63916. }
  63917. /**
  63918. * Sets whether or not the first line should be indented.
  63919. *
  63920. * Sets whether or not the first line (the one with the "/**") should be
  63921. * indented.
  63922. *
  63923. * @param bool $indentFirstLine The new value for this setting.
  63924. *
  63925. * @return $this This serializer object.
  63926. */
  63927. public function setIsFirstLineIndented($indentFirstLine)
  63928. {
  63929. $this->isFirstLineIndented = (bool)$indentFirstLine;
  63930. return $this;
  63931. }
  63932. /**
  63933. * Gets whether or not the first line should be indented.
  63934. *
  63935. * @return bool Whether or not the first line should be indented.
  63936. */
  63937. public function isFirstLineIndented()
  63938. {
  63939. return $this->isFirstLineIndented;
  63940. }
  63941. /**
  63942. * Sets the line length.
  63943. *
  63944. * Sets the length of each line in the serialization. Content will be
  63945. * wrapped within this limit.
  63946. *
  63947. * @param int|null $lineLength The length of each line. NULL to disable line
  63948. * wrapping altogether.
  63949. *
  63950. * @return $this This serializer object.
  63951. */
  63952. public function setLineLength($lineLength)
  63953. {
  63954. $this->lineLength = null === $lineLength ? null : (int)$lineLength;
  63955. return $this;
  63956. }
  63957. /**
  63958. * Gets the line length.
  63959. *
  63960. * @return int|null The length of each line or NULL if line wrapping is
  63961. * disabled.
  63962. */
  63963. public function getLineLength()
  63964. {
  63965. return $this->lineLength;
  63966. }
  63967. /**
  63968. * Generate a DocBlock comment.
  63969. *
  63970. * @param DocBlock The DocBlock to serialize.
  63971. *
  63972. * @return string The serialized doc block.
  63973. */
  63974. public function getDocComment(DocBlock $docblock)
  63975. {
  63976. $indent = str_repeat($this->indentString, $this->indent);
  63977. $firstIndent = $this->isFirstLineIndented ? $indent : '';
  63978. $text = $docblock->getText();
  63979. if ($this->lineLength) {
  63980. //3 === strlen(' * ')
  63981. $wrapLength = $this->lineLength - strlen($indent) - 3;
  63982. $text = wordwrap($text, $wrapLength);
  63983. }
  63984. $text = str_replace("\n", "\n{$indent} * ", $text);
  63985. $comment = "{$firstIndent}/**\n{$indent} * {$text}\n{$indent} *\n";
  63986. /** @var Tag $tag */
  63987. foreach ($docblock->getTags() as $tag) {
  63988. $tagText = (string) $tag;
  63989. if ($this->lineLength) {
  63990. $tagText = wordwrap($tagText, $wrapLength);
  63991. }
  63992. $tagText = str_replace("\n", "\n{$indent} * ", $tagText);
  63993. $comment .= "{$indent} * {$tagText}\n";
  63994. }
  63995. $comment .= $indent . ' */';
  63996. return $comment;
  63997. }
  63998. }
  63999. <?php
  64000. /**
  64001. * phpDocumentor
  64002. *
  64003. * PHP Version 5.3
  64004. *
  64005. * @author Vasil Rangelov <boen.robot@gmail.com>
  64006. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64007. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64008. * @link http://phpdoc.org
  64009. */
  64010. namespace phpDocumentor\Reflection\DocBlock;
  64011. /**
  64012. * The context in which a DocBlock occurs.
  64013. *
  64014. * @author Vasil Rangelov <boen.robot@gmail.com>
  64015. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64016. * @link http://phpdoc.org
  64017. */
  64018. class Context
  64019. {
  64020. /** @var string The current namespace. */
  64021. protected $namespace = '';
  64022. /** @var array List of namespace aliases => Fully Qualified Namespace. */
  64023. protected $namespace_aliases = array();
  64024. /** @var string Name of the structural element, within the namespace. */
  64025. protected $lsen = '';
  64026. /**
  64027. * Cteates a new context.
  64028. * @param string $namespace The namespace where this DocBlock
  64029. * resides in.
  64030. * @param array $namespace_aliases List of namespace aliases => Fully
  64031. * Qualified Namespace.
  64032. * @param string $lsen Name of the structural element, within
  64033. * the namespace.
  64034. */
  64035. public function __construct(
  64036. $namespace = '',
  64037. array $namespace_aliases = array(),
  64038. $lsen = ''
  64039. ) {
  64040. if (!empty($namespace)) {
  64041. $this->setNamespace($namespace);
  64042. }
  64043. $this->setNamespaceAliases($namespace_aliases);
  64044. $this->setLSEN($lsen);
  64045. }
  64046. /**
  64047. * @return string The namespace where this DocBlock resides in.
  64048. */
  64049. public function getNamespace()
  64050. {
  64051. return $this->namespace;
  64052. }
  64053. /**
  64054. * @return array List of namespace aliases => Fully Qualified Namespace.
  64055. */
  64056. public function getNamespaceAliases()
  64057. {
  64058. return $this->namespace_aliases;
  64059. }
  64060. /**
  64061. * Returns the Local Structural Element Name.
  64062. *
  64063. * @return string Name of the structural element, within the namespace.
  64064. */
  64065. public function getLSEN()
  64066. {
  64067. return $this->lsen;
  64068. }
  64069. /**
  64070. * Sets a new namespace.
  64071. *
  64072. * Sets a new namespace for the context. Leading and trailing slashes are
  64073. * trimmed, and the keywords "global" and "default" are treated as aliases
  64074. * to no namespace.
  64075. *
  64076. * @param string $namespace The new namespace to set.
  64077. *
  64078. * @return $this
  64079. */
  64080. public function setNamespace($namespace)
  64081. {
  64082. if ('global' !== $namespace
  64083. && 'default' !== $namespace
  64084. ) {
  64085. // Srip leading and trailing slash
  64086. $this->namespace = trim((string)$namespace, '\\');
  64087. } else {
  64088. $this->namespace = '';
  64089. }
  64090. return $this;
  64091. }
  64092. /**
  64093. * Sets the namespace aliases, replacing all previous ones.
  64094. *
  64095. * @param array $namespace_aliases List of namespace aliases => Fully
  64096. * Qualified Namespace.
  64097. *
  64098. * @return $this
  64099. */
  64100. public function setNamespaceAliases(array $namespace_aliases)
  64101. {
  64102. $this->namespace_aliases = array();
  64103. foreach ($namespace_aliases as $alias => $fqnn) {
  64104. $this->setNamespaceAlias($alias, $fqnn);
  64105. }
  64106. return $this;
  64107. }
  64108. /**
  64109. * Adds a namespace alias to the context.
  64110. *
  64111. * @param string $alias The alias name (the part after "as", or the last
  64112. * part of the Fully Qualified Namespace Name) to add.
  64113. * @param string $fqnn The Fully Qualified Namespace Name for this alias.
  64114. * Any form of leading/trailing slashes are accepted, but what will be
  64115. * stored is a name, prefixed with a slash, and no trailing slash.
  64116. *
  64117. * @return $this
  64118. */
  64119. public function setNamespaceAlias($alias, $fqnn)
  64120. {
  64121. $this->namespace_aliases[$alias] = '\\' . trim((string)$fqnn, '\\');
  64122. return $this;
  64123. }
  64124. /**
  64125. * Sets a new Local Structural Element Name.
  64126. *
  64127. * Sets a new Local Structural Element Name. A local name also contains
  64128. * punctuation determining the kind of structural element (e.g. trailing "("
  64129. * and ")" for functions and methods).
  64130. *
  64131. * @param string $lsen The new local name of a structural element.
  64132. *
  64133. * @return $this
  64134. */
  64135. public function setLSEN($lsen)
  64136. {
  64137. $this->lsen = (string)$lsen;
  64138. return $this;
  64139. }
  64140. }
  64141. <?php
  64142. /**
  64143. * phpDocumentor
  64144. *
  64145. * PHP Version 5.3
  64146. *
  64147. * @author Mike van Riel <mike.vanriel@naenius.com>
  64148. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64149. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64150. * @link http://phpdoc.org
  64151. */
  64152. namespace phpDocumentor\Reflection\DocBlock\Type;
  64153. use phpDocumentor\Reflection\DocBlock\Context;
  64154. /**
  64155. * Collection
  64156. *
  64157. * @author Mike van Riel <mike.vanriel@naenius.com>
  64158. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64159. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64160. * @link http://phpdoc.org
  64161. */
  64162. class Collection extends \ArrayObject
  64163. {
  64164. /** @var string Definition of the OR operator for types */
  64165. const OPERATOR_OR = '|';
  64166. /** @var string Definition of the ARRAY operator for types */
  64167. const OPERATOR_ARRAY = '[]';
  64168. /** @var string Definition of the NAMESPACE operator in PHP */
  64169. const OPERATOR_NAMESPACE = '\\';
  64170. /** @var string[] List of recognized keywords */
  64171. protected static $keywords = array(
  64172. 'string', 'int', 'integer', 'bool', 'boolean', 'float', 'double',
  64173. 'object', 'mixed', 'array', 'resource', 'void', 'null', 'scalar',
  64174. 'callback', 'callable', 'false', 'true', 'self', '$this', 'static'
  64175. );
  64176. /**
  64177. * Current invoking location.
  64178. *
  64179. * This is used to prepend to type with a relative location.
  64180. * May also be 'default' or 'global', in which case they are ignored.
  64181. *
  64182. * @var Context
  64183. */
  64184. protected $context = null;
  64185. /**
  64186. * Registers the namespace and aliases; uses that to add and expand the
  64187. * given types.
  64188. *
  64189. * @param string[] $types Array containing a list of types to add to this
  64190. * container.
  64191. * @param Context $location The current invoking location.
  64192. */
  64193. public function __construct(
  64194. array $types = array(),
  64195. Context $context = null
  64196. ) {
  64197. $this->context = null === $context ? new Context() : $context;
  64198. foreach ($types as $type) {
  64199. $this->add($type);
  64200. }
  64201. }
  64202. /**
  64203. * Returns the current invoking location.
  64204. *
  64205. * @return Context
  64206. */
  64207. public function getContext()
  64208. {
  64209. return $this->context;
  64210. }
  64211. /**
  64212. * Adds a new type to the collection and expands it if it contains a
  64213. * relative namespace.
  64214. *
  64215. * If a class in the type contains a relative namespace than this collection
  64216. * will try to expand that into a FQCN.
  64217. *
  64218. * @param string $type A 'Type' as defined in the phpDocumentor
  64219. * documentation.
  64220. *
  64221. * @throws \InvalidArgumentException if a non-string argument is passed.
  64222. *
  64223. * @see http://phpdoc.org/docs/latest/for-users/types.html for the
  64224. * definition of a type.
  64225. *
  64226. * @return void
  64227. */
  64228. public function add($type)
  64229. {
  64230. if (!is_string($type)) {
  64231. throw new \InvalidArgumentException(
  64232. 'A type should be represented by a string, received: '
  64233. .var_export($type, true)
  64234. );
  64235. }
  64236. // separate the type by the OR operator
  64237. $type_parts = explode(self::OPERATOR_OR, $type);
  64238. foreach ($type_parts as $part) {
  64239. $expanded_type = $this->expand($part);
  64240. if ($expanded_type) {
  64241. $this[] = $expanded_type;
  64242. }
  64243. }
  64244. }
  64245. /**
  64246. * Returns a string representation of the collection.
  64247. *
  64248. * @return string The resolved types across the collection, separated with
  64249. * {@link self::OPERATOR_OR}.
  64250. */
  64251. public function __toString()
  64252. {
  64253. return implode(self::OPERATOR_OR, $this->getArrayCopy());
  64254. }
  64255. /**
  64256. * Analyzes the given type and returns the FQCN variant.
  64257. *
  64258. * When a type is provided this method checks whether it is not a keyword or
  64259. * Fully Qualified Class Name. If so it will use the given namespace and
  64260. * aliases to expand the type to a FQCN representation.
  64261. *
  64262. * This method only works as expected if the namespace and aliases are set;
  64263. * no dynamic reflection is being performed here.
  64264. *
  64265. * @param string $type The relative or absolute type.
  64266. *
  64267. * @uses getNamespace to determine with what to prefix the type name.
  64268. * @uses getNamespaceAliases to check whether the first part of the relative
  64269. * type name should not be replaced with another namespace.
  64270. *
  64271. * @return string
  64272. */
  64273. protected function expand($type)
  64274. {
  64275. $type = trim($type);
  64276. if (!$type) {
  64277. return '';
  64278. }
  64279. if ($this->isTypeAnArray($type)) {
  64280. return $this->expand(substr($type, 0, -2)) . self::OPERATOR_ARRAY;
  64281. }
  64282. if ($this->isRelativeType($type) && !$this->isTypeAKeyword($type)) {
  64283. $type_parts = explode(self::OPERATOR_NAMESPACE, $type, 2);
  64284. $namespace_aliases = $this->context->getNamespaceAliases();
  64285. // if the first segment is not an alias; prepend namespace name and
  64286. // return
  64287. if (!isset($namespace_aliases[$type_parts[0]])) {
  64288. $namespace = $this->context->getNamespace();
  64289. if ('' !== $namespace) {
  64290. $namespace .= self::OPERATOR_NAMESPACE;
  64291. }
  64292. return self::OPERATOR_NAMESPACE . $namespace . $type;
  64293. }
  64294. $type_parts[0] = $namespace_aliases[$type_parts[0]];
  64295. $type = implode(self::OPERATOR_NAMESPACE, $type_parts);
  64296. }
  64297. return $type;
  64298. }
  64299. /**
  64300. * Detects whether the given type represents an array.
  64301. *
  64302. * @param string $type A relative or absolute type as defined in the
  64303. * phpDocumentor documentation.
  64304. *
  64305. * @return bool
  64306. */
  64307. protected function isTypeAnArray($type)
  64308. {
  64309. return substr($type, -2) === self::OPERATOR_ARRAY;
  64310. }
  64311. /**
  64312. * Detects whether the given type represents a PHPDoc keyword.
  64313. *
  64314. * @param string $type A relative or absolute type as defined in the
  64315. * phpDocumentor documentation.
  64316. *
  64317. * @return bool
  64318. */
  64319. protected function isTypeAKeyword($type)
  64320. {
  64321. return in_array(strtolower($type), static::$keywords, true);
  64322. }
  64323. /**
  64324. * Detects whether the given type represents a relative or absolute path.
  64325. *
  64326. * This method will detect keywords as being absolute; even though they are
  64327. * not preceeded by a namespace separator.
  64328. *
  64329. * @param string $type A relative or absolute type as defined in the
  64330. * phpDocumentor documentation.
  64331. *
  64332. * @return bool
  64333. */
  64334. protected function isRelativeType($type)
  64335. {
  64336. return ($type[0] !== self::OPERATOR_NAMESPACE)
  64337. || $this->isTypeAKeyword($type);
  64338. }
  64339. }
  64340. <?php
  64341. /**
  64342. * phpDocumentor
  64343. *
  64344. * PHP Version 5.3
  64345. *
  64346. * @author Mike van Riel <mike.vanriel@naenius.com>
  64347. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64348. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64349. * @link http://phpdoc.org
  64350. */
  64351. namespace phpDocumentor\Reflection\DocBlock;
  64352. use phpDocumentor\Reflection\DocBlock;
  64353. /**
  64354. * Parses a tag definition for a DocBlock.
  64355. *
  64356. * @author Mike van Riel <mike.vanriel@naenius.com>
  64357. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64358. * @link http://phpdoc.org
  64359. */
  64360. class Tag implements \Reflector
  64361. {
  64362. /**
  64363. * PCRE regular expression matching a tag name.
  64364. */
  64365. const REGEX_TAGNAME = '[\w\-\_\\\\]+';
  64366. /** @var string Name of the tag */
  64367. protected $tag = '';
  64368. /**
  64369. * @var string|null Content of the tag.
  64370. * When set to NULL, it means it needs to be regenerated.
  64371. */
  64372. protected $content = '';
  64373. /** @var string Description of the content of this tag */
  64374. protected $description = '';
  64375. /**
  64376. * @var array|null The description, as an array of strings and Tag objects.
  64377. * When set to NULL, it means it needs to be regenerated.
  64378. */
  64379. protected $parsedDescription = null;
  64380. /** @var Location Location of the tag. */
  64381. protected $location = null;
  64382. /** @var DocBlock The DocBlock which this tag belongs to. */
  64383. protected $docblock = null;
  64384. /**
  64385. * @var array An array with a tag as a key, and an FQCN to a class that
  64386. * handles it as an array value. The class is expected to inherit this
  64387. * class.
  64388. */
  64389. private static $tagHandlerMappings = array(
  64390. 'author'
  64391. => '\phpDocumentor\Reflection\DocBlock\Tag\AuthorTag',
  64392. 'covers'
  64393. => '\phpDocumentor\Reflection\DocBlock\Tag\CoversTag',
  64394. 'deprecated'
  64395. => '\phpDocumentor\Reflection\DocBlock\Tag\DeprecatedTag',
  64396. 'example'
  64397. => '\phpDocumentor\Reflection\DocBlock\Tag\ExampleTag',
  64398. 'link'
  64399. => '\phpDocumentor\Reflection\DocBlock\Tag\LinkTag',
  64400. 'method'
  64401. => '\phpDocumentor\Reflection\DocBlock\Tag\MethodTag',
  64402. 'param'
  64403. => '\phpDocumentor\Reflection\DocBlock\Tag\ParamTag',
  64404. 'property-read'
  64405. => '\phpDocumentor\Reflection\DocBlock\Tag\PropertyReadTag',
  64406. 'property'
  64407. => '\phpDocumentor\Reflection\DocBlock\Tag\PropertyTag',
  64408. 'property-write'
  64409. => '\phpDocumentor\Reflection\DocBlock\Tag\PropertyWriteTag',
  64410. 'return'
  64411. => '\phpDocumentor\Reflection\DocBlock\Tag\ReturnTag',
  64412. 'see'
  64413. => '\phpDocumentor\Reflection\DocBlock\Tag\SeeTag',
  64414. 'since'
  64415. => '\phpDocumentor\Reflection\DocBlock\Tag\SinceTag',
  64416. 'source'
  64417. => '\phpDocumentor\Reflection\DocBlock\Tag\SourceTag',
  64418. 'throw'
  64419. => '\phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag',
  64420. 'throws'
  64421. => '\phpDocumentor\Reflection\DocBlock\Tag\ThrowsTag',
  64422. 'uses'
  64423. => '\phpDocumentor\Reflection\DocBlock\Tag\UsesTag',
  64424. 'var'
  64425. => '\phpDocumentor\Reflection\DocBlock\Tag\VarTag',
  64426. 'version'
  64427. => '\phpDocumentor\Reflection\DocBlock\Tag\VersionTag'
  64428. );
  64429. /**
  64430. * Factory method responsible for instantiating the correct sub type.
  64431. *
  64432. * @param string $tag_line The text for this tag, including description.
  64433. * @param DocBlock $docblock The DocBlock which this tag belongs to.
  64434. * @param Location $location Location of the tag.
  64435. *
  64436. * @throws \InvalidArgumentException if an invalid tag line was presented.
  64437. *
  64438. * @return static A new tag object.
  64439. */
  64440. final public static function createInstance(
  64441. $tag_line,
  64442. DocBlock $docblock = null,
  64443. Location $location = null
  64444. ) {
  64445. if (!preg_match(
  64446. '/^@(' . self::REGEX_TAGNAME . ')(?:\s*([^\s].*)|$)?/us',
  64447. $tag_line,
  64448. $matches
  64449. )) {
  64450. throw new \InvalidArgumentException(
  64451. 'Invalid tag_line detected: ' . $tag_line
  64452. );
  64453. }
  64454. $handler = __CLASS__;
  64455. if (isset(self::$tagHandlerMappings[$matches[1]])) {
  64456. $handler = self::$tagHandlerMappings[$matches[1]];
  64457. } elseif (isset($docblock)) {
  64458. $tagName = (string)new Type\Collection(
  64459. array($matches[1]),
  64460. $docblock->getContext()
  64461. );
  64462. if (isset(self::$tagHandlerMappings[$tagName])) {
  64463. $handler = self::$tagHandlerMappings[$tagName];
  64464. }
  64465. }
  64466. return new $handler(
  64467. $matches[1],
  64468. isset($matches[2]) ? $matches[2] : '',
  64469. $docblock,
  64470. $location
  64471. );
  64472. }
  64473. /**
  64474. * Registers a handler for tags.
  64475. *
  64476. * Registers a handler for tags. The class specified is autoloaded if it's
  64477. * not available. It must inherit from this class.
  64478. *
  64479. * @param string $tag Name of tag to regiser a handler for. When
  64480. * registering a namespaced tag, the full name, along with a prefixing
  64481. * slash MUST be provided.
  64482. * @param string|null $handler FQCN of handler. Specifing NULL removes the
  64483. * handler for the specified tag, if any.
  64484. *
  64485. * @return bool TRUE on success, FALSE on failure.
  64486. */
  64487. final public static function registerTagHandler($tag, $handler)
  64488. {
  64489. $tag = trim((string)$tag);
  64490. if (null === $handler) {
  64491. unset(self::$tagHandlerMappings[$tag]);
  64492. return true;
  64493. }
  64494. if ('' !== $tag
  64495. && class_exists($handler, true)
  64496. && is_subclass_of($handler, __CLASS__)
  64497. && !strpos($tag, '\\') //Accept no slash, and 1st slash at offset 0.
  64498. ) {
  64499. self::$tagHandlerMappings[$tag] = $handler;
  64500. return true;
  64501. }
  64502. return false;
  64503. }
  64504. /**
  64505. * Parses a tag and populates the member variables.
  64506. *
  64507. * @param string $name Name of the tag.
  64508. * @param string $content The contents of the given tag.
  64509. * @param DocBlock $docblock The DocBlock which this tag belongs to.
  64510. * @param Location $location Location of the tag.
  64511. */
  64512. public function __construct(
  64513. $name,
  64514. $content,
  64515. DocBlock $docblock = null,
  64516. Location $location = null
  64517. ) {
  64518. $this
  64519. ->setName($name)
  64520. ->setContent($content)
  64521. ->setDocBlock($docblock)
  64522. ->setLocation($location);
  64523. }
  64524. /**
  64525. * Gets the name of this tag.
  64526. *
  64527. * @return string The name of this tag.
  64528. */
  64529. public function getName()
  64530. {
  64531. return $this->tag;
  64532. }
  64533. /**
  64534. * Sets the name of this tag.
  64535. *
  64536. * @param string $name The new name of this tag.
  64537. *
  64538. * @return $this
  64539. * @throws \InvalidArgumentException When an invalid tag name is provided.
  64540. */
  64541. public function setName($name)
  64542. {
  64543. if (!preg_match('/^' . self::REGEX_TAGNAME . '$/u', $name)) {
  64544. throw new \InvalidArgumentException(
  64545. 'Invalid tag name supplied: ' . $name
  64546. );
  64547. }
  64548. $this->tag = $name;
  64549. return $this;
  64550. }
  64551. /**
  64552. * Gets the content of this tag.
  64553. *
  64554. * @return string
  64555. */
  64556. public function getContent()
  64557. {
  64558. if (null === $this->content) {
  64559. $this->content = $this->description;
  64560. }
  64561. return $this->content;
  64562. }
  64563. /**
  64564. * Sets the content of this tag.
  64565. *
  64566. * @param string $content The new content of this tag.
  64567. *
  64568. * @return $this
  64569. */
  64570. public function setContent($content)
  64571. {
  64572. $this->setDescription($content);
  64573. $this->content = $content;
  64574. return $this;
  64575. }
  64576. /**
  64577. * Gets the description component of this tag.
  64578. *
  64579. * @return string
  64580. */
  64581. public function getDescription()
  64582. {
  64583. return $this->description;
  64584. }
  64585. /**
  64586. * Sets the description component of this tag.
  64587. *
  64588. * @param string $description The new description component of this tag.
  64589. *
  64590. * @return $this
  64591. */
  64592. public function setDescription($description)
  64593. {
  64594. $this->content = null;
  64595. $this->parsedDescription = null;
  64596. $this->description = trim($description);
  64597. return $this;
  64598. }
  64599. /**
  64600. * Gets the parsed text of this description.
  64601. *
  64602. * @return array An array of strings and tag objects, in the order they
  64603. * occur within the description.
  64604. */
  64605. public function getParsedDescription()
  64606. {
  64607. if (null === $this->parsedDescription) {
  64608. $description = new Description($this->description, $this->docblock);
  64609. $this->parsedDescription = $description->getParsedContents();
  64610. }
  64611. return $this->parsedDescription;
  64612. }
  64613. /**
  64614. * Gets the docblock this tag belongs to.
  64615. *
  64616. * @return DocBlock The docblock this tag belongs to.
  64617. */
  64618. public function getDocBlock()
  64619. {
  64620. return $this->docblock;
  64621. }
  64622. /**
  64623. * Sets the docblock this tag belongs to.
  64624. *
  64625. * @param DocBlock $docblock The new docblock this tag belongs to. Setting
  64626. * NULL removes any association.
  64627. *
  64628. * @return $this
  64629. */
  64630. public function setDocBlock(DocBlock $docblock = null)
  64631. {
  64632. $this->docblock = $docblock;
  64633. return $this;
  64634. }
  64635. /**
  64636. * Gets the location of the tag.
  64637. *
  64638. * @return Location The tag's location.
  64639. */
  64640. public function getLocation()
  64641. {
  64642. return $this->location;
  64643. }
  64644. /**
  64645. * Sets the location of the tag.
  64646. *
  64647. * @param Location $location The new location of the tag.
  64648. *
  64649. * @return $this
  64650. */
  64651. public function setLocation(Location $location = null)
  64652. {
  64653. $this->location = $location;
  64654. return $this;
  64655. }
  64656. /**
  64657. * Builds a string representation of this object.
  64658. *
  64659. * @todo determine the exact format as used by PHP Reflection and implement it.
  64660. *
  64661. * @return void
  64662. * @codeCoverageIgnore Not yet implemented
  64663. */
  64664. public static function export()
  64665. {
  64666. throw new \Exception('Not yet implemented');
  64667. }
  64668. /**
  64669. * Returns the tag as a serialized string
  64670. *
  64671. * @return string
  64672. */
  64673. public function __toString()
  64674. {
  64675. return "@{$this->getName()} {$this->getContent()}";
  64676. }
  64677. }
  64678. <?php
  64679. /**
  64680. * phpDocumentor
  64681. *
  64682. * PHP Version 5.3
  64683. *
  64684. * @author Mike van Riel <mike.vanriel@naenius.com>
  64685. * @copyright 2010-2011 Mike van Riel / Naenius (http://www.naenius.com)
  64686. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64687. * @link http://phpdoc.org
  64688. */
  64689. namespace phpDocumentor\Reflection\DocBlock;
  64690. use phpDocumentor\Reflection\DocBlock;
  64691. /**
  64692. * Parses a Description of a DocBlock or tag.
  64693. *
  64694. * @author Mike van Riel <mike.vanriel@naenius.com>
  64695. * @license http://www.opensource.org/licenses/mit-license.php MIT
  64696. * @link http://phpdoc.org
  64697. */
  64698. class Description implements \Reflector
  64699. {
  64700. /** @var string */
  64701. protected $contents = '';
  64702. /** @var array The contents, as an array of strings and Tag objects. */
  64703. protected $parsedContents = null;
  64704. /** @var DocBlock The DocBlock which this description belongs to. */
  64705. protected $docblock = null;
  64706. /**
  64707. * Populates the fields of a description.
  64708. *
  64709. * @param string $content The description's conetnts.
  64710. * @param DocBlock $docblock The DocBlock which this description belongs to.
  64711. */
  64712. public function __construct($content, DocBlock $docblock = null)
  64713. {
  64714. $this->setContent($content)->setDocBlock($docblock);
  64715. }
  64716. /**
  64717. * Gets the text of this description.
  64718. *
  64719. * @return string
  64720. */
  64721. public function getContents()
  64722. {
  64723. return $this->contents;
  64724. }
  64725. /**
  64726. * Sets the text of this description.
  64727. *
  64728. * @param string $content The new text of this description.
  64729. *
  64730. * @return $this
  64731. */
  64732. public function setContent($content)
  64733. {
  64734. $this->contents = trim($content);
  64735. $this->parsedContents = null;
  64736. return $this;
  64737. }
  64738. /**
  64739. * Returns the parsed text of this description.
  64740. *
  64741. * @return array An array of strings and tag objects, in the order they
  64742. * occur within the description.
  64743. */
  64744. public function getParsedContents()
  64745. {
  64746. if (null === $this->parsedContents) {
  64747. $this->parsedContents = preg_split(
  64748. '/\{
  64749. # "{@}" is not a valid inline tag. This ensures that
  64750. # we do not treat it as one, but treat it literally.
  64751. (?!@\})
  64752. # We want to capture the whole tag line, but without the
  64753. # inline tag delimiters.
  64754. (\@
  64755. # Match everything up to the next delimiter.
  64756. [^{}]*
  64757. # Nested inline tag content should not be captured, or
  64758. # it will appear in the result separately.
  64759. (?:
  64760. # Match nested inline tags.
  64761. (?:
  64762. # Because we did not catch the tag delimiters
  64763. # earlier, we must be explicit with them here.
  64764. # Notice that this also matches "{}", as a way
  64765. # to later introduce it as an escape sequence.
  64766. \{(?1)?\}
  64767. |
  64768. # Make sure we match hanging "{".
  64769. \{
  64770. )
  64771. # Match content after the nested inline tag.
  64772. [^{}]*
  64773. )* # If there are more inline tags, match them as well.
  64774. # We use "*" since there may not be any nested inline
  64775. # tags.
  64776. )
  64777. \}/Sux',
  64778. $this->contents,
  64779. null,
  64780. PREG_SPLIT_DELIM_CAPTURE
  64781. );
  64782. $count = count($this->parsedContents);
  64783. for ($i=1; $i<$count; $i += 2) {
  64784. $this->parsedContents[$i] = Tag::createInstance(
  64785. $this->parsedContents[$i],
  64786. $this->docblock
  64787. );
  64788. }
  64789. //In order to allow "literal" inline tags, the otherwise invalid
  64790. //sequence "{@}" is changed to "@", and "{}" is changed to "}".
  64791. //See unit tests for examples.
  64792. for ($i=0; $i<$count; $i += 2) {
  64793. $this->parsedContents[$i] = str_replace(
  64794. array('{@}', '{}'),
  64795. array('@', '}'),
  64796. $this->parsedContents[$i]
  64797. );
  64798. }
  64799. }
  64800. return $this->parsedContents;
  64801. }
  64802. /**
  64803. * Return a formatted variant of the Long Description using MarkDown.
  64804. *
  64805. * @todo this should become a more intelligent piece of code where the
  64806. * configuration contains a setting what format long descriptions are.
  64807. *
  64808. * @codeCoverageIgnore Will be removed soon, in favor of adapters at
  64809. * PhpDocumentor itself that will process text in various formats.
  64810. *
  64811. * @return string
  64812. */
  64813. public function getFormattedContents()
  64814. {
  64815. $result = $this->contents;
  64816. // if the long description contains a plain HTML <code> element, surround
  64817. // it with a pre element. Please note that we explicitly used str_replace
  64818. // and not preg_replace to gain performance
  64819. if (strpos($result, '<code>') !== false) {
  64820. $result = str_replace(
  64821. array('<code>', "<code>\r\n", "<code>\n", "<code>\r", '</code>'),
  64822. array('<pre><code>', '<code>', '<code>', '<code>', '</code></pre>'),
  64823. $result
  64824. );
  64825. }
  64826. if (class_exists('Parsedown')) {
  64827. $markdown = \Parsedown::instance();
  64828. $result = $markdown->parse($result);
  64829. } elseif (class_exists('dflydev\markdown\MarkdownExtraParser')) {
  64830. $markdown = new \dflydev\markdown\MarkdownExtraParser();
  64831. $result = $markdown->transformMarkdown($result);
  64832. }
  64833. return trim($result);
  64834. }
  64835. /**
  64836. * Gets the docblock this tag belongs to.
  64837. *
  64838. * @return DocBlock The docblock this description belongs to.
  64839. */
  64840. public function getDocBlock()
  64841. {
  64842. return $this->docblock;
  64843. }
  64844. /**
  64845. * Sets the docblock this tag belongs to.
  64846. *
  64847. * @param DocBlock $docblock The new docblock this description belongs to.
  64848. * Setting NULL removes any association.
  64849. *
  64850. * @return $this
  64851. */
  64852. public function setDocBlock(DocBlock $docblock = null)
  64853. {
  64854. $this->docblock = $docblock;
  64855. return $this;
  64856. }
  64857. /**
  64858. * Builds a string representation of this object.
  64859. *
  64860. * @todo determine the exact format as used by PHP Reflection
  64861. * and implement it.
  64862. *
  64863. * @return void
  64864. * @codeCoverageIgnore Not yet implemented
  64865. */
  64866. public static function export()
  64867. {
  64868. throw new \Exception('Not yet implemented');
  64869. }
  64870. /**
  64871. * Returns the long description as a string.
  64872. *
  64873. * @return string
  64874. */
  64875. public function __toString()
  64876. {
  64877. return $this->getContents();
  64878. }
  64879. }
  64880. Version
  64881. Copyright (c) 2013-2015, Sebastian Bergmann <sebastian@phpunit.de>.
  64882. All rights reserved.
  64883. Redistribution and use in source and binary forms, with or without
  64884. modification, are permitted provided that the following conditions
  64885. are met:
  64886. * Redistributions of source code must retain the above copyright
  64887. notice, this list of conditions and the following disclaimer.
  64888. * Redistributions in binary form must reproduce the above copyright
  64889. notice, this list of conditions and the following disclaimer in
  64890. the documentation and/or other materials provided with the
  64891. distribution.
  64892. * Neither the name of Sebastian Bergmann nor the names of his
  64893. contributors may be used to endorse or promote products derived
  64894. from this software without specific prior written permission.
  64895. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  64896. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  64897. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  64898. FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  64899. COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  64900. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  64901. BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  64902. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  64903. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  64904. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  64905. ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  64906. POSSIBILITY OF SUCH DAMAGE.
  64907. <?php
  64908. /*
  64909. * This file is part of the Version package.
  64910. *
  64911. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  64912. *
  64913. * For the full copyright and license information, please view the LICENSE
  64914. * file that was distributed with this source code.
  64915. */
  64916. namespace SebastianBergmann;
  64917. /**
  64918. * @since Class available since Release 1.0.0
  64919. */
  64920. class Version
  64921. {
  64922. private $path;
  64923. private $release;
  64924. private $version;
  64925. /**
  64926. * @param string $release
  64927. * @param string $path
  64928. */
  64929. public function __construct($release, $path)
  64930. {
  64931. $this->release = $release;
  64932. $this->path = $path;
  64933. }
  64934. /**
  64935. * @return string
  64936. */
  64937. public function getVersion()
  64938. {
  64939. if ($this->version === null) {
  64940. if (count(explode('.', $this->release)) == 3) {
  64941. $this->version = $this->release;
  64942. } else {
  64943. $this->version = $this->release . '-dev';
  64944. }
  64945. $git = $this->getGitInformation($this->path);
  64946. if ($git) {
  64947. if (count(explode('.', $this->release)) == 3) {
  64948. $this->version = $git;
  64949. } else {
  64950. $git = explode('-', $git);
  64951. $this->version = $this->release . '-' . end($git);
  64952. }
  64953. }
  64954. }
  64955. return $this->version;
  64956. }
  64957. /**
  64958. * @param string $path
  64959. * @return bool|string
  64960. */
  64961. private function getGitInformation($path)
  64962. {
  64963. if (!is_dir($path . DIRECTORY_SEPARATOR . '.git')) {
  64964. return false;
  64965. }
  64966. $dir = getcwd();
  64967. chdir($path);
  64968. $returnCode = 1;
  64969. $result = @exec('git describe --tags 2>&1', $output, $returnCode);
  64970. chdir($dir);
  64971. if ($returnCode !== 0) {
  64972. return false;
  64973. }
  64974. return $result;
  64975. }
  64976. }
  64977. °=ä�kheÕ§ÃQ·Ú¼B¡í¡e{�#xça›{â[�Òg¿éì~<Þã(݆Hðn©º�1ÅÃÜeM±uÈ[���GBMB